Fact-checked by Grok 2 weeks ago

File Control Block

The File Control Block (FCB) is a data structure used in the operating system and early versions of to maintain the state of an open . It stores essential about a in the application's , enabling file operations such as opening, reading, writing, and closing. The FCB typically includes the file name (padded to 8.3 format), current position, file size, and drive/user information, along with allocation details for disk blocks. The originated in , developed by and first released in 1974 as one of the earliest operating systems for microcomputers. It was designed to provide a simple interface for programs to access files without direct hardware interaction. This structure was adopted in 1.0 in 1981 to ensure compatibility with software, remaining a core component until 2.0 introduced directory support, though functions persisted in later versions until deprecation in favor of handle-based APIs. In file system implementation for these systems, the serves as a per-open-file unit managed by the application, bridging logical file operations with physical via system calls to the (in ) or kernel. When a file is opened, the application initializes an , which the OS uses to locate and access the file's directory entry and data blocks. This contrasts with modern systems, where file state is typically tracked in -managed tables; for example, systems use inodes for on-disk metadata, while Windows stores equivalent file records in the Master File Table and employs a separate in-memory FCB structure in file system drivers for open files. The plays a critical role in ensuring basic data access and integrity in and early by supporting sequential access and simple allocation methods, such as extent-based allocation in .

Introduction

Definition and Purpose

A () is a employed in early operating systems to represent and manage the state of an open . It serves as a kernel-level construct that encapsulates essential , such as the drive identifier, , extension, count, and allocation information, enabling the operating system to track and manipulate files on disk. The primary purpose of an is to provide a standardized for operations, including opening, reading, writing, closing, and deleting s, while maintaining the file's current position for sequential or . By holding a memory-resident copy of directory entry data, the FCB allows programs to interact with the without directly accessing disk sectors, thereby abstracting low-level details and ensuring during operations. This structure is managed by the operating system's basic (BDOS) or equivalent, which updates the FCB as needed and synchronizes changes back to the disk upon file closure. In , the is a fixed 36-byte structure (33 bytes in CP/M 1.0) typically located in low , such as at 0x5C, and is passed to BDOS functions via registers for all file-related calls, supporting extents of up to 16 KB each to handle larger files. inherits and extends this model with a 37-byte normal FCB and a 44-byte extended variant, incorporating additional fields like (e.g., read-only), with timestamps and further attributes added in later versions such as 2.0 and 3.0, while using Interrupt 21h for operations to enable compatibility with CP/M-style applications. Both implementations prioritize simplicity for 8-bit systems, limiting concurrent open files and record sizes to 128 bytes by default.

Historical Development

The File Control Block (FCB) originated in the CP/M operating system, developed by Gary Kildall at Digital Research in 1974 as a disk operating system for the Intel Intellec-8 microcomputer. In CP/M version 1.0, the FCB was a 33-byte data structure used exclusively for file operations, including opening, reading, writing, and closing files, providing a standardized interface for applications to interact with the file system on floppy disks. This design emphasized simplicity and portability across early microcomputers, with the FCB containing fields for drive specification, an 8-character filename, a 3-character extension, file type (text or binary), and extent information to manage file fragmentation. CP/M's FCB evolved through subsequent versions to support growing hardware capabilities. In CP/M 2.0 (1979), it expanded to 36 bytes, incorporating a 16-bit random number for sequential and file , along with a file write flag to track modifications. CP/M 3.0 (1982) further enhanced it with an 18-bit addressing scheme and the F_TRUNCATE function (BDOS call #99) for efficient file resizing, while introducing user areas and limited subdirectory support in third-party implementations like DOS Plus. These updates maintained but highlighted the FCB's limitations in handling hierarchical structures, as CP/M retained a flat model. The was adopted into through its predecessor, (also known as QDOS), developed by in 1980, which closely mirrored 's architecture for compatibility with existing software. licensed and released it as 1.0 in 1981 for the PC, where the 37-byte remained the primary mechanism for file I/O via INT 21h interrupts, supporting up to 15 open files per process without path or subdirectory capabilities. This ensured a smooth transition for applications ported to the PC platform. With 2.0 in 1983, the introduction of hierarchical directories and the (FAT) file system rendered the traditional incompatible for path-based operations, prompting the addition of a handle-based inspired by UNIX for more flexible file management. support persisted for compatibility, evolving into an extended 44-byte form in later versions to include attributes like hidden files and volume labels, but it was gradually deprecated as handle functions dominated. By 3.0 (1984), the FILES= directive in allowed up to 255 s for sharing, though usage declined with the rise of graphical interfaces and modern file systems.

