« articles

Running DOS Apps on Windows


It's well documented that a great selling point of Windows throughout all its early editions (up to at least 95) was the ability to run DOS applications, and specifically to run multiple at once. Most of us have probably done this at some point, unless you're young enough that the first Windows you ever used was 64-bit, where they removed DOS functionality.

Despite this capability being mentioned in countless reviews of the success story of Windows, the actual functionality of it is almost entirely undocumented online. When I looked into it myself, I discovered that the experience actually changed considerably between early Windows versions, in some cases in surprising ways.

Having thoroughly explored everything from Windows 1 to Windows 95, I'd like to document everything I learned about this. If you only experienced this after 1995, some of this might be quite surprising to you.

I have gone into deeper detail than I probably needed to, but if I didn't go into detail, there wouldn't be that much to write here at all. This will be a highly tedious description of the specific functionality of five releases of Windows, and a fairly visual one, so I recommend you follow along with the screenshots even if you're listening to this in audio form.

If you like my writing, consider tossing me a few bucks. It takes a lot of work and payment helps me be motivated.

Listen to this article (Part 1): Listen to this article
(Article is not guaranteed to be identical to audio)

Listen to this article (Part 2): Listen to this article
(Article is not guaranteed to be identical to audio)

Table of Contents

Windows 1.0
Windows 2.11 / 286
Windows 2.11 / 386
Windows 3.0
Windows 3.1
Windows 95


7/25/2020: Corrected an error regarding color support - bright white background colors were available in DOS windows beginning in 3.1. I was confused because in QBasic, "White" is actually what we would call "light grey," the color named "Grey" is a dark grey, and the actual "Bright White" color is all the way at the bottom of the list.

7/24/2020: Originally published



It's worth discussing how all this works so you understand the challenges that are being overcome here. The ability to run multiple DOS programs at once is a pretty neat trick, given that this software heralds from an era of computing that was just barely ahead of what the Apple ][ was doing in 1978. If you want to skip this, go ahead.

The root of the problem is that the IBM PCs basic architecture crystallized a very long time ago, in 1981. In a world where ten kilobytes of RAM counted for about what a gig does now, there was not a lot of room for "overhead" and the idea that you would run two programs simultaneously was generally unrealistic except at the high end of the computing world, which most PC buyers were nowhere near. You needed every bit (ha) of memory you could get, and when memory became more affordable a few years later, it was too late to change anything.

After just a couple years on the market, MS-DOS had become the unquestioned OS of choice for the PC* and developed a monumental stable of software, every bit of which was essential to someone, somewhere, and could not be easily replaced. Thus began one of the longest tails in technology history, as the PC industry and Microsoft began contorting themselves to try not to break compatibility with old software while still moving forward with advanced functionality.
*(specifically, since there were MS-DOSes for other architectures, and other OSes for the PC)

Because DOS was developed under constraints very similar to those in the late '70s that gave us the "bitty boxes" (C64, Apple ][, ZX Spectrum, etc.) it was not built with any kind of "supervision" in mind. In other words, there was no abstraction level above the current running program. DOS was more like a set of tools than what we think of as an operating system now - specifically, it had no "process management"; no concept of "processes" at all, in fact.


When the machine booted, the part of DOS that was considered "the OS" - the code for accessing disk drives, writing text to screen, etc. - was copied into memory, and then execution was handed off to the command interpreter, COMMAND.COM, which was an application like any other, at which point you could begin entering commands to use the computer.

At this point, DOS was no longer "running" in any meaningful way. The code was "resident," meaning it was present in the computer's memory, but the processor wasn't  executing any of it. Instead, the CPU was busy executing whatever the current program was - if you were at the command prompt, then all the code the PC was executing was part of COMMAND.COM. When you launched another application, COMMAND.COM was vacated and replaced by that other application.

In other words, while an application was running, DOS was almost totally out of the picture. The only time execution returned to DOS itself was when the application requested a "service" from DOS, like accessing a disk drive, at which point it would tell the CPU to go execute one of DOS' stored routines for this, and when that routine was done, control would return to the application. This meant that, generally speaking, the current program had absolute control of the PCs execution and it's memory. It could in fact choose to overwrite DOS itself, obliterating it out of memory, and DOS couldn't do a damn thing about it.

The currently running app also had the option to speak directly to hardware. The whole purpose of DOS was to abstract things like that so programs wouldn't need to know the details of the system they were running on, but since the IBM PC was extremely consistent hardware-wise in its early incarnations, it was entirely optional for developers to take advantage of that, and often there were reasons - of performance, perhaps - to bypass DOS and do things directly.

DOS provided disk access routines, but the app could blow right by them and shoot commands straight to the floppy drive if it wanted. DOS provided routines for printing text and clearing the screen, but the app could just write directly to video memory. I can't speak to how common this kind of behavior actually was, but it certainly wasn't rare, and it speaks to a larger problem - DOS apps simply expect total control over the system.

If you run two DOS apps at once, they're going to stomp on each other, because each one thinks it's in charge of the whole machine. The first one would store data in the same spot that the second one stored program code, and thus one would overwrite the other and crash it. So DOS was a single-tasking operating system - you could run one program at a time, and when you wanted to run another, you had to exit, return to the command prompt, and then launch your other app.

Consequently, if you were working on something in Microsoft Multiplan and wanted to go look up some data in dBase, you had to quit completely out of Multiplan and then start dBase, which would take over the system and totally overwrite the previous app. To get back to where you were you'd have to exit dBase, restart Multiplan, load your document and find your place again - in the process, totally forgetting what you were there to do in the first place, because it's so many steps and takes so long.

Right from the get-go, PC users wanted to be able to look at one program, then rapidly switch to another. On its face this seems to mean "run two programs at once," which is what we do now, but that's not quite the full story. Let's touch on how that works nowadays, however.


To be clear, you cannot run two programs "at once" on a computer. Some would call this semantics, but it's important in a very real way, especially when talking about 80s-era PCs.

Modern multicore CPUs get very close to true parallel processing by letting separate programs run on separate cores, but of course, nobody has a CPU so big that they have one core per process. And even if you did, programs still have to share other resources - the system bus, hard drives, and so on. Access to these resources has to be carefully managed so that only one application can use them at a time, and each one has to be cleaned up after before another one can use the same resources. Otherwise, one program could leave the hardware in a state where the commands that the next program sends put it in an unusable state and crash the machine, or corrupt data.

Even with all our modern pipelined cleverness, you have the fundamental problem that a CPU, and a computer in general, has a limited amount of physical hardware and can't dedicate some to each individual program that's running. When you have more processes running than you have silicon, the only option left is to share resources by dividing up the amount of time that each process gets to use the hardware - this is one of the oldest concepts in computing, and goes back to the late '50s.

The fundamentals of this process are simple: At any given moment, one program has near-total control of the entire system, to execute its code and use all the resources, and then after it executes for a bit, it goes into a paused state and control is handed off to the next program, which does its work and then hands off to the next. This continues in a round-robin fashion, so that every program gets to use the hardware for a certain portion of every second.

Modern implementations take this to a fever pitch with all the complex machinations used to make this process efficient, but the fundamentals have never changed; this is how your PC is operating right now.

One big hurdle to overcome in implementing this is that programs don't just execute instructions in a vacuum. As code is executed, there are side effects. Some are values internal to the CPU, like the  status of CPU registers and the current position of the instruction pointer. This is called "CPU state," and is specific to each running program. When you switch from one program to another, you have to save that information - called "context switching" - and restore it when you come back. Storing this info takes extra time and memory.

Another hurdle is the state of other hardware. If two programs are talking to the hard drive, you can't let them both just blindly issue commands every time they get control of the CPU. The first process might start a data read that the second process interrupts with a data write, confusing the hard drive controller. So when switching from one process to another, you also have to save the state of these other hardware resources - and possibly even delay switching tasks until those hardware requests are complete.

If you have enough RAM to store this state, and if your apps don't need too many cycles per second to appear responsive, you can do all this and the user will feel like they're "running multiple programs at once."

Now, in business applications - the driving force behind the first couple decades of computing - actual "multiprocessing" of this type is not as important as simple usability - users just don't want to have to close one program in order to open another, as they did throughout the DOS days. That, ultimately, is the goal: it doesn't matter if the computer is perfectly speedy, or if programs can run simultaneously, it just matters that users not have to lose all their work in one program simply in order to look at another.


This desire was of course tremendous right from the start of computing. Who wants to be stuck in one program at a time? So, almost from the earliest days of the IBM PC, software was created to enable task switching with various degrees of success.

Early Attempts

Multitasking DOS 4

Microsoft actually released a version of DOS with true multitasking support, but it generally required software to be specially written for it. You can see it here - EDLIN is running, and I can switch to a new command prompt by pressing Alt and selecting from a menu, or I can start a new task.

