This the multi-page printable view of this section.Click here to print.

Return to the regular view of this page.

CBM DOS

Disk format for the C64 1541 disk drive

Table of Contents

The 1541 disk drive used 5.25" disks. The standard CBM DOS format is 170 KB with 35 tracks and 256-byte sectors providing 165K for storage.

Although standard disks are only 35 tracks, it was mechanically possible to get 40 tracks by using either custom formatting or third party DOS's.

The format described in this section also applies to .D64 disk images that can be used with both Emulators like VICE and the PI1541 attached to a real C64.

1 - Physical layout

Physical Disk Layout for the 1540/1541

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, varied the number of sectors per track and data densities across the disk to optimize available storage.

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 counting starts at 1, not 0, and goes up to 35.

Track's 36…40 are only valid for 40 track disks, although with low-level programming the 1541 drive could access tracks 36…40.

Some copy-protection schemes did this.

Sector counting starts at 0, not 1, for the first sector, therefore a track with 21 sectors will go from 0 to 20.

Track layout
Track Sectors/Track # Sectors Storage in bytes
01 17 21 357 7820
18 24 19 133 7170
25 30 18 108 6300
31 35 17 85 6020
36* 40* 17 85 6020

* Standard CBM DOS disks had only 35 tracks.

2 - Directory Track

Directory track 18

The directory track is contained totally on track 18. Sectors 1…18 contain the directory entries whilst 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.

Byte Content
7 6 5 4 3 2 1 0
00 15 Location of next directory sector, 0x0000=end 8 First Directory entry
01 7 0
02 Closed Locked Save 30File Type
03 15 Location of first sector of file 8
04 7 0
05 Filename in PETASCII padded with 0xA0
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15 15 Location of first side-sector block 8
16 7 0
17 REL file record length, max value 254
18 Unused in CBM DOS, GEOS only
19
1A
1B
1C
1D
1E 7 File size in sectors 0
1F 15 8
20 Must be set to 0x0000 Second Directory entry
21
22 Closed Locked Save 30File Type
23 15 Location of first sector of file 8
24 7 0
25 Filename in PETASCII padded with 0xA0
26
27
28
29
2A
2B
2C
2D
2E
2F
30
31
32
33
34
35 15 Location of first side-sector block 8
36 7 0
37 REL file record length, max value 254
38 Unused in CBM DOS, GEOS only
39
3A
3B
3C
3D
3E 7 File size in sectors 0
3F 15 8
   

Sector pointers

The sector pointers at offset 0x00, 0x03 & 0x15 are Track/Sector values.

The track number is in the first byte, sector number in the second.

Next directory sector pointer

The next directory sector pointer at offset 0 points to the next directory sector in the chain. If it's the last entry in the chain then it is set to 0x0000.

It is only valid for the first directory entry. On file entries other than the first one in the sector this pointer is unused & is set to 0x0000.

File Type

7 3 2 1 0 Name File Type
00000Scratched, deleted file entry
10000DELDeleted
10001SEQSequential
10010PRGProgram
10011USRUser
10100RELRel

All other values are illegal and will produce strange results.

Some routines use all 4 lower bits, some ignore bit 3.

All file types require the Closed flag (bit 7) to be set. Only DEL is valid with Closed cleared when it indicates a deleted file entry.

File length

The file length is a little endian value with the lsb first, msb last. It is a sector count, not the file count.

REL files

Bytes with offset 0x15…0x17 are only used for REL files.

3 - Block Availability Map

Directory track 18 sector 0, the BAM and disk details

Track 18 sector 0 contains the Block Availability Map (BAM) and details about the disk including it's title.

Track 18 Sector 0

Byte Content
7 6 5 4 3 2 1 0
00 15 Location of first directory sector 8 Header
01 7 0
02 DOS version type, normally 0x41 "A"
03
04 Free sector count Track 1 Block Availability Map
05 S7 S6 S5 S4 S3 S2 S1 S0
06 S15 S14 S13 S12 S11 S10 S9 S8
07 S20 S19 S18 S17 S16
08 Free sector count Track 2
09 S7 S6 S5 S4 S3 S2 S1 S0
0A S15 S14 S13 S12 S11 S10 S9 S8
0B S20 S19 S18 S17 S16
   
44 Free sector count Track 17
45 S7 S6 S5 S4 S3 S2 S1 S0
46 S15 S14 S13 S12 S11 S10 S9 S8
47 S20 S19 S18 S17 S16
48 Directory Track 18 = 0 Free
49 All allocated so should be set to 0
4A as entire track is reserved for the directory
4B
4C Free sector count Track 19
4D S7 S6 S5 S4 S3 S2 S1 S0
4E S15 S14 S13 S12 S11 S10 S9 S8
4F S18 S17 S16
   
