Skip to content
FreeDOSDeep Dive Published Updated 7 min readViews unavailable

DOS INT 21h AH=36h: Disk-Free Space, Cluster Math, and Limits

Read the INT 21h AH=36h register contract correctly, calculate free bytes without overflow, and handle invalid drives and changing volumes.

DOS INT 21h function AH=36h reports disk allocation information for a drive. It returns cluster counts and geometry values from which a program can estimate filesystem free space. It does not reserve that space, guarantee a subsequent write will fit, or describe every physical property of a modern storage device. The function dates to DOS 2.0-era APIs, so its small register-sized fields and DOS filesystem assumptions should be treated as a compatibility interface, not a high-capacity storage API.

Register contract

Call INT 21h with AH=36h and place a drive number in DL: zero selects the default drive, one selects A:, two selects B:, and so on. On success, the returned registers are:

  • AX: sectors per cluster (allocation unit)
  • BX: available clusters
  • CX: bytes per sector
  • DX: total clusters on the drive

If the drive number is invalid, AX returns FFFFh. Check that error sentinel before interpreting AX as a sector count. Do not use the carry flag as the sole success indication for this function; the documented error contract is the value in AX.

An assembly-level call for the current C: drive would select drive number 3:

mov ah, 36h
mov dl, 3          ; 0=default, 1=A:, 2=B:, 3=C:
int 21h
cmp ax, 0FFFFh
je invalid_drive
; AX, BX, CX, and DX now contain the documented values

This snippet only performs the query. It does not print the result or test whether a later file creation succeeds. Preserve any register values your caller still needs before making DOS calls, following the calling convention of your compiler or assembler environment.

Convert allocation units into bytes

The documented formula for free bytes is:

available clusters × sectors per cluster × bytes per sector

That is BX × AX × CX using the returned values. Total volume bytes can be estimated as DX × AX × CX. The returned unit is a cluster, the filesystem’s allocation unit; a small file can consume an entire cluster, so application data bytes and available filesystem capacity are not the same thing.

The intermediate product can exceed a 16-bit word. Even a 32-bit unsigned result can overflow for larger geometries because three 16-bit factors are multiplied. A C program should promote before multiplication and use a sufficiently wide intermediate, such as a 64-bit integer where its compiler supports it. On older 16-bit compilers without a native 64-bit type, use a checked multiword multiply or report cluster count and cluster size separately instead of printing a wrapped byte total.

For example, this is unsafe in C if ax, bx, and cx are 16-bit integers:

free_bytes = ax * bx * cx; /* may overflow before assignment */

Casting only the final result does not repair an overflow that already occurred during 16-bit multiplication. A safer modern-C expression promotes an operand before arithmetic:

uint64_t free_bytes = (uint64_t)available_clusters
                    * sectors_per_cluster
                    * bytes_per_sector;

The uint64_t type requires a compiler and headers that provide it; do not paste that declaration into a vintage compiler without checking support.

Drive numbering and DOS path semantics

The DL drive number is not an ASCII letter. Programs that begin with C: must convert the drive letter to its ordinal value, while preserving zero as the “default drive” request. In DOS path syntax, a rooted path such as C:\DATA\FILE.DAT is distinct from a drive-relative path like C:FILE.DAT; the latter uses the current directory associated with that drive. A correct free-space query should use the same drive that the program will actually use for file creation.

If the application accepts a path from a user, parse the path according to DOS rules and identify its volume before querying. An omitted drive usually means the current default drive, not necessarily the drive used by a later path after a shell or library changes state. When the path includes a network redirector, SUBST-like mapping, or a volume abstraction, the value reported reflects the DOS-visible drive and its implementation.

What the counters mean and do not mean

The function returns allocation units that DOS considers available and total. It does not report contiguous free space, the largest file that can be created, space reserved by an application, or the status of physical sectors not yet allocated. FAT free-cluster accounting also differs from visible file-size sums because files consume whole clusters and filesystem structures occupy space.

The call is a snapshot. Another program, TSR, network user, or disk utility can allocate space immediately after it returns. A program should therefore use AH=36h to display an estimate or reject an obviously insufficient operation, but still check the actual result of file creation and writes. A successful preflight query is not a reservation.

The 16-bit register contract constrains how much information is expressible. Different DOS versions and filesystem drivers may expose different supported volume sizes and reporting behavior. Do not infer that a large modern volume is fully represented just because a DOS-compatible layer returns plausible numbers. Validate against the target FreeDOS kernel, filesystem, and device driver, and compare the result with a second trusted interface when capacity matters.

Error handling and test cases

Test at least four cases on a disposable environment: the default drive (DL=0), a valid removable drive, a valid hard-disk volume, and an invalid drive number. Confirm AX is checked before arithmetic. Test a nearly full volume and a volume with a large cluster size, then verify the displayed estimate against the DOS DIR/volume information available in that environment. The user-interface display may round units; compare raw clusters and sector sizes when debugging a discrepancy.

Do not use an invalid-drive test that changes the default drive or writes to media. The invalid case only needs to call the API with a non-existent drive ordinal and observe AX. For 16-bit programs, store outputs before invoking other DOS calls because subsequent calls can overwrite registers. If a compiler runtime wraps the call, verify its structure field widths and drive-number convention against the compiler manual.

Compatibility and extended interfaces

Older DOS interfaces include related drive-information functions, but AH=36h became the standard call for free-space information because it returns both available cluster count and geometry. Later DOS-compatible environments added other APIs with different input structures and larger counters. Those interfaces are not interchangeable: their version requirements, carry-flag behavior, path conventions, and output fields must be checked independently.

Do not assume a Windows API name or modern statvfs model maps directly to AH=36h. A compatibility layer may implement DOS semantics over a host filesystem, while a physical FreeDOS machine queries its active filesystem driver. The portable approach is to code against the documented register contract, detect the supported environment, and preserve a fallback path where larger volumes must be handled.

Use in a storage preflight

A robust installer can query the destination, calculate a conservative estimate in wide arithmetic, and report available clusters and bytes before copying. It should account for its own metadata, temporary files, and the possibility that the volume changes during the run. It must still treat create/write errors as authoritative and should not erase data automatically when space is insufficient.

For a disk image or archival workflow, do not rely solely on AH=36h to decide whether an image will fit. The image’s exact byte size, destination filesystem maximum file size, directory-entry limits, and free clusters all matter. FAT variants impose format-specific constraints, while the DOS API only exposes the values available through the current DOS implementation. Verify the output file after copying and retain a source image until the copy is proven usable.

Acceptance criteria

An AH=36h implementation is ready when it uses the correct zero-based/default and one-based/letter drive mapping, checks AX=FFFFh, names every returned field correctly, promotes arithmetic before multiplication, and treats the result as a changing estimate. Its test record should include the FreeDOS kernel and storage-driver versions and the media type. If the application needs capacity beyond the legacy interface’s proven range, select and document a wider API rather than silently trusting a potentially truncated value.

Related:

Sources:

Comments