Structure

CP/M File Control Block

The File Control Block (FCB) in is a fixed-size that serves as the primary for file operations within the operating system, enabling programs to specify, open, read, write, and manage on disk. Introduced in the original version 1.0 and standardized across subsequent releases up to 2.2, the FCB encapsulates essential such as the drive, filename, filetype, and allocation details, which are passed to the Basic (BDOS) for processing. This design reflects 's emphasis on simplicity and portability across early microcomputer hardware, where are organized into 128-byte records grouped into 16K-byte extents, and the FCB provides the necessary mapping for both sequential and modes. The measures 36 bytes in length for full random-access functionality, though sequential operations utilize only the first 33 bytes; it is conventionally located at 005CH in the Transient Program Area (TPA), immediately following the command buffer. User initialize the FCB by setting the filename and filetype fields, while the BDOS populates and updates system-reserved fields during file operations like opening or closing. For instance, when executing a command such as copying a , the Console Command Processor (CCP) parses the command line to fill one or two FCBs—one for the source and one for the destination—before invoking BDOS functions. This structure ensures that all disk I/O, including directory searches and record allocation, revolves around the FCB, making it integral to CP/M's flat without hierarchical . The layout of the FCB is rigidly defined to align with CP/M's 8-bit architecture and disk sector organization, as outlined in the following table:
Byte OffsetFieldSize (Bytes)Description
00Drive Code (dr)1Specifies the disk drive (0 = default, 1 = A:, up to 16 = P:); defaults to the current drive if unset.
01–08Filename (f1–f8)8Eight uppercase ASCII characters for the filename, left-justified and space-padded; high bits cleared (0). No wildcards or special characters allowed.
09–11Filetype (t1–t3)3Three uppercase ASCII characters for the extension (e.g., "ASM"), left-justified and space-padded; high bits cleared. Byte 09's high bit indicates read-only status if set.
12Extent (ex)1Low byte of the extent number (0–31), representing 16K-byte file segments; high byte in byte 13 for multi-extent files.
13Extent High (s1)1High byte of extent (usually 0); reserved and set to 0 on file creation or open.
14System Use (s2)1Reserved; initialized to 0 by user and managed by BDOS.
15Record Count (rc)1Number of 128-byte records in the current extent (0–127); updated by BDOS on write operations.
16–31Disk Map (d0–d15)16Allocation bitmap or directory code; filled by BDOS during search/open and reserved for system use.
32Current Record (cr)1Position within the current extent for sequential access (0–127); reset to 0 for new operations.
33–35Random Record (r0–r2)3Three-byte random record number for direct access (r0 = low byte, r1 = middle, r2 = high/overflow); enables jumping to specific records up to 65,535 (2^{16}-1), with r2 as an overflow indicator.
This format supports file specifications in the conventional syntax of [d:]filename.ext, where the drive is optional, filenames are 1–8 characters, and extensions are 1–3 characters, all converted to uppercase ASCII without . For example, the file "PROGRAM.BAS" would populate bytes 01–07 with "PROGRAM" (space-padded) and bytes 09–11 with "BAS" (space-padded). The BDOS uses the to match against directory entries on disk, which mirror this structure, ensuring consistent file identification across 512-byte directory blocks. In practice, the FCB facilitates BDOS calls invoked via software at 0005H, such as 15 (open) to validate and load data into the FCB, or 20 (close) to update the with extent and counts from bytes 12–15. For , programs compute the desired number and store it in bytes 33–35 before issuing a read or write call, allowing efficient navigation in larger files spanning multiple extents. Limitations inherent to the FCB include its fixed 36-byte size, which caps filenames at eight characters and precludes support for long paths or like timestamps, though these constraints aligned with the era's hardware constraints and influenced later systems like . The structure remained largely unchanged from 1.4 through 2.2, with minor enhancements in 3 for multitasking via MP/M, but the core FCB design persisted as the foundation for file handling.

MS-DOS File Control Block

