Added information about commodore formats

This commit is contained in:
2015-03-25 02:19:24 +00:00
parent a110d79c87
commit 712ac67072
52 changed files with 24638 additions and 0 deletions

52
Commodore/64LAN.TXT Normal file
View File

@@ -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 64LAN<41>IDBLOCK<43><4B><EFBFBD>
0010: 73 64 66 67 73 66 20 20 20 20 20 20 20 20 20 20 sdfgsf<73><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 0D 0A 30 38 30 31 2C 44 33 45 42 0D 0A 20 20 20 <20><>0801,D3EB<45><42><EFBFBD><EFBFBD><EFBFBD>
0030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 20 20 20 20 0D 0A 20 20 20 20 20 20 20 20 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 20 20 20 20 20 20 20 20 20 20 20 20 20 0D 0A 1A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 09 65 FF FF FF FF FF 01 00 00 00 00 00 00 00 00 <20>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0100: 0E 08 E9 03 9E 20 28 32 30 36 34 29 00 00 00 78 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(2064)<29><><EFBFBD>x
Bytes: $00-0F: 64LAN file signature ("64LAN IDBLOCK ", with <CR><LF>)
10-21: 16-byte filename of contained C64 file, with <CR><LF>.
Filename padded with $20 (spaces!)
22-2C: Starting and ending HEX load addresses, with <CR><LF>
2D-55: 39-byte comment #1, with <CR><LF>
56-7E: 39-byte comment #2, with <CR><LF>
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 <CR> and <LF> 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.

82
Commodore/64NET.TXT Normal file
View File

@@ -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<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 31 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
20: 35 58 58 20 2D 3E 20 36 34 4E 45 54 00 00 00 00 5XX<58>-><3E>64NET<45><54><EFBFBD><EFBFBD>
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
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".

59
Commodore/ARC.TXT Normal file
View File

@@ -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 ..<2E><>G.<2E>.<2E>P.A<>:!<21>
0010: 00 01 FE 00 02 FE 03 02 A9 00 20 90 FF A9 02 A6 <20>.<2E><>.<2E>..<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
0020: BA A0 01 20 BA FF A9 04 A2 35 A0 02 20 BD FF A2 <20><>.<2E><><EFBFBD><EFBFBD>.<2E>5<EFBFBD>.<2E><><EFBFBD><EFBFBD>
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.

136
Commodore/ARK-SRK.TXT Normal file
View File

@@ -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 .<2E><>BOOT<4F><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 82 F1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E><><EFBFBD>
0020: 53 55 50 45 52 20 4B 4F 4E 47 A0 A0 A0 A0 A0 A0 SUPER<45>KONG<4E><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 00 00 00 79 00 82 FB 41 54 4F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>y<EFBFBD><79><EFBFBD>ATO
0040: 4D 49 43 20 48 41 4E 44 42 41 4C 4C A0 00 00 00 MIC<49>HANDBALL<4C><4C><EFBFBD><EFBFBD>
0050: 00 00 00 00 00 00 0F 00 82 FE 58 45 52 4F 4E 53 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E><><EFBFBD>XERONS
0060: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 00 00 00 2A 00 82 FF 57 45 54 20 50 41 49 4E 54 <20><><EFBFBD>*<2A><><EFBFBD>WET<45>PAINT
0080: A0 A0 A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 12 00 82 5A 47 52 4F 55 4E 44 20 53 4E 49 50 45 .<2E><>ZGROUND<4E>SNIPE
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.

111
Commodore/BINARY.TXT Normal file
View File

@@ -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 ....<2E>.<2E><>(2064)<29><>
0010: 00 78 A2 FF 9A A0 00 84 01 A2 CC BD 57 08 9D 33 <20>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>̽W.<2E>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

40
Commodore/BITMAP.TXT Normal file
View File

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

58
Commodore/C128BOOT.TXT Normal file
View File

@@ -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<42><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɀ<EFBFBD><C980><EFBFBD>
0010: 5F FF A9 05 8D 06 D5 A9 4E 8D 00 FF 4C 00 0C 00 _<><5F><EFBFBD><EFBFBD><EFBFBD>թN<D5A9><4E><EFBFBD>L<EFBFBD><4C><EFBFBD>
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

55
Commodore/C64S_FRZ.TXT Normal file
View File

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

779
Commodore/CBMFS Normal file
View File