60 Free sector count Track 24
61 S7 S6 S5 S4 S3 S2 S1 S0
62 S15 S14 S13 S12 S11 S10 S9 S8
63 S18 S17 S16
64 Free sector count Track 25
65 S7 S6 S5 S4 S3 S2 S1 S0
66 S15 S14 S13 S12 S11 S10 S9 S8
67 S17 S16
   
78 Free sector count Track 30
79 S7 S6 S5 S4 S3 S2 S1 S0
7A S15 S14 S13 S12 S11 S10 S9 S8
7B S17 S16
7C Free sector count Track 31
7D S7 S6 S5 S4 S3 S2 S1 S0
7E S15 S14 S13 S12 S11 S10 S9 S8
7F S16
   
8C Free sector count Track 35
8D S7 S6 S5 S4 S3 S2 S1 S0
8E S15 S14 S13 S12 S11 S10 S9 S8
8F S16
90 Disk Name padded with 0xA0 Disk title & type
91
92
93
94
95
96
97
98
99
9A
9B
9C
9D
9E
9F
A0 Unused set to 0xA0A0
A1
A2 7 Disk ID 0
A3 15 8
A4 Unused set to 0xA0
A5 DOS type, usually ASCII "2A"
A6
A7 Unused set to 0xA0
A8
A9
AA
AB Unused, set to 0x00 Reserved
 
FF

Offset for each Track BAM entry

Track Offset
0104
0208
030C
0410
0514
0618
071C
0820
0924
1028
112C
1230
1334
1438
153C
1640
1744
1848
194C
2050
2154
2258
235C
2460
2564
2668
276C
2870
2974
3078
317C
3280
3384
3488
358C

How BAM entries work

Each track has a BAM entry, which consists of 4 bytes. The first byte is the number of free sectors on that track.

The next three bytes form a bit map of the available sectors in little endian format. A 1 represents a free sector, whilst a 0 represents an allocated sector.

As there are 24 bits available but tracks range from 16 to 21 sectors then the unavailable sectors are marked as allocated, i.e. 0.

4 - File format

How files are stored on the disk

In the directory a file's location on the disk is stored with the first Track/Sector it occupies and the file length is in sectors not bytes.

This is done because on the disk a file is a linked list of sectors with each sector consisting of two bytes containing the Track/Sector of the next sector then 254 bytes of data.

The last sector of the file is marked when the Track ID is set to 0. When this happens the Sector portion indicates how many bytes remain for the file, a value from 1 to 254 bytes.

Byte First sectors Last sector
00 15 Next sector location 8 EOF marker Header
01 7 0 Number of bytes
02 254 bytes data remaining bytes data Data
nn
  Undefined
FF

Example

Let's imaging we have a file that's 1322 bytes long spread over 6 sectors. The first sector of the file is stored at Track 17 Sector 21.

In the directory we have the start sector set to 17/21.

1 2 3 4 5 6
T S T S T S T S T S T S
17 0 17 10 17 20 17 1 17 11 0 52

The first 2 bytes of that sector consists of 17 and 0 indicating the next sector is track 17 sector 0. The rest of that sector is 254 bytes of data.

The second sector at Track 17 Sector 0 consists of 17 and 10 which points to the third sector. It also has 254 bytes.

The sixth and final sector has Track set to 0. This is not a valid track as they start from 1, so it marks this sector as the final one in the file.

Here, the sectorId is taken as the number of bytes in this sector which contains data, 52 bytes in this instance. All other bytes in the sector after the data is ignored.

5 - D64 Image Format

CBM DOS as a single image for Emulators

The .D64 disk image format follows the format as defined for CBM DOS. Images of this format can be used in Emulators like VICE and the PI1541 attached to a real C64.

As stated in Physical Layout, Track numbers start from 1 but Sectors in a track start from 0.

35 track images are exactly 174848 bytes long whilst a 40 track image is exactly 196608 bytes.

The table below shows the position of the start of each 256 byte sector within the .D64 file.

Track Sector Sectors In D64 Offset Track Sector Sectors In D64 Offset
1 21 0 0x00000 21 19 414 0x19E00
2 21 21 0x01500 22 19 433 0x1B100
3 21 42 0x02A00 23 19 452 0x1C400
4 21 63 0x03F00 24 19 471 0x1D700
5 21 84 0x05400 25 18 490 0x1EA00
6 21 105 0x06900 26 18 508 0x1FC00
7 21 126 0x07E00 27 18 526 0x20E00
8 21 147 0x09300 28 18 544 0x22000
9 21 168 0x0A800 29 18 562 0x23200
10 21 189 0x0BD00 30 18 580 0x24400
11 21 210 0x0D200 31 17 598 0x25600
12 21 231 0x0E700 32 17 615 0x26700
13 21 252 0x0FC00 33 17 632 0x27800
14 21 273 0x11100 34 17 649 0x28900
15 21 294 0x12600 35 17 666 0x29A00
16 21 315 0x13B00 36* 17 683 0x2AB00
17 21 336 0x15000 37* 17 700 0x2BC00
18 19 357 0x16500 38* 17 717 0x2CD00
19 19 376 0x17800 39* 17 734 0x2DE00
20 19 395 0x18B00 40* 17 751 0x2EF00