This didn't solve the core problem - that you wanted to run your old, 1983-vintage copy of dBase II, and your old copy of Multiplan, at the same time. Since neither of those programs were developed for this version of DOS, they couldn't play ball. This creates a chicken and egg problem wherein nothing was written for multitasking DOS, so nobody would buy multitasking DOS, and since nobody had that DOS, nothing would be written for it.

Even if software did get updated for new OSes, users had already spent a lot of money on the software they had by the time anyone started trying to solve this problem, and they wouldn't have wanted to re-buy that software. The feature that users needed was to share the machine between two apps of any vintage, with both apps thinking they were the only program running on the machine.

TopView title screen  TopView running two apps at once Topview PIF editor

An IBM product, TopView, was another early attempt to fully solve this problem. It was a textmode program, not a graphical one, but it allowed multiple DOS apps to run at once, with their text output diverted into separate "windows" on a shared "desktop." Here you can see it running fdisk and GWBASIC simultaneously, with both executing at once - while I'm doing things in fdisk, the code in GWBASIC continues incrementing a number. So this is true multiprocessing, after a fashion.

TopView only worked if the apps were "well behaved." This is a term you'll see throughout articles on this topic, and what it means is that the app didn't do any direct hardware access - it used DOS "system calls" for everything, which gave TopView an opportunity to "intercept" those calls and redirect them for its own purposes.

For instance, when a program wrote to what it thought was character position 2,10 on the screen, TopView altered the coordinates so they drew into the "window" it had created for that app instead. The advantage to this is that you can simply hand off the processor to each app one at a time and allow them to do what they want, and the results will always end up safely back in TopView's hands where it can figure out where they're meant to go.

The biggest problem is that this stops working the moment your app touches direct video memory, for instance, which many did, making them incompatible with this approach. Also, TopView just sucked. I used it for about 20 minutes while writing this article and every step of the process was unpleasant. Being limited to textmode does nothing to help the situation.

Footnote: The third pic is the TopView PIF Editor for later reference. PIFs tell Topview how to run apps - this will be explained much more thoroughly later in this article, since TopView evolved, in a sense, into Windows itself.

Task Switchers

There was a specific class of commercial products called "task switchers" that allowed you to run multiple programs and switch between them with a shortcut like alt+tab, and in fact early versions of Windows, as you'll see, were often little more than this. These programs couldn't run simultaneously - at any given moment, one program had complete control of the screen and all hardware resources, and then when you switched tasks, that program got completely suspended and another one took over.

There's very little info about how these worked online but as far as I can tell, they just used brute force. I mean, I can't think of any other approach, and talking to friends who have done more research into this than me they seem to agree: When you hit the task switch shortcut, the switcher just takes a snapshot of various hardware resources like video memory and CPU register status, saves it all to another spot in memory, then transfers control to another app, all with what we would now call "userland" code - the switcher is just another program running on the computer.

I don't know how popular these programs were, but they certainly had their proponents - since they didn't try to "intercept" the input/output from apps, but mostly let them run as if they were in total control of the system, I imagine they were somewhat more compatible with not-so-well-behaved apps.

But what happens when the program you want to run is even more poorly behaved, if you will? Since these switchers would have needed to "manually" save the state of all hardware resources, they would have to predict what was in use. If a program did anything the switcher wasn't prepared for, like alter graphics card configuration registers, the system could have entered an unusable state or even crashed when a task switch occurred.

Also, while lots of DOS apps were nice enough to pay attention to where they were in memory and only make changes to their own data, nothing stopped any app from scribbling all over system memory and corrupting other programs.

I may not have hard answers to how these switchers worked, but the proof is in the pudding - while you can probably tell me the name of the OS installed on Macs in 1985, and you can definitely name the most popular way to run multiple DOS programs on the PC in 1995, you almost certainly can't name a DOS task switcher or multitasking environment offhand. There were at least a half dozen and none of them are remembered now, which tells us they didn't do brisk business.

You actually can name one of them, though you might not know it. For it's first couple versions, Windows' ability to run multiple DOS apps was a hybrid of "task switching" and the TopView approach. Compatible apps could run in windows concurrently, while apps that wanted to write to the screen and so on were ceded control of the hardware while running. The fact that most people have never seen or heard of these editions of Windows also speaks to how poorly this approach probably went for Microsoft.

To sum it all up, the trick we're discussing here is just incredibly difficult to pull off. Taking programs that were meant to run using the entire resources of a computer and trying to gimmick them into sharing the computer is just incredibly difficult - until hardware changes came that specifically enabled this.

Hardware Advances

The original IBM PC CPU was an Intel 8088, a cost-reduced form of their more-or-less flagship 8086 chip, and throughout the 80s it remained the overwhelming definition of the platform. Though it was an advanced processor perhaps in 1981, in retrospect it looks like little more than a fast calculator now, without a lot of advanced purpose-oriented features. Though Intel released several considerably faster and more advanced processors throughout the 80s, the bulk of PC software targeted the 8086/8088. The newer processors had backwards compatibility modes allowing them to run 8086 software at faster speeds, but only a few programs actually targeted the newer chips.

The 286

The 80286 was Intel's consumer followup to the 8086, and it introduced a much more advanced mode of operation, called protected mode. The full details of this are extremely complicated, but in the simplest terms, protected mode allowed multiple programs to share one PC without being able to interfere with each other. Each process gets locked into an area of memory in which it can do whatever it likes, but an attempt to reach outside of that area results in a CPU-level alert being triggered, at which point the operating system - which actually has a higher privilege level within the CPU itself - is allowed to take over execution and decide what to do about it.

This feature allows you to run multiple programs without worrying that one might overwrite another's memory or crash the entire system. If a program tries to access memory it's not allowed to touch, the CPU stops it, and the OS can step in and make a judgment call - either permitting the access if it thinks it's reasonable, redirecting the access to somewhere else in memory, or stopping the process in its tracks and terminating it.

This is a fantastic capability and could have revolutionized computing overnight when it was released in 1982, except that by that point there was already an enormous DOS software ecosystem. Protected mode completely altered how the system worked, and virtually no DOS software would run correctly in this state. So instead, these chips were largely relegated to running in backwards compatibility mode - called "real mode" - and while they could be switched between protected and real mode, it was extremely slow and awkward, so it had little impact on the PC world.

The 386

The 80386 was the third major leap forward in Intel's x86 processor line, and it would have been very easy at release to totally miss the feature that was going to change how the IBM PC worked completely. I think I actually found some articles in magazines about the 386 which did exactly this - decried it as a simple bump in speed and instruction set that had no real impact on the evolution of the platform.

Buried in the feature list however was something called Virtual 8086 mode, and this feature was in fact a massive step forward for the DOS application ecosystem of the day. It fixed the problems with protected mode, enabling the CPU to run DOS apps and new protected mode apps at the same time, by - in no uncertain terms - running the DOS apps in virtual machines.

This works pretty much like the virtual machines we use nowadays. Each DOS app gets cordoned off into a space in memory where, as far as it knows, it's the only program running on the machine. When it tries to write to, say, the spot in memory where 8088 machines stored their video, the CPU catches those write attempts and alerts the operating system, which can redirect them to a device driver or put them in an entirely different spot in memory so they can be displayed only when the OS chooses.

In fact, all the hardware of the host machine is emulated - the OS presents a "fake" graphics card, a "fake" keyboard, a "fake" hard drive and so on, all of which translate the blunt, simplistic requests of 1981-era software into the polite, cooperative discourse of modern, community-conscious software. In this way, multiple concurrent DOS apps can run in these tiny walled gardens, and as far as they know, each one has a whole PC to itself, while in reality their input and output is entirely simulated - a Truman Show for elderly software.

This is how the Windows that most of us remember worked. By leveraging the capabilities of the 386, Windows was able to run multiple DOS apps simultaneously. Microsoft took a run at making this happen without the capabilities of the 386, but it was not a pretty sight, as you'll see - it was fragile, tedious and limited, and therefore failed to put Windows on the map. Curiously, not even the addition of the 386 to the equation solved this problem - before Windows could gain any respect, it had to make significant leaps forward in the overall user experience.

Now, let's look at how this all worked.


Windows 1.0 (1985)

Windows 1.01 desktop Windows 1.0 Write Windows 1.0 running multiple apps

Windows 1.0 is as far as I can tell roundly considered a joke, a token effort meant to fill a commitment Microsoft had made and little more. Whether it was ever intended to actually run DOS applications in any context more demanding than a public tech demo is questionable.

One of the problems with it is that it has no overlapping windows, but uses a tiling window manager instead. This is pretty unpleasant to look at, but surprisingly well designed all things considered. When you launch an app, it usually takes up the entire screen by default, with other apps minimized to icons in the taskbar - that's the green area, where you can see a floppy icon representing a minimized MS-DOS Executive. Once you've started an app however, you can then drag another icon onto the screen to split the view either horizontally or vertically, and you can resize these splits to fit windows to their contents. You can then drag apps by their titlebars to rearrange and add new splits as desired.