@@ -0,0 +1,779 @@
<!DOCTYPE html>
<html lang="en" dir="ltr" class="client-nojs">
<head>
<title>CBMFS - Just Solve the File Format Problem</title>
<meta charset="UTF-8" />
<meta name="generator" content="MediaWiki 1.19.2" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch_desc.php" title="Just Solve the File Format Problem (en)" />
<link rel="EditURI" type="application/rsd+xml" href="http://fileformats.archiveteam.org/api.php?action=rsd" />
<link rel="copyright" href="http://creativecommons.org/publicdomain/zero/1.0/" />
<link rel="alternate" type="application/atom+xml" title="Just Solve the File Format Problem Atom feed" href="/index.php?title=Special:RecentChanges&amp;feed=atom" />
<link rel="stylesheet" href="http://fileformats.archiveteam.org/load.php?debug=false&amp;lang=en&amp;modules=mediawiki.legacy.commonPrint%2Cshared%7Cskins.vector&amp;only=styles&amp;skin=vector&amp;*" />
<meta name="ResourceLoaderDynamicStyles" content="" />
<style>a:lang(ar),a:lang(ckb),a:lang(fa),a:lang(kk-arab),a:lang(mzn),a:lang(ps),a:lang(ur){text-decoration:none}a.new,#quickbar a.new{color:#ba0000}
/* cache key: justsolve:resourceloader:filter:minify-css:7:c88e2bcd56513749bec09a7e29cb3ffa */
</style>
<script src="http://fileformats.archiveteam.org/load.php?debug=false&amp;lang=en&amp;modules=startup&amp;only=scripts&amp;skin=vector&amp;*"></script>
<script>if(window.mw){
mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"CBMFS","wgTitle":"CBMFS","wgCurRevisionId":17112,"wgArticleId":3282,"wgIsArticle":true,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["File Formats","Electronic File Formats","Filesystem","FormatInfo without extensions","FormatInfo without mimetypes","Commodore computers"],"wgBreakFrames":false,"wgPageContentLanguage":"en","wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgRelevantPageName":"CBMFS","wgRestrictionEdit":[],"wgRestrictionMove":[]});
}</script><script>if(window.mw){
mw.loader.implement("user.options",function($){mw.user.options.set({"ccmeonemails":0,"cols":80,"date":"default","diffonly":0,"disablemail":0,"disablesuggest":0,"editfont":"default","editondblclick":0,"editsection":1,"editsectiononrightclick":0,"enotifminoredits":0,"enotifrevealaddr":0,"enotifusertalkpages":1,"enotifwatchlistpages":0,"extendwatchlist":0,"externaldiff":0,"externaleditor":0,"fancysig":0,"forceeditsummary":0,"gender":"unknown","hideminor":0,"hidepatrolled":0,"highlightbroken":1,"imagesize":2,"justify":0,"math":1,"minordefault":0,"newpageshidepatrolled":0,"nocache":0,"noconvertlink":0,"norollbackdiff":0,"numberheadings":0,"previewonfirst":0,"previewontop":1,"quickbar":5,"rcdays":7,"rclimit":50,"rememberpassword":0,"rows":25,"searchlimit":20,"showhiddencats":0,"showjumplinks":1,"shownumberswatching":1,"showtoc":1,"showtoolbar":1,"skin":"vector","stubthreshold":0,"thumbsize":2,"underline":2,"uselivepreview":0,"usenewrc":0,"watchcreations":0,"watchdefault":0,"watchdeletion":0,
"watchlistdays":3,"watchlisthideanons":0,"watchlisthidebots":0,"watchlisthideliu":0,"watchlisthideminor":0,"watchlisthideown":0,"watchlisthidepatrolled":0,"watchmoves":0,"wllimit":250,"variant":"en","language":"en","searchNs0":true,"searchNs1":false,"searchNs2":false,"searchNs3":false,"searchNs4":false,"searchNs5":false,"searchNs6":false,"searchNs7":false,"searchNs8":false,"searchNs9":false,"searchNs10":false,"searchNs11":false,"searchNs12":false,"searchNs13":false,"searchNs14":false,"searchNs15":false});;},{},{});mw.loader.implement("user.tokens",function($){mw.user.tokens.set({"editToken":"+\\","watchToken":false});;},{},{});
/* cache key: justsolve:resourceloader:filter:minify-js:7:9983699ab6150ffa89a90653b2338ac8 */
}</script>
<script>if(window.mw){
mw.loader.load(["mediawiki.page.startup","mediawiki.legacy.wikibits","mediawiki.legacy.ajax"]);
}</script>
<!--[if lt IE 7]><style type="text/css">body{behavior:url("/skins/vector/csshover.min.htc")}</style><![endif]--></head>
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-CBMFS skin-vector action-view">
<div id="mw-page-base" class="noprint"></div>
<div id="mw-head-base" class="noprint"></div>
<!-- content -->
<div id="content" class="mw-body">
<a id="top"></a>
<div id="mw-js-message" style="display:none;"></div>
<!-- firstHeading -->
<h1 id="firstHeading" class="firstHeading">
<span dir="auto">CBMFS</span>
</h1>
<!-- /firstHeading -->
<!-- bodyContent -->
<div id="bodyContent">
<!-- tagline -->
<div id="siteSub">From Just Solve the File Format Problem</div>
<!-- /tagline -->
<!-- subtitle -->
<div id="contentSub"></div>
<!-- /subtitle -->
<!-- jumpto -->
<div id="jump-to-nav" class="mw-jump">
Jump to: <a href="#mw-head">navigation</a>,
<a href="#p-search">search</a>
</div>
<!-- /jumpto -->
<!-- bodycontent -->
<div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><table class="infobox formatinfo" border="0" style="float: right; border: 1px solid #666666; max-width: 25%; overflow: hidden; background-color: #F8E0F7; padding: 0.25em; margin: 0.25em 1em;">
<tr>
<th colspan="2"><a href="/wiki/File_Formats" title="File Formats">File Format</a></th>
</tr>
<tr>
<th>Name</th>
<td>CBMFS</td>
</tr>
<tr>
<th> Ontology
</th>
<td>
<ul><li>
<a href="/wiki/Electronic_File_Formats" title="Electronic File Formats">Electronic File Formats</a>
<ul><li>
<a href="/wiki/Filesystem" title="Filesystem">Filesystem</a>
<ul><li>
<strong class="selflink">CBMFS</strong>
</li></ul>
</li></ul>
</li></ul>
</td>
</tr>
</table>
<p>The <b>CBM File System</b> 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.
</p><p>The most popular CBM drive was the <a href="/wiki/Commodore_1541_disk" title="Commodore 1541 disk">1541</a>, which supported 35 tracks using <a href="/wiki/GCR_encoding" title="GCR encoding">GCR encoding</a>. A later drive, the <a href="/wiki/Commodore_1571_disk" title="Commodore 1571 disk">1571</a> disk, used a double-sided format for twice the space. 3 1/2" disks were later introduced to the Commodore via the <a href="/wiki/Commodore_1581_disk" title="Commodore 1581 disk">1581</a> format, which used a variant of CBMFS (see <a href="/wiki/Commodore_1581_filesystem" title="Commodore 1581 filesystem">Commodore 1581 filesystem</a>).
</p>
<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div>
<ul>
<li class="toclevel-1 tocsection-1"><a href="#D64_File_Format"><span class="tocnumber">1</span> <span class="toctext">D64 File Format</span></a></li>
<li class="toclevel-1 tocsection-2"><a href="#Physical_media"><span class="tocnumber">2</span> <span class="toctext">Physical media</span></a></li>
<li class="toclevel-1 tocsection-3"><a href="#CBM_DOS_Directory_Structure"><span class="tocnumber">3</span> <span class="toctext">CBM DOS Directory Structure</span></a></li>
<li class="toclevel-1 tocsection-4"><a href="#Variations_on_the_D64_layout"><span class="tocnumber">4</span> <span class="toctext">Variations on the D64 layout</span></a></li>
<li class="toclevel-1 tocsection-5"><a href="#What_it_takes_to_support_D64"><span class="tocnumber">5</span> <span class="toctext">What it takes to support D64</span></a></li>
<li class="toclevel-1 tocsection-6"><a href="#Utilities"><span class="tocnumber">6</span> <span class="toctext">Utilities</span></a></li>
</ul>
</td></tr></table>
<h2> <span class="mw-headline" id="D64_File_Format"> D64 File Format </span></h2>
<p>The <a href="/wiki/D64" title="D64">D64</a> 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.
</p>
<h2> <span class="mw-headline" id="Physical_media"> Physical media </span></h2>
<p>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.
</p>
<pre> 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)
</pre>
<pre> 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
</pre>
<pre> (*)Tracks 36-40 apply to 40-track images only
</pre>
<h2> <span class="mw-headline" id="CBM_DOS_Directory_Structure">CBM DOS Directory Structure </span></h2>
<p>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.
</p><p>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.
</p><p>Each directory sector has the following layout (18/1 partial dump):
</p>
<pre> 00: 12 04 81 11 00 4E 41 4D 45 53 20 26 20 50 4F 53 &lt;- notice the T/S link
10: 49 54 A0 A0 A0 00 00 00 00 00 00 00 00 00 15 00 &lt;- to 18/4 ($12/$04)
20: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 &lt;- and how its not here
30: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 &lt;- ($00/$00)
</pre>
<p>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.
</p><p>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:
</p>
<pre> 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 "&gt;" 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 &lt;= #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
</pre>
<p>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.
</p><p>Note: No GEOS entries are listed in the above description. See <a href="/wiki/GEOS_VLIR" title="GEOS VLIR">GEOS VLIR</a> for GEOS info.
</p><p><br />
The layout of the BAM area (sector 18/0) is a bit more complicated...
</p>
<pre> 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
</pre>
<pre> 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)
</pre>
<p>Note: The BAM entries for SPEED, DOLPHIN and ProLogic DOS use the same layout as standard BAM entries.
</p><p>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.
</p><p>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.
</p>
<pre> 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
</pre>
<p>These entries must be viewed in binary to make any sense. We will use the
first entry (track 1) at bytes 04-07:
</p>
<pre> FF=11111111, F9=11111001, 17=00010111
</pre>
<p>In order to make any sense from the binary notation, flip the bits around.
</p>
<pre> 111111 11112222
01234567 89012345 67890123
--------------------------
11111111 10011111 11101000
^ ^
sector 0 sector 20
</pre>
<p>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.
</p><p>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.
</p>
<pre> 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)
</pre>
<h2> <span class="mw-headline" id="Variations_on_the_D64_layout"> Variations on the D64 layout </span></h2>
<p>These are some variations of the D64 layout:
</p><p>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.
</p><p>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.
</p><p>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.
</p><p><br />
Below is a small chart detailing the standard file sizes of D64 images,
35 or 40 tracks, with or without error bytes.
</p>
<pre> 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
</pre>
<p><br />
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 <a href="/wiki/G64" title="G64">G64</a> for a better
explanation of these bytes.
</p>
<pre> 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'
------------------------------------------------------------
</pre>
<p><br />
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.
</p><p>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.
</p><p><br />
Below is a HEX dump of a Speed DOS BAM sector. Note the location of the
extra BAM info from $C0-D3.
</p>
<pre> 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 &#160;????????????????
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 &#160;????????????????
00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 &#160;??00?2A?????????
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
</pre>
<p><br />
Below is a HEX dump of a Dolphin DOS BAM sector. Note the location of the
extra BAM info from $AC-BF.
</p>
<pre> 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 &#160;????????????????
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 &#160;????????????????
00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01 &#160;??00?2A?????????
00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
</pre>
<p><br />
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.
</p>
<pre> 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 &#160;????????????????
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 &#160;????????????????
00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 &#160;????????????????
00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 00 &#160;??????00?2P?????
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
00ED: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 &#160;????????????????
</pre>
<p><br />
</p><p>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.
</p><p>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.
</p><p>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.
</p>
<pre> 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.
</pre>
<p>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.
</p><p>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.
</p><p>Note that the entire sector is read before these errors are detected.
Therefore the data, checksum and off bytes are available.
</p>
<pre> 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)
</pre>
<p>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.
</p>
<pre> 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.
</pre>
<p>This is not an error at all, but when gets reported when the read of a
sector is ok.
</p>
<pre> 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.
</pre>
<p>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.
</p><p><br />
</p>
<h2> <span class="mw-headline" id="What_it_takes_to_support_D64"> What it takes to support D64 </span></h2>
<p>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.
</p><p>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.
</p><p>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.
</p><p>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.)
</p><p>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.
</p><p>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).
</p><p>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.
</p><p>(Content taken from <a rel="nofollow" class="external text" href="http://unusedino.de/ec64/technical/formats/d64.html">D64.TXT</a> in Peter Scheper's excellent compendium of C64 file format information).
</p>
<h2> <span class="mw-headline" id="Utilities"> Utilities </span></h2>
<ul><li> <a rel="nofollow" class="external text" href="http://style64.org/dirmaster">DirMaster: reads C64 disk images / archives / files in Windows</a>
</li></ul>
<!--
NewPP limit report
Preprocessor node count: 108/1000000
Post-expand include size: 1225/2097152 bytes
Template argument size: 272/2097152 bytes
Expensive parser function count: 0/100
-->
<!-- Saved in parser cache with key justsolve:pcache:idhash:3282-0!*!0!!en!*!* and timestamp 20150324234932 -->
</div> <!-- /bodycontent -->
<!-- printfooter -->
<div class="printfooter">
Retrieved from "<a href="http://fileformats.archiveteam.org/index.php?title=CBMFS&amp;oldid=17112">http://fileformats.archiveteam.org/index.php?title=CBMFS&amp;oldid=17112</a>" </div>
<!-- /printfooter -->
<!-- catlinks -->
<div id='catlinks' class='catlinks'><div id="mw-normal-catlinks" class="mw-normal-catlinks"><a href="/wiki/Special:Categories" title="Special:Categories">Categories</a>: <ul><li><a href="/wiki/Category:File_Formats" title="Category:File Formats">File Formats</a></li><li><a href="/wiki/Category:Electronic_File_Formats" title="Category:Electronic File Formats">Electronic File Formats</a></li><li><a href="/wiki/Category:Filesystem" title="Category:Filesystem">Filesystem</a></li><li><a href="/wiki/Category:Commodore_computers" title="Category:Commodore computers">Commodore computers</a></li></ul></div><div id="mw-hidden-catlinks" class="mw-hidden-catlinks mw-hidden-cats-hidden">Hidden categories: <ul><li><a href="/wiki/Category:FormatInfo_without_extensions" title="Category:FormatInfo without extensions">FormatInfo without extensions</a></li><li><a href="/wiki/Category:FormatInfo_without_mimetypes" title="Category:FormatInfo without mimetypes">FormatInfo without mimetypes</a></li></ul></div></div> <!-- /catlinks -->
<div class="visualClear"></div>
<!-- debughtml -->
<!-- /debughtml -->
</div>
<!-- /bodyContent -->
</div>
<!-- /content -->
<!-- header -->
<div id="mw-head" class="noprint">
<!-- 0 -->
<div id="p-personal" class="">
<h5>Personal tools</h5>
<ul>
<li id="pt-login"><a href="/index.php?title=Special:UserLogin&amp;returnto=CBMFS" title="You are encouraged to log in; however, it is not mandatory [o]" accesskey="o">Log in / create account</a></li>
</ul>
</div>
<!-- /0 -->
<div id="left-navigation">
<!-- 0 -->
<div id="p-namespaces" class="vectorTabs">
<h5>Namespaces</h5>
<ul>
<li id="ca-nstab-main" class="selected"><span><a href="/wiki/CBMFS" title="View the content page [c]" accesskey="c">Page</a></span></li>
<li id="ca-talk" class="new"><span><a href="/index.php?title=Talk:CBMFS&amp;action=edit&amp;redlink=1" title="Discussion about the content page [t]" accesskey="t">Discussion</a></span></li>
</ul>
</div>
<!-- /0 -->
<!-- 1 -->
<div id="p-variants" class="vectorMenu emptyPortlet">
<h4>
</h4>
<h5><span>Variants</span><a href="#"></a></h5>
<div class="menu">
<ul>
</ul>
</div>
</div>
<!-- /1 -->
</div>
<div id="right-navigation">
<!-- 0 -->
<div id="p-views" class="vectorTabs">
<h5>Views</h5>
<ul>
<li id="ca-view" class="selected"><span><a href="/wiki/CBMFS" >Read</a></span></li>
<li id="ca-viewsource"><span><a href="/index.php?title=CBMFS&amp;action=edit" title="This page is protected.&#10;You can view its source [e]" accesskey="e">View source</a></span></li>
<li id="ca-history" class="collapsible"><span><a href="/index.php?title=CBMFS&amp;action=history" title="Past revisions of this page [h]" accesskey="h">View history</a></span></li>
</ul>
</div>
<!-- /0 -->
<!-- 1 -->
<div id="p-cactions" class="vectorMenu emptyPortlet">
<h5><span>Actions</span><a href="#"></a></h5>
<div class="menu">
<ul>
</ul>
</div>
</div>
<!-- /1 -->
<!-- 2 -->
<div id="p-search">
<h5><label for="searchInput">Search</label></h5>
<form action="/index.php" id="searchform">
<div>
<input type="search" name="search" title="Search Just Solve the File Format Problem [f]" accesskey="f" id="searchInput" /> <input type="submit" name="go" value="Go" title="Go to a page with this exact name if exists" id="searchGoButton" class="searchButton" /> <input type="submit" name="fulltext" value="Search" title="Search the pages for this text" id="mw-searchButton" class="searchButton" /> <input type='hidden' name="title" value="Special:Search"/>
</div>
</form>
</div>
<!-- /2 -->
</div>
</div>
<!-- /header -->
<!-- panel -->
<div id="mw-panel" class="noprint">
<!-- logo -->
<div id="p-logo"><a style="background-image: url(/thumbsup.png);" href="/wiki/Main_Page" title="Visit the main page"></a></div>
<!-- /logo -->
<!-- navigation -->
<div class="portal" id='p-navigation'>
<h5>Navigation</h5>
<div class="body">
<ul>
<li id="n-mainpage-description"><a href="/wiki/Main_Page" title="Visit the main page [z]" accesskey="z">Main page</a></li>
<li id="n-File-formats"><a href="/wiki/File_Formats">File formats</a></li>
<li id="n-Formats-by-extension"><a href="/wiki/Category:File_formats_by_extension">Formats by extension</a></li>
<li id="n-Still-more-extensions"><a href="/wiki/Category:File_Format_Extension">Still more extensions</a></li>
<li id="n-Software"><a href="/wiki/Software">Software</a></li>
<li id="n-Glossary"><a href="/wiki/Glossary">Glossary</a></li>
<li id="n-Library"><a href="/wiki/Library">Library</a></li>
<li id="n-Sources"><a href="/wiki/Sources">Sources</a></li>
<li id="n-Categories"><a href="/wiki/Category:Top_Level_Categories">Categories</a></li>
<li id="n-portal"><a href="/wiki/Just_Solve_the_File_Format_Problem:Community_portal" title="About the project, what you can do, where to find things">Community portal</a></li>
<li id="n-recentchanges"><a href="/wiki/Special:RecentChanges" title="A list of recent changes in the wiki [r]" accesskey="r">Recent changes</a></li>
<li id="n-randompage"><a href="/wiki/Special:Random" title="Load a random page [x]" accesskey="x">Random page</a></li>
</ul>
</div>
</div>
<!-- /navigation -->
<!-- SEARCH -->
<!-- /SEARCH -->
<!-- TOOLBOX -->
<div class="portal" id='p-tb'>
<h5>Toolbox</h5>
<div class="body">
<ul>
<li id="t-whatlinkshere"><a href="/wiki/Special:WhatLinksHere/CBMFS" title="A list of all wiki pages that link here [j]" accesskey="j">What links here</a></li>
<li id="t-recentchangeslinked"><a href="/wiki/Special:RecentChangesLinked/CBMFS" title="Recent changes in pages linked from this page [k]" accesskey="k">Related changes</a></li>
<li id="t-specialpages"><a href="/wiki/Special:SpecialPages" title="A list of all special pages [q]" accesskey="q">Special pages</a></li>
<li><a href="/index.php?title=CBMFS&amp;printable=yes" rel="alternate">Printable version</a></li>
<li id="t-permalink"><a href="/index.php?title=CBMFS&amp;oldid=17112" title="Permanent link to this revision of the page">Permanent link</a></li>
</ul>
</div>
</div>
<!-- /TOOLBOX -->
<!-- LANGUAGES -->
<!-- /LANGUAGES -->
</div>
<!-- /panel -->
<!-- footer -->
<div id="footer">
<ul id="footer-info">
<li id="footer-info-lastmod"> This page was last modified on 22 April 2014, at 02:18.</li>
<li id="footer-info-viewcount">This page has been accessed 2,051 times.</li>
<li id="footer-info-copyright">Content is available under <a class="external" href="http://creativecommons.org/publicdomain/zero/1.0/">Creative Commons 0</a>.</li>
</ul>
<ul id="footer-places">
<li id="footer-places-privacy"><a href="/wiki/Just_Solve_the_File_Format_Problem:Privacy_policy" title="Just Solve the File Format Problem:Privacy policy">Privacy policy</a></li>
<li id="footer-places-about"><a href="/wiki/Just_Solve_the_File_Format_Problem:About" title="Just Solve the File Format Problem:About">About Just Solve the File Format Problem</a></li>
<li id="footer-places-disclaimer"><a href="/wiki/Just_Solve_the_File_Format_Problem:General_disclaimer" title="Just Solve the File Format Problem:General disclaimer">Disclaimers</a></li>
</ul>
<ul id="footer-icons" class="noprint">
<li id="footer-copyrightico">
<a href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="http://www.mediawiki.org/w/skins/common/images/cc-0.png" alt="Creative Commons 0" width="88" height="31" /></a>
</li>
<li id="footer-poweredbyico">
<a href="//www.mediawiki.org/"><img src="/skins/common/images/poweredby_mediawiki_88x31.png" alt="Powered by MediaWiki" width="88" height="31" /></a>
</li>
</ul>
<div style="clear:both"></div>
</div>
<!-- /footer -->
<script src="http://fileformats.archiveteam.org/load.php?debug=false&amp;lang=en&amp;modules=skins.vector&amp;only=scripts&amp;skin=vector&amp;*"></script>
<script>if(window.mw){
mw.loader.load(["mediawiki.user","mediawiki.page.ready"], null, true);
}</script>
<!-- Served in 0.069 secs. -->
</body>
</html>

42
Commodore/CKIT.TXT Normal file
View File

@@ -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 MMS<4D><53>XX!<21><><EFBFBD><EFBFBD>`<60>.<2E>
0010: 00 29 5A EC 94 03 40 06 20 2F BF D5 20 B4 68 81 <20>)Z<><5A>.@.<2E>/<2F><><EFBFBD><EFBFBD>h<EFBFBD>
0020: A0 8D 10 B4 10 AF 15 03 61 08 07 50 00 10 80 68 <20><>.<2E>.<2E>..a..P<>.<2E>h
0030: 8A 88 08 91 03 32 1A 0F B7 30 1D 94 D0 7B 28 80 <20><>.<2E>.2..<2E>0.<2E><>{(<28>
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.

102
Commodore/CPK.TXT Normal file
View File

@@ -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 <20>"<22><><EFBFBD><EFBFBD>ANLEITUNG<4E>
0020: 5A 55 4D 20 40 41 53 53 45 4D 42 4C 45 52 00 4E ZUM<55>@ASSEMBLER<45>N
0030: 08 6E 00 99 22 11 40 41 53 53 20 49 53 54 20 45 .n<><6E>".@ASS<53>IST<53>E
0040: 49 4E 20 32 2D 50 41 53 53 2D 41 53 53 45 4D 42 IN<49>2-PASS-ASSEMB
0050: 4C 45 52 2E 20 44 45 52 00 78 08 78 00 99 22 11 LER.<2E>DER<45>x.x<><78>".
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 <20>"<22><><EFBFBD><EFBFBD>ANLEITUNG<4E>
...
0270: 00 83 0A E6 00 99 22 11 20 20 31 32 33 F7 08 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>".<2E><>123<32>.<2E>
0280: 2D 44 45 5A 49 4D 41 4C 00 A4 0A F0 00 99 22 11 -DEZIMAL<41><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>".
0290: 20 20 24 33 34 35 F7 07 20 2D 48 45 58 41 44 45 <20><>$345<34>.<2E>-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 .. .. .. .. .. .. .. ......<2E>.<2E>.......
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.

1201
Commodore/CRT.TXT Normal file

File diff suppressed because it is too large Load Diff

137
Commodore/CVT.TXT Normal file
View File

@@ -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 <20><><EFBFBD>DESK<53>TOP<4F><50><EFBFBD><EFBFBD><EFBFBD>
0010: A0 A0 A0 00 00 01 04 58 08 13 0D 23 78 00 50 52 <20><><EFBFBD><EFBFBD><EFBFBD>..X...#x<>PR
0020: 47 20 66 6F 72 6D 61 74 74 65 64 20 47 45 4F 53 G<>formatted<65>GEOS
0030: 20 66 69 6C 65 20 56 31 2E 30 00 00 00 00 00 00 <20>file<6C>V1.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..
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 <20><><EFBFBD><EFBFBD><EFBFBD>I.<2E><>.<2E><>.<2E><><EFBFBD>
0110: A0 00 5D BF FF C1 A0 00 5D A1 C6 55 A0 29 5D A0 <20><>]<5D><><EFBFBD><EFBFBD><EFBFBD>]<5D><>U<EFBFBD>)]<5D>
0120: C9 41 A1 09 41 B9 D6 41 A8 00 41 BF FF C1 80 00 <20>A<EFBFBD>.A<><41>A<EFBFBD><41>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>
0130: 1D 9C 00 15 9C 00 15 80 00 1D 80 00 01 FF FF FF .<2E><>.<2E><>.<2E><>.<2E><>.<2E><><EFBFBD>
0140: 83 04 01 56 19 55 19 75 51 64 65 73 6B 54 6F 70 <20>..V.U.uQdeskTop
0150: 20 41 4D 20 20 56 32 2E 30 00 00 00 00 42 72 69 <20>AM<41><4D>V2.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Bri
0160: 61 6E 20 44 6F 75 67 68 65 72 74 79 00 00 00 00 an<61>Dougherty<74><79><EFBFBD><EFBFBD>
0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0180: 00 00 00 00 00 4C 2A 5B 4C 59 5D 4C A7 61 4C 3A <20><><EFBFBD><EFBFBD><EFBFBD>L*[LY]L<>aL:
0190: 62 AD 8A 84 D0 01 60 20 7E 23 20 9C 55 73 65 20 b<><62><EFBFBD><EFBFBD>.`<60>~#<23><>Use<73>
01A0: 74 68 65 20 64 65 73 6B 54 6F 70 20 74 6F 20 6D the<68>deskTop<6F>to<74>m
01B0: 61 6E 61 67 65 20 61 6E 64 20 6D 61 6E 69 70 75 anage<67>and<6E>manipu
01C0: 6C 61 74 65 20 79 6F 75 72 20 66 69 6C 65 73 2E late<74>your<75>files.
01D0: 00 03 20 E3 5C 68 85 FB 20 4F 61 20 13 61 20 32 <20>.<2E><>\h<><68><EFBFBD>Oa<4F>.a<>2
01E0: 61 20 F2 5C A9 0C 20 CC 49 A9 2E 85 13 A9 F9 85 a<><61>\<5C>.<2E><>I<EFBFBD>.<2E>.<2E><><EFBFBD>
01F0: 12 A9 2F 85 15 A9 01 85 14 A9 84 85 .. .. .. .. .<2E>/<2F>.<2E>.<2E>.<2E><><EFBFBD>....
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 .<2E><><EFBFBD>.<2E><>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F0: 00 00 00 00 00 00 00 00 00 00 .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>......
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 ..........<2E><><EFBFBD><EFBFBD>.<2E>
0300: FE B9 86 84 30 06 29 0F C9 02 D0 12 A4 70 B9 86 <20><><EFBFBD><EFBFBD>0.).<2E>.<2E>.<2E>p<EFBFBD><70>
0310: 84 30 06 29 0F C9 02 D0 05 A9 07 8D A0 1D 20 1E <20>0.).<2E>.<2E>.<2E>.<2E><>.<2E>.
0320: 23 20 04 1A 8A D0 20 20 12 1A 18 A9 00 6D F4 03 #<23>..<2E><><EFBFBD><EFBFBD>...<2E><>m<EFBFBD>.
0330: 8D F4 03 A9 03 6D F5 03 8D F5 03 20 C5 22 20 7C <20><>.<2E>.m<>.<2E><>.<2E><>"<22>|
0340: 1B 20 04 1A 20 6B 1A A9 08 8D A0 1D B8 50 53 8D .<2E>..<2E>k.<2E>.<2E><>.<2E>PS<50>
0350: EE 04 20 12 1A A2 00 A4 70 20 3F 24 C9 04 B0 3F <20>.<2E>..<2E><><EFBFBD>p<EFBFBD>?$<24>.<2E>?