The File Control Block () is a fixed-size used by the operating system to manage file operations, particularly for compatibility with CP/M-style sequential and . It is allocated in the application's memory space and passed to MS-DOS interrupt 21h functions for tasks such as opening, reading, writing, and closing files. In MS-DOS versions 1.0 through 2.0, the standard FCB is 37 bytes long, while later versions introduced an extended variant for additional attributes. The standard FCB begins with fields for file identification and proceeds to metadata for . The drive number (1 byte at offset 00h) specifies the disk (0 for , 1 for A:, 2 for B:, etc.), set by the program before opening. The filename (8 bytes at offset 01h) and extension (3 bytes at offset 09h) are left-justified and padded with spaces, supporting conventions but limited to the 8.3 format without paths in early . The current block number (2 bytes at offset 0Ch), initialized to 0 on open, tracks the 128-record block position for . The record size (2 bytes at offset 0Eh) defaults to 128 bytes but can be modified by the program. (4 bytes at offset 10h) is set by upon opening, representing the total bytes. The last write date (2 bytes at offset 14h) encodes year (bits 9-15, offset from ), month (bits 5-8), and day (bits 0-4), while the time (2 bytes at offset 16h) uses hours (bits 11-15), minutes (bits 5-10), and two-second increments (bits 0-4). Eight reserved bytes at offset 18h are for internal use, varying by version (e.g., cluster numbers in DOS 2.x). The current record (1 byte at offset 20h) ranges from 0 to 127 within the block, and the random record number (4 bytes at offset 21h) enables direct access calculations as (block * records_per_block) + current_record. For more advanced file handling, 2.0 and later support an extended , which prepends 7 bytes to the , making it 44 bytes total. The first byte ( 00h) is set to 0FFh to identify it as extended. Five reserved bytes follow at 01h. The byte (1 byte at 06h) includes bits for read-only (bit 0), (bit 1), (bit 2), volume label (bit 3), subdirectory (bit 4), and (bit 5), allowing operations on non- files. The remaining fields mirror the but are by 7 bytes (e.g., drive at 07h, filename at 08h). This extension addresses limitations in the original , such as attribute support, while maintaining . In 3.x and beyond, reserved fields at 18h-1Fh evolved to include sharing modes, device attributes, and cluster information, reflecting enhancements like and larger disks. The following table summarizes the standard FCB structure for 2.0:
Offset (hex)Size (bytes)Field NameDescription
001Drive number0=default; 1=A:, etc. Program-set.
018FilenameLeft-justified, space-padded. Program-set.
093ExtensionLeft-justified, space-padded. Program-set.
0C2Current blockBlock index (0-based). -set on open.
0E2Record sizeBytes per record (default 128). Program-set.
104File sizeTotal bytes. -set.
142Last write datePacked: year/month/day. -set.
162Last write timePacked: hour/minute/2s. -set.
188Reserved internal (e.g., clusters in 2.x).
201Current record0-127 in block. Program-set.
214Random recordFor direct access. Program-set.

Usage

In CP/M and Early DOS

In CP/M, the File Control Block (FCB) served as the primary data structure for applications to perform file input/output operations through the Basic Disk Operating System (BDOS) interface. Programs would allocate an FCB in memory, typically at fixed locations such as offset 005CH for the first file specification, and populate its fields with details like the drive code, filename (up to 8 characters), filetype (up to 3 characters), and extent number before invoking BDOS function calls. For instance, to open a file, an application sets the filename in the FCB and calls BDOS function 15 (open file), which activates the file on disk and returns a directory code indicating success or failure; subsequent sequential reads or writes use functions 20 and 21, respectively, transferring 128-byte records while the BDOS automatically increments the current record field (CR) in the FCB. Random access was supported via function 33 (read random record), where the application updated the random record number fields (R0-R2) in the FCB to seek to a specific 128-byte record. The Command Processor (CCP) also utilized FCBs by constructing them from command-line arguments, enabling transient programs to access input and output files without manual setup. Early versions of , such as 1.x and 2.x, retained the model from to ensure compatibility with existing software, allowing applications to manage s using a 37-byte normal FCB or a 44-byte extended FCB that included additional attribute bytes for features like read-only or hidden status. Applications reserved space for the FCB in their segment, filled it with details similar to CP/M (drive, format, and size defaulting to 128 bytes), and invoked via Interrupt 21h with CP/M-compatible function numbers; for example, function 0Fh opened a by the FCB and returning an if the was not found in the current , while functions 14h and 15h handled sequential reads and writes by advancing the current field. Random operations used functions 27h and 28h, enabling direct access to disk s based on the FCB's number and size fields, which proved useful for ported CP/M programs handling fixed- s like databases. However, FCB-based I/O was inherently sequential and -limited, lacking support for paths or hierarchical structures until later versions introduced handle-based alternatives. This approach in both systems emphasized simplicity for 8-bit microcomputers with limited resources, where applications directly managed record positioning and error handling through the structure's fields, such as the record count () for tracking file extents. In practice, utilities like the program or early file copiers manipulated FCB fields like the extent (EX) and current record () to perform seeks without dedicated random-access calls, demonstrating its role in enabling efficient, low-level file manipulation on resource-constrained hardware.