At higher resolutions (which were possible, though rare) this might be a somewhat usable UI, but I find it pretty hard to look at, and given the public response to Windows 1.0 I'd guess I'm not alone. Notice of course that there are native graphical apps for this OS - a few programs actually got published for Windows 1.0, and the API was sufficiently stable that they still run in much, much later editions.

My experience with this version is disjointed to say the least. It took me several days to manage to get it to run correctly at all, and I eventually found out that you have to run it on DOS 3.3 or it'll just break in a bunch of weird ways. I also can't find a manual anywhere, so I had to puzzle out how it worked based partially on the documentation for the non-enhanced version of Windows 2, which is largely similar.

DOS Apps

So first, I'll try to run dBase II. This is a very old but extremely venerable PC app from 1983 which I imagine some people would still have had around in '85, although it had been supplanted by dBase III in '84.

Windows 1.0 with a "no PIF" error

This is your very first experience using Windows for one of its core purposes, so how does this process feel to the user? Well, this is, unmistakably, an error message. You have attempted to run one of the many programs you've used for years, which you were told Windows will run, and you have received an error saying that Windows cannot find a file, and given no explanation for why that matters. This is a resounding UX wet fart, no bones about it.

I can't find a Windows 1 manual, but for Windows 2, the manual section referred to is 163 pages into the Windows User Guide and runs for dozens more - this part is more understandable, given that the technology to figure out how to run a DOS program automatically had not yet arrived in the pre-386 era. In short, the user is about to be taken to old program school and made to earn a degree.

However, if we just hit OK, the app launches:

dBase running in fullscreen dBase terminated

Notice that it's running in fullscreen - the app takes up the entire screen, just as if it were running in DOS normally, and there is no way (that I can tell) to get back to Windows or change programs.

When you quit the app, it stays on the screen until you press a key - this is so that if the program printed something before it exited, you can read it before Windows takes over the screen again. Some apps, you can imagine, would be useless if they hadn't done this.

When operating this way, Windows is nothing more than a program launcher of the sort that was common at this time, with no multitasking at all. In order to go beyond this, you need a Program Information File - the missing "PIF" that was mentioned.

Program Information Files

What I've shown you above is not Windows putting its best foot forward. There are better ways to run DOS software, but they require significant work on the users part.

If programs are (sigh) well-behaved, Windows can run them in a far more modern format. To wit:

Windows 1.0 running dBase in a window 

Here, dBase II is running in a window. It updates more slowly than when running fullscreen, and I'd guess that's because Windows has replaced the BIOS routines for printing text with its own code, that stores each DOS app's text output in a different spot in memory, and it only periodically checks that memory for updates and updates the graphical screen.

There are other things I can do in this mode, but we'll cover those shortly. Let's first look at how I accomplished this. To make this program run, I created a PIF with Pifedit.exe:

Windows 1.0 PIF editor

You may know the PIF format as the one that continued being used for shortcuts to DOS apps in Windows 95. This format originated in IBM TopView, and never changed in concept, except that by Windows 95 user intervention was not needed in most cases. Here, it absolutely is.

A PIF primarily tells Windows how (sigh) "well behaved" an app is. The various Directly Modifies checkboxes warn Windows about the parts of the app that it needs to be careful around. About half of these options disable windowed mode and force the app to run in fullscreen. Here's roughly what the settings do:

  • First, you have to give the executable name so Windows knows when to engage this PIF - unlike later versions of Windows, PIFs are not tied to specific files on the disk. If you launch DBASE.EXE (or .COM) anywhere on the machine, regardless of drive or folder, this PIF will take effect.
  • You can also give a "friendly name" to the app so that it shows up with a better title than just the filename, and give command line parameters and a default directory to run in.
  • Then we have options to tell Windows how much RAM the program needs, and how much it prefers. This affects the amount of available RAM that Windows reports to the program, so if you set the minimum to 128k and the desired to 512k, and Windows finds 256k free, it'll report that much to the app.
  • Now we have the Modifies boxes:
    • The Screen checkbox is for apps that write directly to video memory, and simply forces fullscreen mode.
    • Keyboard is for apps that read the keyboard directly, and disables all task switching shortcuts - meaning if you enable this and an app won't let you exit, you're stuck in it permanently until you reboot.
    • Memory is for a couple scenarios: one is for apps (called TSRs) that launch and then exit, leaving themselves "resident" in memory so that other apps can access their code, and another is when you want to run an app that takes up nearly all system memory, in which case Windows will swap itself to disk to leave more room for the app to run.
    • COM1 and 2 are interesting; they just give exclusive access to a serial port to that program so two apps that want to use the same port can't run simultaneously. It's surprising to me that this doesn't also apply to printers, but I think at this point printing was meant to be handled through the Windows print spooler anyway.
  • Next is the Program Switch option. This touches on the mechanics of task switching.
    In order to tab away from one program and into another, Windows needs to save a copy of the screen so that it can restore it when the app is recalled. "Text" reserves 4KB, enough for a single screen of text. "Graphics/Multiple Text" reserves up to 36KB to save a bitmap screen. "Prevent" disables switching, saving 4KB.
  • Screen Exchange is supposed to refer to printscreen behavior - but I can't get this to work in Windows 1.
    In 2.x, these settings allow you to press Alt+Printscreen to screenshot a running DOS app, which requires Windows to reserve some memory to store the shot. Note that in textmode, a screenshot will just be the text, which you can paste into e.g. Notepad, while in graphical mode it will be a bitmap you can paste into e.g. Paint.
    I'm not sure why this isn't working, and I don't have a manual to refer to.
  • Finally, you can have the app close automatically on exit - otherwise we get a "zombie window" which you'll see later.

As the user, you are expected to create one of these PIFs manually for every program you want to run. Windows comes with a small assortment:

Windows 1.0 PIF collection

These are of course optimized for popular third party apps of the time, a practice Microsoft would continue with increasing fervor as the years went on. At this point there were thousands of DOS applications in the world however, so with only 60 or so shipped with the OS, the user would almost certainly need to create their own PIFs frequently.

Fullscreen Capabilities

If a program is set up with a PIF that makes it run in fullscreen, you don't get a lot of amenities other than the ability to minimize it with Alt+Tab. Here's a minimized dBase, in the taskbar:

Windows 1.0 with dBase minimized Windows 1.0 showing an icon menu

You could start multiple copies of dBase and switch between them by alt+tabbing out, then clicking on the one you want. This seems like a pretty irritating process - I don't appear to be able to alt+tab directly from program to program; it just highlights the icon, after which I have to press Space to get this menu, then select Zoom to reopen the app. It's not smooth at all.

There doesn't appear to be anything else you can do with a fullscreen app. This would get better for a bit in a later edition, but Windows is mostly about... windows, so that's where the bulk of functionality will remain.

Windowed Capabilities

Windowed mode confers a number of new options. Here I've tested with fdisk, since it's a very clean, first-party Microsoft app with a textmode UI:

Windows 1.0 running fdisk and a file browser Windows 1.0 running four fdisks

First, as seen here, we can run in a split window, with other DOS apps or with native Windows graphical apps. This gets cramped very fast, but a pair of side by side windows would probably be a somewhat useful geometry. You can keep launching processes until you run out of RAM - I made it to 3 here, but with some adjustments to the PIF I might be able to run more.

When an app finishes executing, it usually hangs open like this;

Windows 1.0 with a terminated app

Notice the parentheses around the name - like fullscreen mode, Windows leaves the app open so you can see the final output. In order to actually close the window you can't just press a key however, you have to go up and actually hit the Close option on the window menu.

Curiously, this doesn't seem to happen with all programs - some, like fdisk, exit immediately. I'm not sure if this is because they're returning some different exit code to the OS or what. This is what the "Close window on exit" option in the PIF is supposed to control.

Windows 1.0 with fdisk maximized

You can maximize a DOS window to fill the entire screen, covering even the taskbar, at which size I believe you get a full 80x25 display.

Windows 1.0 marking and copying text Windows 1.0 showing text pasted into Write

With an app running in a window, you can now interact with it in a limited fashion using the mouse. Here, I've copied some text from a DOS window and pasted it into Write.

You can also paste directly into a DOS box, and your text will be entered as virtual keystrokes. This interoperability is a big bullet point justifying Windows' existence - I could, for instance, copy complex commands I made in a dBase session and save them in a text file for frequent re-use, something that was probably enabled by special programs called "TSRs" under DOS, but would have been tedious at best.

You'll notice something about that window menu - the Close option is greyed out. Would you be surprised to learn that in this version of Windows, it is impossible to exit a DOS program without its cooperation? There's no trick, no workaround - it cannot be done. Once a DOS program is launched, it has to exit of its own free will, or it's simply stuck running.

Also, while we can open multiple copies of a program at once...

Windows 1.0 running two copies of dBase