689
Commodore/D2M-DNP.TXT Normal file
View File

@@ -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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190510: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190520: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190530: FF FF FF FF FF FF FF FF 00 00 FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190540: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190550: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190560: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190570: 00 0C FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190580: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190590: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905A0: FF FF FF FF FF FF FF FF 00 80 FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905E0: 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1905F0: 43 4D 44 20 46 44 20 53 45 52 49 45 53 20 20 20 CMD<4D>FD<46>SERIES<45><53><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD>SYSTEM<45><4D><EFBFBD><EFBFBD><EFBFBD>
190810: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190820: 00 00 04 00 00 31 35 38 31 2F 50 41 52 54 49 54 <20><><EFBFBD><EFBFBD><EFBFBD>1581/PARTIT
190830: 49 4F 4E A0 A0 00 00 00 00 00 00 00 00 00 06 40 ION<4F><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@
190840: 00 00 03 00 00 31 35 37 31 50 41 52 54 49 54 49 <20><><EFBFBD><EFBFBD><EFBFBD>1571PARTITI
190850: 4F 4E A0 A0 A0 00 06 40 00 00 00 00 00 00 02 AC ON<4F><4E><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190860: 00 00 02 00 00 31 35 34 31 50 41 52 54 49 54 49 <20><><EFBFBD><EFBFBD><EFBFBD>1541PARTITI
190870: 4F 4E A0 A0 A0 00 08 EC 00 00 00 00 00 00 01 56 ON<4F><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V
190880: 00 00 01 00 00 4E 41 54 49 56 2D 50 41 52 54 49 <20><><EFBFBD><EFBFBD><EFBFBD>NATIV-PARTI
190890: 54 49 4F 4E A0 00 0A 42 00 00 00 00 00 00 02 00 TION<4F><4E><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1908F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190900: 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1909F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A00: 01 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B00: 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
190BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD>SYSTEM<45><4D><EFBFBD><EFBFBD><EFBFBD>
190810: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD>1581/PARTIT
190830: 49 4F 4E A0 A0 00 00 00 00 00 00 00 00 00 06 40 ION<4F><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@
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 <20>$H<>SUBDIR18<31><38><EFBFBD><EFBFBD>
0010: A0 A0 A0 A0 A0 A0 54 49 A0 31 48 A0 A0 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TI<54>1H<31><48><EFBFBD><EFBFBD><EFBFBD>
0020: 01 23 01 01 01 22 02 00 00 00 00 00 00 00 00 00 <20>#<23><><EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 00 00 00 00 00 00 00 00 00 00 00 01 25 47 45 4F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%GEO
00B0: 53 20 66 6F 72 6D 61 74 20 56 31 2E 31 00 00 00 S<>format<61>V1.1<EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><>H<EFBFBD>JO<4A><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000220: 00 00 00 00 0F FF FF FF 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0002A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0002B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0002C0: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD>
0002D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0002E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0002F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
..
000500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000530: 00 00 00 00 00 00 00 07 FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000540: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000550: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
<20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
<20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
<20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
<20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
<20> Sec 7 <20> Sec 15 <20> Sec 23 <20> Sec 31 <20> Sec 39 <20> 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 <20>#<23><>@ECHO<48>HAWK<57><4B>
002210: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 13 02 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
002220: 00 00 86 02 32 50 4C 55 52 41 4C A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD>2PLURAL<41><4C><EFBFBD><EFBFBD><EFBFBD>
002230: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 19 02 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
002240: 00 00 86 03 04 52 45 41 43 54 4F 52 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>REACTOR<4F><52><EFBFBD><EFBFBD>
002250: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 20 04 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
002260: 00 00 86 04 D8 54 48 45 20 54 52 41 49 4E A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>THE<48>TRAIN<49><4E>
002270: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 10 23 03 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD>#<23><>
002280: 00 00 86 06 62 49 4E 46 49 4C 54 52 41 54 4F 52 <20><><EFBFBD><EFBFBD>bINFILTRATOR
002290: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 10 2B 06 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD>+<2B><>
0022A0: 00 00 86 08 FE 53 54 4F 4E 45 20 41 47 45 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>STONE<4E>AGE<47><45>
0022B0: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 12 04 05 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0022C0: 00 00 86 0A D6 4E 49 43 4B 20 46 41 4C 44 4F 20 <20><><EFBFBD><EFBFBD><EFBFBD>NICK<43>FALDO<44>
0022D0: 47 4F 4C 46 A0 00 00 00 00 60 01 0A 12 09 02 00 GOLF<4C><46><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0022E0: 00 00 86 0A D8 52 2D 54 59 50 45 A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>R-TYPE<50><45><EFBFBD><EFBFBD><EFBFBD>
0022F0: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 12 0D 05 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20>AH<41>ECHO<48>HAWK<57><4B><EFBFBD>
004010: A0 A0 A0 A0 A0 A0 4A 4F A0 31 48 A0 A0 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>JO<4A>1H<31><48><EFBFBD><EFBFBD><EFBFBD>
004020: 01 40 01 01 01 22 02 00 00 00 00 00 00 00 00 00 <20>@<40><><EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
004090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

690
Commodore/D64.TXT Normal file
View File

@@ -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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 <20><>00<30>2A<32><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01 <20><>00<30>2A<32><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>00<30>2P<32><50><EFBFBD><EFBFBD><EFBFBD>
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00ED: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
---------------------------------------------------------------------------
*** 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)

420
Commodore/D71.TXT Normal file
View File

@@ -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 <20><><EFBFBD>.<2E>JET<45>SET<45>WIL
10: 4C 59 A0 A0 A0 00 00 00 00 00 00 00 00 00 2B 00 LY<4C><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B>
20: 00 00 82 0F 01 4A 53 57 20 31 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>..JSW<53>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 BF 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 82 06 03 53 4F 4E 20 4F 46 20 42 4C 41 47 <20><><EFBFBD>..SON<4F>OF<4F>BLAG
50: 47 45 52 A0 A0 00 00 00 00 00 00 00 00 00 AE 00 GER<45><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 00 00 82 15 0D 50 4F 54 54 59 20 50 49 47 45 4F <20><><EFBFBD>..POTTY<54>PIGEO
70: 4E A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 A2 00 N<><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<>.<2E><>..<2E><>..<2E><>.
10: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F .<2E><>..<2E><>..<2E><>..<2E><>.
20: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F .<2E><>..<2E><>..<2E><>..<2E><>.
30: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F .<2E><>..<2E><>..<2E><>..<2E><>.
40: 15 FF FF 1F 15 FF FF 1F 11 FC FF 07 13 FF FF 07 .<2E><>..<2E><>..<2E><>..<2E><>.
50: 13 FF FF 07 13 FF FF 07 13 FF FF 07 13 FF FF 07 .<2E><>..<2E><>..<2E><>..<2E><>.
60: 13 FF FF 07 12 FF FF 03 12 FF FF 03 12 FF FF 03 .<2E><>..<2E><>..<2E><>..<2E><>.
70: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01 .<2E><>..<2E><>..<2E><>..<2E><>.
80: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 .<2E><>..<2E><>..<2E><>..<2E><>.
90: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 <20><>00<30>2A<32><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 15 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
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 <20><>.<2E><>.<2E><>.<2E><>.<2E><>.<2E>
10: FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF <20>.<2E><>.<2E><>.<2E><>.<2E><>.<2E><>
20: 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F .<2E><>.<2E><>.<2E><>.<2E><>.<2E><>.
30: FF FF 1F 00 00 00 FF FF 07 FF FF 07 FF FF 07 FF <20><>.<2E><><EFBFBD><EFBFBD><EFBFBD>.<2E><>.<2E><>.<2E>
40: FF 07 FF FF 07 FF FF 07 FF FF 03 FF FF 03 FF FF <20>.<2E><>.<2E><>.<2E><>.<2E><>.<2E><>
50: 03 FF FF 03 FF FF 03 FF FF 03 FF FF 01 FF FF 01 .<2E><>.<2E><>.<2E><>.<2E><>.<2E><>.
60: FF FF 01 FF FF 01 FF FF 01 00 00 00 00 00 00 00 <20><>.<2E><>.<2E><>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD>..ADDITIONAL<41>
10: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 INFO<46>..<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>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)

464
Commodore/D80-D82.TXT Normal file
View File

@@ -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 &<26>C<EFBFBD><43><EFBFBD>sample<6C>d80
10: A0 A0 A0 A0 A0 A0 A0 A0 65 72 A0 32 43 A0 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>er<65>2C<32><43><EFBFBD>
20: A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
...
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 '<27><>&<26>TEST<53><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 00 00 82 26 02 54 45 53 54 32 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>&<26>TEST2<54><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 82 26 04 54 45 53 54 33 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>&<26>TEST3<54><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 00 00 82 26 0B 54 45 53 54 34 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>&<26>TEST4<54><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 09 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 82 26 14 54 45 53 54 35 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>&<26>TEST5<54><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0C 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 82 28 00 54 45 53 54 36 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>(<28>TEST6<54><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 82 28 01 54 45 53 54 37 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>(<28>TEST7<54><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 82 28 02 54 45 53 54 38 A0 A0 A0 A0 A0 A0 <20><><EFBFBD>(<28>TEST8<54><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 &<26>C<EFBFBD><43>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1B <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: F6 FF FF 1F 1B FC FF FF 1F 1B FF FF FF 07 1B FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 '<27>C<EFBFBD>3N<33><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 <20><><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD>
60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 <20><><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F>
70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF <20><><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD>
80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00 <20><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD>
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 &<26>C<EFBFBD>3e<33><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 <20><><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD>
60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 <20><><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F>
70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF <20><><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD>
80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 1D FF FF <20><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD>
90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 &<26>C<EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 1F 1D FF FF FF 1F 1B FF FF FF 07 1B FF FF FF 07 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: FF 07 1B FF FF FF 07 1B FF FF FF 07 19 FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: FF FF 01 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD>
E0: 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F <><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD>
F0: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 <20><><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD>
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 '<27>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD>
10: 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

575
Commodore/D81.TXT Normal file
View File

