SJ Research MDFS Filesystem Structure ===================================== http://mdfs.net/Docs/Comp/Disk/Format/SJ/MDFS The MDFS uses 1024-bytes disk blocks. Blocks are counted with 16-bit numbers from &0000 at the start of the filesystem. Floppy disks are formatted to 2 sides, 80 tracks, 5 sectors, 1024 bytes, and tracks are interleaved, that is block=sector+side*5+track*10. Block zero is zero bytes from the start of the physical disk (ie, sector &0000). Hard drives have 512-byte sectors. Block zero is 1024 bytes from the start of the physical disk (ie sector &0002). Disk partitions are accessed by stepping past each partition according to the partition size in each partition's Block Zero. Theoretically this allows partitions of variable sizes, but standard tools make them all the same. Block zero ---------- The first disk block contains information about the disk as a whole, where to find special objects such as "$" and "%PASSWORDS", and the printer types defined on that disk. 000-03F: Directory entry for "$". 040-056: String that identifies this as a disk. "SJ Research MDFS disk " - MDFS disk "SJ Research File Server" - FDFS/HDFS disk 057-060: Disk title, terminated with if less than ten characters. 061 : Disc type: &00 for FDFS disc with fileserver code in blocks 2..65 Usually set to &FF in other cases 062-063: Disk size in blocks. Maximum disk size is &FFFF blocks, 1024 bytes less than 64M. Also the offset from the start of this partition to the start of the next partition. 064 : Message channel (1=parallel port, 2=serial port) 065-06C: Auto_print 06D : initial printer (printer number selected at logon) 06E : Trace level (severity of logging sent to message_channel) 06F : unpriv_time - flag that allows non-syst users to set clock 070-079: unused 07A-07B: Disk mount date in standard format. (May be initial creation date) 07C-07E: Disk mount time, Hours, Minutes, Seconds. (May be initial creation time) 07F : Random number The values in 07A-07F are used to detect if a disk has in fact been changed after the Release Discs button is pressed. It is written with current date/time and a random number when the disk is mounted. 080-0BF: Directory entry for "%PASSWORDS". 0C0-1BF: Sixteen 16-byte printer entries or eight 32-byte printer entries. 1C0-1FF: Directory entry for "%PRINTQ". 200-3FF: 256x16-bit account balances accounts for &000-&0FF If more than 256 accounts are used, then the account balances continue in blocks 1 onwards up to block 4. Printer Entries --------------- 16-byte printer entry: 000-005: Printer name, padded with spaces, or six spaces for none. 006 : ??? 007 : ??? 008 : ??? 009-00F: ??? - usually set to &00 32-byte printer entry: 000-005: Printer name, padded with spaces, or six spaces for none. 006 : Printer flags: bit 0: entry exists bit 1: anonymous bit 2: account required bit 3: non-spooling 007-008: Account number required to use printer 009-01F: Banner filename, terminated with Directories ----------- Directories contain a number of 64-byte entries. Entry zero is the directory header containing information about the directory. Directory entries are not stored in any particular order. They are kept in alphabetical order through a linked list. A directory has the following layout. 0000 : Directory Header 0040 : First directory entry 0080 : Second directory entry 00C0 : Third directory entry ... 3F80 : 254th directory entry 3FC0 : 255th directory entry Information about the directory is also stored in the directory's directory entry in its parent directory. Directory Header ---------------- 000-01F: Occupied entry bitmap. Each bit is set if the corresponding directory entry is used, up to 256 directory entries. Byte 0, bit 0 represents entry 0, byte 0, bit 1 represents entry 1, and so on. Entry zero is the directory header and will always be occupied. 020-03D: Head of linked list for directory entry chain table. These are linked lists of directory entries in case-insensitive alphabetical order, following the 'next' field in the directory entry. 020-021: filenames <'A' 030-031: filenames 'O','P' 022-023: filenames 'A','B' 032-033: filenames 'Q','R' 024-025: filenames 'C','D' 034-035: filenames 'S','T' 026-027: filenames 'E','F' 036-037: filenames 'U','V' 028-029: filenames 'G','H' 038-039: filenames 'W','X' 02A-02B: filenames 'I','J' 03A-03B: filenames 'Y','Z' 02C-02D: filenames 'K','L' 03C-03D: filenames >'Z' 02E-02F: filenames 'M','N' Each entry in the head is: byte 0: count of entries in this chain byte 1: entry number of first entry in this chain 03E-03F: unused. Directory Entry --------------- 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |Ac| Object name and attributes |Nx| Load Addr | Exec Addr | Length |At|CDate|MDate|MTime|Accnt| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 000 : Account number b0-b7. 001-00A: Object name, terminated by or <00> if less than ten characters. 00B : Next - entry number of next entry in alphabetical order 00C-00F: Load address. 010-013: Exec address. 014-016: Length. If object is a directory, length is zero. 017 : Access: Multiple:Private:Directory:Locked:OwnerW:OwnerR:PublicW:PublicR 018-019: Creation date in standard format. 01A-01B: Modification date in standard format. 01C-01D: Modification time, Hours, Minutes (no seconds). 01E : Auxilary account number b0-b7. 01F : b0 : 0=16xblock pointers, 1=16xAllocation block pointers b1-b3: account number b8-b10 b4-b6: auxilary account number b8-b10 b7 : not used, normally set to zero If the object is a directory: LOAD: 00C : default access. 00D : cycle number, incremented when directory changed 00E-00F: parent directory block number EXEC: 010 : parent directory entry number 011 : contains the number of entries. 012 : unused, set to zero 013 : unused, set to zero If the object is a %PRINTQ item: 00C-013 : holds user name compressed to 6 bits per character 013 b4-b7: last four bits of compressed user name b0-b3: logical printer number ACCESS: 017 : --D----r for /spl printer spool files --D---wr for /prt printout file DATE: 018-019 : station number printed from Files are created with the default access for the directory. Directories are created unlocked with access D/. 020-03F: Allocation vector of sixteen 16-bit block numbers. If byte &01F bit 0 is zero, then the sixteen blocks pointed to by the allocation vector contain the object's data. The first pointer points to the object's first 1024 bytes, the second pointer to the second 1024 bytes, etc, up to 16K in total. If byte &01F bit 0 is one, then the sixteen blocks pointed to by the allocation vector contain up to 512 block pointers that actually point to the object's contents. The first pointer points to a block that points to the data for the first 512K, the second pointer points to a block that points to the data for the second 512K, etc, up to 8M in total. A block number of zero indicaties that that part of the object has not been allocated any disk space, and will be read as zeroes when accessed. If the object is a directory, a vector of block numbers is used. Note that the NetFS access byte format is different to the standard filing system access byte format. The internal byte can be converted to the standard access byte with the following code: access%=(nfsacc%AND3)*16+(nfsacc%AND12)/4+(nfsacc%AND16)/2 This converts the NetFS access byte MPDLWRwr to the filing system access byte 00wrL0WR. 8-bit NetFS returns the two 'E' bits as duplicates of the 'R' bits on reading and ignores the 'E' bits on writing. RISC OS NetFS returns the Owner 'E' bit clear and the public 'E' bit as the MDFS 'P' bit on reading. Standard date and time format ----------------------------- Byte 0 b0-b4: day of month. b5-b7: (year-1981) bit 4-bit 6. Byte 1 b0-b3: month. b4-b7: (year-1981) bit 0-bit 3. Byte 0 : hours 00-23 Byte 1 : minutes 00-59 Byte 2 : seconds 00-59 The standard time&date is the two-byte date followed by the three-byte time. Parent directory ---------------- The parent directory is not specified in the directory. It is recorded in the directory's own directory entry in the parent directory as the block number of the parent directory and the entry number in that directory. For example, a directory in the root directory has a parent of &0000/&00, which references the root directory's entry in block &0000. The parent of $, %PRINTQ and %PASSWORDS is the root directory at block &0000, entry &00. %PRINTQ ------- Compressed user name. Contents of /prt and /spl files. %PASSWORDS ---------- See mdfs.net/Docs/Books/SJMDFS for %PASSWORDS file format. Version History --------------- 1.00 12-Sep-2004 First draft. 1.01 19-Apr-2007 Account balances, hard drive layout, disk creation date, 32-byte printer entries. 1.02 22-Apr-2021 Adding updates from Andrew Gordon, ex-SJ engineer. Directory info for %PRINTQ entries.