...only one actually executes at a time. When I click away from the first one to the second, it freezes and the second one starts running. Windows only gives processor time to one DOS task, probably because the complexity of constantly unloading and reloading the hardware context of multiple apps is just too high to do efficiently and reliably.

The apps I've run so far are extremely simple in how they interact with the screen - all they do is print text. If we try to run something more sophisticated, Windows has problems. Here's Multiplan 4:

Multiplan 4 running in fullscreen

This launches in fullscreen, but if I turn off the Directly Modifies: Screen flag in the PIF, I get a blank white window with no text. I got the same result from trying to run anything else that attempts to have a "textmode GUI" style interface, like DOS Edit or QBasic. Curiously, it also crashes as soon as I press any key - and this happens even if I run it in fullscreen. As long as there's a PIF at all, it crashes as soon as I do anything - if I delete the PIF, it runs fine, but in fullscreen and with no task switching.

FDisk fullscreen Windows 1.0 with fdisk maximized

Another thing I should point out is that there is no color text support at all - here is fdisk running fullscreen, versus windowed. Notice that the fullscreen text is bright white and grey, but in a window it all renders as black on white. I'm not sure offhand why this is - Windows has color support, and this information is definitely being stored in memory, so why they wouldn't use it I don't know.


As noted before, Windows 1 was not meant to be good by all reports, and I would say it isn't.

The tiling window manager is very uncomfortable, and it feels like it makes very poor use of screen space despite it being about as lean as it possibly could be. It does not look or feel polished, and it requires too much tedious fiddling to make everything work - you can't tell from the screenshots, but it took ages to get all this working just because moving from task to task in this OS requires a ton of extraneous clicks. The GUI is not good.

With that said, it does do what it promises to some extent. Once you create PIFs, DOS apps do work if they're sufficiently basic, and copying text between programs is extremely useful. However, a number of apps that I threw at it wouldn't run in a window, and one wouldn't run at all.

This release would not put Windows on the map. That wouldn't happen for a while, but let's see where Microsoft goes next.


Windows 2.x / 286 (1987-89)

Note: There were several versions of this OS including 2.03, 2.1 and 2.11.

The naming conventions of this OS are confusing. There are several versions, some sold as "Windows 2.0," some sold as "Windows/286," some sold as "Windows/386." All of these are versions of Windows 2.x.

The name Windows/286 does not mean that this version of the OS requires a 286 - it will run on an 8088 with almost full features, it just distinguishes that it is not the 386-enhanced version, but that it does have support for expanded memory, which was introduced on the 286.

I will be referring to Windows/286 and Windows/386 as if they were different operating systems, but they were released simultaneously, and it's probably accurate to say that both are simply Windows 2 running in two different modes.

Windows/286 2.11 Windows/286 2.11 running Write

2.x continued Windows' trend of unsuccess in the market, but that's not to say that it did nothing to improve the functionality of DOS apps. In fact, there are considerable improvements throughout.

The new window manager (with overlapping windows!) is drastically more pleasant to use than its predecessor. I have found references in magazines to Windows 2 being used by actual consumers, which I can't say for Windows 1, so let's consider this very possibly to be the first Windows anyone ever bothered with.

Nothing has improved in the basic "run an app" process:

Windows/286 giving PIF error Windows/286 editing the fdisk PIF

The same PIF error happens, and the PIF editor hasn't added anything new - Windows/286 appears to be mostly identical to Windows 1 in terms of what it can run and how, but there are changes right off the bat.

Fullscreen Capabilities

Windows/286 default DOS app

An app with no PIF launches fullscreen, taking over the entire computer. This is Windows operating in "task switcher" mode, mostly like it did in Windows 1.0 - it doesn't know enough about the program to try to put it in a window, so it's ceding the entire system to it. Compared to the previous version however, there are new capabilities even here.

If you're used to Windows 95, you might try hitting Alt+Enter at this point, but that key combo does nothing. The next thing you might try, if you had a lot of experience with DOS on Windows, is Alt+Spacebar, and that does do something:

Windows/286 textmode menu

When you hit that key combo, Windows now injects this textmode menu. You'll notice the "Restore" option is not functional - in other words, you can't change this app to a window (the thing that Alt+Enter does in later versions.) Window-izing an app is only possible with a PIF setting; you can't switch modes on the fly.

You can also Alt+Tab to cycle through running apps, and it shows you a preview of the app you're about to switch to using the menubar:

Windows/286 textmode task switching

Notice that the title says MS-DOS Executive - the name of the app that will be switched to if I let go of Alt. Selecting this allows you to escape back to Windows, but as with Windows 1.0, you still can't quit a DOS program without using its Exit option - even after you get back to Windows, you can't exit it while DOS programs are running.

Windows/286 with an app minimized Windows/286 showing an icon menu

There's no longer a "taskbar" area, minimized icons just go to the bottom of the "desktop." With a DOS program minimized, you can see it there as before. The menu allows you to return to the app, that's it.

Windows/286 mark text menu Windows/286 marking text

From within the app, you can now use the menu to copy and paste text, an improvement for apps that can only run in fullscreen textmode. To do so, you press Alt+Spacebar, select the Mark option, and then use the arrow keys to navigate the cursor and shift to select text.

In the above pictures I'm marking a command I had previously entered. I can then go back into the menu, select Copy, and then go back in and select Paste, which reenters the text as virtual keystrokes. If I had entered a complex command, I could store it in the clipboard so I don't have to retype it multiple times. This uses the Windows global clipboard, so I can still use this to interchange text with Windows apps like Notepad.

Probably the oddest thing about all this is what happens when you do quit a DOS app the correct way, by choosing the apps own Exit option. The app ends and becomes a zombie, like this:

Windows/286 with an inactive app

You may recall that the term "Inactive" remained for a long time. When you quit a DOS app in Windows 95 or later, the window would often switch to this Inactive title and remain until you closed it. This makes sense, and as in Windows 1.0 it's good that windows hangs here, but because it doesn't have the ability to convert the program to a window - as later versions could - you're stuck in full-screen with this dead app. Pressing enter does not close it as it did in Windows 1.0.

At this point, in order to return to Windows, you need to press either Alt+Spacebar or the down arrow key to summon the window menu and navigate to Close. If you hit Escape out of reflex you could simply be stuck here, looking at a blinking cursor on a black screen, unsure what's going on. It's not catastrophic, but it's, uh, not a fantastic user experience.

Windowed Capabilities

  Windows/286 running two fdisks

Windowed mode has not directly improved, except that it benefits from the new overlapping window manager. Everything you could do in Windows 1.0, you can do here.

Windows/286 with an inactive windowed app

When apps end, the window also obtains the Inactive banner, as it does in textmode, which is clearer than the parentheses.


If you create PIFs for each of the apps you use, and those apps are reasonably sensible in their behavior, Windows/286 will let you run them side by side in decent harmony.

Windows/286 running two apps at once

With the new window manager, this is definitely a more pleasant experience. However, in practice, I still have not been able to get most apps to work in windowed mode. Lotus 1-2-3 and Multiplan, for instance, can be made to work in fullscreen but I cannot find a configuration that will let them run in a window - they just say there isn't enough memory, no matter what I do.

Perhaps this is because I don't exactly understand the memory model of this era - I never was able to make sense of EMS and XMS in the 95 days, and while you could say this limited perspective makes me unqualified to write this article, I should clarify that I have the entire Internet at my disposal, and someone in 1985 did not. If I can't figure this shit out now, what was it like 33 years ago?

Also, I don't think that non-textmode apps can run in windowed mode at all. In any case the memory requirements to do this are so high that I couldn't figure out an incantation that didn't just throw a memory error and refuse to run.

With that said, the need to run apps in a window is not paramount. It is, however, a tremendous bummer if you ask me. Running multiple apps on the same screen had been a white whale of the IBM PC for years at this point and it would have been remarkable if this edition of Windows had fully achieved it.

As with Windows 1, apps do not execute simultaneously. Whichever app is focused executes and all others are suspended.

This is not the holy grail that Windows was meant to be, mostly because the hardware just didn't have what it took yet. It seems like a pretty solid task switcher, but the privations of getting tasks running are so intense that I imagine many people never even gave it a solid try.



Windows 2.x / 386 (1987-89)

Windows/386 is another beast entirely.

Given the monumental new capabilities offered by the 80386 processor's Virtual 8086 Mode (V-8086), the experience of running DOS apps changes completely for the better.

Windows/386 desktop Windows/386 running native app

As you can see, there's no obvious difference between this and the previous unenhanced edition, but let's launch a DOS app:

Windows/386 running fdisk fullscreen

It doesn't look very different, but here, you can press Alt+Enter:

Windows/386 running fdisk windowed

Windows/386 has added considerable new functionality to DOS apps, now that it can run them in VMs.

Programs don't give an error about a missing PIF on startup, they just start immediately and go to fullscreen. At this point you can now hit Alt+Enter to switch to windowed mode, which Just Works - no PIF required. You can create PIFs (which you'll see shortly) but they're only to help Windows when it can't figure out what an app wants.

