The Macintosh File System, or MFS, is the original Macintosh filesystem created for use on 400K floppy disks. It was first released in January 1984, and effectively discontinued September 1985 with the introduction of HFS. Write support was removed in Mac OS version 7.6, and read support was removed in version 8.
MFS is a very limited filesystem. This means it's simple to implement, but less efficient than its successors. All files are stored in a single directory.
An MFS volume consists of a boot block, a master directory block, some file directory blocks, and some allocation blocks. It may also have a backup master directory block, but this is optional. These blocks are each defined in terms of 512-byte sectors.
Unless otherwise specified, all values are big-endian (MSB first).
The boot block is the first two sectors of the volume. Boot code can be placed here to make a bootable disk.
Master Directory Block
The Master Directory Block (MDB) is the two sectors immediately following the boot block. It consists of the volume information and the block map. The format of the volume information is:
|Offset (in bytes)||Size (in bytes)||Typical value (400K disk)||Meaning|
|0||2||0xD2D7||Signature. This must always be the value 0xD2D7 to identify a MFS volume.|
|2||4||Creation date, in seconds since midnight January 1st 1904.|
|6||4||Last backup date, in seconds since midnight January 1st 1904.|
|10||2||0x0000||Attributes. Bit 7 is set if the volume is locked by hardware. Bit 15 is set if the volume is locked by software. Other bits are unknown.|
|12||2||Number of files.|
|14||2||4||File directory start. This is the first sector of the directory, relative to the start of the volume.|
|16||2||12||File directory length. This is the length of the directory, in sectors.|
|18||2||391||Number of allocation blocks.|
|20||4||1024||Allocation block size, in bytes. This may be any multiple of 512, not just powers of 2.|
|24||4||8192||Clump size, in bytes. This is a hint to the filesystem driver for how many allocation blocks to reserve when increasing the size of a file. This must be a multiple of the allocation block size.|
|28||2||16||Allocation block start. This is the first sector of the first allocation block, relative to the start of the volume.|
|30||4||Next file number. This is a hint to the filesystem driver for which file number it should assign to the next file.|
|34||2||Free allocation blocks.|
|36||28||Volume name. This field has a fixed length, but it contains a variable-length Pascal string. The first byte indicates the number of characters in the string, and that many of the following bytes contain the string. Any remaining bytes should be padded with zeroes.|
Immediately following the volume information is the block map. The block map is an array of 12-bit entries, packed together MSB-first. Every three bytes contains two entries. Each 12-bit entry points to the next allocation block of the file. It's similar to the file allocation table in FAT12, except FAT12 is LSB-first.
Like FAT, allocation blocks are numbered starting from 2. However, unlike FAT, the block map begins with allocation block 2 instead of skipping the first two entries.
Some values have special meanings: 0x000 means the current allocation block is free, 0x001 means the current allocation block is the last allocation block of the file, and 0xFFF means the current allocation block contains some of the file directory blocks.
File Directory Blocks
The file directory blocks are a contiguous set of sectors on the disk. Each file directory block is one sector. Typically, they are located between the MDB and the first allocation block, but they may also be between the last allocation block and the backup MDB, or contained within some of the allocation blocks.
Variable-length directory entries are placed in the file directory blocks. Entries are placed starting at the first byte of the block, and do not cross block boundaries. Entries are padded to 2-byte aligned addresses. The format of the directory entries is:
|Offset (in bytes)||Size (in bytes)||Meaning|
|0||1||Flags. Bit 7 is always set in a directory entry; when clear, it indicates empty space with no further directory entries in this block. Bit 0 is set if the file is locked. Other bits are unknown.|
|1||1||Version. Always 0x00.|
|2||4||File type. This is often (but not always) a readable 4-character string. When the type is unknown, it should be set to 0x3F3F3F3F.|
|6||4||File creator. This is often (but not always) a readable 4-character string. When the appropriate application to open the file is unknown, it should be set to 0x3F3F3F3F.|
|10||2||Finder flags. Some of these flags mean different things depending on the Finder version, so they're not documented here. Applications may require some of these bits to be set, but most other files do not.|
|12||4||Position. This determines where in the window the file's icon will be displayed. This may safely be set to 0 when it's not needed.|
|16||2||Folder number. This determines which window the file will be displayed in. The value 0 means the main volume window, -2 means the desktop, and -3 means the trash. A positive value is the ID number for a folder.|
|18||4||File number. This number must be unique for each file in the volume.|
|22||2||First data fork allocation block. If the data fork has no allocation blocks, this should be 0.|
|24||4||Data fork size, in bytes.|
|28||4||Data fork allocated space, in bytes. This is the total size of all the allocation blocks belonging to the data fork, including any space that isn't used.|
|32||2||First resource fork allocation block. If the resource fork has no allocation blocks, this should be 0.|
|34||4||Resource fork size, in bytes.|
|38||4||Resource fork allocated space, in bytes. This is the total size of all the allocation blocks belonging to the resource fork, including any space that isn't used.|
|42||4||Creation date, in seconds since midnight January 1st 1904.|
|46||4||Modification date, in seconds since midnight January 1st 1904.|
|50||1-256||File name. This field has a variable length and contains a Pascal string. The first byte indicates the number of characters in the string, and that many of the following bytes contain the string.|
Backup Master Directory Block
If present, the backup MDB will be in the last two sectors of the volume. It's a copy of the MDB, so it shares the same layout.