How MS-DOS DoubleSpace and DriveSpace Compress Data

MS-DOS 6.22 included DriveSpace (an updated replacement for DoubleSpace) to address the severe storage constraints of early 1990s hard disks. This utility provided transparent, real-time disk compression, effectively doubling the apparent capacity of a drive without requiring hardware upgrades. The system operated by storing an entire compressed file system inside a single, hidden container file, utilizing low-level DOS kernel drivers and a variation of the Lempel-Ziv compression algorithm to compress and decompress data on the fly.

The Compressed Volume File (CVF)

Rather than compressing individual files one by one, DoubleSpace and DriveSpace manage entire drives using a container known as a Compressed Volume File (CVF). Stored on the uncompressed host drive (typically hidden with the name DRVSPACE.000 or DBLSPACE.000), this single massive file behaves as a virtual hard drive.

When MS-DOS boots, a pre-loaded kernel driver (DRVSPACE.BIN or DBLSPACE.BIN) intercepts disk operations. The system performs a drive-letter swap: the uncompressed physical partition is reassigned a higher letter (such as H:), and the CVF is mounted as drive C:. To the user and running applications, the CVF looks and behaves like a standard, uncompressed FAT16 disk.

The Modified Lempel-Ziv Algorithm

The underlying compression mechanism is a proprietary hardware-agnostic variation of the LZ77 (Lempel-Ziv 1977) lossless data compression algorithm.

As data passes through the driver, the algorithm analyzes byte streams using a sliding dictionary window. When it encounters repeating sequences of data, it replaces the duplicate data with a compact reference pointer consisting of an offset and a match length. Small repeated patterns require fewer bits to represent than the raw data itself, resulting in typical text, executable, and database files shrinking by roughly 50 percent (a 2:1 compression ratio). Highly random or pre-compressed data (such as PKZIP archives) yields little to no compression, while repetitive files compress significantly more.

Variable-Length Cluster Allocation

Standard FAT16 file systems divide disk space into fixed-size allocation units called clusters (commonly 2 KB, 4 KB, or 8 KB). A file that only uses a few bytes of a cluster still consumes the entire cluster, leading to significant wasted space known as slack space.

DriveSpace eliminates internal cluster slack by decoupling logical clusters from physical storage. While the operating system believes it is writing to standard fixed-size clusters:

  1. The driver compresses the data designated for that cluster.
  2. The compressed data is mapped to a variable number of contiguous 512-byte physical sectors inside the CVF.
  3. If an 8 KB cluster compresses down to 1,200 bytes, DriveSpace allocates only three 512-byte sectors (1,536 bytes) within the CVF, leaving the remaining space free for other data.

BitFAT and Metadata Tracking

To manage this variable mapping, the CVF introduces internal data structures not present on a standard FAT volume:

  • MDBPB (Microsoft DoubleSpace BIOS Parameter Block): Defines the geometry and internal layout of the CVF.
  • BitFAT: An allocation map located inside the CVF that tracks exactly which 512-byte sectors belong to which logical FAT clusters.

When a standard FAT directory entry points to cluster 10, the DriveSpace driver references the BitFAT to locate the exact sector offset and sector count reserved for that cluster inside the CVF.

The Read/Write Lifecycle

Every I/O operation is processed transparently in system memory before hitting physical media:

  • Writing to Disk: When an application saves a file, MS-DOS issues a write request via INT 21h or INT 13h. The resident DRVSPACE.BIN driver captures the uncompressed data in a small RAM cache, runs the LZ77 variant compression routines, queries the BitFAT for available contiguous 512-byte sectors within the CVF, writes the compressed payload, and updates the BitFAT.
  • Reading from Disk: When an application requests file data, the driver reads the corresponding compressed sectors from the CVF, decompresses the data in memory using the pointer-length pairs, and delivers the original, uncompressed bytes back to the application.