I'm not sure how much heavy lifting V-8086 is doing here. It appears that we no longer need to allocate memory for programs, for instance - I can launch apps that I couldn't get running with the defaults (or at all) in Windows/286 and they just work, immediately. Switching dynamically to windowed mode requires a considerable amount of RAM, since Windows has to store their entire screen contents as well as its own - and in color, as you'll see - yet Windows manages it without a hitch.

My guess is that Windows/386 is able to leverage extended memory to make this all Just Work without any user intervention, by placing VMs and saved screen contents up in higher RAM areas that Windows/286 could barely use. Also, since V-8086 turns over control to Windows when an app tries to reach outside of its allocated memory, Windows can probably allocate more on the fly as long as the access was legitimate, removing the need to specify how much RAM an app needs ahead of time.

A nice improvement over the previous OS is that when you exit a fullscreen app, instead of becoming inactive and staying fullscreen, it now switches to windowed mode automatically, which makes it much clearer how to move forward.


You'll have noticed that the color scheme of textmode DOS windows is now white-on-black instead of the opposite. This is not an arbitrary change, but is actually because VM windows now support color:

Windows/386 running QBasic Windows/386 displaying qbasic color issues QBasic under DOS

QBasic wouldn't even run in a window in previous versions, but now works quite well in one, with full color... sort of.

These aren't the exact intended colors of QBasic - the third image is a screenshot of it running in fullscreen to demonstrate what it should look like. Everything's brighter and washed out in windowed mode. This is odd, because Windows is running in VGA here. Even in 16-color mode it should have been able to choose a reasonable palette to match textmode colors. I'm not sure exactly what's going on here, but I think it's something like this:

Windows 2.x ostensibly supports VGA graphics, but was made at a time when those cards were still rare and expensive, so it's really designed for EGA.

The only thing that the VGA driver does is increase the screen resolution to 640x480, at which resolution it only has 16 colors available. That 16-color palette can be chosen from the entire 256 color VGA gamut, but Windows uses the default EGA palette for compatibility with the majority of Windows apps, which would have expected to run mostly on EGA cards.

Now, EGA also had fully saturated colors in its gamut, but not in it's default palette, which was based in turn on the 16-color CGA palette. CGA's palette had eight colors, plus light and dark variants, and its light colors were unpleasantly desaturated. It's "bright blue" was the unsatisfying shade (Dodger Blue) you see above, for instance. I have always hated CGA's colors, but they're what IBM chose in 1981, so it is what it is, and that's why the bright blue here looks like that instead of a nice fully-saturated blue - because Windows is using the most compatible palette possible.

But that doesn't explain it all. Why is the background color a bright blue at all, instead of the dark one, as intended? The CGA palette did contain a dark blue, so why not use that? Well, for some reason all the background colors in the DOS window are being forced to their "high intensity" variants. Grey becomes white, dark blue becomes Dodger Blue, and so on. This is why the white characters in each menu option are invisible - they were supposed to be on a grey background where they would have shown up, but that grey has become white.

Why did Microsoft do this? I'm not enough of a wizard to dig into the hardware registers and find out what palette is actually being used, but even running in EGA mode Windows should have had better colors available. Did they not actually use the original CGA palette's dark colors? Why wouldn't they have done that? It's a weird problem, and what's weirder is that it's retained in several subsequent Windows releases, but changes to introduce new problems with each version as the Windows default palette changes.

This is a minor complaint however, because it's still worth it to be able to run an app with somewhat correct color, instead of the black and white of Windows/286.


Now, in addition to color, DOS apps can even display graphics in a window now. This app, Xanaro Agility, uses medium resolution CGA graphics and it works perfectly in a window:

Windows/386 displaying a graphical DOS app Windows/386 running Ability Windows/386 pasting graphics into Paint

I believe the reason this was not possible before is that graphics mode under DOS never used system calls to draw anything - programs always wrote their graphics directly into video memory, and without the V-8086 VM it would have been impossible to intercept those calls and redirect them. Windows/386 is perfectly capable of doing that however, and does so with aplomb.

Now that graphics work, the Mark feature now allows you to copy graphics out of a window and paste them into other apps, as you can see here. Paint at this point used strictly one-bit black and white due to memory constraints, so copying a color CGA app would require a third party app.

You can now even run certain games in a window, like Bruce Lee here (although it runs too fast to play):

Windows/386 running a game in a window

All of this "just works" - I didn't have to make any PIFs or change any settings - although Windows included one for dBase, it still works if I delete it.

Let's talk more about games for a second.


Windowed games do not work, and never really would, however they can tell us where the limits of Windows' DOS emulation are, since high resolution DOS graphics are relevant to productivity software as well. Games of course push graphics to their limit - Bruce Lee runs as shown above, but it's an extremely old, CGA-era title. Newer games using EGA/VGA do not work correctly:

Windows/386 starting Crystal Caves Windows/386 with Crystal Caves at the title screen Crystal Caves running in fullscreen Windows/386 refusing to run Crystal Caves

Here I'm attempting to run Apogee's Crystal Caves. It's able to make it as far as the title screen (although you'll notice, again, that the colors have been coerced into the high-intensity palette - compare to the fullscreen version in the third image), but when it tries to load the menu, Windows identifies some kind of faux pas it has committed and gives the error you see in the fourth image.

Commander Keen fails immediately on startup with this same message. Note that these games do run in fullscreen mode and can be alt+tabbed out of just fine, they just refuse to run windowed.

While Windows was never intended to run games in this era, there are certainly business applications that would run into these same problems. A high resolution GIF viewer for viewing files downloaded from BBSes for instance may have had this kind of issue.

This makes me wonder what exactly the issue was. I'm not certain what graphics mode Crystal Caves is in during startup, but I would have guessed it's 320x200x4 EGA, the same mode the game itself runs in. Executing it in DOSbox, I don't see anything that looks like a mode change when it switches from the title screen to the menu. The only thing I can think of is that this occurs when a DOS app makes a write to video memory that doesn't fall within the parameters that Windows expects.

I assume that windowed graphics work essentially by emulating a graphics card. Since video on a PC is generated by reading a series of memory locations and interpreting them based on the status of a bunch of graphics card config registers, Windows must be interpreting those register writes by the software in order to know how to render what's being written to video memory.

Presumably Microsoft made code that accounts for certain video modes and settings typical of business software, but isn't ready for everything that can be done with a graphics card. If it sees anything it doesn't understand, it panics and pitches the program to exclusive fullscreen mode where it can program the graphics card directly without interfering with the rest of the OS.

Fullscreen Mode

An interesting loss of functionality actually occurred for apps that run in fullscreen: Alt+Spacebar no longer summons a textmode menubar. Instead, it punches out to windowed mode immediately, where the user can then use the Mark, Copy and Paste options. This means that the textmode menubar existed in only a single version of Windows, which is intriguing considering how clever it was.

Consequently, when you Alt+Tab, instead of seeing the menubar with the name of the app you're about to switch to layered on top of your current program, the entire screen blanks and you see this instead:

Windows/386 textmode task switcher

It's interesting that they decided to forego the approach of layering the switcher interface over the app itself. Maybe they found the latter was visually confusing, or something about the V-8086 architecture prevented it.


In previous versions, I could run multiple DOS apps, but only one would execute at a time. Under Windows/386, I can run multiple apps concurrently, as in, both executing at once:

Windows/386 multitasking dbase

You can't see it in this non-moving picture, but then it's also not very visually impressive, despite still being a tremendous technological advance - both copies of dBase II here are running an infinite loop that increments a number, and both are updating simultaneously. This is proper multiprocessing, just like what we have nowadays. Making this work, however, requires some user intervention - by default, only the currently selected app will execute and all others are paused, and the user has to change some settings to alter that.

Program Settings

Windows/386 program settings

By pulling up Settings from the window menu of a running app, you can see some on-the-fly configuration for the DOS VM that's now available. Display Options obviously just switches from windowed to fullscreen, but the others do interesting things. There's no specific manual for Windows/386 apparently, so some of this I have to infer:

  • Execution allows you to simply pause a program. I assume this is so that you can halt an app that consumes a ton of CPU time and totally hangs the rest of the machine, do something in another app briefly, and then return and resume the CPU-hog app.
  • Tasking Options allows you to specify whether an app should execute only while in the foreground, continue executing when in the background, or take exclusive control. This latter forces the program to run in fullscreen, and I believe it also pauses any other apps while this one is selected, even if they were set to run in the background.
    Notably, a program set to fullscreen mode, but with Background enabled, will actually continue executing even when not focused, even though the output is totally invisible at that point.
  • Terminate is a novel feature. As I said, in prior versions of Windows you could not stop a program without using its Exit option. In Windows/386, presumably because of the process isolation offered by V-8086, you can do this - but it gives you a scare message first:

Windows/386 terminating an app

