IDE64 Filesystem 0.11 revision 5 © 2001-2003 by Soci/Singular (Commodore File System)

This document describes the new filesystem layout to be used with IDE64 and other systems. The expected behaviour for attributes, etc. is also explained.

This document is written in HTML 4.01 Transitional with CSS1. Use browser version 5 or above in 1024x768, or text based browser with table rendering.
Most recent version available at http://singularcrew.hu/idedos/cfs.html.

"Boot sector" layout

The disk starts with a "boot sector". This contains the identification string ("C64 CFS V 0.11B "), the global disklabel, a pointer to @Partition directory and it's backup, and the last sectors address. The default partition number (DP) is used to select which partition will be automatically selected after power on. Values of 0-15 are valid. The global disklabel is shown in partition listing. The @Last disk sector points to the last accessible sector on disk. If this pointer has the LBA bit set, this disk uses LBA addressing.

OFFSET01234567
$0000UnusedDP@Last disk sector
$0008$43$36$34$20$43$46$53$20
$0010$56$20$30$2E$31$31$42$20
$0018@Partition directory@Partition directory backup
$0020Global disklabel padded with $20 if shorter
$0028

If there's a PC BIOS style partition table in the rest of the sector, then one of the partitions must cover all the C64 partitions. In this case use $CF as partition type.

Pointers (@...) usually have the following structure:
Byte / Bit76543210
Byte 00LBA00HEAD / LBA HIGHEST
Byte 1CYLINDER HIGH / LBA HIGH
Byte 2CYLINDER LOW / LBA LOW
Byte 3SECTOR / LBA LOWEST
If LBA=1 then this pointer is in LBA format.

The partition directory & backup

The partition directory is 1 sector long, and holds 16 entrys from the following 32 bytes long structure:

A partition entry:
OFFSET01234567
$0000Partition's name padded with $00 if shorter.
$0008
$0010@Start of partition@End of partition
$0018Additional info (filesystem specific, see below)
First byte of @Start of partition has additional fields:
Byte / Bit76543210
Byte 0VALIDLBAHIDDENWRITEABLEHEAD / LBAHIGHEST
If VALID=1 then this partition is valid.
If HIDDEN=1 then this partition won't show up in partition listing.
If WRITEABLE=0 then this partition is readonly.
First byte of @End of partition has additional fields:
Byte / Bit76543210
Byte 0TYPELBATYPEHEAD / LBAHIGHEST
TYPE is 4 bit number extracted by clearing the LBA bit, so 8 combinations are possible.
If TYPE=%0000 then partition is unformatted.
If TYPE=%0001 then filesystem is CFS.
If TYPE=%0010 then disk space is used by GEOS.
TYPE values of %0011-%1011 are reserved.
Additional info layout for CFS:
OFFSET01234567
$0018@Deleted directory@Root directory
First byte of @Deleted directory has no additional fields:
Byte / Bit76543210
Byte 0reserved (0)LBAreserved (0)HEAD / LBAHIGHEST
First byte of @Root directory has additional fields:
Byte / Bit76543210
Byte 0BITMAPLBAreserved (0)HEAD / LBAHIGHEST
If BITMAP=0 then this CFS partition uses the #1 usage bitmap, otherwise the #2.
A CFS partition layout:
1st usage bitmap sector #14
0
9
6
1st usage bitmap sector #2
4094 data sectors
2nd usage bitmap sector #14
0
9
6
2nd usage bitmap sector #2
4094 data sectors
...etc....
A usage bitmap sector:
Byte / Bit76543210
Byte 0001st-6th data sectors useage
Byte 17th-14th data sectors useage
......etc...
Byte 5114087th-4094th data sectors useage
Each bit represents a free data sector (1) or used data sector (0).
If there aren't 4094 data sectors at the end of partition, all sectors not part of this partition must be marked as used.

CFS Directory sectors

A directory sector holds 16 file entrys and a pointer to @Next directory sector.
Filesize range is from 0 to 4294967295 bytes, for relative files max. 16711425 bytes.