@@ -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 (.D<>1581<38>UTILITY
10: 20 56 30 31 A0 A0 47 42 A0 33 44 A0 A0 00 00 00 <20>V01<30><31>GB<47>3D<33><44><EFBFBD><EFBFBD><EFBFBD>
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 (.<2E>+<2B>SCREEN<45><4E>3<EFBFBD><33>
10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 02 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
20: 00 00 81 2B 01 53 43 52 45 45 4E 20 20 34 A0 A0 <20><><EFBFBD>+.SCREEN<45><4E>4<EFBFBD><34>
30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 03 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
40: 00 00 81 2B 02 53 43 52 45 45 4E 20 20 35 A0 A0 <20><><EFBFBD>+.SCREEN<45><4E>5<EFBFBD><35>
50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
60: 00 00 81 2B 08 53 43 52 45 45 4E 20 20 36 A0 A0 <20><><EFBFBD>+.SCREEN<45><4E>6<EFBFBD><36>
70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 08 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
80: 00 00 81 2B 14 53 43 52 45 45 4E 20 20 37 A0 A0 <20><><EFBFBD>+.SCREEN<45><4E>7<EFBFBD><37>
90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
A0: 00 00 81 24 00 53 43 52 45 45 4E 20 20 38 A0 A0 <20><><EFBFBD>$<24>SCREEN<45><4E>8<EFBFBD><38>
B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0B 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
C0: 00 00 82 24 04 46 49 4C 45 34 32 39 33 36 39 30 <20><><EFBFBD>$.FILE4293690
D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
E0: 00 00 82 24 06 46 49 4C 45 32 35 37 38 38 31 35 <20><><EFBFBD>$.FILE2578815
F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>
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 (.D<>GB<47><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
20: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
30: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
40: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
50: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
60: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
70: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
80: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
90: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
A0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
B0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
C0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
D0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
E0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
F0: FF FF FF FF 28 FF FF FF FF FF 24 F0 FF 2D FF FE <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>$<24><>-<2D><>
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 <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>$<24><>-<2D><>
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 (.D<>GB<47><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
20: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
30: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
40: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
50: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
60: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
70: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
80: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
90: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
A0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
B0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
C0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
D0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF (<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
E0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28>
F0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD>'<27>ADDITIONAL<41>
10: 49 4E 46 4F A0 27 02 FE 00 00 00 00 00 00 D2 0B INFO<46>'...<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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 '.<2E>'.....8.J.<2E><><EFBFBD>
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD>)<29>PARTITION<4F>1
10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 40 06 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@.
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 <20><><EFBFBD>..SMALLPART<52>2
10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0A 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 (.D<>CD<43><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 23 C1 FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF #<23><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
20: FF FF 28 FF FF FF FF FF 1E 01 F8 FF FF FF 28 FF <20><>(<28><><EFBFBD><EFBFBD><EFBFBD>..<2E><><EFBFBD><EFBFBD>(<28>
^^^^^^^^^^^^^^^^^
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)

791
Commodore/DISK.TXT Normal file
View File

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

196
Commodore/F64.TXT Normal file
View File

@@ -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 ..-<2D><>+<2B><>+<2B>G+<2B><>+<2B>
0010: 80 2B 07 C3 2B 07 1C 2B 07 4E 2B 07 EC 2B 07 47 <20>+<2B><>+<2B><>+<2B>N+<2B><>+<2B>G
0020: 2B 07 FE 2B 07 5F 2B 07 69 2B 07 F3 2B 07 90 2B +<2B><>+<2B>_+<2B>i+<2B><>+<2B><>+
0030: 07 22 2B 07 4D 2D 07 01 2D 07 01 2D 07 01 2D 07 <20>"+<2B>M-<2D><>-<2D><>-<2D><>-<2D>
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

404
Commodore/F64.html Normal file
View File

@@ -0,0 +1,404 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- DW6 -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Decoding the F64 Filetype</title>
<link rel="stylesheet" href="2col_leftNav.css" type="text/css">
<style type="text/css">
<!--
.style1 {font-size: small}
.style2 {font-size: small; font-weight: bold; }
.style3 {font-size: large; font-weight: bold; }
.style4 {font-size: x-large; font-weight: bold; }
.style99 {
font-family: Arial, Helvetica, sans-serif;
font-size: x-small;
font-weight: bold;
color: #000000;
}
-->
</style>
</head>
<!-- The structure of this file is exactly the same as 2col_rightNav.html;
the only difference between the two is the stylesheet they use -->
<body>
<div id="masthead">
<h1 class="style4" id="siteName">64Copy Central</h1>
</div>
<span class="style4">
<!-- end masthead -->
</span>
<div id="content">
<a name="#top"></a><h2 class="style3" id="pageName">Decoding the F64 filetype</h2>
<div class="feature">
<p align="right" class="style1">Written by Peter Schepers on March 12, 2004 - Last updated Oct 4, 2007</p>
<p class="style2">Some History</p>
<p class=style1>Already several years ago (likely around 2000) I was asked to include F64 error conversion in <a href="personal.html"><b>64COPY</b></a>. The trouble was that F64&rsquo;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 <a
href="http://www.whiz-zards.com/"><b>Whiz-zards</b></a> 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&rsquo;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.&nbsp;</p>
<p class=style1> 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 <b><a href="http://sta.c64.org/">F64Check program</a></b> (available from his site) to aid in the discovery of the layout.</p>
<p class=style1>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 &lsquo;L&rsquo;, &lsquo;F&rsquo; and &lsquo;H&rsquo;. </p>
<p class=style1>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:</p>
<ul>
<li class="style1">FCOPY III can&rsquo;t detect an error 29, and therefore neither does FCOPY-PC</li>
<li class="style1">It doesn&rsquo;t differentiate between error 20 (bad ID) and 27 (bad checksum, both header errors)</li>
</ul>
<p class=style1>Error 29 requires that you know the master ID&rsquo;s of the disk you are reading but FCOPY-III doesn&rsquo;t read them from track 18 before copying the disk. Error 20 and 27 are both header errors, so there wasn&rsquo;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 &ldquo;an error&rdquo; 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&rsquo;t take this into account and so it is hard to know what error to use (27 or 20) when the &lsquo;H&rsquo; code is encountered.</p>
<p class=style1>The layout of the F64 file is deceptively simple. There&rsquo;s 2 bytes at the beginning of the file which are the master disk format ID&rsquo;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.</p>
<p class=style1>&nbsp;</p>
<p class=style2>Some Time Later</p>
<p class=style1>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&rsquo;s website, acquired the latest version of his F64 documentation, but I didn&rsquo;t agree with it as some of the error codes and the errors they were assigned to didn&rsquo;t make sense with some of my early experiments.</p>
<p class=style1>On <a
href="http://d81.de/"><b>Wolfgang Moser&rsquo;s</b></a> 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 &lsquo;L&rsquo; and &lsquo;F&rsquo; errors together, and they also commented on the &lsquo;P&rsquo; and &lsquo;S&rsquo; 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&rsquo;t fully understand what the code was doing.</p>
<p class=style1>At this point I realized I would need to construct the setup necessary for using Markus Brenner&rsquo;s <a href="http://markus.brenner.de/"><b>MNIB</b></a> utility, Joe Forsters/STA <a href="http://sta.c64.org/"><b>Star Commander</b></a> and the Whiz-zards <b><a href="DOWNLOAD/FCOPYPC.ZIP">FCOPY-PC</a></b>. I would have to pull my C64 out of mothballs, build all the cables, install parallel ports in my 1541&rsquo;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&rsquo;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!</p>
<p class=style1><a href="1541par.html"><strong>Installing the parallel port in a 1541</strong></a> 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 <a href="ccisa.html"><strong>The Complete Commodore Innerspace Anthology</strong></a> 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. </p>
<p class=style1><strong><a href="f64cable.html"> Building the FCOPY-PC cable</a></strong> is a little more difficult in that it needs more components (3 connectors, two cables and 4 resistors) but it was easily done. <strong><a href="xep1541.html">Building the XEP1541 parallel cable</a></strong> 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&rsquo;t <i>require</i> 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&rsquo;s site. <strong><a href="c64par.html">Building the parallel cable from the C64 to the 1541</a></strong> 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.</p>
<p class=style1>One word of warning: the documentation that comes with FCOPY-PC for building the parallel cable (from the 1541 drive to the C64) is <b>wrong</b>. Do not use it, as it connects to the incorrect pins on the VIA in the drive! Joe&rsquo;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.</p>
<p class=style1>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&rsquo;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&hellip; it didn&rsquo;t work, same problem. Frustration was setting in.</p>
<p class=style1>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&rsquo;t work, although it claimed to see the drive and the parallel cable. Joe&rsquo;s XEP1541 documentation does mention that the parallel port on some mainboards won&rsquo;t work with this cable, and you need the XA1541 or XAP1541 cable instead. I didn&rsquo;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&rsquo;t like the XEP and X cables.)</p>
<p class=style1>I MNIB&rsquo;d all the sample disks I had, and created a 1541 disk with the FCOPY software for the C64. Using the <a href="http://www.viceteam.org/"><b>VICE C64 emulator</b></a>, I typed in the sample programs from the book <a href="icd.html"><strong>Inside Commodore DOS</strong></a> by Immers/Neufeld for creating errors on a 1541 floppy disk. (I will put this floppy image on-line at another time as I&rsquo;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.</p>
<p class=style1>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 <a href="diagnostic.html"><strong>C64 diagnostic setup</strong></a> (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&rsquo;t have anything anymore. Frustration level is starting to rise again! I realized I would have to fix my C64 before I could continue.</p>
<p class=style1>Once again, I went digging through my parts drawers to find my stash of C64 chips. I started to replace them one by one&hellip; 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!</p>
<p class=style1>I started <a href="floppies.html"><strong>FCOPY&rsquo;ing all my disks</strong></a>, 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&rsquo;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&rsquo;d the disks for comparison. The error codes were starting to make sense. I was also very glad that I hadn&rsquo;t sold all of Commodore equipment as I had planned to a few months before.</p>
<p class=style1>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. <a href="fcopypc.html"><strong>I copied it with FCOPY-PC and watched the error pattern</strong></a>. It appeared I had finally established the errors for &lsquo;+&rsquo;, &lsquo;L&rsquo;, &lsquo;I&rsquo;, &lsquo;C&rsquo; and somewhat for &lsquo;H&rsquo;, but I still didn&rsquo;t know what &lsquo;F&rsquo; was, nor &lsquo;P&rsquo; and &lsquo;S&rsquo;. I had also mistakenly assigned the &lsquo;-&lsquo; code to error 29 as the only two sectors on my &ldquo;created&rdquo; disk with the &lsquo;-&lsquo; code did have error 29 assigned to them.</p>
<p class=style1>I started to write up the changes to my <a href="formats/F64.TXT"><strong>F64.TXT</strong></a> document, but I realized I had made a mistake assigning error 29 to the &lsquo;-&lsquo; code. Many F64 files had &lsquo;-&lsquo; errors and they couldn&rsquo;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 &lsquo;-&lsquo; 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 &ldquo;compression&rdquo;, allowing FCOPY to copy an entire disk into C64 memory (no disk swaps), provided that most of the disk is empty.</p>
<p class=style1>I also noticed that one of my sample disks had an &lsquo;F&rsquo; error that covered several tracks but I still didn&rsquo;t know what it was. I MNIB&rsquo;d the disk, and on the &lsquo;F&rsquo; tracks MNIB reported &lsquo;Fexact match&rsquo; (a very strange response), but the MNIB output was the same for an &lsquo;L&rsquo; track. I started wondering if this was a <b>killer track</b>, one that has all SYNC marks, but MNIB wasn&rsquo;t outputting the correct track data.</p>
<p class=style1>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. </p>
<p class=style1>&nbsp;</p>
<p class=style2>Where Things Were Left Off </p>
<p class=style1>This is the condition I have left things. I have basically decoded all the errors except &lsquo;P&rsquo; and &lsquo;S&rsquo;. I don&rsquo;t believe they are read-error codes, but instead are related to verification when writing the destination disk, and are therefore not applicable.</p>
<p class=style1>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&rsquo;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.</p>
<p class=style1>I hope I haven&rsquo;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 <a
href="DOWNLOAD/FORMATS.ZIP"><b>FORMATS.ZIP</b></a> archive contains the new write-up, or you can <a href="formats/F64.TXT"><b>view it from here</b></a>.</p>
<p class=style1>&nbsp;</p>
<p class=style2>Below is the chart I now use to decode F64 files.</p>
<table width="623" border="1">
<tr class="style1">
<td width="92" class="style1"><div align="center" class="style2"><strong>Error Code </strong></div></td>
<td width="515" class="style1"><strong class="style2">Description</strong></td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">+</div></td>
<td class="style1">Sector ok and has data</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">-</div></td>
<td class="style1">Sector ok, but empty (filled with $01)</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">C</div></td>
<td class="style1">Error 23 &ldquo;data checksum&rdquo; (use the second and third bytes to reconstruct the sector)</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">L</div></td>
<td class="style1">Error 21 &ldquo;track has no SYNC mark&rdquo;</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">I</div></td>
<td class="style1">Error 22 &ldquo;data ID missing&rdquo; (use the second and third bytes to reconstruct the sector)</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">H</div></td>
<td class="style1">Error 20/27 &ldquo;Header ID missing&rdquo; or &ldquo;Bad header checksum&rdquo;</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">F</div></td>
<td class="style1">Killer track (full of SYNC)</td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">S</div></td>
<td class="style1">???, likely a verify error </td>
</tr>
<tr class="style1">
<td class="style1"><div align="center">P</div></td>
<td class="style1">???, likely a verify error </td>
</tr>
</table>
<p class=style1>&nbsp;</p>
<p class=style2>Update, June 8, 2004</p>
<p class=style1>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.</p>
<p class=style1>&nbsp;</p>
<p class=style2>Update, Oct 4, 2007</p>
<p class=style1>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:</p>
<p class="style1">&quot;Hi Peter, I just came over your article about F64 files and FCopyPC. My name is Guido Gouweloos, <em><strong>Unicorn</strong></em> 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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style2"><em>Why the severe lack of documentation about the F64 format in the first place?</em></p>
<p class="style1">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).</p>
<p class="style1">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.</p>
<p class="style2"><em>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?</em></p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style2"><em>...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.</em></p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">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.</p>
<p class="style1">Regards,
Guido.&quot;</p>
<p class="style1"><a href="#top"><strong>Back to top</strong></a></p>
<hr width="100%">
<p class="style1" align="left">Email the author: <a href="mailto:schepers@uwaterloo.ca">Peter Schepers</a> | Last updated: Oct 4, 2007</p>
</div>
</div>
<!--end content -->
<div id="navBar">
<div id="sectionLinks">
<h3>Site Index</h3>
<ul>
<li><a href="personal.html">64Copy Home</a></li>
<li><a href="news.html">64Copy Development News</a></li>
<li><a href="download.html">Software Downloads page</a></li>
<li><a href="transmag.html">Transactor Magazines Scans</a></li>
<li><a href="formats.html">View the Formats docs</a></li>
<li><a href="F64.html">Decoding the F64 filetype</a></li>
<li><a href="diagnostic.html">Commodore Diagnostic Setup</a></li>
<li><a href="gallery.html">Gallery</a></li>
<li><a href="FAQ.html">64Copy FAQ</a></li>
<li><a href="./MJK/index.html">Marc-Jano Knopp Site</a></li>
<li><a href="aboutme.html">About the author</a><br />
</li>
</ul>
</div>
<div id="sectionLinks">
<h3><br />
Cables, ROM's & Troubleshooting</h3>
<ul>
<li><a href="cables.html">Buy or Build X-series Cables</a></li>
<li><a href="pick.html">Choosing a Cable</a></li>
<li><a href="imaging.html">DOS Boot Imaging CD for 1541/71</a></li>
<li><a href="trouble.html">Troubleshooting Cables Under DOS</a></li>
<li><a href="mnib.html">Working with MNIB/NIBTOOLS</a></li>
<li><a href="roms.html">C64/1541 ROMs</a></li>
<li><a href="sockets.html">ROM Socket Adapters</a></li>
</ul>
</div>
<div id="sectionLinks">
<h3><br />
Special Links</h3>
<ul>
<li><a href="http://www.fairlight.to" target="_blank">Fairlight</a></li>
<li><a href="http://sta.c64.org" target="_blank">Star Commander</a></li>
<li><a href="http://markus.brenner.de" target="_blank">Markus Brenner (MNIB) </a></li>
<li><a href="http://arnold.c64.org" target="_blank">Arnold C64 Archive</a></li>
<li><a href="http://www.zimmers.net" target="_blank">Bo Zimmerman </a></li>
<li><a href="http://www.csbruce.com/~csbruce/cbm" target="_blank">Craig Bruce</a></li>
<li><a href="http://d81.de" target="_blank">Wolfgang Moser</a></li>
<li><a href="http://rittwage.com/c64pp/dp.php?pg=home" target="_blank">C= Preservation Project (NIBTOOLS)</a></li>
</ul>
</div>
<div id="sectionLinks">
<h3><br />
Emulator Links</h3>
<ul>
<li><a href="http://www.viceteam.org" target="_blank">Vice Emulator</a></li>
<li><a href="http://www.computerbrains.com" target="_blank">CCS64 Emulator</a></li>
</ul>
</div>
</div>
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="schepers@uwaterloo.ca">
<input type="hidden" name="item_name" value="64Copy development">
<input type="hidden" name="currency_code" value="CAD">
<input type="hidden" name="amount" value="25.00">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" hspace="20" vspace="20" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
<!--end navbar -->
</body>
</html>

473
Commodore/G64.TXT Normal file
View File

@@ -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-1541<34>T<EFBFBD><54>....
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 ............<2E><><EFBFBD><EFBFBD>
0010: 00 00 00 00 A6 21 00 00 00 00 00 00 A0 40 00 00 <20><><EFBFBD><EFBFBD><EFBFBD>!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><>
0020: 00 00 00 00 9A 5F 00 00 00 00 00 00 94 7E 00 00 <20><><EFBFBD><EFBFBD><EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><>
0030: 00 00 00 00 8E 9D 00 00 00 00 00 00 88 BC 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 00 82 DB 00 00 00 00 00 00 7C FA 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD>
0050: 00 00 00 00 76 19 01 00 00 00 00 00 70 38 01 00 <20><><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p8<70><38>
0060: 00 00 00 00 6A 57 01 00 00 00 00 00 64 76 01 00 <20><><EFBFBD><EFBFBD>jW<6A><57><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dv<64><76>
0070: 00 00 00 00 5E 95 01 00 00 00 00 00 58 B4 01 00 <20><><EFBFBD><EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><58><EFBFBD>
0080: 00 00 00 00 52 D3 01 00 00 00 00 00 4C F2 01 00 <20><><EFBFBD><EFBFBD>R<EFBFBD><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>
0090: 00 00 00 00 46 11 02 00 00 00 00 00 40 30 02 00 <20><><EFBFBD><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@0<><30>
00A0: 00 00 00 00 3A 4F 02 00 00 00 00 00 34 6E 02 00 <20><><EFBFBD><EFBFBD>:O<><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4n<34><6E>
00B0: 00 00 00 00 2E 8D 02 00 00 00 00 00 28 AC 02 00 <20><><EFBFBD><EFBFBD>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD>
00C0: 00 00 00 00 22 CB 02 00 00 00 00 00 1C EA 02 00 <20><><EFBFBD><EFBFBD>"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 00 00 00 00 16 09 03 00 00 00 00 00 10 28 03 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>
00E0: 00 00 00 00 0A 47 03 00 00 00 00 00 04 66 03 00 <20><><EFBFBD><EFBFBD><EFBFBD>G<EFBFBD><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD><66>
00F0: 00 00 00 00 FE 84 03 00 00 00 00 00 F8 A3 03 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0100: 00 00 00 00 F2 C2 03 00 00 00 00 00 EC E1 03 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0110: 00 00 00 00 E6 00 04 00 00 00 00 00 E0 1F 04 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0120: 00 00 00 00 DA 3E 04 00 00 00 00 00 D4 5D 04 00 <20><><EFBFBD><EFBFBD><EFBFBD>><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]<5D><>
0130: 00 00 00 00 CE 7C 04 00 00 00 00 00 C8 9B 04 00 <20><><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ț<EFBFBD><C89B>
0140: 00 00 00 00 C2 BA 04 00 00 00 00 00 BC D9 04 00 <20><><EFBFBD><EFBFBD>º<EFBFBD><C2BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0150: 00 00 00 00 B6 F8 04 00 00 00 00 00 .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.....
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 ............<2E><><EFBFBD><EFBFBD>
02B0: FF FF FF 52 54 B5 29 4B 7A 5E 95 55 55 55 55 55 <20><><EFBFBD>RT<52>)Kz^<5E>UUUUU
02C0: 55 55 55 55 55 55 FF FF FF FF FF 55 D4 A5 29 4A UUUUUU<55><55><EFBFBD><EFBFBD><EFBFBD>Uԥ)J
02D0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)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<><52>)JR<4A><52>)JR<4A><52>)JR
1FF0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 <20><>)JR<4A><52>)JR<4A><52>)JR<4A>
2000: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
2010: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR<4A><52>)JR<4A><52>)JR<4A><52>)
2020: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)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<55><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
21A0: FF FF FF FF FF FF .. .. .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..........
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 ............<2E><><EFBFBD><EFBFBD>
0160: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0170: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0180: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0190: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01A0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01B0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01C0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01D0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01E0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01F0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0200: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0210: 00 00 00 00 02 00 00 00 00 00 00 00 01 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0220: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0230: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0240: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02A0: 00 00 00 00 00 00 00 00 00 00 00 00 .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>....
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
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20> <20> <20> <20>
<20> <20> <20> <20><> 4'th byte speed (binary 11, 3 dec)
<20> <20> <20><><EFBFBD><EFBFBD> 3'rd byte speed (binary 11, 3 dec)
<20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2'nd byte speed (binary 11, 3 dec)
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>RT<52>)Kz^<5E>U
0010: 55 55 55 55 55 55 55 55 55 55 FF FF FF FF FF 55 UUUUUUUUUU<55><55><EFBFBD><EFBFBD><EFBFBD>U
0020: D4 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 ԥ)JR<4A><52>)JR<4A><52>)JR<4A>
0030: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
0040: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR<4A><52>)JR<4A><52>)JR<4A><52>)
0050: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)J
0060: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)JR
0070: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 <20><>)JR<4A><52>)JR<4A><52>)JR<4A>
0080: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
0090: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR<4A><52>)JR<4A><52>)JR<4A><52>)
00A0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)J
00B0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)JR
00C0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 <20><>)JR<4A><52>)JR<4A><52>)JR<4A>
00D0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
00E0: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR<4A><52>)JR<4A><52>)JR<4A><52>)
00F0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)J
0100: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)JR
0110: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 <20><>)JR<4A><52>)JR<4A><52>)JR<4A>
0120: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
0130: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR<4A><52>)JR<4A><52>)JR<4A><52>)
0140: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)J
0150: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)JR
0160: 94 A5 29 4A 55 55 55 55 55 55 FF FF FF FF FF 52 <20><>)JUUUUUU<55><55><EFBFBD><EFBFBD><EFBFBD>R
0170: 54 A5 2D 4B 7A 5E 95 55 55 55 55 55 55 55 55 55 T<>-Kz^<5E>UUUUUUUUU
0180: 55 55 FF FF FF FF FF 55 D4 A5 29 4A 52 94 A5 29 UU<55><55><EFBFBD><EFBFBD><EFBFBD>Uԥ)JR<4A><52>)
0190: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR<4A><52>)JR<4A><52>)JR<4A><52>)J
01A0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R<><52>)JR<4A><52>)JR<4A><52>)JR
01B0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 <20><>)JR<4A><52>)JR<4A><52>)JR<4A>
01C0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 <20>)JR<4A><52>)JR<4A><52>)JR<4A><52>
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