Forcibly terminating processes remained a sketchy option through all Windows versions prior to NT taking over the product line. Up until Windows ME, ctrl+alt+del was a way to sometimes regain control of your system in an emergency, but frequently failed, and even when it succeeded it often corrupted the system state.

It was better than having to hit the reset button, but not by much, so I'm assuming the same is true here - this would let you recover to a point, but a savvy user would heed this warning and reboot as soon as possible after saving their work.

Program Information Files

The PIF remains in Windows/386, but some changes have occurred.

Windows/386 PIF editor

While there are similarities, the Directly Modifies section - the most important element of the old PIF editor - is completely gone. Windows no longer needs forewarning of how the app behaves, because V-8086 allows it to run rampant within its sandbox. The section has been replaced with Usage Controls which just replicates the options from the application settings regarding background and exclusive execution.

The change here is enormous. The PIF is no longer an essential part of launching an app, just a way of tuning it - giving it more initial memory so it's less likely to run out, for instance, or just providing a nicer title, or making it close on exit. These are handy, but not required. Apps mostly run fine with the default settings.

The PIF would remain throughout the history of Windows, but would become less and less useful over time as Windows got better at figuring things out on its own like this.


Needless to say, this version of Windows is a tremendous leap forward. I grabbed four programs and just ran them with no effort - some of which wouldn't run on the previous OS at all.

The simple way to put it is that, although there will be significant refinements in later editions, the functionality of the DOS VM in Windows/386 is pretty much a solved problem as far as business software goes.. I was not, for instance, expecting graphical apps to work in a window at all - I assumed that functionality had come in Windows 95, and while there will be enhancements at that point, everything seems to work pretty well in this version. The 386's new features appear to have knocked this problem right out of the park.


Windows 3.0 (1990)

Windows 3.0 desktop

Windows 3.0 was heralded as the OS Microsoft had promised in 1983 and failed to deliver until 1990. It's improvements were far too numerous to list, but we'll focus on the enhancements to DOS apps.

First, although Windows 2.x ostensibly supported VGA resolution, I guess I'd have to say it didn't make very good use of it. I'm not sure why offhand, but Windows 3.0 running at nearly the same resolution* seems to have much more "breathing room."
* Windows/286 ran at exactly the same resolution as Windows 3.0 here - 640x480. Windows/386 runs at 640x450 for some arcane compatibility purpose, but both feel equally cramped.

Here, let's launch fdisk:

Windows 3.0 running fdisk Comparison of fonts and borders

Despite there being no more pixels on the screen, this feels like I can breathe a little easier while using it. The second image above proves that the text size is exactly the same, and the window border appears to be only two pixels larger on either side. Maybe that's enough to make the difference, or maybe it's a subtler psychovisual effect, but 3.0 definitely feels lighter to work with, which is probably a big part of why it succeeded.

Another thing you might notice is that the colors are better. The FDISK in Windows 2 was all in bright white text, while under 3.0 it has white and grey. Let's check out QBasic:

Windows 3.0 running QBasic

It's still not quite where it should be. The menus are now grey as they should be, so the white letters show up now, but the text area and bottom status bar are intense colors when they should be dim ones. In fact, all background colors are still forced to high-intensity - except bright white, which always appears as grey, and dark grey renders as black.

Some of these are explained by the aforementioned palette issues, but white for instance was obviously available in the Windows palette, and is an option for foreground text, just not background color, so I don't get this.

Also, notice that the bright blue is now fully saturated instead of the awful old CGA Dodger Blue.

Program Settings

In general, running apps seems the same:

Windows 3.0 running two dBase instances

But some interesting changes have occurred. Let's take a look at the program settings again:

Windows 3.0 program settings

Notice that there are now priority "weights" which allow you to give a program a very specific position in the CPU scheduling hierarchy - this implies a design that anticipates that you might run many concurrent applications, to the point where you need three digits of precision to specify the order in which they should be given processor time. This speaks to significant ambition on Microsoft's part, which probably proved to be valid.

The Tasking Options have changed to checkboxes from radio buttons, which belies a very interesting improvement in functionality. You used to have to select either foreground, or background, or exclusive, but now you can select a combination, because Microsoft has added some novel new options.

First, Exclusive no longer makes an app fullscreen. Instead, it simply pauses all other DOS VMs while it has focus - in other words, "exclusivity" now only applies to how processor time is scheduled amongst DOS apps - it does not require taking over the whole system and pausing all Windows apps.

In addition however, you can now select both Exclusive and Background at once. This seems contradictory at first, but remember that we are talking about very precise tuning features at this point. If Exclusive is selected, that means this app will always pause all other apps when focused, even ones that have Background enabled. If Exclusive and Background are selected however, this app will continue running when it doesn't have the focus, just without exclusive access to the processor.

Now, as I said before, the PIF has not gone anywhere, and there's a lot to explore there.

Program Information Files

This version of Windows no longer comes with a PIF folder containing presets for certain apps. It does, however, have a small list of known programs in SETUP.INF, which I believe is used by a search feature built into the OS which scans your hard drive for EXEs and adds them to Program Manager for you. If any of those EXEs match a program in SETUP.INF, a PIF is autocreated to give it functioning default settings based on Microsoft's testing. This would expand considerably in 95, where I will describe it in more detail.

Windows 3.0 PIF Editor Windows 3.0 PIF editor, advanced settings

The initial view of the new PIF editor looks a lot like the old PIF editor, with some minor changes. However, as you can see, there is now an Advanced dialog with a ton of extra options - again, all for fine tuning behavior.

We have the new priority settings, a lot more options for assigning XMS and EMS memory, keyboard shortcut adjustment to suit applications with special needs, and then a whole host of strange things I can't begin to understand, like "Emulate Text Mode" and "Lock Application Memory."

There's also an option to allow an app to be closed while active, meaning you don't have to go into it's Settings menu and click Terminate. You'll still get a warning if you try to close it, but it's nonetheless more convenient, and it suggests more confidence on Microsoft's part that you can force-quit DOS tasks without wrecking the system.

The Windows 3.0 manual - a substantial tome - goes into excruciating detail about all of these settings, but what I find the most interesting is actually what you don't see right away.

Notice the Mode menu? Selecting that gives us two options, 386 Enhanced and Standard. If we select the latter, we get this:

Windows 3.0 PIF editor standard mode

Suddenly we're back to the old nonsense, like Directly Modifies. What gives?

Despite the clear improvements that the 80386 offered, and the fact that this chip was now five years old and had even been superseded by the 80486, Windows 3.0 still supports operation on 8088 and 286 machines, as well as machines with extremely little RAM (less than a megabyte!) For these systems, you need to run Windows in reduced operating modes.

In Real Mode, Windows 3.0 works like Windows/286 did - DOS apps have the same constraints, and in fact even worse ones. Even using the PIF editor, there is no way to run a program in a window in this mode. All DOS apps run fullscreen, and the Alt+Spacebar menu is gone - the only thing you can do is Alt+Tab between programs. I'm not sure if copy/paste even works in this mode, since you can't mark a part of the screen to copy anymore.

Standard Mode is like Real Mode except it can still use expanded memory, which provides support for the 80286 as well as better memory utilization on low-RAM 386s. As far as I can tell the same constraints to program operation apply in Standard Mode, though I can't test this because it crashes my VM - since the PIF Editor doesn't distingush between Real and Standard, and since the 286 doesn't have Virtual 8086 Mode, I have to assume there are no improvements over Windows/286's capabilities here.

The other reason Real Mode exists is for compatibility with native Windows 1.x/2.x apps that won't run under 386 Enhanced Mode - per the manual, Windows 3.0 will detect this situation and tell you that you need to restart with WIN /R to run them.


Windows 3.0 running three apps

While there are many more tuning options in Windows 3.0, based on my limited testing it seems like Windows/386 had largely solved the problem of being able to throw a DOS app at Windows and have it just get right to running it, so, despite this OS release being Microsoft's first great triumph in the GUI world, it seems like the DOS element was a sufficiently solved problem that all there was to do from here on was tweak it.


Windows 3.1 (1992)

Windows 3.1 desktop

I'm not sure why it is that Windows 3.1 is the go-to when people name a Windows OS of this era. It came out two years after 3.0, and does not seem to contain any enormous leaps in functionality that my eyes can see, but it must have been astronomically successful even compared to 3.0. The phrase "Windows three point one" seems to just roll off people's tongues, and when referring to the series, "Windows three" feels somehow incomplete.

The changes to DOS performance in Windows 3.1 do not seem enormous. Once again the palette issues with DOS VMs have changed to new ones:

Windows 3.1 running QBasic with correct colors Windows 3.1 displaying incorrect DOS colors

The overall QBasic editor finally appears more or less correct - the low-intensity colors are now available, so the background is no longer an eye-searing blue.