"Empty entry / Directory separator" type
A "DEL" entry (FILETYPE=%000):
OFFSET01234567
$0000Filename padded with $00 if shorter.
$0008
$0010$00$00$00$00@reserved
$0018AT$44$45$4CCreation time
If CLOSED=0 then this is a free entry, can be reused next time. It's skipped in directory list.
If CLOSED=1 then this is a directory separator entry in this case:
The READABLE, WRITEABLE, EXECUTEABLE, bits must be always 0, these flags are not changeable!
A directory separator cannot hold real data, it's only a directory entry.
Should appear with filetype "DEL" in directory listing.
"Normal file" type
A normal file entry (FILETYPE=%001):
OFFSET01234567
$0000Filename padded with $00 if shorter.
$0008
$0010Filesize@Data tree
$0018ATFiletype padded with $00Modification time
Filetype "D"/"DEL" is not valid, because it's an alias of "DEL", and it's handled elsewere.
Filetype "S" is not valid, because it's an alias of "SEQ".
Filetype "P" is not valid, because it's an alias of "PRG".
Filetype "U" is not valid, because it's an alias of "USR".
Filetype "L"/"R"/"REL" is not valid, because it's an alias of "REL", and it's handled elsewere.
Filetype "C"/"CBM" is not valid, because it's an alias of "CBM", and it's reserved.
Filetype "B"/"DIR" is not valid, because it's an alias of "DIR", and it's handled elsewere.
Filetype "J"/"LNK" is not valid, because it's an alias of "LNK", and it's handled elsewere.
Normal file type includes "SEQ", "PRG", "USR", and user defined filetypes.
Behaviour of flags:
If EXECUTEABLE=1, it's possible to load this file, otherwise it's skipped when searching (might be still openable!).
If READABLE=1, it's possible to open this file, otherwise error happens (might be still loadable!).
"Relative file" type
A "REL" entry (FILETYPE=%010):
OFFSET01234567
$0000Filename padded with $00 if shorter.
$0008
$0010FilesizeRS@Data tree
$0018AT$52$45$4CModification time
Traditionally used for random access files in CBM DOS.
RS is the record size, from 1 to 255. 0 is invalid.
Should appear with filetype "REL" in directory listing.
"Subdirectory / Directory label" type
A subdirectory entry (FILETYPE=%011):
OFFSET01234567
$0000Dirname padded with $00 if shorter.
$0008
$0010$00$00$00$00@Sub directory
$0018AT$44$49$52Creation time
If CLOSED=1 this entry is a regular subdirectory.
If CLOSED=0 this is a directory label.
The directory label must be always the first entry in the directory. It holds the @Parent directory and @This directory pointer. The name field will show up in directory listing as directory label.
A directory label entry (FILETYPE=%011):
OFFSET01234567
$0000Dirlabel padded with $20 if shorter.
$0008
$0010@This directory@Parent directory
$0018AT$44$49$52Creation time
The DELETEABLE, EXECUTEABLE, WRITEABLE, READABLE, HIDDEN flags must be the same as for the directory entry for this dir in the parent directory. Name is changeable by user, defaults to it's "DIR" entry's name.
Behaviour of flags (for both):
If READABLE=0 if's not possible to list this dir.
If WRITEABLE=0 if's not possible to create/delete/rename file in dir.
If EXECUTEABLE=0 it's not possible to change to this dir.
"Link" type
A "LNK" entry (FILETYPE=%100):
OFFSET01234567
$0000Filename padded with $00 if shorter.
$0008
$0010Pathlength$00$00@Link sector
$0018AT$4C$4E$4BModification time
The Pathlength represents the size of the string in the link sector.
The link sector holds a string ending with $00. It is a relative path to a file from the current dir.
File cannot be longer than 1 sector.
"Reserved" types
FILETYPE=%101,%110,%111 are reserved for future use.
The attributes field:
All entrys have an 1 byte attribute field (AT) at the same position, which specifies flags and filetype.
Byte / Bit76543210
Byte 0CLOSEDDELETEABLEREADABLEWRITEABLEEXECUTEABLEFILETYPE
Behaviour of flags:
If CLOSED=0 then this file cannot be accessed, because it wasn't closed (yet).
If DELETEABLE=0 then this file cannot be deleted.
If READABLE=0 then this file cannot be opened for reading. (might be still loadable)
If WRITEABLE=0 then this file is readonly.
If EXECUTEABLE=0 then this file cannot be loaded. (file is skipped for load)
Packed Creation / Modification time bits:
Byte / Bit76543210
Byte 0Month HIGHSecond (0-59)
Byte 1Month LOWMinute (0-59)
Byte 2Hour HIGHYear (0-63)
Byte 3Hour LOWDay (1-31)
Month (1-12), Hour (0-23). Year begins from 1980, so 2001 is 21.
First byte of @file pointers (at offset $0014) have additional meaning:
Byte / Bit76543210
Byte 0HIDDENLBANEXTSHEAD / LBAHIGHEST
If HIDDEN=1 this file is hidden, so it won't show up in directory listing.
The @Next directory sector pointer is sliced in 16 parts, and the parts are in the NEXTS fields.
@Next directory sector slicing:
Byte / Bit76543210
Byte 0in 13rd entryin 14th entryin 15th entryin 16th entry
Byte 1in 9th entryin 10th entryin 11th entryin 12th entry
Byte 2in 5th entryin 6th entryin 7th entryin 8th entry
Byte 3in 1st entryin 2nd entryin 3rd entryin 4th entry
If all 4 bytes of @Next directory sector pointer are 0s. we reachd end of directory.

