The 1541’s file system keeps everything about the disk on track 18: the block
availability map (BAM) and disk name in sector 0, and the directory from sector 1. Every
directory and file sector starts with a two-byte link to the next one. Text is PETSCII,
padded with A0. Numbers are little-endian. This page follows
the VICE manual, section 17.5 (The D64 disk image format).
Sector chains
| Offset | Size | Name | Description |
|---|---|---|---|
0x00 | 1 | Next track | Track of the next sector in the chain; 0 in the last sector. |
0x01 | 1 | Next sector | Its sector. In the last sector, this is instead the index of the last used byte (so the sector holds that − 1 bytes of data). |
0x02 | 254 | Data | Data bytes. |
VICE’s example: a chain ending in 00 34 means the last sector holds
bytes 0x02–0x34. Files are written with a sector interleave
of 10, the directory with 3.
BAM: track 18, sector 0
| Offset | Size | Name | Description |
|---|---|---|---|
0x00 | 2 | Directory start | Track and sector of the first directory sector, normally 18/1. |
0x02 | 1 | DOS version | 0x41 (A). Any other value except 0 makes the 1541 treat the disk as write-protected. |
0x03 | 1 | – | Unused. |
0x04 | 140 | BAM entries | Four bytes for each of tracks 1 to 35; see below. |
0x90 | 16 | Disk name | Padded with A0. |
0xA0 | 2 | – | A0 A0. |
0xA2 | 2 | Disk ID | The two-character ID given when the disk was formatted. |
0xA4 | 1 | – | Usually A0. |
0xA5 | 2 | DOS type | Usually 2A. |
0xA7 | 4 | – | A0. |
0xAB | 1 | – | 0. |
0xAC | 20 | Dolphin DOS BAM | Entries for tracks 36–40 on 40-track disks made with Dolphin DOS. |
0xC0 | 20 | Speed DOS BAM | Entries for tracks 36–40 on 40-track disks made with Speed DOS. |
0xD4 | 44 | – | 0. |
ProLogic DOS puts its entries for tracks 36–40 at 0x90–0xA3
and moves the disk name and ID to 0xA4.
Each BAM entry is a count of free sectors on the track, then three bytes of bitmap:
bit 0 of the first byte is sector 0, bit 7 sector 7, bit 0 of the second byte sector 8,
and so on. A set bit means the sector is free. For example 12 FF F9 17 is
a track 1 with 18 sectors free and sectors 9, 10 and 19 used.
Directory
Directory sectors start at 18/1 and chain like any other; each holds eight 32-byte entries, at most 144 in all. Only the first entry of each sector uses bytes 0–1, for the chain link.
| Offset | Size | Name | Description |
|---|---|---|---|
0x00 | 2 | Next directory sector | Track and sector link (first entry of the sector only; 00 00 elsewhere). |
0x02 | 1 | File type | See file types. 00 is an empty or deleted entry. |
0x03 | 2 | First sector | Track and sector of the file’s first sector. |
0x05 | 16 | File name | PETSCII, padded with A0. |
0x15 | 2 | Side-sector block | REL files only: track and sector of the first side-sector block (the record index). |
0x17 | 1 | Record length | REL files only: bytes per record, at most 254. |
0x18 | 6 | – | Unused, except on GEOS disks. |
0x1E | 2 | Size | The file’s length in sectors (“blocks”), low byte first. |
| Bits | Meaning |
|---|---|
| 0–3 | Type: 0 DEL, 1 SEQ (sequential data), 2 PRG (program), 3 USR (user), 4 REL (relative, record-based); 5–15 illegal (VICE: the 1541 treats these bits inconsistently, some routines ignoring bit 3). |
| 4 | Unused. |
| 5 | Set only while a file is being replaced with SAVE "@:…". |
| 6 | Locked: set produces “>” locked files in the listing. |
| 7 | Closed. A file left open (clear) is a “splat” file, listed with *. |
So 0x82 is an ordinary closed program, 0x81 a closed
sequential file and 0xC2 a locked program.
Example
00016500 12 01 41 00 12 FF F9 17 15 FF FF 1F 15 FF FF 1F ..A.............
…
00016590 44 45 4D 4F 20 44 49 53 4B A0 A0 A0 A0 A0 A0 A0 DEMO DISK.......
000165A0 A0 A0 30 31 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 ..01.2A.........
…
00016600 00 FF 82 11 00 48 45 4C 4C 4F A0 A0 A0 A0 A0 A0 .....HELLO......
00016610 A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 ................
Reading it: the directory starts at 18/1; DOS version A; track 1 has 18
free sectors, tracks 2 and 3 all 21; the disk is named DEMO DISK, ID
01, DOS type 2A. The first directory sector (18/1, at
0x16600) is the last one (next track 0); its first entry is a closed
PRG called HELLO starting at track 17 sector 0, one block
long.