Over 30 years ago, in March 1993, Microsoft released MS-DOS 6.00, the next major release of MS-DOS after 5.00 shipped in June 1991.
In addition to several new full-screen utilities, like
DEFRAG to defragment your hard disk (licensed from Symantec),
MSBACKUP to efficiently backup your hard disk (also licensed from Symantec), and
MSAV to check for viruses (licensed
from Central Point Software), there were a number of new command-line programs, such as
But the biggest addition to MS-DOS 6.00 was a new feature called DoubleSpace (dubbed “MagicDrive” internally) that automatically compressed everything on your hard disk, providing up to “double” the amount of effective disk space – or more, or less, depending on how compressible your files were overall.
DoubleSpace was a significant feature that required changes across the entire system. Most of the action, however,
took place inside a new device driver,
DBLSPACE.BIN, that stored all your data in a Compressed Volume File (CVF) generally
DBLSPACE.000. In fact, if you booted an older version of MS-DOS (like 5.00), you wouldn’t see much more than that:
A>DIR C: /A Volume in drive C is HOST_FOR_C Volume Serial Number is 5739-B1B5 Directory of C:\ IO SYS 40470 03-10-93 6:00a MSDOS SYS 38138 03-10-93 6:00a DBLSPACE BIN 51214 03-10-93 6:00a DBLSPACE INI 91 10-03-23 12:26p DBLSPACE 000 131474432 10-03-23 12:26p 5 file(s) 131604345 bytes 2605056 bytes free
When MS-DOS 6.00 starts up, it reads
DBLSPACE.INI, which usually looks something like this:
MaxRemovableDrives=2 FirstDrive=D LastDrive=H MaxFileFragments=115 ActivateDrive=H,C0
and tells the operating system to mount the real drive C: as drive H: instead, and to mount the CVF as drive C:
C:\>DIR /C Volume in drive C is MS-DOS_6 Volume Serial Number is 101B-323E Directory of C:\ DOS <DIR> 09-25-23 10:13p COMMAND COM 52925 03-10-93 6:00a 1.4 to 1.0 WINA20 386 9349 03-10-93 6:00a 5.3 to 1.0 AUTOEXEC BAT 75 09-26-23 8:55a 16.0 to 1.0 CONFIG SYS 109 09-26-23 8:55a 16.0 to 1.0 2.0 to 1.0 average compression ratio 5 file(s) 62458 bytes 253927424 bytes free
So our original hard disk, a 128Mb drive, now appears to be almost twice as large – thanks to DoubleSpace.
Aside from the new
DBLSPACE.BIN driver, the other main piece of DoubleSpace functionality resided in
operated as both a setup and a maintenance program. It provided a friendly full-screen interface, making it easy to create
additional CVFs, as well as resize, defragment, reformat, unmount, remount, and more.
Feel free to tinker with MS-DOS 6.00 on the website:
Microsoft bootstrapped its compression efforts by licensing code from Vertisoft, makers of DoubleDisk, a disk compression
product first released in 1989. Starting with Verisoft’s code, Microsoft created
DBLSPACE.BIN, along with operating system
changes that allowed it to be loaded before CONFIG.SYS was processed – so that CONFIG.SYS and any system files loaded
from that point forward could be inside the compressed volume instead of outside it.
Vertisoft was not directly involved with any of that work, but they did help produce other pieces of functionality, such as code to convert Stacker and SuperStor compressed disks to DoubleSpace – although apparently Stacker conversion was pulled at the last minute, in February 1993, just as MS-DOS 6.00 was being finalized.
Or rather, February 1993 would have been “last minute”, until the lawsuit filed by Stac in January 1993 forced Microsoft to re-evaluate. Stac claimed that the DoubleSpace infringed two of Stac’s patents: 5,016,009 and 4,701,745.
For me, life quickly changed on February 13, 1993, when I received this email:
From: Paul Maritz Sent: Saturday, February 13, 1993 12:06 PM To: Jeff Parsons; Mark Zbikowski Cc: Ben Slivka; Brad Chase; Brad Silverberg; Jim Allchin; John Mason; Nathan Myhrvold; Rick Rashid Subject: special duty You are both amongst the best x86 assembly language coders that we have at MS. We are thus asking you to help out with a very serious problem that we face - namely the STAC / DOS6 lawsuit. Our lawyers have recommended that we have a backup compression mechanism for DOS6 ready to go as soon as possible. The initial work on this has been done under Rick Rashid in Nathanm's area. They have a C language implementation of a technique that we believe is safe (covered under patents that we have rights to). The challenge is to get this technique into the tightest possible x86 assembly code, as soon as possible. This is where we are asking you to help. Jimall and Bradsi are aware that you will be "stolen" for some weeks. Could you both meet with Rick Rashid as early as possible on Monday to get this effort under way as soon as is possible. Thanks.
The next several weeks were probably some of the most stressful that I’d experienced at Microsoft. Looking back, it’s amazing to me that with all the critical-path code that was being rewritten at that late date, MS-DOS 6.00 still shipped the following month, in March 1993.
I don’t recall all the details of the alleged patent infringement, and I’m not sure I ever knew all the details, because frankly, it wasn’t necessary for me to know the details. A number of other people had already been working on the problem and had come up with several solutions, and it simply fell to me and MarkZ to implement them in x86 assembly – preferably very fast, bug-free assembly, of course.
As far as I can tell now, Stac patent 5,016,009 was the crux of the problem. It combined LZ77 compression with hashing, and while LZ77 compression was fine, and hashing was fine, apparently the combination of the two became a patentable innovation.
So we were initially tasked with writing a compressor based on Miller-Wegman, an algorithm that was either not patented or that Microsoft owned or licensed. When that turned out to be too slow, we instead built a compressor (internally known as XCFR or the “Rashid Search Algorithm”) that avoided hashing by using a 256x8 look-up table along with a 256-entry LRU table, and also incorporated a new Microsoft Realtime Compression Format (MRCF) for outputting the raw bytes and offset-length pairs. That, of course, meant that the decompressor had to be rewritten as well.
With hindsight, it’s probably safe to say that Microsoft should not have shipped MS-DOS 6.00 quite so quickly after that rewrite, because unfortunately, our code (well, in the case below, my code) was not, um, bug-free:
From: Chuck Strouss To: SYS Astro Team Development Group; Peter Stewart; Jeff Parsons Subject: Bug in DBLSPACE decompress Date: Monday, June 14, 1993 3:40PM In RDCOMP.ASM, near the first JC instruction, there is a bug when a block ends at 10000h and the last several bytes are in a repeat string. It was reported by Temporal Acuity Products.
to which I replied:
From: Jeff Parsons Sent: Monday, June 14, 1993 4:49 PM To: Chuck Strouss; Ben Slivka; Jim Mathews; Peter Stewart Subject: RE: Bug in DBLSPACE decompress well... shit!
That bug was only in the 80386 code path, so it could be avoided by adding an undocumented “ENABLE386=0” to
DBLSPACE.INI, but that wasn’t much consolation. And it was one of at least a half-dozen or so DoubleSpace bugs that Microsoft was aware by June of 1993. Other bugs included:
I don’t know if the video memory issue was ever fixed. Wikipedia’s article on DriveSpace (which was the new name for DoubleSpace as of MS-DOS 6.22) alludes to the problem:
A few computer programs, particularly games, were incompatible with DoubleSpace because they effectively bypassed the DoubleSpace driver.
But I’m not aware of any problems that involved “bypassing” the driver. Any game-related problems were almost certainly due to DoubleSpace decompressing data directly into video memory when the video card’s read and write modes differed.
On a happier, or at least less contentious note, MS-DOS 6.00 also introduced a feature known as MultiConfig, which I have some fondness for, because it was something I personally championed and implemented. And – good news – I don’t think it had any serious bugs.
I don’t recall precisely where the idea came from. I think it started as something that I and Naveen Jain, a Program Manager on the team, discussed in early 1992. He created a preliminary spec in February 1992, and then I implemented the feature in March 1992 and updated the spec to match what I had implemented.
The code was originally added to Jaguar, which was planned to be the next major update to MS-DOS after 5.00. But at some point, Astro – originally intended as a smaller interim MS-DOS update – grew to the point where it was clearly going to be the next major update, thanks in large part to the addition of DoubleSpace disk compression.
When it was clear that Astro would become MS-DOS 6.00, I think management went looking for other low-hanging fruit, such as any new Jaguar features that could be incorporated into Astro relatively easily with minimal risk. MultiConfig fit the bill.
However, it wasn’t a slam dunk. I had to push for it, because there were a few risk-averse people in management that felt the risk/reward ratio was too high. They claimed that most users would not use this feature (which was true), but that point also worked in my favor: most of the new code would not be executed until and unless someone actually added one or more of the new commands to their CONFIG.SYS. So any risks largely affected only “power users”.
MultiConfig was a collection of features added to the processing of CONFIG.SYS, to make it easier to start your PC in a particular way without having to boot from a special floppy or edit/copy a new CONFIG.SYS each time. It added some new commands to CONFIG.SYS:
and it included some new ways to interact with CONFIG.SYS. The message “Starting MS-DOS…” was added as an indirect means of alerting you that you now had two seconds to press one of several new start-up keys:
You could also tap a Shift key – that was equivalent to pressing F5. Apparently there was an Astro “press tour” in August 1992, and someone in that tour suggested adding the Shift key, so we did. They claimed that holding the Shift key while starting Windows also bypassed certain files and/or functions, but I don’t recall to what extent that was true.
Additionally, if you didn’t want anyone using your machine to bypass or alter CONFIG.SYS, you could add these lines to the file:
/N also implied /F, since if start-up keys were disabled, there was no need to wait two seconds.
Note that SWITCHES was not a new command; other older “switches” included:
Finally, while we’re on the subject of the keyboard-related features, I should add that NUMLOCK wasn’t really a MultiConfig feature; it was just something I thought would be handy. Recall that early PCs had no BIOS setup screens, and MS-DOS was still an operating system designed to run on any PC, including the original IBM PC. So this CONFIG.SYS command:
could be used to set your keyboard’s initial Num-Lock state. A case could be made for this being a legitimate MultiConfig feature though, since you could select menu items with arrow keys or by pressing the number of a menu item. So if you wanted to use your numeric keypad, then you would want to ensure that Num-Lock matched your preferred selection method.
The real power of MultiConfig was the ability to create user-friendly boot menus and let you organize sets of CONFIG.SYS
commands into either named or
[common] blocks. Blocks began with a bracketed block name (eg,
and ended at the next bracketed block name (or end of file).
Here’s a simple example:
[menu] menuitem=doslow,Load DOS in LOW memory menuitem=doshigh,Load DOS in HIGH memory menudefault=doslow,15 menucolor=15,1 [common] device=c:\dos\himem.sys [doslow] dos=low [doshigh] dos=high [common] device=c:\dos\setver.exe files=30
And the screen that would appear when booting:
menuitem in the
[menu] block describes a menu item; the first argument is a block name (eg,
and the second argument is a description. Other
[menu] block keywords included
menudefault, which specifies the
default menu item (and optional timeout value in seconds), and
menucolor, which selects foreground and background colors
for the menu.
In the above example, no matter which menu item you selected, HIMEM.SYS would always be loaded first, because it was in a
[common] block that appeared before the other blocks. Then all commands in the selected block (
[doshigh]) would be processed next, then all the commands in the next
[common] block – and so on.
Another feature was “forced prompting”. If you included a
? after the
DEVICE keyword, you would receive an unconditional
prompt for that particular driver. For example:
would always generate the following prompt:
And that feature wasn’t limited to device drivers. The following line:
would also generate a prompt:
Below is a more complex example, extracted from an email I wrote back on July 1, 1992 (at 2:34am apparently).
This example illustrates how you could use
submenu (as opposed to
menuitem) to define menu items that
referred to other menu blocks, in order to create multi-level menus. Originally, the keyword for that feature was
menu, but the Astro team (specifically, Betsy Tinney, who helped refine the MultiConfig UI for Astro)
suggested a keyword that was clearer.
It also shows how you could
include named blocks from other blocks. For example, a number of the blocks, like
include another block,
[dos], that contains commands common to the other blocks. Every block could duplicate those
commands itself, but factoring out common sets of commands made for a more maintainable CONFIG.SYS. Blocks named
were always processed in the order they appeared, whereas blocks with any other name would be processed whenever
(and only whenever) they were explicitly included.
Finally, this example also uses the
SET command, which defines environment variables to be passed to
In addition, a special
CONFIG environment variable is automatically set to the name of the block from the final selected
dosumb). This was useful for batch files like AUTOEXEC.BAT, if they needed to customize their actions
according to the selected CONFIG.SYS configuration.
[menu] numlock=off menucolor=15,1 menudefault=lanmenu,15 submenu=dosmenu,DOS configurations submenu=lanmenu,LanMan configurations [dosmenu] menudefault=dosumb,15 menuitem=dosumb, DOS 7.00 only menuitem=dosems, DOS 7.00 w/EMS menuitem=dosansi, DOS 7.00 w/ANSI menuitem=dos386max, DOS 7.00 w/386Max menuitem=dosdbg, DOS 7.00 w/Soft-ICE menuitem=cougar, DOS 7.00 w/Cougar [lanmenu] menudefault=winball,15 menuitem=lanman20, DOS 7.00 w/Lanman 2.0 menuitem=lanman21, DOS 7.00 w/Lanman 2.1 w/XNS menuitem=lanman21nb, DOS 7.00 w/Lanman 2.1 w/XNS+NetBeui ;menuitem=lanman21xm,DOS 7.00 w/Lanman 2.1 w/XNS Mono menuitem=lanman21dbg,DOS 7.00 w/Lanman 2.1 w/Soft-ICE menuitem=winball, DOS 7.00 w/Winball [common] set tmp=c:\tmp set linktmp=c:\tmp set temp=c:\win31\temp set dircmd=/l/o set home=d:\tools\bound set init=d:\tools\bound set alias=jeffpar set logname=jeffpar set mailname=jeffpar set basspec=d:\tools\dos set helpfiles=d:\tools\help;c:\src\cougar\dev\tools\help set country=usa-ms set proj=c:\src\cougar\dos\dos86 set lib=d:\tools\windev\lib set include=d:\tools\windev\include;d:\src\myinc set path=d:\tools\dos;d:\tools\bound;d:\tools\windev;c:\lanman\netprog;c:\win31;c:\dos set prompt=$p$g [dos] break=on dos=high,umb files=60 buffers=10 stacks=9,256 lastdrivehigh=z shell=c:\dos\command.com /p c:\dos /e:1024 /z [dosumb] include dos device=c:\win31\himem.sys device=c:\win31\emm386.exe noems i=b000-b7ff x=d800-dfff [dosems] include dos device=c:\win31\himem.sys device=c:\win31\emm386.exe 1024 ram i=b000-b7ff x=d800-dfff frame=e000 [dosansi] include dosumb devicehigh=c:\dos\ansi.sys [dos386max] include dos device=d:\tools\386max\386max.sys [dosdbg] device=c:\s-ice\s-ice.exe /tra 1000 include dos [lanman20] include dosumb include lanman20_drivers include lanman_logon [lanman20_drivers] devicehigh=c:\lanman\drivers\protman\protman.dos /i:c:\lanman devicehigh=c:\lanman\drivers\ethernet\ub\ubnei.dos devicehigh=c:\lanman\drivers\protocol\netbeui\netbeui.dos devicehigh=c:\lanman\drivers\protocol\xns\ubxpw.dos devicehigh=c:\lanman\drivers\protocol\xns\ubloop.dos installhigh c:\lanman\drivers\protman\netbind.exe [lanman21] include dosumb include lanman21_drivers include lanman_logon [lanman21nb] include dosumb include lanman21_drivers install c:\lanman\netprog\load.com netbeui include lanman_logon [lanman21xm] include dosumb install c:\lanman\xnsmono\loadniu.exe -r -d -m:d8 -i:5 -p:4 c:\lanman\xnsmono\exniu2.xfm c:\lanman\xnsmono\1a.lc install c:\lanman\xnsmono\xnsbios.exe -m:d8 -i:5 -p:4 include lanman_logon [lanman21dbg] device=c:\s-ice\s-ice.exe /tra 1000 include dos include lanman21_drivers include lanman_logon [lanman21_drivers] devicehigh=c:\lanman\drivers\protman\protman.dos /i:c:\lanman devicehigh=c:\lanman\drivers\ethernet\ub\ubnei.dos device=c:\lanman\drivers\protocol\ubxns\ubxps.dos install c:\lanman\netprog\netbind.com [lanman_logon] install c:\lanman\netprog\net.exe start workstation install c:\lanman\netprog\net.exe logon jeffpar2 /y ;install c:\lanman\netprog\net.exe use k: \\jeffpar\astro dos6 ;install c:\lanman\netprog\net.exe use j: \\jeffpar\cougar dos7 [winball] include dosumb include lanman21_drivers devicehigh=c:\win31\redirdrv.sys devicehigh=c:\win31\system\vnbhlp.dos shell=c:\dos\command.com /p c:\dos /e:1024 /z /k windb set path=d:\tools\dos;d:\tools\bound;d:\tools\windev;c:\win31;c:\dos [cougar] include dosumb include lanman21_drivers devicehigh=c:\win31\redirdrv.sys devicehigh=c:\win31\system\vnbhlp.dos shell=c:\dos\command.com /p c:\dos /e:1024 /z /k cougar7 set path=d:\tools\dos;d:\tools\bound;d:\tools\windev;c:\win31;c:\dos;d:\cougar [common] installhigh d:\tools\dos\keyfix.com installhigh c:\win31\mouse.com installhigh c:\dos\share.exe installhigh c:\win31\smartdrv.exe 1024 installhigh c:\dos\doskey.com /a /e /x /p /k:128 /f:d:\tools\dos\aliases install c:\dos\mode.com con:rate=30 delay=1 install d:\tools\dos\50.com
Oct 4, 2023