If we check the options however, we find that dark red and brown both render as a strange maroon-puce kind of thing. This again appears to be an issue with the default palette selected by Windows - if I mess around in the color control panel I can discover this maroon-ish color as one of the few solid colors in the brown region. But why not dither these colors? Acceptable brown and red colors could be accomplished that way. I really don't get it.

There is also a delightful new desaturated green I cannot begin to explain. I think my optic nerve isn't really sure what to do with it, but it must have been needed for some striking icons in order to justify adding it to the stock VGA palette. With all that said, bright white is now available, so at this point arguably the only colors that are problematic are red and brown, since they both appear as the exact same color.

There are few functional changes - minor alterations to the layout and options in the PIF editor give access to new EMS/XMS features that the vast majority of users would never have understood, for instance:

Windows 3.1 PIF editor Windows 3.1 PIF editor advanced

And the font of DOS VMs can now be changed:

 Windows 3.1 permits font selection of DOS windows

And finally, there's an interesting alteration to the message you get when you terminate a DOS app:

Windows 3.1 terminating an app

This new message doesn't actually say that the system will become unstable if you do this, it just says it's not a great idea and should only be done as a last resort. This suggests Microsoft had become bolder about V-8086 and trusted it more firmly.

Other than that however, this is largely identical to Windows 3.0.

Program Information Files

Part of why I include 3.1 here at all is because a significant expansion to the way Windows handles DOS apps was added in this release. C:\Windows\System\Apps.inf contains a big list of programs that Microsoft tested in-house and found good default settings for. This concept was coming into existence in 3.0 but had not been expanded into an automatic system yet, and 3.1's approach would be extended even further in 95, so I documented it in more detail down there.


Windows 95 (1995)

Windows 95 desktop

Windows 95 was, of course, Microsoft's Great Shift, the grand alteration of the cosmos, but what impact did it have on the person who primarily used DOS software? At this point, what were the majority of computer owners using on a daily basis - Windows 3.x apps, or DOS apps? I don't know, but DOS certainly remained a significant element of Microsoft's plan.

Program Settings

The process of launching a DOS app is not fundamentally different than Windows 3.x; you just click on it. Here's fdisk and Ability for comparison:

Windows 95 running FDISK Windows 95 running Ability Windows 95 program properties

Several things have changed. Windows now have a toolbar where you can select a different font size on the fly, which I appreciate quite a bit. You can access the Mark, Copy and Paste options from buttons, instead of making trip after trip to the program menu, also an improvement.

Also, while there are plenty of program settings still accessible from the new Properties button, they've also provided a button for direct access to toggle the Background execution option - which, as of this edition of Windows, is finally on by default for the first time. Windows 95 feels confident enough in its DOS multitasking ability that all launched apps will execute concurrently, and the option to disable background execution is presumably only provided in case a program misbehaves.

The actual program settings we'll explore later in the PIF section. They're basically identical to the PIF settings we'll see there, although curiously, some of them are meaningless here - you can't adjust the Working directory, for instance, since that only applies when a program first starts, so changes made to that field just go nowhere.


Let's take a look at QBasic again:

  Windows 95 running QBasic Windows 95 showing QBasic colors

The colors have gotten neither worse nor better since 3.1, and would not - these are the best colors that Windows would ever use for DOS VMs in VGA 16 color mode.

A comment I should make here is that the above problem would probably go away if I ran in a color depth above 4bpp (16 colors), but I'm deliberately not doing that, because I don't think higher resolutions or color depths were part of Microsoft's target platform, nor do I necessarily think many users had those things.

I do not know very much about the state of graphics cards in this era. To be frank, I was actually astonished to learn a few years ago that Windows 3 could run at resolutions above 640x480 at all. I had simply never thought about it very hard, but when I did, I found that I felt like I had never seen a machine running Windows 3 in a higher resolution than that, and since 3 was so old, it just seemed natural that it wouldn't be able to do any better.

In actual fact, graphics cards have been available for many years that could run even Windows 1 in higher resolutions and color depths. I can't give you specific dates and models, but I can say that in 1991 you could certainly buy a 1024x768 monitor and a card to drive it at higher color depths.

How many people ran Windows 3 or even Windows 2 at higher resolutions and color depths I can't say however, and I also suspect that even by the time 95 came out, Microsoft did not assume that anyone had anything better than that. Windows 95 will no longer run on an EGA card like previous editions, but it is very much at home on VGA - that's what's listed in the system requirements, all the screen metrics are very comfortable at that resolution, and all the icons are designed to look great in 16 colors.

It would take another 6 years for Windows XP to begin demanding a higher resolution or color depth, hardware permitting, so I feel pretty comfortable saying that this is how Windows 95 was meant to be used and so I have not installed an SVGA or VESA driver for any of these screenshots. I could have done that in Windows 3 even, and didn't do it there for the same reason - I think that what we see in these pictures is how possibly a majority of business users experienced Windows, so this is what counts for historical accuracy.


Once again Windows 95 feels like it has more breathing room on the screen, like Microsoft has squeezed even more pixels out of 640x480 somehow - but this time, it's actually because the default font for DOS VM windows has been changed.

Windows 3.1 vs 95 DOS font

Under Windows 3 and earlier, the default font was 8x12, but under 95 the default is 6x8, so the dimensions and aspect ratio have both changed. The above image shows the newer font below the older, demonstrating just how much space this saves.

Oddly, I don't remember this being the default in any version of Windows I ever used, but I've tested on 98 and ME and they all use this font by default, so my memory appears to be false. I think this is because my use of DOS on Windows 95 and 98 was primarily for games, which I usually ran in fullscreen. By the time I spent significant time in the command prompt within Windows rather than under real DOS mode, I was running NT - and I've found that NT's equivalent, NTVDM, also runs in 8x12 by default even in the first release, so I think my memories blurred together.

Sometimes these new font sizes have strange effects. For instance, with some apps, Windows picks the extremely tiny, nigh-unreadable 4x6 font, for unknown reasons.

Windows 95 showing a very tiny DOS box

Program Information Files

While the PIF remains, 95 does a lot to isolate the user from them wherever possible.

Automatic PIFs

QuickBASIC title bar

You'll notice that QBasic does not show up as simply "QBASIC" here, but has an icon and full name - a "friendly name" as programmers put it.

This is part of Microsoft's lengthy and storied backwards compatibility struggle. As part of the runup to Windows 95's release, Microsoft tested an unholy number of programs - basically everything they could get their hands on - and analyzed in extreme detail how they worked. Some of that analysis resulted in hardcoded changes to how Windows operated to make specific programs run, but a lot of apps just needed adjustments to their memory settings and that sort of thing.

Microsoft could have implemented this by creating PIFs for every program they tested, which is exactly what they had done with Windows/386, but starting in 3.1 they decided to take a more abstract approach. The file C:\Windows\Inf\Apps.inf contains presets, icon assignments and names for all the programs they tested.

APPS.INF 1 APPS.INF APPS.INF 3 Windows 95 PIFs folder

When you launch an app listed in this file, these settings are condensed and compiled into a PIF file. If the program is on a floppy, the PIF goes to C:\Windows\Pif, exactly as it worked in previous editions of Windows; otherwise it goes in the program directory. There's something like 460 entries in this file.

I'm guessing the reason they didn't just ship the premade PIFs in C:\Windows\PIF like they did in 2.x is because every PIF takes up a certain minimum amount of disk space, and 460 PIFs would have taken up at least half a megabyte at a time when that was a precious resource.

PIF Settings

Now, creating PIFs yourself is certainly possible. In fact, it's now fully automated - you don't actually have to create one by hand, or even locate a special PIF editor program as in previous versions - just pull up the properties on a DOS app:

Windows 95 program settings Windows 95 PIF memory settings Windows 95 app misc settings Windows 95 PIF file

The number of settings here has actually decreased - Windows 3.1 had a ton of arcane options that seem to have disappeared. The priority settings for instance are gone, and all the extremely esoteric stuff like "Lock Application Memory." Presumably Windows had gotten so much better at process management that it no longer needed those things.

A particularly interesting change is that Allow close when active has changed to Warn if still active. In other words, Windows now considers it universally acceptable to exit a running DOS app with the window Close button rather than having to dive into the settings and hit Terminate; this is just a normal thing to do now. There is still a warning by default:

Windows 95 program termination warning

But the warning has become even gentler than 3.1's. Now it just says you'll lose data, and carries a yellow warning rather than a red "STOP!" icon.

PIF Creation

Now, when you make any changes to the program settings, Windows automatically creates or updates a PIF named after the executable in the same directory. This has many implications.

This new behavior is an improvement over previous editions, where PIFs had no fixed storage location. I'm not sure exactly how it worked, but it seems like when you ran any executable in previous versions, Windows scanned the program directory, C:\Windows\PIF, and who knows where else looking for a matching PIF. I've had PIFs work even if they were just in the Windows directory itself, or the root of the drive, regardless of where the EXE that I launched was.