Limitations and Deprecation

The File Control Block (FCB) in early versions suffered from several inherent limitations stemming from its origins in CP/M's flat design. Primarily, the FCB enforced an convention, with names and extensions limited to eight and three characters respectively, padded with spaces and converted to uppercase, which restricted usability as file systems evolved to support longer, case-sensitive names. Additionally, the fixed 37-byte structure of a standard FCB provided no fields for pathnames or hierarchical , confining operations to the current and rendering it incompatible with the tree-structured directories introduced in 2.0. Access patterns were another constraint, as FCB-based I/O relied on fixed-length records—defaulting to 128 bytes—with limited by a three-byte relative record field that capped effective addressing at smaller file sizes in practice, making it less efficient for byte-oriented or variable-length data compared to modern stream-based interfaces. The number of concurrently open FCB-handled files was also restricted by memory allocation, typically set via the FCBS parameter in (defaulting to a low value like four), beyond which would close earlier files to free resources, hindering multitasking or multi-file applications. These limitations contributed to the FCB's deprecation starting with 2.0 in 1983, when Microsoft introduced a handle-based file API (via 21h functions such as 3Dh for opening and 3Fh/40h for read/write) that supported paths, larger files, and more flexible access without the rigid structure of FCBs. While retained for backward with and DOS 1.x software, FCB functions were explicitly marked as , with new programs encouraged to use handles for better integration with the hierarchical and to avoid compatibility issues on larger volumes. By 3.0 and later, handle APIs became the standard, further marginalizing FCBs, which saw incomplete support for features like extended attributes and volumes over 32 MB without additional utilities like SHARE.EXE. In contemporary contexts, FCBs are obsolete, supported only in DOS emulators for running vintage software.

Disk Transfer Area