† Track 18 is reserved for the Directory and Block Allocation Map.
* Track's 36…40 are only available on 40 track images.

6 - Auto boot

Making a disk bootable on the C128

On the Commodore C128 it was possible to auto-boot a floppy disk that's in the drive when the system is powered up. This does NOT work on the C64.

This only works if Track 1 Sector 0 is allocated and contains a specific signature.

I don't have a C128 so I cannot confirm this, only know of this functionality as it's mentioned in some documentation about the disk format and even then they are not 100% certain if even this is accurate.

Boot sector format

Byte Content Description
00 Signature Auto-boot Signature "CBM"
01
02
03 Additional sectors Track/Sector address or 0x0000 for none
04
05 Bank Bank for additional sectors, default 0x00
06 Load count Number of sectors to load, default 0x00
07 Boot message 0x00 terminated string, can be just 0x00 for "BOOTING..."
08+b Program name 0x00 terminated string, can be just 0x00 for none
09+b+p Boot Loader Boot Loader code, padded with 0x00
 
FF

Example 1

This is from lemon64.com which has an example of a boot sector in DASM.

In this instance it autoboot's CPM:

Boot loader:
C128 boot sector. (T1, S0)
Compile without a load address. {-f3}
processor 6502
org0x0b00
byte"CBM"Auto boot signature
word0x0000Load address for additional sectors. (T1, S1)
byte0x00Bank number for additional sectors.
byte0x00Number of sectors to load.
byte"", 0x00Boot message: "BOOTING..."
byte"", 0x00Program to load on boot.
startldx#<cmd-1Address of command -1
ldy#>cmd
jmp0xafa5Execute BASIC command
cmdbyte"OPEN1,8,15,", $22
byte"CD:CPM.D64", $22
byte":CLOSE1:BOOT"
org0xbff, 0x00Fill with 0x00 to make 256 bytes
byte0x00

Example 2

This is from C128BOOT.txt which seems to be different to the above.

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 43424D 000C 00020000 A5D7 C980 F003 20 Code
10 5FFF A9058D06D5A94E8D00FF4C000C
20 All 0x00 Blank
 
F0

The code for the above loader is:

Boot loader:
ORG0x0c00start at 0x0c00 as defined in bytes 3 & 4 of boot sector
bootloaderLDA0xD7If 0xD7 = 0x80 then do some initialisation
CMP#0x80
BEQinit
JSR0xFF5FCall unknown OS call but why JSR not JMP?
initLDA#0x05Initialise 0xD506 to 5
STA0xD506
LDA#0x4Eand 0xFF00 to 0x4e
STA0xFF00
JMPbootloaderRestart the boot loader

7 - GEOS Extensions

GEOS VLIR (Variable Length Index Record)

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.

Directory entry

Byte Content
7 6 5 4 3 2 1 0
00 15 As per CBM DOS, Location of next directory sector
or 0x0000 for last sector or not first file
8
01 7 0
02 Closed Locked Save 30CBM File Type
03 15 Location of first sector of file 8
04 7 0
05 Filename in PETASCII padded with 0xA0
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
12
13
14
15 15 Location of info block 8
16 7 0
17 GEOS file structure, 00=Sequential 01=VLIR file
18 GEOS file type
19 Year (1900+value)
1A Month (1-12)
1B Day (1-31)
1C Hour (0-23)
1D Minute (1-59)
1E 7 File size in sectors 0
1F 15 8

Info block

Byte Content
7 6 5 4 3 2 1 0
00 15 Always 0x00, 0xFF as this is 1 sector long 8
01 7 0
02 Information sector ID Always 0x03 0x15, 0xBF
03
04
05 Icon bitmap in sprite format, 63 bytes
 
43
44 30CBM File Type
45 GEOS file type
46 GEOS file structure
47 7 Program load address 0
48 15 8
49 7 Program end address
Accessories only
0
4A 15 8
4B 7 Program start address 0
4C 15 8
4D Class text, terminated with 0x00
 
60
61 Author, terminated with 0x00
 
74
75 If document name of application that created it
 
88
89 Free for applications, unreserved
 
9F
A0 Description, terminated with 0x00
 
FF

The CBM File Type, GEOS file type and GEOS file structure fields are duplicated in both structures

CBM DOS file type

REL files are not permitted with GEOS. If byte 0x18 in the directory entry is 0x00 then it's a standard CBM DOS file, otherwise it's a GEOS file.

GEOS File type

Value Type Value Type
00Normal C64 file 08Font File
01BASIC 09Printer Driver
02Assembler 0AInput Driver
03Data file 0BDisk Driver
04System file 0CSystem Boot file
05Desk Accessory 0DTemporary
06Application 0EAuto-Execute file
07Application Data 0FUndefined

File types 0x0F…0xFF are undefined.

Sources