304
Commodore/GEOS.TXT Normal file
View File

@@ -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 <20><><EFBFBD><EFBFBD><EFBFBD>?<3F><>@D<><44>8ⵓ
10: 59 AA 92 A9 B5 93 59 AA 92 A9 BF 93 F9 B1 93 19 Y<><59><EFBFBD><EFBFBD><EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 8E 10 E1 BB 93 B9 B5 93 59 AA 92 A9 B5 93 59 AE <20><><EFBFBD><E1BB93><EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD>Y<EFBFBD>
30: 92 E9 B1 93 19 80 10 01 BF 93 F9 FF D7 FD 80 38 <20><EFBFBD><E9B193><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8
40: 03 FF FF FF 83 05 00 00 2E D9 54 00 2E 50 68 6F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E>T<EFBFBD>.Pho
50: 74 6F 20 4D 67 72 20 20 20 56 32 2E 31 00 00 00 to<74>Mgr<67><72><EFBFBD>V2.1<EFBFBD><EFBFBD><EFBFBD>
60: 00 43 68 72 69 73 20 48 61 77 6C 65 79 00 00 00 <20>Chris<69>Hawley<65><79><EFBFBD>
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 00 53 61 76 65 20 70 68 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Save<76>ph
90: 6F 74 6F 20 69 6D 61 67 65 73 20 69 6E 20 61 20 oto<74>images<65>in<69>a<EFBFBD>
A0: 53 61 76 65 20 70 68 6F 74 6F 20 69 6D 61 67 65 Save<76>photo<74>image
B0: 73 20 69 6E 20 61 20 70 68 6F 74 6F 20 61 6C 62 s<>in<69>a<EFBFBD>photo<74>alb
C0: 75 6D 20 66 6F 72 20 6C 61 74 65 72 20 75 73 65 um<75>for<6F>later<65>use
D0: 20 69 6E 20 67 65 6F 57 72 69 74 65 20 6F 72 20 <20>in<69>geoWrite<74>or<6F>
E0: 67 65 6F 50 61 69 6E 74 2E 00 02 85 06 85 07 85 geoPaint.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 08 85 09 85 16 A9 04 85 11 A9 00 85 10 4C 2F C2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L/<2F>
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 <20><>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i)<29><><EFBFBD><EFBFBD><EFBFBD>
10: 0C 96 D6 16 01 00 00 10 00 00 00 00 11 FD BD 1D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 15 FF FF 1F 0C 96 D6 16 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
40: 00 00 00 00 00 00 00 00 0F FC FD 05 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
50: 00 00 00 00 06 05 05 05 01 00 40 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD>
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
80: 00 00 00 00 00 00 00 00 01 00 02 00 11 FF FF 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
90: 41 70 70 6C 69 63 61 74 69 6F 6E 73 A0 A0 A0 A0 Applications<6E><73><EFBFBD><EFBFBD>
A0: A0 A0 4A 44 A0 32 41 A0 A0 A0 A0 13 08 47 45 4F <20><>JD<4A>2A<32><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GEO
B0: 53 20 66 6F 72 6D 61 74 20 56 31 2E 30 50 BD 1E S<>format<61>V1.0P<EFBFBD><EFBFBD>
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
D0: 00 00 00 00 00 00 00 00 00 00 00 18 2D 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD>
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

277
Commodore/INTRO.TXT Normal file
View File

@@ -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.
<CR> - Short form for a Carriage Return ($0D) symbol.
<LF> - 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.

125
Commodore/LBR.TXT Normal file
View File

@@ -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 <CR>.
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 DWB<57>9<EFBFBD><39>SUPER<45>DOS
0010: 0D 50 0D 20 31 35 30 37 20 0D 44 4D 43 20 31 2E <20>P<EFBFBD><50>1507<30><37>DMC<4D>1.
0020: 32 2F 47 52 41 46 46 49 54 59 0D 50 0D 20 32 30 2/GRAFFITY<54>P<EFBFBD><50>20
0030: 32 34 31 20 0D 42 2E 44 45 4C 54 41 20 5A 41 4B 241<34><31>B.DELTA<54>ZAK
0040: 20 2E 44 4D 43 0D 50 0D 20 32 37 30 32 20 0D 42 <20>.DMC<4D>P<EFBFBD><50>2702<30><32>B
0050: 2E 52 4F 43 4B 20 5A 41 4B 31 20 2E 44 4D 43 0D .ROCK<43>ZAK1<4B>.DMC<4D>
0060: 50 0D 20 32 38 38 36 20 0D 49 4E 46 4F 52 4D 41 P<><50>2886<38><36>INFORMA
0070: 54 49 4F 4E 2E 2E 2E 0D 50 0D 20 38 38 34 38 20 TION...<2E>P<EFBFBD><50>8848<34>
0080: 0D 42 2E 4B 49 44 44 49 4E 47 20 20 20 2E 44 4D <20>B.KIDDING<4E><47><EFBFBD>.DM
0090: 43 0D 50 0D 20 32 38 39 31 20 0D 42 2E 47 41 4C C<>P<EFBFBD><50>2891<39><31>B.GAL
00A0: 57 41 59 20 5A 41 4B 2E 44 4D 43 0D 50 0D 20 32 WAY<41>ZAK.DMC<4D>P<EFBFBD><50>2
00B0: 38 36 30 20 0D 42 2E 41 20 4D 55 53 49 43 20 20 860<36><30>B.A<>MUSIC<49><43>
00C0: 20 2E 44 4D 43 0D 50 0D 20 33 31 33 37 20 0D 47 <20>.DMC<4D>P<EFBFBD><50>3137<33><37>G
00D0: 2E 50 41 43 4D 41 4E 49 41 20 20 2E 44 4D 43 0D .PACMANIA<49><41>.DMC<4D>
00E0: 50 0D 20 33 32 36 32 20 0D 01 08 0B 08 00 00 9E P<><50>3262<36><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <CR> at the end of the
string.
0000: .. .. .. 20 39 20 0D .. .. .. .. .. .. .. .. .. ...<2E>9<EFBFBD>..........
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 <CR>. From my experiments with the Library program, it does *not*
support REL files.
0000: .. .. .. .. .. .. .. 53 55 50 45 52 20 44 4F 53 .......SUPER<45>DOS
0010: 0D 50 0D 20 31 35 30 37 20 0D .. .. .. .. .. .. .P.<2E>1507<30>.......
Following this are the remaining directory entries.
0010: .. .. .. .. .. .. .. .. .. .. 44 4D 43 20 31 2E ..........DMC<4D>1.
0020: 32 2F 47 52 41 46 46 49 54 59 0D 50 0D 20 32 30 2/GRAFFITY.P.<2E>20
0030: 32 34 31 20 0D .. .. .. .. .. .. .. .. .. .. .. 241<34>............
...
00C0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 47 ...............G
00D0: 2E 50 41 43 4D 41 4E 49 41 20 20 2E 44 4D 43 0D .PACMANIA<49><41>.DMC.
00E0: 50 0D 20 33 32 36 32 20 0D .. .. .. .. .. .. .. P.<2E>3262<36>.......
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 <CR> of the last entry it is the first byte of the first
entry.
00E0: .. .. .. .. .. .. .. .. .. 01 08 0B 08 00 00 9E .............<2E><><EFBFBD>
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 <CR>) 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.

119
Commodore/LHA.TXT Normal file
View File

@@ -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 M4<4D>S"). 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.

226
Commodore/LNX.TXT Normal file
View File