The Disk Transfer Area (DTA) is a dedicated buffer employed alongside the File Control Block (FCB) in operating systems like and to handle data transfers during file operations. It acts as an intermediary space for records moved between and the program's addressable , enabling efficient low-level file access without direct hardware interaction. The DTA's design reflects the era's emphasis on and , typically sized to match the underlying sector or granularity of the filesystem. In , the DTA constitutes a contiguous 128-byte region, aligned to the system's standard sector size, serving as the default destination or for in FCB-mediated reads and writes. Positioned by default at offset 0080H within the Transient Program Area (TPA)—immediately following the FCB default locations at 005CH and 006CH—it can be reassigned via BDOS Function 26 (SETDMA), where the pair specifies the new starting to ensure at least 128 bytes of free, contiguous . This relocation capability prevents overlaps with program code or other buffers, promoting flexible utilization in resource-constrained environments. During operations such as sequential reading (BDOS Function 20) or writing (Function 21), the Basic (BDOS) uses the FCB to identify the target , extent, and number, then performs the exclusively through the current DTA; for , Functions 33 (Read Random) and 34 (Write Random) similarly rely on the DTA while updating the FCB's random field. Failure to set an appropriate DTA address results in or , underscoring the programmer's responsibility for buffer management. MS-DOS inherited and extended the DTA concept from to maintain for FCB-based applications, designating it as a variable-length (defaulting to 128 bytes) for I/O and additional utilities like directory enumeration. By convention, the default DTA resides at offset 80H in the (PSP), overlapping the command-tail storage area (offsets 80H-FFH), which mandates explicit reconfiguration via interrupt 21h with AH=1Ah (DS:DX pointing to the desired ) to avoid inadvertent overwrites during command-line . Retrieval of the current DTA occurs through AH=2Fh (returning ES:BX). In FCB contexts, functions like sequential read (AH=0Fh) or random write (AH=22h) direct data transfers to or from the DTA, with the FCB providing such as , name, and record pointers; MS-DOS supports record sizes beyond 128 bytes for enhanced flexibility, though CP/M-compatible programs adhere to the standard. Beyond pure I/O, the DTA supports non-FCB operations, such as searches via AH=4Eh (Find First) and AH=4Fh (Find Next), where it stores structured results including a 21-byte reserved prefix followed by the file's attribute byte, time/date stamps (two words), size (doubleword), and a null-terminated 13-character pathname. This dual role illustrates the DTA's evolution as a , albeit rudimentary, data conduit in 's transitional architecture.
DTA Usage in Key MS-DOS Functions (Interrupt 21h)DescriptionRelation to FCB
AH=1Ah (Set DTA)Specifies buffer address for subsequent I/O or searchesPrepares DTA for FCB read/write operations
AH=2Fh (Get DTA)Returns current buffer addressAllows verification before FCB-based transfers
AH=0Fh (Sequential Read)Reads record into DTAUses FCB for file/record selection
AH=4Eh/4Fh (Find First/Next)Populates DTA with matching file detailsIndependent of FCB; stores search results in DTA format
The DTA's integration with the FCB exemplifies the procedural, assembly-oriented of these systems, where explicit buffer control ensured predictable performance on limited but introduced error-prone complexities compared to modern abstracted interfaces. Its deprecation in favor of file handles in later versions and Windows APIs marked a shift toward safer, higher-level abstractions.

Program Segment Prefix

The Program Segment Prefix (PSP) is a 256-byte in , positioned at the base of a program's memory segment, that stores essential information for the executing program, including pointers to the environment, command-line arguments, and default File Control Blocks (FCBs) for legacy file operations. It was created by the DOS loader immediately before placing the program code into memory, with the PSP's segment address passed to the program via the DS register, allowing access through DOS interrupts like INT 21h (AH=51h in DOS 2.0+). This structure evolved from 's , adapting early file handling mechanisms to the PC environment while supporting the FCB-based inherited from CP/M compatibility. Within the PSP, two reserved areas serve as default unopened FCBs, enabling programs to perform file I/O using the original FCB functions (e.g., 21h functions 0Fh-21h) without explicit allocation. The first default FCB occupies offsets 5Ch to 6Bh (16 bytes), populated from the first command-line parameter if present, such as a for immediate opening via calls. The second default FCB follows at offsets 6Ch to 7Bh (16 bytes, though sometimes documented as 20 bytes in overlays), filled from the second command-line parameter; however, opening the first FCB overlays part of this area, and vice versa, reflecting the space-constrained design of early . These FCB slots mimic the FCB format, containing fields for drive, , extent, size, date, and record allocation, but they are limited to 8.0 filenames and lack support for long paths or subdirectories introduced in later versions. The integration of FCB areas in the PSP facilitated backward compatibility for CP/M ports and early DOS applications, where programs could parse command lines via the PSP's parameter buffer (offsets 80h-FFh) and directly reference these FCBs for operations like opening or reading files without additional setup. For instance, a program invoked as "PROG FILE1.TXT FILE2.DAT" would have "FILE1.TXT" loaded into the first and "FILE2.DAT" into the second, allowing seamless use of FCB routines. However, this approach became obsolete with the shift to file handle APIs (INT 21h functions 3Dh-4Fh) in 2.0, as FCBs offered no security, poor error handling, and incompatibility with FAT16+ filesystems. A known issue in 5.00 involved incorrect FCB filling during high-memory loads, where the first FCB remained empty and the second absorbed the initial parameter, underscoring the structure's aging limitations. Despite , the PSP's FCB regions persisted in through version 7.0 for support, influencing emulator implementations and extenders that mimic the environment for running old executables. Modern analyses highlight its role in understanding 's transitional architecture from single-tasking roots to multitasking extensions like DPMI.

