Commodore‎ > ‎C128‎ > ‎CP/M‎ > ‎

Disk Format

A CP/M disk is divided into 3 main parts:
  • Boot sector(s)
  • Directory
  • Data
  Boot Sector(s)
The beginning of the disk is reserved by CP/M for holding a "boot image".  For "bootable" / "system" disks, this region holds the code to load the operating system (CP/M) into the host computer (boot code).   The C128 only uses 1 sector... it is very small (compared to other implementations of CP/M) because it makes calls to the C128's ROM (programs stored in permanent [non-disk] memory). and it loads the CP/M system from a "normal file" (listed in the directory; not a secret of the boot sectors).

NOTE: Many (most?) other versions of CP/M store the system software (CP/M) in the boot sector(s).... this means the system code is "hidden" once CP/M is running.  On the C128, the boot sector simply "loads" a standard CP/M file as the operating system (a file listed in the Directory... see below).

INCOMPATIBILITY: Each version of CP/M had it's own value for the number of boot sectors... so a Kapro machine might use 36 sectors, while an Osborne machine might use 27 sectors, and the C128 would use 1 sector...The important thing is there is no record on the disk which describes how many sectors are used "to boot"!  In other words, there is no record of where the next part (the directory) begins!!  Thus, trying to use disks between various CP/M implementations will almost always fail... (Each version expects a very specific count of "boot sectors", but there is no standard.).

After the boot sector(s) is the Directory.  The Directory holds information about all files on the disk (and with CP/M v3, meta data like "disk name").
Unlike modern computers, CP/M has a "flat" directory.... there are no "sub-folders" or "sub-directories".... in theory!

However, each entry in the "flat" directory also has a "user number".  This allows CP/M to virtually divide the "flat" directory into 16 parts.  The "default part" (user 0) is designed to hold "system" programs.  In other words, any file designated as "user 0" could be accessed by any/every program.

The other 15 parts (user numbers) are specific to the current "user number" within CP/M.  So there is 1 (and only one) directory on a disk of CP/M, but the files could be assigned as either "global" (user 0) or "private" (user-specific; user 1 to 15).  Note: this mean that a maximum of 15 users (or 15 "virtual sub-directories") could exist.  Completely lame by modern (year 2000+) computer standards, but quite usable back in the day (around 1980).

Each entry in the CP/M directory ("dirent") can only reference a limited amount of file data.  The actual amount varies by disk format / vendor.  In detail, each directory entry has 16 bytes to reference sectors on the disk (sectors used by the file).  The actual amount of data a directory entry ("dirent") may reference depends on the disk format of the host computer system.  So each sector referenced in the directory entry may refer to 128 bytes, 256 bytes, 512 bytes, or 1024 bytes.  The actual number-of-bytes is NOT (officially) store anywhere!  In other words, the system/user must know the correct value!  The C128 is very flexible (will allow any size of sector) but actually getting the C128 to use a specific value is not always easy...

If that isn't bad enough (it is TERRIBLE in my opinion), another problem is each block (sector) allocated by a file may use either 1 or 2 bytes (8 or 16 bits).  Once again, there is nothing to describe how many "bytes per block" are used within an entry of the Directory.  So a 16-byte "dirent" (fixed size) may refer to either 8 or 16 blocks (depending if a block needs 1 or 2 bytes for specification).  If you are keeping score, CP/M FAIL = 1 + 1 = 2...

Anyway, if the "user space" (all sectors not used by "Boot" or by "Directory") is less than or equal to 256 sectors, then each directory entry will hold 16 references (16*1 bytes).  On the other hand, if the "user space" (all sectors not used by "Boot" or by "Directory") is more than 256 sectors, then each directory entry will only hold 8 references (8*2 bytes)

The most unique thing about the CP/M directory (my opinion) is that a single file may consume more than 1 directory entry (multiple "dirents").  For example, imagine your CP/M disk format allows 16 sectors (blocks) for each directory entry.  If the file uses more than 16 "blocks" then there will be multiple "dirents" (directory entries) for that one file!  Note the DIR (directory) command hides all this from the user: a file will only be listed once, with no indication of how many "dirents" are used in the directory.

In other words, a single file (if "large") may consume multiple directory entries!  This is quite unlike most modern file systems!

Perhaps the most important thing to know is that CP/M does not directly maintain a list of free/available blocks (sectors).  CP/M will "calculate" the available sectors as:
  • Free sectors = TOTAL_SECTORS - Sum( Used_Sectors( file ) )

The important thing to note is that TOTAL_SECTORS depends on the disk format of the host CP/M system!!!  (In short, not reliable / portable.)

  File Data
After the directory is the actual blocks ("sectors") of file data.  Each used block is referenced by an entry in the Directory.  Unused ("free") blocks are simply not referenced by any entry in the directory. 

NOTE: this means CP/M must read the entire Directory to determine which blocks are used (an thus calculate which are available)! Reading the entire directory makes CP/M slow compared to modern operating systems.

© H2Obsession, 2015, 2018