@@ -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 ..[.<2E><><EFBFBD>53280,0:<3A>
0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31 53281,0:<3A>646,<2C>(1
0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22 62):<3A>"<22>........"
0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58 :<3A>"<22><><EFBFBD><EFBFBD><EFBFBD>USE<53>LYNX
0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49 <20>TO<54>DISSOLVE<56>THI
0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 0D 20 S<>FILE":<3A>10<31><30><EFBFBD>.<2E>
0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20 1<><31>*LYNX<4E>XV<58><56>BY<42>
0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D WILL<4C>CORLEY.<2E>4<EFBFBD>.
0080: 34 21 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 4!ZONE<4E>OF<4F>D-/AVT
0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D 31 21 .<2E>71<37>.P.<2E>160<36>.1!
00A0: 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 ZONE<4E>OF<4F>D-/AVT.<2E>
00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D 32 21 5A 4F 75<37>.P.<2E>151<35>.2!ZO
00C0: 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 37 NE<4E>OF<4F>D-/AVT.<2E>17
00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E 0<>.P.<2E>249<34>.3!ZON
00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38 E<>OF<4F>D-/AVT.<2E>158
00F0: 20 0D 50 0D 20 31 33 38 20 0D 00 00 00 00 00 04 <20>.P..138<EFBFBD>.<2E><><EFBFBD><EFBFBD><EFBFBD>
0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03 .<2E>....<2E><><EFBFBD><EFBFBD>…..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"<CLS><DOWN><DOWN><DOWN>
<DOWN><DOWN><DOWN><DOWN><DOWN>":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 ..[.<2E><><EFBFBD>53280,0:<3A>
0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31 53281,0:<3A>646,<2C>(1
0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22 62):<3A>"<22>........"
0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58 :<3A>"<22><><EFBFBD><EFBFBD><EFBFBD>USE<53>LYNX
0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49 <20>TO<54>DISSOLVE<56>THI
0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 .. .. S<>FILE":<3A>10<31><30><EFBFBD>..
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 <CR> 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 <CR>.
0050: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 0D 20 ................
0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20 1<><31>*LYNX<4E>XV<58><56>BY<42>
0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D WILL<4C>CORLEY.<2E>4<EFBFBD>.
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!ZONE<4E>OF<4F>D-/AVT
0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D .. .. .<2E>71<37>.P.<2E>160<36>...
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 ZONE<4E>OF<4F>D-/AVT.<2E>
00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D .. .. .. .. 75<37>.P.<2E>151<35>.....
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 NE<4E>OF<4F>D-/AVT.<2E>17
00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E 0<>.P.<2E>249<34>.3!ZON
00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38 E<>OF<4F>D-/AVT.<2E>158
00F0: 20 0D 50 0D 20 31 33 38 20 0D .. .. .. .. .. .. <20>.P.<2E>138<33>.......
This is the third and fourth entry.
00F0: .. .. .. .. .. .. .. .. .. .. 00 00 00 00 .. .. ..........<2E><><EFBFBD><EFBFBD>..
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 ..............<2E>.
0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03 .<2E>....<2E><><EFBFBD><EFBFBD>.<2E>..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

225
Commodore/PC64.TXT Normal file
View File

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

46
Commodore/PC64_FRZ.TXT Normal file
View File

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

22
Commodore/PC64_ROM.TXT Normal file
View File

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

32
Commodore/PCLINK.TXT Normal file
View File

@@ -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́<38>PCLINK<4E><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
20: 00 00 00 00 01 08 0B 08 00 00 9E 32 30 36 31 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2061<36>
30: 00 00 78 A2 FB 9A 20 18 E5 20 55 10 A9 00 8D 20 <20><>x<EFBFBD><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>U<EFBFBD><55><EFBFBD><EFBFBD><EFBFBD>
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.

107
Commodore/PCVIC.TXT Normal file
View File

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

138
Commodore/PHAUZEH.TXT Normal file
View File

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

62
Commodore/POWER64.TXT Normal file
View File

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

110
Commodore/REL.TXT Normal file
View File

@@ -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 <20><><EFBFBD>..ADDITIONAL<41>
10: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 INFO<46>..<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 11 02 11 0D 11 03 11 0E 11 04 11 0F 11 05 11 10 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 11 06 11 11 11 07 11 12 11 08 11 13 11 09 11 14 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 11 0A 11 0B 10 00 10 0A 10 14 10 08 10 12 10 06 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 10 10 10 04 10 0E 10 02 10 0C 10 01 10 0B 10 03 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 10 0D 10 05 10 0F 10 07 10 11 10 09 10 13 0F 07 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 0F 11 0F 05 0F 0F 0F 03 0F 0D 0F 01 0F 0B 0F 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0070: 0F 0A 0F 14 0F 08 0F 12 0F 06 0F 10 0F 04 0F 0E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0080: 0F 02 0F 0C 0F 09 0F 13 0E 07 0E 11 0E 05 0E 0F <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: 0E 03 0E 0D 0E 01 0E 0B 0E 00 0E 0A 0E 14 0E 08 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00A0: 0E 12 0E 06 0E 10 0E 04 0E 0E 0E 02 0E 0C 0E 09 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 0E 13 0D 07 0D 11 0D 05 0D 0F 0D 03 0D 0D 0D 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 0D 0B 0D 00 0D 0A 0D 14 0D 08 0D 12 0D 06 0D 10 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 0D 04 0D 0E 0D 02 0D 0C 0D 09 0D 13 0C 07 0C 11 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00E0: 0C 05 0C 0F 0C 03 0C 0D 0C 01 0C 0B 0C 00 0C 0A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 0C 14 0C 08 0C 12 0C 06 0C 10 0C 04 0C 0E 0C 02 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

60
Commodore/SDA.TXT Normal file
View File

@@ -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 ....<2E><><EFBFBD>(2063)<29><><EFBFBD>
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.

67
Commodore/SFX.TXT Normal file
View File

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

510
Commodore/SIDPLAY.TXT Normal file
View File

@@ -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=<loadAddress>,<initAddress>,<playAddress>
SONGS=<total>[,<start>]
SPEED=<hexValue>
NAME=<name of music/tune>
AUTHOR=<name of author/composer>
COPYRIGHT=<year/name of copyright owner/company>
RELEASED=<year/name of copyright owner/company>
SIDSONG=<YES|NO>
RELOC=<hexValue>,<hexValue>
CLOCK=<PAL|NTSC>
SIDMODEL=<6581|8580>
COMPATIBILITY=<R64|BASIC>
The first line of the text containing ``SIDPLAY INFOFILE'' is only used
to identify the type of file.
ADDRESS=<loadAddress>,<initAddress>,<playAddress>
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.
<loadAddress> 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.
<initAddress> 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.
<playAddress> 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=<total>,[<start>]
<total> is the decimal number of songs (or sound effects) that can be
initialized by calling the init address. The minimum is 1.
<start> 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=<value>
<value> 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=<name of music/tune>
AUTHOR=<name of author/composer>
RELEASED=<year/name of copyright owner/company>
or
COPYRIGHT=<year/name of copyright owner/company>
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=<YES|NO>
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=<hexValue>,<hexValue>
is used to indicate a free memory range not used by the sid tune. (e.g.
RELOC=04,65)
CLOCK=<PAL|NTSC>
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=<R64|BASIC>
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 ``<name>''
+36 ``<author>''
+56 ``<released>'' (also known as ``<copyright>'')
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 <data>
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 <data>
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).

131
Commodore/SPYNE.TXT Normal file
View File

@@ -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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD>Щ
0010: 04 8D 1F D0 20 44 E5 A9 D8 85 FC A0 00 84 FB A2 <20><><EFBFBD><EFBFBD><EFBFBD>D<EFBFBD><44>؅<EFBFBD><D885><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 04 A9 0D 91 FB C8 D0 FB E6 FC CA D0 F6 20 A5 FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20><><EFBFBD>02.DIGITAL<41>MA
0EF2: 47 49 43 00 00 00 00 88 18 B5 FF 00 2B 00 00 00 GIC<49><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD>
0F02: 82 00 00 30 39 2E 2D 2D 2D 3E 20 42 59 20 3C 2D <20><><EFBFBD>09.---><3E>BY<42><-
0F12: 2D 2D 2D 00 00 00 00 00 7A 44 FF 00 2D 00 00 00 ---<2D><><EFBFBD><EFBFBD><EFBFBD>zD<7A><44>-<2D><><EFBFBD>
0F22: 82 00 00 30 33 2E 2D 3E 20 46 4F 52 43 45 53 20 <20><><EFBFBD>03.-><3E>FORCES<45>
0F32: 3C 2D 2D 00 00 00 00 11 BE 89 FF 00 20 00 00 00 <--<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0F42: 82 00 00 30 37 2E 2D 3E 20 4F 46 20 45 56 49 4C <20><><EFBFBD>07.-><3E>OF<4F>EVIL
0F52: 20 3C 2D 00 00 00 00 4F 78 11 FF 00 26 00 00 00 <20><-<2D><><EFBFBD><EFBFBD>Ox<4F><78><EFBFBD>&<26><><EFBFBD>
0F62: 82 00 00 30 34 2E 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D <20><><EFBFBD>04.----------
0F72: 2D 2D 2D 00 00 00 00 40 58 D2 FF 00 28 00 00 00 ---<2D><><EFBFBD><EFBFBD>@X<><58><EFBFBD>(<28><><EFBFBD>
0F82: 82 00 00 30 31 2E 20 52 45 4C 45 41 53 45 44 20 <20><><EFBFBD>01.<2E>RELEASED<45>
0F92: 4F 4E A0 00 00 00 00 05 D5 0F FF 00 29 00 00 00 ON<4F><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD>
0FA2: 82 00 00 30 35 2E 20 4A 41 4E 55 41 52 59 20 31 <20><><EFBFBD>05.<2E>JANUARY<52>1
0FB2: 53 54 20 00 00 00 00 F7 FA EC FF 00 24 00 00 00 ST<53><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>$<24><><EFBFBD>
0FC2: 82 00 00 30 38 2E 20 20 20 31 39 39 36 A0 A0 A0 <20><><EFBFBD>08.<2E><><EFBFBD>1996<39><36><EFBFBD>
0FD2: A0 A0 A0 00 00 00 00 39 71 C8 FF 00 36 00 82 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>9q<39><71><EFBFBD>6<EFBFBD><36><EFBFBD>
0FE2: 00 30 36 2E 20 28 4D 4F 52 45 20 4C 49 4B 45 29 <20>06.<2E>(MORE<52>LIKE)
0FF2: A0 00 00 00 00 40 33 CF FF 00 32 00 00 00 82 00 <20><><EFBFBD><EFBFBD><EFBFBD>@3<><33><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>
1002: 00 31 30 2E 20 28 31 32 2F 32 38 2F 39 35 21 29 <20>10.<2E>(12/28/95!)
1012: A0 00 00 00 00 AD 1C 0F FF 00 2B 00 00 00 82 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD><EFBFBD>
1022: 00 44 49 47 49 54 41 4C 20 4E 4F 54 45 A0 A0 A0 <20>DIGITAL<41>NOTE<54><45><EFBFBD>
1032: A0 00 00 00 00 49 B0 CB 00 00 14 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

221
Commodore/T64.TXT Normal file
View File

@@ -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 (?)

75
Commodore/TAP.TXT Normal file
View File

@@ -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<41><57><EFBFBD><EFBFBD>
0010: 51 21 08 00 2F 0F 0D 31 64 1D 26 0D 07 21 0A 12 Q!<21><>/<2F><>1d<31>&<26><>!<21><>
0020: 4A 2F 2C 34 07 18 0D 31 07 04 23 04 0D 42 0D 1E J/,4<><34><EFBFBD>1<EFBFBD><31>#<23><>B<EFBFBD><42>
0030: 34 04 42 0D 20 15 5E 04 0D 18 61 0D 26 29 34 0D 4<>B<EFBFBD><42><EFBFBD>^<5E><><EFBFBD>a<EFBFBD>&)4<>
0040: 23 0D 07 0A 3F 55 04 0A 13 3F 07 0D 12 2B 18 0A #<23><><EFBFBD>?U<><55><EFBFBD>?<3F><><EFBFBD>+<2B><>
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.

969
Commodore/VICE_FRZ.TXT Normal file
View File