Additionally, while PIFs in previous Windows editions could specify an "initial directory," which would tell any launched copy of that program where to find its data files, they didn't point to specific programs. That is to say, a PIF for Dbase.exe under Windows 3.1 would apply to any program with the name Dbase.exe, anywhere on the system or on removable media, so if it specified an initial directory on the C drive, a copy of the app launched from floppy would start in that folder - an inflexible approach.

Under Windows 95 however, a PIF applies only to a specific copy of a program, e.g. C:\dbase\dbase.exe - in fact, if that program is moved or deleted, you have to edit the PIF to point to the new location or it'll stop working. This gives flexibility, because you can create PIFs specific to particular copies of an app, but it also creates some fragility, because even just renaming a folder will cause the PIFs in that folder to "break" since they now point to a folder that doesn't exist.

This new direct linkage turns the PIF from an abstract, OS-level "setting" into something specific to a particular EXE file, emphasized by the fact that it usually lives with the program. PIFs were placed in the same folder as the program they were created for, and DOS software sold at this time included PIFs on the install media that were placed in the installed directory.

"Implicit PIF creation," if you will, masks the user from a lot of irritating extra steps, but also begins an era of growing "side effects" in Windows - the OS silently creating files in response to innocuous user input, with specific information baked into them, without making it quite clear it has done so, creating potential confusion in the process, as well as potential new compatibility issues.


Windows 95 famously does a tremendous amount behind the scenes to try to make apps run, far more than previous versions, and while this is generally beneficial, you as the user do not really know what's being done to "help" you at any given moment.

 For instance, while testing Xanaro Ability, I created a PIF entirely by accident - I had changed some innocuous setting in the properties and then set them back, but a PIF got created anyway. After that, the app crashed every time I tried to launch it, even when I clicked on the EXE file itself - because if a PIF is present in the same folder as an EXE, it'll be used even if you didn't click on it.

Deleting the PIF made the program run again, but I eventually found that by changing the startup mode in the PIF to Windowed instead of Fullscreen it would also fix it - but it still launched fullscreen when I did this, and I had to alt+enter to actually window it. I have no idea why this happened, and I'm sure it's not the strangest thing new users might encounter.

dBase II, which had run perfectly in each previous edition, has finally broken in 95. The app launches okay, but as soon as you try to open a database it reports "FCB unavailable," a critical error.

Windows 95 showing a Dbase II error

In 2020, I'm able to google this and find out that very early editions of DOS (<2.x) used something called a File Control Block, which was replaced by file handles in later releases. There was a backwards compatibility feature in DOS that the user could enable or disable as needed, and presumably Windows 95 now has this compatibility mode turned on implicitly - unfortunately, dBase only works if the compatibility option is off.

 Supposedly there are ways to correct this problem but nothing I could find would do it - dBase simply refused to run with any settings I could find, and those suggestions (if one even works) would have been much harder to find in 1995. Dropping to actual DOS fixed it.

dBase II is from 1983, so it probably wasn't within Microsoft's target software demographic by this point, but the fact of the matter is that it worked in Windows 2.0 and 3.1 but no longer does, at least without arcane wrangling. I suspect this is because Microsoft had by this time built new functionality into the underlying DOS in order to make things Just Work better for most apps, and not tested it against extremely old software like this, figuring it was pretty reasonable at this point to say "just get a new version, that program's 12 years old."

Graphics & Games

Support for graphical DOS apps has increased a tiny bit.

Windows 95 displaying Crystal Caves in a window

This is the menu of Crystal Caves, which Windows 3 refused to run at all. Under Windows 95 it works just fine at this stage, although it runs at about 3 FPS. As a footnote, I remember running (in later versions of Windows) much more sophisticated games in DOS VMs, and they also worked fine but ran at about 3 FPS. This is probably because Windows has too much going on in full GUI mode to have time to waste copying the current state of the video memory to the screen more than a few times a second.

If I try to advance to the game however, it turns to gibberish:

Windows 95 showing Crystal Caves corrupted

To reiterate, I have no idea what's going on here. While Windows 3 punched out after the title, Windows 95 makes it as far as the menu, but when the actual game starts it can't render the graphics. So it gets further but still fails, and I'm not sure why.

Again, all of this should be the same video mode, EGA 320x200x4bpp, so there must be some subtle detail to the video configuration that I don't know about. EGA video is pretty basic and linear, but Windows seems to be interpreting this as if it were some funky interlaced video mode that I don't understand.

So the graphics support of the 95 DOS VM is clearly improved, but not by enough to support games. There may have been productivity applications that were made usable by this improvement, ones that used high res graphics modes but didn't go as far as whatever feature these games depend on.

Now, in Windows 3, when you tried to window-ize a graphical app running in a mode that Windows couldn't handle, it was supposed to suspend the app and then show you a snapshot of the app in the window. I was never able to get that to work - it just threw an error about not having enough RAM. Before we discuss this further though, consider - how would this work? If Windows couldn't handle the app running in a window, why would it be able to handle it when suspended?

Windows 95's answer to that question is... it can't. It attempts, and fails. If I launch Commander Keen (which Windows 3 refuses to run outright) I get this:

Windows 95 running Commander keen

It's totally unable to display Keen, even on the title screen. Windows 3 was right to refuse to try to run this. Windows 95 attempts but fails. It feels like a weird step backwards, especially because I know there are games that do cause Windows 95 to throw an error about the video mode not being possible in a window, although I can't find any at the moment.

As a footnote, the red color here is fully saturated. If I fullscreen this game, that red color becomes the desaturated red that was typical of the old CGA palette. This makes sense because the 95 palette requires fully saturated red, green, yellow and blue in order to create the Windows logo - so the default palette is now totally decoupled from legacy EGA/CGA colors.


I could go through dozens of apps here and test what does and doesn't work, but my object was to stick to a few programs and see how they behave from version to version. I also haven't dug deep into whether they work consistently, don't crash during operation, etc. because that's a massive project - and really, the goal here is more to address the initial user experience. If a program worked, but crashed during operation, I don't think that had nearly as much impact on whether the user liked Windows 95 than if it failed to run at all.

I might be too personally invested to comment accurately on the improvements to the DOS user experience under Windows 95, because I grew up with it. It's natural that I would feel more at home with it than previous editions, but I think there are still some objective truths to be found here.

Although the addition of the Taskbar had impact on the experience of Windows as a whole, I think it made substantial improvements to running DOS apps.

Windows 95 running four DOS apps

DOS programs take up a big chunk of screen space. At 640x480, even at lower font sizes it's hard to fit more than a couple programs on the screen. Under Windows 3 it was easy to lose track of what you actually had running - you could alt+tab, but that required a lot of keystrokes to "experimentally" find out what was running if you'd forgotten. You could also use the task switcher dialog from 3.1 onward, but again, you had to stop what you were doing, hit a key combo, and then explore the list.

The 95 taskbar shows you what's running at a glance, including icons if you or Windows chose one. In the chaotic jumble of programs running above, you can tell what's running immediately, and jump to any program - Ability runs in graphical mode so it really needs to be maximized to be useful, so if you pull that up, all your other windows will be hidden behind it, but you can retrieve one instantly by clicking its taskbar button. Windows 3 could only provide this if you minimized every window when you switched to another one.

Again, this was helpful for native GUI apps as well, but I think it would have made a huge difference in the ability to rapidly switch between programs that all looked kind of same-y.

Overall, using DOS apps on Windows 95 is as good as it gets. I don't think Microsoft made any great leaps forward with DOS "emulation" after this, until NT's completely rerolled DOS emulator, NTVDM, which is an entirely separate topic that I might tackle in another article.

While I stipulated that I did all these tests in basic VGA mode, the fact is that by 1995 you could buy a better graphics card at diminishing prices, and the serious user very probably did do that eventually even if they remained a heavy DOS application user. With higher resolution and color depth, you can get programs to run with larger fonts, accurate colors, and plenty of "breathing room," at which point I think we can safely say that, with exceptions for the rare high-resolution, high-color application, DOS on Windows was a solved problem.




I can't decide whether I think Microsoft took a surprisingly large or surprisingly small number of steps to make it to "full" DOS functionality. Certain things worked much earlier than I would have guessed - and I think it's peculiar that certain things never worked, like 256-color VGA mode.

As Windows became a more capable games platform, Microsoft leaned in hard to videogame support, but never did improve DOS emulation to a point where you could practically play much of anything in a window. In fact, I seem to recall NT did a little better at this at times. You'd think they could have managed it under 9x, and that they would have considered it worthwhile, but perhaps it's a harder trick than I think.

I have no deep insight into how all this works on a technical level - my goal was to document the user experience and the apparent capabilities, especially because there's so little coverage of the details of early Windows editions online. I hope you liked it and maybe learned something interesting.

If this was interesting to you, or if you found errors and wish to submit corrections, email me:

If you like my writing, consider tossing me a few bucks. It takes a lot of work and payment helps me be motivated.

List of Articles