formats index
*** D64 (Electronic form of a physical 1541 disk)
** Document revision 1.1
(Note: This document will try to explain the layout of the 1541 disks, as
well as the files they contain. However, I do not explain GEOS files here.
See the file GEOS.TXT for more information on that file type and disk
layout.)
First and foremost we have D64, which is basically a sector-for-sector
copy of a 1540/1541 disk. There are several versions of these which I will
cover shortly. The standard D64 is a 174848 byte file comprised of 256 byte
sectors arranged in 35 tracks with a varying number of sectors per track
for a total of 683 sectors. Track counting starts at 1, not 0, and goes up
to 35. Sector counting starts at 0, not 1, for the first sector, therefore
a track with 21 sectors will go from 0 to 20.
The original media (a 5.25" disk) has the tracks laid out in circles,
with track 1 on the very outside of the disk (closest to the sides) to
track 35 being on the inside of the disk (closest to the hub ring).
Commodore (in their infinite wisdom) varied the number of sectors per track
(and data densities across the disk) to optimize available storage,
resulting in the chart below. It shows the sectors/track for a standard
D64. Since the outside diameter of a circle is the largest (versus closer
to the center), the outside tracks have the largest amount of storage.
Track Sectors/track # Sectors
----- ------------- ---------
1-17 21 357
18-24 19 133
25-30 18 108
31-35 17 85
---
683
Track #Sect #SectorsIn D64 Offset Track #Sect #SectorsIn D64 Offset
----- ----- ---------- ---------- ----- ----- ---------- ----------
1 21 0 $00000 21 19 414 $19E00
2 21 21 $01500 22 19 433 $1B100
3 21 42 $02A00 23 19 452 $1C400
4 21 63 $03F00 24 19 471 $1D700
5 21 84 $05400 25 18 490 $1EA00
6 21 105 $06900 26 18 508 $1FC00
7 21 126 $07E00 27 18 526 $20E00
8 21 147 $09300 28 18 544 $22000
9 21 168 $0A800 29 18 562 $23200
10 21 189 $0BD00 30 18 580 $24400
11 21 210 $0D200 31 17 598 $25600
12 21 231 $0E700 32 17 615 $26700
13 21 252 $0FC00 33 17 632 $27800
14 21 273 $11100 34 17 649 $28900
15 21 294 $12600 35 17 666 $29A00
16 21 315 $13B00 36* 17 683 $2AB00
17 21 336 $15000 37* 17 700 $2BC00
18 19 357 $16500 38* 17 717 $2CD00
19 19 376 $17800 39* 17 734 $2DE00
20 19 395 $18B00 40* 17 751 $2EF00
*Extra tracks on 40-track images only
The directory track should be contained totally on track 18. Sectors 1-18
contain the entries and sector 0 contains the BAM (Block Availability Map)
and disk name/ID. Since the directory is only 18 sectors large (19 less one
for the BAM), and each sector can contain only 8 entries (32 bytes per
entry), the maximum number of directory entries is 18 * 8 = 144. The first
directory sector is always 18/1, even though the t/s pointer at 18/0 (first
two bytes) might point somewhere else. It then follows the same chain
structure as a normal file.
Each directory sector has the following layout (18/1 partial dump):
00: 12 04 81 11 00 4E 41 4D 45 53 20 26 20 50 4F 53 <- notice the T/S link
10: 49 54 A0 A0 A0 00 00 00 00 00 00 00 00 00 15 00 <- to 18/4 ($12/$04)
20: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 <- and how its not here
30: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 <- ($00/$00)
The first two bytes of the sector ($12/$04) indicate the location of the
next track/sector of the directory (18/4). If the track is set to $00, then
it is the last sector of the directory. It is possible, however unlikely,
that the directory may *not* be competely on track 18 (some disks do exist
like this). Just follow the chain anyhow.
When the directory is done, the track value will be $00. The sector link
should contain a value of $FF, meaning the whole sector is allocated, but
the actual value doesn't matter. The drive will return all the available
entries anyways. This is a breakdown of a standard directory sector and
entry:
Bytes: $00-1F: First directory entry
00-01: Track/Sector location of next directory sector ($00 $00 if
not the first entry in the sector)
02: File type.
Typical values for this location are:
$00 - Scratched (deleted file entry)
80 - DEL
81 - SEQ
82 - PRG
83 - USR
84 - REL
Bit 0-3: The actual filetype
000 (0) - DEL
001 (1) - SEQ
010 (2) - PRG
011 (3) - USR
100 (4) - REL
Values 5-15 are illegal, but if used will produce
very strange results. The 1541 is inconsistent in
how it treats these bits. Some routines use all 4
bits, others ignore bit 3, resulting in values
from 0-7.
Bit 4: Not used
Bit 5: Used only during SAVE-@ replacement
Bit 6: Locked flag (Set produces ">" locked files)
Bit 7: Closed flag (Not set produces "*", or "splat"
files)
03-04: Track/sector location of first sector of file
05-14: 16 character filename (in PETASCII, padded with $A0)
15-16: Track/Sector location of first side-sector block (REL file
only)
17: REL file record length (REL file only)
18-1D: Unused (except with GEOS disks)
1E-1F: File size in sectors, low/high byte order ($1E+$1F*256).
The approx. filesize in bytes is <= #sectors * 254
20-3F: Second dir entry. From now on the first two bytes of each
entry in this sector should be $00 $00, as they are
unused.
40-5F: Third dir entry
60-7F: Fourth dir entry
80-9F: Fifth dir entry
A0-BF: Sixth dir entry
C0-DF: Seventh dir entry
E0-FF: Eighth dir entry
Note: No GEOS entries are listed in the above description. See the GEOS.TXT
file for GEOS info.
The layout of the BAM area (sector 18/0) is a bit more complicated...
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
-----------------------------------------------
00: 12 01 41 00 12 FF F9 17 15 FF FF 1F 15 FF FF 1F
10: 15 FF FF 1F 12 FF F9 17 00 00 00 00 00 00 00 00
20: 00 00 00 00 0E FF 74 03 15 FF FF 1F 15 FF FF 1F
30: 0E 3F FC 11 07 E1 80 01 15 FF FF 1F 15 FF FF 1F
40: 15 FF FF 1F 15 FF FF 1F 0D C0 FF 07 13 FF FF 07
50: 13 FF FF 07 11 FF CF 07 13 FF FF 07 12 7F FF 07
60: 13 FF FF 07 0A 75 55 01 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 01 08 00 00 03 02 48 00
80: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
90: 53 48 41 52 45 57 41 52 45 20 31 20 20 A0 A0 A0
A0: A0 A0 56 54 A0 32 41 A0 A0 A0 A0 00 00 00 00 00
B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Bytes:$00-01: Track/Sector location of the first directory sector (should
be set to 18/1 but it doesn't matter, and don't trust what
is there, always go to 18/1 for first directory entry)
02: Disk DOS version type (see note below)
$41 ("A")
03: Unused
04-8F: BAM entries for each track, in groups of four bytes per
track, starting on track 1 (see below for more details)
90-9F: Disk Name (padded with $A0)
A0-A1: Filled with $A0
A2-A3: Disk ID
A4: Usually $A0
A5-A6: DOS type, usually "2A"
A7-AA: Filled with $A0
AB-FF: Normally unused ($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 and DOLPHIN dos use the same layout as
standard BAM entries.
One of the interesting things from the BAM sector is the byte at offset
$02, the DOS version byte. If it is set to anything other than $41 or $00,
then we have what is called "soft write protection". Any attempt to write
to the disk will return the "DOS Version" error code 73 ,"CBM DOS V 2.6
1541". The 1541 is simply telling you that it thinks the disk format
version is incorrect. This message will normally come up when you first
turn on the 1541 and read the error channel. If you write a $00 or a $41
into 1541 memory location $00FF (for device 0), then you can circumvent
this type of write-protection, and change the DOS version back to what it
should be.
The BAM entries require a bit (no pun intended) more of a breakdown. Take
the first entry at bytes $04-$07 ($12 $FF $F9 $17). The first byte ($12) is
the number of free sectors on that track. Since we are looking at the track
1 entry, this means it has 18 (decimal) free sectors. The next three bytes
represent the bitmap of which sectors are used/free. Since it is 3 bytes (8
bits/byte) we have 24 bits of storage. Remember that at most, each track
only has 21 sectors, so there are a few unused bits.
Bytes: 04-07: 12 FF F9 17 Track 1 BAM
08-0B: 15 FF FF FF Track 2 BAM
0C-0F: 15 FF FF 1F Track 3 BAM
...
8C-8F: 11 FF FF 01 Track 35 BAM
These entries must be viewed in binary to make any sense. We will use the
first entry (track 1) at bytes 04-07:
FF=11111111, F9=11111001, 17=00010111
In order to make any sense from the binary notation, flip the bits around.
111111 11112222
01234567 89012345 67890123
--------------------------
11111111 10011111 11101000
^ ^
sector 0 sector 20
Since we are on the first track, we have 21 sectors, and only use up to
the bit 20 position. If a bit is on (1), the sector is free. Therefore,
track 1 has sectors 9,10 and 19 used, all the rest are free.
Each filetype has its own unique properties, but most follow one simple
structure. The first file sector is pointed to by the directory and follows
a t/s chain, until the track value reaches $00. When this happens, the
value in the sector link location indicates how much of the sector is used.
For example, the following chain indicates a file 6 sectors long, and ends
when we encounter the $00/$34 chain. At this point the last sector occupies
from bytes $02-$34.
1 2 3 4 5 6
---- ----- ----- ----- ----- -----
17/0 17/10 17/20 17/1 17/11 0/52
(11/00) (11/0A) (11/14) (11/01) (11/0B) (0/34)
---------------------------------------------------------------------------
*** REL files
The REL filetype, however, has a most unusual structure. It was designed
to make access to data *anywhere* on the disk very fast. Take a look at
this directory entry...
00: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 úú„..ADDITIONALú
10: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 INFO ..þúúúúúúa.
The third byte ($84) indicates this entry is a REL file and that the
three normally empty entries at offset $15, $16 and $17 are now used as
they are explained above. It's the sector chain that this entry points to
(called the SIDE SECTORS) which are of interest here (in this case, 17/12).
Here is a dump of the beginning of that sector...
00: 0C 13 00 FE 11 0C 0C 13 06 09 00 00 00 00 00 00
10: 11 02 11 0D 11 03 11 0E 11 04 11 0F 11 05 11 10
Bytes: $00: Track location of next side-sector ($00 if last sector)
01: Sector location of next side-sector
02: Side-sector block number (first sector is $00, the next is
$01, then $02, etc)
03: REL file RECORD size (from directory entry)
04-0F: Track/sector locations of the six other side-sectors. Note
the first entry is this very sector we have listed here.
The next is the next t/s listed at the beginning of the
sector. All of this information must be correct. If one of
these chains is $00/$00, then we have no more side sectors.
Also, all of these (up to six) side sectors must have the
same values in this range.
10-FF: T/S chains of *each* sector of the data portion. When we
get a $00/$00, we are at the end of the file.
If the speed advantage regarding this type file file isn't obvious yet,
consider the following scenario... If we need record 4000, its only a
couple of calculations to see how many bytes into the file it is (record# *
record length). Once we know this, we can calculate how many sectors into
the file it is (result/254). Now that we know the number of sectors, we can
look it up in our side-sector tables to see where the record is. The speed
of this system is truly amazing, given the era of the C64, and a floppy
drive.
---------------------------------------------------------------------------
*** Variations on the D64 layout
These are some variations of the D64 layout:
1. Standard 35 track layout but with 683 error bytes added on to the end
of the file. Each byte of the error info corresponds to a single
sector stored in the D64, indicating if the sector on the original
disk contained an error. The first byte is for track 1/0, and the last
byte is for track 35/16.
2. A 40 track layout, following the same layout as a 35 track disk, but
with 5 extra tracks. These contain 17 sectors each, like tracks 31-35.
Some of the PC utilities do allow you to create and work with these
files.
The location of the extra BAM information in sector 18/0 will be
different depending on what standard the disks have been formatted
with. SPEED DOS stores them from $C0 to $D3, and DOLPHIN DOS stores
them from $AC to $BF. 64COPY and Star Commander let you select from
several different types of extended disk formats you want to
create/work with.
Disk type Size
--------- ------
35 track, no errors 174848
35 track, 683 error bytes 175531
40 track, no errors 196608
40 track, 768 error bytes 197376
Here is the meaning of the error bytes added onto the end of any extended
D64. The CODE is the same as that generated by the 1541 drive controller...
it reports these numbers, not the error code we usually see when an error
occurs.
Some of what comes below is taken from Immers/Neufeld book "Inside
Commodore DOS". Note the descriptions are not completely accurate as to
what the drive DOS is actually doing to seek/read/decode/write sectors, but
serve as simple examples only. The "type" field is where the error usually
occurs, but it can occur elsewhere.
Code Error Type 1541 error description
---- ----- ---- ------------------------------
01 00 N/A No error.
Self explanatory. No errors were detected in the
reading and decoding of the sector.
02 20 Read Header descriptor byte not found ($08)
Each sector is preceeded by an 8-byte header block,
which starts with the value $08. If this value is
not $08, this error is generated.
03 21 R/W No sync sequence found.
Each sector data block and header block are
preceeded by SYNC marks. If *no* sync sequence is
found, then the whole track is unreadable, and
likely unformatted.
04 22 Read Data descriptor byte not found ($07)
Each sector data block is preceeded by the value
$07, the "data block" descriptor. If this value is
not there, this error is generated. Each encoded
sector has actually 260 bytes. First is the
descriptor byte, then follows the 256 bytes of
data, a checksum, and two "off" bytes.
05 23 Read Checksum error in data block
The checksum of the data read of the disk is
calculated, and compared against the one stored at
the end of the sector. If there's a discrepancy,
this error is generated.
06 24 Write Write verify (on format)
07 25 Write Write verify error
Once the GCR-encoded sector is written out, the
drive waits for the sector to come around again and
verifies the whole 325-byte GCR block. Any errors
encountered will generate this error.
08 26 Write Write protect on
Self explanatory. Remove the write-protect tab, and
try again.
09 27 Seek Checksum error in header block
The 8-byte header block contains a checksum value,
calculated by XOR'ing the TRACK, SECTOR, ID1 and
ID2 values. If this checksum is wrong, this error
is generated.
0A 28 Write Write error
In actual fact, this error never occurs, but it is
included for completeness.
0B 29 Seek Disk sector ID mismatch
The ID's from the header block of the currently
read sector are compared against the ones from the
header of 18/0. If there is a mismatch, this error
is generated.
0F 74 Read Drive Not Ready (no disk in drive or no device 1)
The advantage with using the 35 track D64 format, regardless of error
bytes, is that it can be converted directly back to a 1541 disk by either
using the proper cable and software on the PC, or send it down to the C64
and writing it back to a 1541. It is the best documented format since it is
also native to the C64, with many books explaining the disk layout and the
internals of the 1541.
---------------------------------------------------------------------------
What it takes to support D64:
The D64 layout is probably the most robust of all the ones that exist,
being that it is an electronic representation of a physical 1541 disk. It
shares *most* of the 1541 attributes and it supports all file formats,
since all C64 files came from here. The only file I have found that can't
be copied to a D64 is a T64 FRZ (FRoZen image), since you lose the file
type attribute.
Since the D64 layout seems to be an exact byte copy of a 1541 floppy, it
would appear to be the perfect format for *any* emulator. However, it does
not contain certain vital bits of information that, as a user, you normally
don't have access to.
Preceeding each sector on a real 1541 disk, there is a header block which
contains the sector ID bytes and checksum. From the information contained
in the header, the drive determines if there's an error on that header
(27-checksum error, 29-disk ID mismatch). The sector itself also contains
info (data block signature, checksum) that result in error detection (23
checksum, 22 data block not present, etc). The error bytes had to be added
on to the D64 image, "extending" the format to take into account the
missing info.
The disk ID is important in the copy protection of some programs. 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 a
file is really what it claims to be. In order to determine if a file is a
D64, you must check the file size.
---------------------------------------------------------------------------
Overall Good/Bad of D64 Files:
Good
----
* D64 files are the most widely supported and well-defined format, as it
is simply an electronic version of a 1541 disk
* Supports *all* filenames, even those with $00's in them
* Filenames are padded with the standard $A0 character
* Supports GEOS and REL files
* Allows complete directory customization
* Because it is a random-access device, it supports fast-loaders and
random sector access
* Cluster slack-space loss is minimized since the file is a larger fixed
size
* Has a label (description) field
* Format extentible to allow for 40-track disks
* With the inclusion of error bytes, you have support for basic
copy-protection
* Files on a disk can easily be re-written, as long as there is free
blocks
Bad
---
* The format doesn't contain *all* the info from the 1541 disk (no sector
header info like ID bytes, checksums). This renders some of the
original special-loaders and copy-protection useless.
* You don't *really* know the file size of the contained C64 files in
bytes, only blocks
* It can't store C64s FRZ files due to FRZ files needing a special flag
that a D64 can't store
* It is not an expandable filesize, like LNX or T64
* Unless most of the space on a D64 disk is used, you do end up with
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 support, GEOS interleave)
ÿ