@@ -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 VICE<43>Snapshot<6F>Fi
0010: 6C 65 1A 00 00 43 31 32 38 00 00 00 00 00 00 00 le<6C><65><EFBFBD>C128<32><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 00 00 00 00 00 .. .. .. .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD>...........
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<50><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 35 00 00 00 F8 0E AA 00 00 00 00 F3 5E C2 <20><>5<EFBFBD><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<5E>
0020: 22 F0 01 00 00 F1 00 AA 00 32 15 09 00 2B 00 00 "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD>+<2B><>
0030: 00 33 FE A9 00 .. .. .. .. .. .. .. .. .. .. .. <20>3<EFBFBD><33><EFBFBD>...........
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<45><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 1A 00 01 00 37 2F 00 00 2F 37 00 AA B1 91 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>7/<2F><>/7<><37><EFBFBD><EFBFBD>
0020: B3 22 22 00 00 00 00 FF 00 00 00 00 00 00 00 00 <20>""<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 19 16 00 0A 76 A3 00 00 00 00 00 00 76 A3 B3 BD <20><><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD>
0040: 00 00 00 00 00 01 08 03 08 03 08 03 08 00 A0 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 16 50 00 00 85 56 20 0F BC A5 61 C9 88 90 <20><><EFBFBD>P<EFBFBD><50><EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><61>
0020: 03 20 D4 BA 20 CC BC A5 07 18 69 81 F0 F3 38 E9 <20><>Ժ<EFBFBD>̼<EFBFBD><CCBC><EFBFBD>i<EFBFBD><69><EFBFBD>8<EFBFBD>
0030: 01 48 A2 05 B5 69 B4 61 95 61 94 69 CA 10 F5 A5 <20>H<EFBFBD><48><EFBFBD>i<EFBFBD>a<EFBFBD>a<EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>
0040: 56 85 70 20 53 B8 20 B4 BF A9 C4 A0 BF 20 59 E0 V<>p<EFBFBD>S<EFBFBD><53><EFBFBD><EFBFBD><EFBFBD>Ġ<EFBFBD><C4A0>Y<EFBFBD>
0050: A9 00 85 6F 68 20 B9 BA 60 85 71 84 72 20 CA BB <20><><EFBFBD>oh<6F><68><EFBFBD>`<60>q<EFBFBD>r<EFBFBD>ʻ
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<49><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 DD 04 00 00 01 00 01 0E 0E 0E 0E 0E 0E 0E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 02 41 00 00 00 7F 00 FF 00 09 2C FF FF 00 00 <20><>A<EFBFBD><41><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>
0020: 00 01 00 01 01 08 25 40 FF FF 00 40 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%@<40><><EFBFBD>@<40><><EFBFBD><EFBFBD>
0030: 00 00 02 00 00 00 00 2B 1C 00 00 63 08 28 11 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD>c<EFBFBD>(<28><>
0040: 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. <20>...............
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<41><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 02 41 00 00 00 97 00 3F 00 FF FF FF FF 00 00 <20><>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 00 01 00 00 08 08 FF FF FF FF 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 02 00 00 00 00 2B 1C 00 00 28 11 28 11 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD>(<28>(<28><>
0040: 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. <20>...............
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<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 36 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><>6<EFBFBD><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 .. .. .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..........
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<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 2A 00 08 00 00 02 00 00 50 4A 00 00 00 00 <20><>*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PJ<50><4A><EFBFBD><EFBFBD>
0020: 00 00 00 00 00 00 00 00 00 00 0C 00 76 00 D4 BE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Ծ
0030: 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<45><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 21 00 02 00 00 3F 7F 01 41 B7 04 00 00 01 <20><>!<21><><EFBFBD><EFBFBD>?<>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>
0020: 00 2F C3 00 00 00 00 00 00 00 00 00 00 00 9B 00 <20>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 00 FF FF 1B 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 00 00 03 02 00 00 00 00 00 00 00 01 1C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 16 C0 00 00 A2 FF 78 9A D8 A9 00 8D 00 FF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x<EFBFBD>ة<EFBFBD><D8A9><EFBFBD><EFBFBD>
0020: A2 0A BD 4B E0 9D 00 D5 CA 10 F7 8D 04 0A 20 CD <20><><EFBFBD>K<EFBFBD><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: E0 20 F0 E1 20 42 E2 20 09 E1 20 3D F6 48 30 07 <20><><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD>=<3D>H0<48>
0040: A9 A5 CD 02 0A F0 03 20 93 E0 20 56 E0 20 00 C0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD>
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<45><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 17 A8 00 00 2F 4C 48 D2 AA D1 91 D3 22 22 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/LHҪё<D2AA>""
0020: 00 00 00 00 FF 00 00 00 00 00 00 00 00 19 16 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 0A 76 C3 00 00 00 00 00 00 76 C3 B3 DD 00 00 00 <20>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><76><C3B3><EFBFBD><EFBFBD>
0040: 00 00 01 12 03 12 03 12 03 12 00 80 00 00 00 80 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 17 50 00 00 00 0F DC A5 61 C9 88 90 03 20 <20><><EFBFBD>P<EFBFBD><50><EFBFBD><EFBFBD>ܥaɈ<61><C988><EFBFBD>
0020: D4 DA 20 CC DC A5 07 18 69 81 F0 F3 38 E9 01 48 <20><><EFBFBD><EFBFBD>ܥ<EFBFBD><DCA5>i<EFBFBD><69><EFBFBD>8<EFBFBD><38>H
0030: A2 05 B5 69 B4 61 95 61 94 69 CA 10 F5 A5 56 85 <20><><EFBFBD>i<EFBFBD>a<EFBFBD>a<EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>V<EFBFBD>
0040: 70 20 53 D8 20 B4 DF A9 C4 A0 DF 20 56 E0 A9 00 p<>S<EFBFBD><53><EFBFBD>ߩĠ<DFA9><C4A0>V<EFBFBD><56><EFBFBD>
0050: 85 6F 68 20 B9 DA 60 85 71 84 72 20 CA DB A9 57 <20>oh<6F><68><EFBFBD>`<60>q<EFBFBD>r<EFBFBD><72>۩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<><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 2B 08 00 00 01 00 00 00 00 06 06 06 06 06 <20><>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 06 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 01 01 01 01 01 01 01 06 06 06 06 06 06 06 06 06 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 2C 00 00 00 00 00 F7 FF 26 48 05 2C FF AB <20><>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>&H<>,<2C><>
0020: F9 80 00 40 DE 00 40 00 00 80 FF 00 .. .. .. .. <20><><EFBFBD>@<40><>@<40><><EFBFBD><EFBFBD><EFBFBD>....
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<41><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 2C 00 00 00 00 80 00 00 FF FF CE 66 FF AB <20><>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<EFBFBD><66>
0020: F9 00 00 40 FE 00 02 80 00 C0 7C 00 .. .. .. .. <20><><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C>....
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<45><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 02 1D 88 00 00 02 00 20 00 07 4C 73 C3 22 22 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ls<4C>""
0020: 5B 00 FF 00 01 00 00 00 00 00 00 00 FF FF 16 13 [<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 08 12 B3 00 00 00 00 00 00 12 B3 E9 CE 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 00 00 01 04 03 04 03 04 03 04 00 80 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 17 50 00 00 04 54 4F 4F 20 4D 41 4E 59 20 <20><><EFBFBD>P<EFBFBD><50><EFBFBD>TOO<4F>MANY<4E>
0020: 46 49 4C 45 D3 46 49 4C 45 20 4F 50 45 CE 46 49 FILE<4C>FILE<4C>OPE<50>FI
0030: 4C 45 20 4E 4F 54 20 4F 50 45 CE 46 49 4C 45 20 LE<4C>NOT<4F>OPE<50>FILE<4C>
0040: 4E 4F 54 20 46 4F 55 4E C4 0D 53 45 41 52 43 48 NOT<4F>FOUN<55><4E>SEARCH
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<54><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 55 00 00 00 FF 07 00 08 00 20 00 10 FF 1F <20><>U<EFBFBD><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 00 10 00 02 00 3F 28 32 08 20 10 19 1D 00 08 00 <20><><EFBFBD><EFBFBD><EFBFBD>?(2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 10 00 00 00 00 00 00 00 00 00 1F 06 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 00 10 B0 09 00 00 00 C0 02 1A 01 00 00 00 00 1C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 00 39 01 1D 01 .. .. .. .. .. .. .. .. .. .. .. <20>9<EFBFBD><39><EFBFBD>...........
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<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 1D 00 00 00 F9 0F 3C FF 00 3D C0 .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<3C><>=<3D>...
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<41><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 1D 00 00 00 FF 00 3C FF FF 3C C0 .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<3C><><<3C>...
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<49><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 2C 00 00 00 00 00 DF 1E FF FF CE 7B 0E 58 <20><>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{<7B>X
0020: 77 00 00 00 0E 40 00 80 00 C0 00 DF .. .. .. .. w<><77><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>....
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<45><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 1B 10 02 00 01 00 02 0F 01 0F 01 4C A7 9B <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C>
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 D4 FA 02 00 FF FF 00 FF FF C8 FA 5E FA 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<5E><>
0040: 00 00 00 00 00 00 00 00 03 00 05 00 02 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0050: 02 00 00 00 02 00 BD FA 00 00 BD FA 02 00 FF 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0060: 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 17 70 00 00 00 4C 09 EE EA 4C 44 E0 4C FE <20><><EFBFBD>p<EFBFBD><70><EFBFBD>L<EFBFBD><4C><EFBFBD>LD<4C>L<EFBFBD>
0020: E0 4C 79 E1 4C 99 E2 4C 3F E0 4C 65 E8 4C DA E0 <20>Ly<4C>L<EFBFBD><4C>L?<3F>Le<4C>L<EFBFBD><4C>
0030: 4C 25 E0 4C 3A E0 4C 70 E9 4C F8 E6 B0 0E 86 CA L%<25>L:<3A>Lp<4C>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0040: 86 CF 84 CB 84 CE 20 CD E0 20 DA E0 A6 CA A4 CB <20>τ˄<CF84><CB84><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD>
0050: 60 A2 00 A0 DC 60 A2 50 A0 19 60 A9 00 A2 23 95 `<60><><EFBFBD><EFBFBD>`<60>P<EFBFBD><50>`<60><><EFBFBD>#<23>
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<49><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 20 00 00 00 38 3F 00 3F 7D FF E3 00 00 40 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8?<3F>?}<7D><><EFBFBD><EFBFBD>@
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<49><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 20 00 00 00 7F FF 00 FF FF 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<61><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 20 00 00 00 00 00 10 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 01 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
--------------------------------------------------------------------------

145
Commodore/WAV.TXT Normal file
View File

@@ -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 RIFF<46>E<EFBFBD><45>WAVEfmt<6D>
0010: 10 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>D<EFBFBD><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 04 00 10 00 64 61 74 61 B0 45 CC 01 95 00 6D FF <20><><EFBFBD><EFBFBD>data<74>E<EFBFBD><45><EFBFBD><EFBFBD>m<EFBFBD>
0030: 97 00 77 FF 6E 00 25 FF 58 00 14 FF 75 00 ED FE <20><>w<EFBFBD>n<EFBFBD>%<25>X<EFBFBD><58><EFBFBD>u<EFBFBD><75><EFBFBD>
0040: 62 00 33 FE 2C 00 07 FE C4 FF 7A FE 53 FF C3 FE b<>3<EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>z<EFBFBD>S<EFBFBD><53><EFBFBD>
0050: 91 FF 83 FE 21 00 91 FE EB 00 0D FF FF 00 57 FF <20><><EFBFBD><EFBFBD>!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W<EFBFBD>
0060: 98 00 C4 FF 9F 00 79 00 60 00 DD 00 07 00 1D 01 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>y<EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
$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@<40><><EFBFBD>INFOISFT
2D403C: 15 00 00 00 53 6F 6E 79 20 53 6F 75 6E 64 20 46 <20><><EFBFBD><EFBFBD>Sony<6E>Sound<6E>F
2D404C: 6F 72 67 65 20 37 2E 30 00 00 49 45 4E 47 02 00 orge<67>7.0<EFBFBD><EFBFBD>IENG<EFBFBD><EFBFBD>
2D405C: 00 00 20 00 49 43 52 44 0B 00 00 00 32 30 30 33 <20><><EFBFBD><EFBFBD>ICRD<52><44><EFBFBD><EFBFBD>2003
2D406C: 2D 31 30 2D 31 37 00 02 .. .. .. .. .. .. .. .. -10-17<31><37>........
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<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F488BC: 00 C0 21 00 64 61 74 61 00 00 00 00 00 00 00 00 <20><>!<21>data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F488CC: 00 C0 21 00 02 00 00 00 00 40 11 00 64 61 74 61 <20><>!<21><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><>data
02F488DC: 00 00 00 00 00 00 00 00 00 40 11 00 03 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F488EC: 00 00 3A 00 64 61 74 61 00 00 00 00 00 00 00 00 <20><>:<3A>data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F488FC: 00 00 3A 00 04 00 00 00 00 00 59 00 64 61 74 61 <20><>:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Y<EFBFBD>data
02F4890C: 00 00 00 00 00 00 00 00 00 00 59 00 05 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD><EFBFBD>
02F4891C: 00 C0 6C 00 64 61 74 61 00 00 00 00 00 00 00 00 <20><>l<EFBFBD>data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F4892C: 00 C0 6C 00 06 00 00 00 00 40 84 00 64 61 74 61 <20><>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><>data
02F4893C: 00 00 00 00 00 00 00 00 00 40 84 00 07 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F4894C: 00 80 9A 00 64 61 74 61 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD>data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02F4895C: 00 80 9A 00 08 00 00 00 00 00 AC 00 64 61 74 61 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>data
02F4896C: 00 00 00 00 00 00 00 00 00 00 AC 00 4C 49 53 54 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LIST
02F4897C: 84 00 00 00 61 64 74 6C 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>adtllabl<62><6C><EFBFBD><EFBFBD>
02F4898C: 01 00 00 00 30 31 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>01<30><31>labl<62><6C><EFBFBD><EFBFBD>
02F4899C: 02 00 00 00 30 32 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>02<30><32>labl<62><6C><EFBFBD><EFBFBD>
02F489AC: 03 00 00 00 30 33 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>03<30><33>labl<62><6C><EFBFBD><EFBFBD>
02F489BC: 04 00 00 00 30 34 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>04<30><34>labl<62><6C><EFBFBD><EFBFBD>
02F489CC: 05 00 00 00 30 35 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>05<30><35>labl<62><6C><EFBFBD><EFBFBD>
02F489DC: 06 00 00 00 30 36 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>06<30><36>labl<62><6C><EFBFBD><EFBFBD>
02F489EC: 07 00 00 00 30 37 00 00 6C 61 62 6C 07 00 00 00 <20><><EFBFBD><EFBFBD>07<30><37>labl<62><6C><EFBFBD><EFBFBD>
02F489FC: 08 00 00 00 30 38 00 00 .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD>08<30><38>........
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.

226
Commodore/WRA-WR3.TXT Normal file
View File

@@ -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 <20>BL<42>POOYAN<41>.<2E><>.`
0010: 80 50 01 16 41 59 0C 14 F0 81 0C 47 49 31 11 40 <20>P..AY..<2E><>.GI1.@
0020: 9E 4F 2C 90 49 C2 E2 61 3C 82 44 22 94 84 42 C1 <20>O,<2C>I<EFBFBD><49>a<<3C>D"<22><>B<EFBFBD>
0030: C0 B0 62 00 21 82 02 90 62 0C 61 63 19 43 D4 4D <20><>b<EFBFBD>!<21>.<2E>b.ac.C<>M
0040: 20 92 49 D1 F3 13 41 01 E0 02 78 68 37 1C 0D 40 <20><>I<EFBFBD><49>.A.<2E>.xh7..@
0050: 14 E1 40 00 DD 0B FF 42 4C FF 50 4F 4F 59 41 4E .<2E>@<40><>.<2E>BL<42>POOYAN
0060: 2E 4D 41 49 4E 00 02 7E 0C 0A B0 31 31 00 08 00 .MAIN<49>.~..<2E>11<31>.<2E>
0070: 00 09 40 00 05 2A 00 02 A5 54 3C 81 10 88 00 08 <20><>@<40>.*<2A>.<2E>T<<3C>.<2E><>.
Byte: $00-03: FF 42 4C FF - Compressed file signature "<22>BL<42>"
04-xx: 50 4F 4F 59 41 4E 00 - File name "POOYAN", terminated with
a $00 (null) byte
02 - File type
01 = SEQ
02 = PRG
03 = USR
04 = GEOS
What follows the filetype is compressed file data, up until two bytes
before the next signature, or two bytes to the end of the file, whichever
comes first. The two bytes at the end comprise the 16-bit CRC value.
The Wraptor format does not include information in the header that would
normally be considered important for generic decompression, such as:
1. No original or compressed file sizes
2. No offset to show where the next compressed file starts
3. No version# info, to know if the decompressor you have is the correct
type to uncompress the file. This is determined by the file extension,
with WR3 being the newest. WRA represents version 1.x and 2.x.
The original release of Wraptor (version 1.x) contained a few bugs,
specifically dealing with the compression and decompression of certain GEOS
filetypes, with all of the other file types (PRG, SEQ, USR) being fine.
Version 2.x was released, but more bugs with GEOS files were found. Thus
version 3.x was released.
As of version 3.x, the earlier WRA files are no longer supported, only
the WR3 files. To decode WRA files, you can either use a pre-3.0 version of
Wraptor, or rename the files to end with WR3 and see if version 3 will
unwrap them. If they contain a faulty compressed GEOS file, the file might
not decompress properly.
You can get a list of files contained in a WRA/WR3 file by using one of
the following two methods:
1. Decompress each file in succession, a tedious task at the best of
times. This *is* the method WRAptor uses to display and decompress
files in its archives, and it is very slow!
2. Scan the whole file for the "FF 42 4C FF" signature preceeding each
file, and store the starting offsets. There may be the possibility
that this signature will show up in the normal compressed data, but
the odds are very low.
The Wraptor compression on PRG, SEQ and USR files is very simple to
decode. GEOS files are the exception as they need to be reconstructed
exactly as they were, VLIR chains and all. The following C program explains
how basic decompression works, but not for GEOS:
---------------------------------------------------------------------------
/*
The following code assumes you have already read in the signature,
filename+NULL and filetype byte, and simply want to decode the data.
There is no provision made to decode the GEOS data, or actually show how
to calculate the CRC
*/
void main(void)
{
FILE *readfile, *writefile;
int i;
char data, type, tmp, rep_length, read_bitsize;
unsigned buff_pointer, dict_offset;
/* Output stream buffer */
char buffer[(unsigned)32768];
/* Compressed file to decode */
readfile=fopen("compress.wra","rb");
/* Uncompressed output stream */
writefile=fopen("uncompressed","wb");
/* Initial bitsize of the dictionary lookup */
read_bitsize=8;
/* Clear buffer pointer */
buff_pointer=0;
while(1)
{
/* Get compressed yes/no flag (single bit) from the input stream */
type=get_bits(1);
/* Normal unencoded data, preceeded by a zero bit */
if(!type)
{
/* Get normal 8-bit byte */
data=get_bits(8);
/* Add data to output buffer */
buffer[buff_pointer]=data;
/* Calculate the CRC as we read in the data */
calc_crc(data);
/* Move pointer for next data byte */
buff_pointer++;
/* Has the output buffer filled up? */
if(buff_pointer>=(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<rep_length;i++)
{
buffer[buff_pointer]=buffer[dict_offset-1+i];
buff_pointer++;
/* Write buffer to output file */
/* Here is where we would decode the GEOS file structure */
if(buff_pointer>=(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);
}

94
Commodore/X64.TXT Normal file
View File

@@ -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...#<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.

97
Commodore/ZIP.TXT Normal file
View File

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

185
Commodore/ZIP_DISK.TXT Normal file
View File

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

165
Commodore/ZIP_FILE.TXT Normal file
View File

@@ -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><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(20
0010: 36 34 29 00 00 00 78 A9 34 85 01 A2 05 BD 42 08 64)<29><><EFBFBD>x<EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD>
0020: 9D 2D 00 CA 10 F7 9A A0 00 C6 32 CE 2C 08 B1 31 <20>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>,<2C><>1
0030: 99 00 00 C8 D0 F8 A5 32 C9 08 D0 ED B9 48 08 99 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>H<EFBFBD><48>
0040: 00 01 C8 D0 F7 4C 00 01 01 08 46 4D F3 BB B1 2F <20><><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD>FM<46><4D><EFBFBD>/
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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2061<36><31><EFBFBD><EFBFBD><EFBFBD>
0010: 8C 20 D0 8C 21 D0 B9 C7 08 F0 06 20 D2 FF C8 D0 <20><>Ќ!й<><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0020: F5 85 FF 85 FB A0 0A 84 FC 85 FD 85 FE A0 11 B1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0030: FB 48 AA C8 B1 FB 48 A8 20 4B 09 20 41 09 8A 20 <20>H<EFBFBD>ȱ<EFBFBD>H<EFBFBD><48>K<EFBFBD><4B>A<EFBFBD><41><EFBFBD>
0040: 41 09 98 20 41 09 68 AA 68 18 65 FD 85 FD 8A 65 A<><41><EFBFBD>A<EFBFBD>h<EFBFBD>h<EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD>e
0050: FE 85 FE 20 39 09 20 3C 09 A0 00 B1 FB C9 A0 F0 <20><><EFBFBD><EFBFBD>9<EFBFBD><39><<3C><><EFBFBD><EFBFBD><EFBFBD>ɠ<EFBFBD>
0060: 08 20 41 09 C8 C0 10 D0 F2 20 3C 09 C0 13 F0 06 <20><>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<3C><><EFBFBD><EFBFBD><EFBFBD>
0070: 20 39 09 C8 D0 F6 A0 10 B1 FB 29 7F 20 41 09 20 <20>9<EFBFBD><39><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<>A<EFBFBD><41>
0080: 3F 09 A5 FB 18 69 15 85 FB 90 02 E6 FC E6 FF A5 ?<3F><><EFBFBD><EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0090: FF CD FF 09 D0 97 AA A0 00 20 4B 09 8E 08 09 8C <20><><EFBFBD><EFBFBD>З<EFBFBD><D097><EFBFBD><EFBFBD>K<EFBFBD><4B><EFBFBD><EFBFBD><EFBFBD>
00A0: 09 09 A6 FD A4 FE 20 4B 09 8D 1A 09 8E 1B 09 8C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>K<EFBFBD><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00B0: 1C 09 AD FE 09 09 30 8D 2D 09 A0 00 B9 F7 08 F0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00C0: 06 20 41 09 C8 D0 F5 60 93 9B 11 11 11 11 11 11 <20><>A<EFBFBD><41><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00D0: 11 11 11 11 11 11 11 11 11 11 48 4F 4C 44 20 53 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>HOLD<4C>S
00E0: 54 4F 50 20 54 4F 20 50 41 55 53 45 20 4C 49 53 TOP<4F>TO<54>PAUSE<53>LIS
00F0: 54 49 4E 47 3A 0D 0D 00 0D 0D 54 4F 54 41 4C 20 TING:<3A><><EFBFBD><EFBFBD><EFBFBD>TOTAL<41>
0100: 46 49 4C 45 53 20 20 3D 20 30 30 0D 54 4F 54 41 FILES<45><53>=<3D>00<30>TOTA
0110: 4C 20 42 4C 4F 43 4B 53 20 3D 20 30 30 30 0D 50 L<>BLOCKS<4B>=<3D>000<30>P
0120: 41 43 4B 45 44 20 46 49 4C 45 53 20 3D 20 30 0D ACKED<45>FILES<45>=<3D>0<EFBFBD>
0130: 05 5B 5A 43 20 49 49 5D 0D 00 A9 20 2C A9 22 2C <20>[ZC<5A>II]<5D><><EFBFBD><EFBFBD>,<2C>",
0140: A9 0D 20 D2 FF A5 91 C9 7F F0 FA 60 8E 92 09 8C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><7F>`<60><><EFBFBD><EFBFBD>
0150: 93 09 A0 02 A9 30 99 96 09 88 10 FA A2 02 AD 92 <20><><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0160: 09 38 FD 8F 09 8D 94 09 AD 93 09 E9 00 8D 95 09 <20>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0170: 90 11 AD 94 09 8D 92 09 AD 95 09 8D 93 09 FE 96 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0180: 09 D0 DB CA 10 D8 AD 98 09 AE 97 09 AC 96 09 60 <20><><EFBFBD><EFBFBD><EFBFBD>ح<EFBFBD><D8AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`
0190: 01 0A 64 00 00 00 00 31 32 33 00 00 00 00 00 00 <20><>d<EFBFBD><64><EFBFBD><EFBFBD>123<32><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
01F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0200: 0E 4D 55 53 49 43 20 53 45 4C 45 43 54 4F 52 A0 <20>MUSIC<49>SELECTOR<4F>
0210: A0 D0 B6 00 11 00 31 30 30 31 20 4C 45 54 54 45 <20>ж<EFBFBD><D0B6><EFBFBD>1001<30>LETTE
0220: 52 20 2D 56 2D A0 D0 72 00 13 00 4E 45 57 20 4D R<>-V-<2D><>r<EFBFBD><72><EFBFBD>NEW<45>M
0230: 41 49 4C 2F 44 44 A0 A0 A0 A0 A0 D0 1E 00 19 00 AIL/DD<44><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0240: 4A 41 43 4B 20 54 48 45 20 4E 49 50 50 45 52 A0 JACK<43>THE<48>NIPPER<45>
0250: D0 C0 00 1A 06 54 55 52 4E 45 52 20 49 49 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>TURNER<45>II<49><49>
0260: A0 A0 A0 A0 A0 D0 2B 00 07 00 53 43 52 45 45 4E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD>SCREEN
0270: 20 20 30 A0 A0 A0 A0 A0 A0 A0 D3 07 00 05 00 53 <20><>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>S
0280: 43 52 45 45 4E 20 20 31 A0 A0 A0 A0 A0 A0 A0 D3 CREEN<45><4E>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0290: 0C 00 05 01 53 43 52 45 45 4E 20 20 32 A0 A0 A0 <20><><EFBFBD><EFBFBD>SCREEN<45><4E>2<EFBFBD><32><EFBFBD>
02A0: A0 A0 A0 A0 D3 0B 00 04 00 53 43 52 45 45 4E 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCREEN<45>
02B0: 20 33 A0 A0 A0 A0 A0 A0 A0 D3 02 00 04 01 53 43 <20>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SC
02C0: 52 45 45 4E 20 20 34 A0 A0 A0 A0 A0 A0 A0 D3 03 REEN<45><4E>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02D0: 00 04 03 53 43 52 45 45 4E 20 20 35 A0 A0 A0 A0 <20><><EFBFBD>SCREEN<45><4E>5<EFBFBD><35><EFBFBD><EFBFBD>
02E0: A0 A0 A0 D3 07 00 04 07 53 43 52 45 45 4E 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCREEN<45><4E>
02F0: 36 A0 A0 A0 A0 A0 A0 A0 D3 08 00 03 00 53 43 52 6<><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCR
0300: 45 45 4E 20 20 37 A0 A0 A0 A0 A0 A0 A0 D3 07 00 EEN<45><4E>7<EFBFBD><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0310: 03 01 53 43 52 45 45 4E 20 20 38 A0 A0 A0 A0 A0 <20><>SCREEN<45><4E>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD>
0320: A0 A0 D3 0B 00 03 09 .. .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.........
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 .MUSIC<49>SELECTOR<4F>
0210: A0 D0 B6 00 11 00 31 30 30 31 20 4C 45 54 54 45 <20>ж<EFBFBD><D0B6><EFBFBD>1001<30>LETTE
0220: 52 20 2D 56 2D A0 D0 72 00 13 00 4E 45 57 20 4D R<>-V-<2D><>r<EFBFBD><72><EFBFBD>NEW<45>M
0230: 41 49 4C 2F 44 44 A0 A0 A0 A0 A0 D0 1E 00 19 00 AIL/DD<44><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0240: 4A 41 43 4B 20 54 48 45 20 4E 49 50 50 45 52 A0 JACK<43>THE<48>NIPPER<45>
0250: D0 C0 00 1A 06 54 55 52 4E 45 52 20 49 49 A0 A0 <20><><EFBFBD><EFBFBD><EFBFBD>TURNER<45>II<49><49>
0260: A0 A0 A0 A0 A0 D0 2B 00 07 00 53 43 52 45 45 4E <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD>SCREEN
0270: 20 20 30 A0 A0 A0 A0 A0 A0 A0 D3 07 00 05 00 53 <20><>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>S
0280: 43 52 45 45 4E 20 20 31 A0 A0 A0 A0 A0 A0 A0 D3 CREEN<45><4E>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0290: 0C 00 05 01 53 43 52 45 45 4E 20 20 32 A0 A0 A0 <20><><EFBFBD><EFBFBD>SCREEN<45><4E>2<EFBFBD><32><EFBFBD>
02A0: A0 A0 A0 A0 D3 0B 00 04 00 53 43 52 45 45 4E 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCREEN<45>
02B0: 20 33 A0 A0 A0 A0 A0 A0 A0 D3 02 00 04 01 53 43 <20>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SC
02C0: 52 45 45 4E 20 20 34 A0 A0 A0 A0 A0 A0 A0 D3 03 REEN<45><4E>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
02D0: 00 04 03 53 43 52 45 45 4E 20 20 35 A0 A0 A0 A0 <20><><EFBFBD>SCREEN<45><4E>5<EFBFBD><35><EFBFBD><EFBFBD>
02E0: A0 A0 A0 D3 07 00 04 07 53 43 52 45 45 4E 20 20 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCREEN<45><4E>
02F0: 36 A0 A0 A0 A0 A0 A0 A0 D3 08 00 03 00 53 43 52 6<><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SCR
0300: 45 45 4E 20 20 37 A0 A0 A0 A0 A0 A0 A0 D3 07 00 EEN<45><4E>7<EFBFBD><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0310: 03 01 53 43 52 45 45 4E 20 20 38 A0 A0 A0 A0 A0 <20><>SCREEN<45><4E>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD>
0320: A0 A0 D3 0B 00 03 09 .. .. .. .. .. .. .. .. .. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.........
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.

372
Commodore/ZIP_SIX.TXT Normal file
View File

@@ -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 <20><>$RU%)K<><4B>%UURU5
0010: 2D 4B 9A E7 25 55 55 52 54 A5 49 4B 9A E7 25 55 -K<><4B>%UURT<52>IK<49><4B>%U
0020: 55 52 54 B5 4D 4B 9A E7 25 55 55 52 55 65 39 4B URT<52>MK<4D><4B>%UURUe9K
0030: 9A E7 25 55 55 52 55 75 3D 4B 9A E7 25 55 55 52 <20><>%UURUu=K<><4B>%UUR
0040: 54 E5 59 4B 9A E7 25 55 55 52 54 F5 5D 4B 9A E7 T<>YK<59><4B>%UURT<52>]K<><4B>
0050: 25 55 55 52 55 A5 25 4B 9A E7 25 55 55 52 55 B5 %UURU<52>%K<><4B>%UURU<52>
0060: 65 4B 9A E7 25 55 55 52 54 95 69 4B 9A E7 25 55 eK<65><4B>%UURT<52>iK<69><4B>%U
0070: 55 52 55 95 6D 4B 9A E7 25 55 55 52 55 E5 35 4B URU<52>mK<6D><4B>%UURU<52>5K
0080: 9A E7 25 55 55 52 55 55 75 4B 9A E7 25 55 55 52 <20><>%UURUUuK<75><4B>%UUR
0090: 54 D5 79 4B 9A E7 25 55 55 52 55 D5 55 4B 9A E7 T<>yK<79><4B>%UURU<52>UK<55><4B>
00A0: 25 55 55 52 57 25 A9 4B 9A E7 25 55 55 52 57 35 %UURW%<25>K<EFBFBD><4B>%UURW5
00B0: AD 4B 9A E7 25 55 55 52 56 A5 C9 4B 9A E7 25 55 <20>K<EFBFBD><4B>%UURV<52><56>K<EFBFBD><4B>%U
00C0: 55 52 56 B5 CD 4B 9A E7 25 55 55 52 57 65 B9 4B URV<52><56>K<EFBFBD><4B>%UURWe<57>K
00D0: 9A E7 25 55 55 29 0F 05 C0 99 00 02 C8 D0 D4 A9 <20><>%UU)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԩ
00E0: 02 8D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
00F0: 00 00 00 00 00 00 00 00 00 41 4D 45 3A 20 31 32 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AME:<3A>12
0100: 33 34 15 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 34<33>Ե-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<4B>
0140: B5 2D 4B 52 D4 B5 29 4D 55 55 D4 A5 2D 4B 52 D4 <20>-KRԵ)MUUԥ-KR<4B>
0150: B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 <20>-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).

659
Commodore/d64.html Normal file
View File

@@ -0,0 +1,659 @@
<html>
<head>
<title>D64 (Electronic form of a physical 1541 disk)</title>
</head>
<body bgcolor="#c8c8d8" text="#000000" link="#ffffff" alink="#ffffff" vlink="#404040">
<center><table><tr><td><pre>
*** D64 (Electronic form of a physical 1541 disk)
*** Document revision: 1.9
*** Last updated: March 11, 2004
*** Contributors/sources: Immers/Neufeld &quot;Inside Commodore DOS&quot;
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&quot; 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 &lt;- notice the T/S link
10: 49 54 A0 A0 A0 00 00 00 00 00 00 00 00 00 15 00 &lt;- to 18/4 ($12/$04)
20: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 &lt;- and how its not here
30: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 &lt;- ($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 &quot;&gt;&quot; locked files)
Bit 7: Closed flag (Not set produces &quot;*&quot;, or &quot;splat&quot;
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 &lt;= #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 (&quot;A&quot;)
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 &quot;2A&quot;
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 &quot;soft write protection&quot;. Any attempt to write
to the disk will return the &quot;DOS Version&quot; error code 73 ,&quot;CBM DOS V 2.6
1541&quot;. 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 &quot;auto-boot&quot; 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 &quot;speeder&quot; 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 | &quot;2A&quot; |$41/'A'
------------------------------------------------------------
SpeedDOS+ | 40 | $0f $0f | &quot;2A&quot; |$41/'A'
------------------------------------------------------------
ProfessionalDOS Initial | 35 | $0f $0f | &quot;2A&quot; |$41/'A'
(Version 1/Prototype) | 40 | $0f $0f | &quot;2A&quot; |$41/'A'
------------------------------------------------------------
ProfDOS Release | 40 | $0f $0f | &quot;4A&quot; |$41/'A'
------------------------------------------------------------
Dolphin-DOS 2.0/3.0 | 35 | $0f $0f | &quot;2A&quot; |$41/'A'
Dolphin-DOS 2.0/3.0 | 40 | $0d $0f | &quot;2A&quot; |$41/'A'
------------------------------------------------------------
PrologicDOS 1541 | 35 | $0f $0f | &quot;2A&quot; |$41/'A'
PrologicDOS 1541 | 40 | $0f $0f | &quot;2P&quot; |$50/'P'
ProSpeed 1571 2.0 | 35 | $0f $0f | &quot;2A&quot; |$41/'A'
ProSpeed 1571 2.0 | 40 | $0f $0f | &quot;2P&quot; |$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 &quot;Inside
Commodore DOS&quot;. 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 &quot;type&quot; 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 &quot;seek&quot; 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 &quot;data block&quot; 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 &quot;off&quot; 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, &quot;extending&quot; 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)
</pre></td></tr></table></center>
</body>
</html>

100
Commodore/list.txt Normal file
View File

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

11213
Commodore/vice_15.html Normal file

File diff suppressed because it is too large Load Diff