The File Control Block is a 36-byte data structure (33 bytes in CP/M 1). It is laid out as follows:
DR F1 F2 F3 F4 F5 F6 F7 F8 T1 T2 T3 EX S1 S2 RC .FILENAMETYP... AL AL AL AL AL AL AL AL AL AL AL AL AL AL AL AL ............... CR R0 R1 R2 ....The bytes in it have the following meanings:
FCB+00h DR - Drive. 0 for default, 1-16 for A-P. In DOSPLUS, bit 7 can be set to indicate that the operation should work with subdirectories rather than files. FCB+01h Fn - Filename, 7-bit ASCII. The top bits of the filename bytes (usually referred to as F1' to F8') have the following meanings: F1'-F4' - User-defined attributes. Any program can use them in any way it likes. The filename in the disc directory has the corresponding bits set. F5'-F8' - Interface attributes. They modify the behaviour of various BDOS functions or indicate error conditions. In the directory these bits are always zero. FCB+09h Tn - Filetype, 7-bit ASCII. T1' to T3' have the following meanings: T1' - Read-Only. T2' - System (hidden). System files in user 0 can be opened from other user areas. T3' - Archive. Set if the file has not been changed since it was last copied. FCB+0Ch EX - Set this to 0 when opening a file and then leave it to CP/M. You can rewind a file by setting EX, RC, S2 and CR to 0. FCB+0Dh S1 - Reserved. FCB+0Eh S2 - Reserved. FCB+0Fh RC - Set this to 0 when opening a file and then leave it to CP/M. FCB+10h AL - Image of the second half of the directory entry, containing the file's allocation (which disc blocks it owns). FCB+20h CR - Current record within extent. It is usually best to set this to 0 immediately after a file has been opened and then ignore it. FCB+21h Rn - Random access record number (not CP/M 1). A 16-bit value in CP/M 2 (with R2 used for overflow); an 18-bit value in CP/M 3.
If you are writing an emulator at BDOS level, you need to be aware of how CP/M uses the bytes EX, S2, and CR. Some programs (such as the Digital Research linker, LINK.COM) manipulate these bytes to perform "seek" operations in files without using the random-access calls.
CR = current record, ie (file pointer % 16384) / 128 EX = current extent, ie (file pointer % 524288) / 16384 S2 = extent high byte, ie (file pointer / 524288). The CP/M Plus source code refers to this use of the S2 byte as 'module number'.
In CP/M 2 at least, bit 7 of S2 is the 'File Write Flag'. It is set when a file is opened, and cleared if there is any change to the FCB fields (such as file length or allocation bytes) that should be written back to disk when the file is closed).
The CP/M 2 CCP uses this mechanism to remove the last record of $$$.SUB; it decreases byte 0Fh (RC) by 1, shortening the file, sets S2 to zero so the File Write Flag is cleared, and closes the file. Under CP/M 3 and later, F_TRUNCATE is used instead.