Deleted directory sector

It holds the last 15 deleted files, and is usually placed in first data sector of partition.
It has the same structure as a normal directory, but is only 1 sector long, so the NEXTS field is now called AGE, and it contain the age of entrys instead of next directory sector pointer's slices. Same filenames with same type are eliminated by replacing the first character of an older file's name with a character from "A" to "N". It's directory label is "%DELETED  FILES%", directory label flags: CLOSED=0, DELETEABLE=0, EXECUTEABLE=1, WRITEABLE=0, READABLE=1, HIDDEN=1,

Root directory

It's like any other normal directory, but this is the starting point of directory stucture. It's usually begins in the second data sector (after the deleted directory sector). The root directory label is usually the same as the partition's name, but is changeable. Directory label flags: CLOSED=0, DELETEABLE=0, EXECUTEABLE=1, WRITEABLE=1, READABLE=1, HIDDEN=0,
After the label there's usually a "%DELETED  FILES%" directory entry with flags CLOSED=1, DELETEABLE=0, EXECUTEABLE=1, WRITEABLE=0, READABLE=1, HIDDEN=1, it's pointer points to deleted directory sector.

Data tree sectors

Data sector pointers are organised in balanced tree for fast seeking. Here's a table about amount of sectors to read to search to a position in file:

Tree depthPositionSector(s) to read
10 b - 64 Kb1+1
264 Kb - 576 Kb2+1
3576 Kb - 4.5 Mb3+1
44.5 Mb - 36 Mb4+1
536 Mb - 292 Mb5+1
6292 Mb - 2.2 Gb6+1
72.2 Gb - 4 Gb7+1
Tree sector layout
OFFSET01234567
$0000@Data sector #1@Data sector #2
......etc...
$01F8@Data sector #127@Data sector #128
Each node is 1 sector, and holds 8 @Next tree pointers, and 128 @Data sector pointers.
First byte of pointers have additional meaning:
Byte / Bit76543210
Byte 0reserved (0)LBASLICEHEAD / LBAHIGHEST
@Next tree sector pointers 1-8 are sliced and are in 2 bit pieces (SLICE) in @Data sector pointers. (#1 in 1-16, #2 in 17-32 ...) Same slicing method is used as for @Next directory sector.
The following special @Data sector or @Next tree pointer is used to indicate a hole in file or tree:
Byte / Bit76543210
Byte 0reserved (0)0SLICE0000
Byte 100000000
Byte 200000000
Byte 300000000
Holes are sectors filled with $00, or for relative files $FF at record beginnings and $00 everywhere else. This way unused parts of relative/normal files do not eat up disk space.

Summary

Advantages over 0.02 filesystem:

Disadvantages:

-Soci/Singular-

Document by:

Kajtár Zsolt
mail: soci at c64.rulez.org