References

  1. [1]
    [PDF] Chapter 11: File System Implementation
    File control block – storage structure consisting of information about a file. ▫. Device driver controls the physical device. ▫. File system organized into ...
  2. [2]
    Operating Systems: File-System Implementation
    The File Control Block, FCB, ( per file ) containing details about ownership, size, permissions, dates, etc. UNIX stores this information in inodes, and NTFS in ...
  3. [3]
    The FCB Structure - Windows drivers - Microsoft Learn
    Dec 14, 2021 · The file control block (FCB) structure is pointed to by the FsContext field in the file object. All of the operations that share an FCB refer to the same file.
  4. [4]
    [PDF] CP/M Operating System Manual
    ; FILE CONTROL BLOCK DEFINITIONS. 005C = FCBDN EQU FCB+0. ;DISK NAME. 005D = FCBFN ... File Control Block (FCB): Structure used for accessing files on disk.<|control11|><|separator|>
  5. [5]
    CP/M File Control Block
    The File Control Block (FCB) is a 36-byte data structure (33 in CP/M 1) that includes fields for drive, filename, filetype, and allocation.
  6. [6]
    The MS-DOS Encyclopedia: Appendix G: File Control Block (FCB ...
    Figures G-1 and G-2 (memory block diagrams) and Tables G-1 and G-2 describe the structure of normal and extended file control blocks (FCBs).Missing: definition | Show results with:definition
  7. [7]
    Early Digital Research CP/M Source Code - CHM
    Oct 1, 2014 · CP/M, created by Gary Kildall, was a portable operating system written in PL/M, initially called Control Program/Monitor, and was a dominant OS ...
  8. [8]
    [PDF] File Management In DOS
    The CP/M compatible functions are designated as FCB functions because they are based on a data structure called the FCB. (File Control Block). DOS uses this ...
  9. [9]
    DOS 2.0 and 2.1 | OS/2 Museum
    The impact on the OS and applications was far greater. The CP/M style of file management through FCBs (File Control Blocks) could not be used with directories.
  10. [10]
    [PDF] DIGITAL RESEARCH TM CP/M Operating System Manual CP/M ...
    File Control Block (FCB): Structure used for accessing files on disk. ... SYSGEN cannot use your CP/M source file. SOURCE FILE NAME ERROR. ASM. When you ...<|control11|><|separator|>
  11. [11]
    [PDF] Microsoft_Programmers_Referen...
    Reserved (offset 18H): These fields are reserved for use by. MS-DOS. Current Record (offset 20H): Points to one of the 128 records in the current block. This ...
  12. [12]
    [PDF] MS™- DOS Programmer's Manual - Old Computers
    placing values into or reading values from two system control blocks: the File Control Block (FCB) and directory entry. 1.3 FILE CONTROL BLOCK (FCB). The ...
  13. [13]
    Section 5: CP/M 2 System Interface - gaby.de
    If the command is followed by one or two file specifications, the CCP prepares one or two File Control Block (FCB) names in the system parameter area. These ...Introduction · Operating System Call... · A Sample File-to-File Copy...
  14. [14]
    [PDF] Operating System Programmer's Reference Manual - Bitsavers.org
    MS-DOS control blocks and work areas (Chapter. 4). and EXE file structure and ... system control blocks: the File Control Block (FCB) and directory entry.
  15. [15]
    The AARD Code and DR DOS - Geoff Chappell, Software Analyst
    Aug 13, 2021 · ... FCB structure were deprecated for new programming as soon as MS-DOS 2.00. This second version is a world apart from the first. Putting this ...
  16. [16]
    [PDF] CP/M - Bitsavers.org
    CP/M is a registered trademark of Digital Research. MP/M, MAC, and SID are trade- marks of Digital Research. Z-80 is a trademark of Zilog, Inc.
  17. [17]
  18. [18]
    Appendix H: Program Segment Prefix (PSP) Structure - PCjs Machines
    The MS-DOS Encyclopedia​​ Figure H-1 (memory block diagram) illustrates the structure of the program segment prefix (PSP). Structure of the program segment ...
  19. [19]
    Art of Assembly: Chapter Thirteen-8 - Plantation Productions
    When a program is loaded into memory for execution, DOS first builds up a program segment prefix immediately before the program is loaded into memory. This ...
  20. [20]
    Format of Program Segment Prefix (PSP)
    MS-DOS 5.00 incorrectly fills the FCB fields when loading a program high; the first FCB is empty and the second contains the first parameter. Some DOS extenders ...