DOS programs ran faster than Windows 3.1. Why was that? | Comuniq
This site requires Javascript to work properly. Please enable Javascript in your browser.
/Technology
Gadgets, apps, inventions and everything that involves the world of technology. Share your links here and see what the guys have to say in the comments.
Members: 15 Join
Moderated by: mozzapp
DOS programs ran faster than Windows 3.1. Why was that?
Manon_code<br>1781336389<br>[Technology]<br>2 comments
The short answer is that DOS didn't get in the way. A program wanted to write to the screen, it wrote. It wanted to access the disk, it accessed it. There was no layer between the code and the hardware doing validation, translation, or resource management. That explains most of the difference.
## Direct Hardware Access
In DOS, writing graphics meant literally copying data to a memory address. Segment `0xA000` was VRAM in graphics mode, `0xB800` in text mode. One `MOV` instruction and the pixels were on screen, with no system calls and no intermediate drivers involved.
Windows 3.1 introduced the **GDI (Graphics Device Interface)** to handle all of that. It made sense: with GDI, the same code worked across any printer or video card with a compatible driver. But every call to `DrawLine()` or `BitBlt()` had to pass through several layers before reaching the hardware, including parameter validation, window clipping, and device context management. For simple operations that overhead was barely noticeable. For applications doing thousands of graphics operations per second, it added up.
Technical reference: [Raymond Chen, The Old New Thing (Microsoft)](https://devblogs.microsoft.com/oldnewthing/)
## Real Mode vs Protected Mode
The 8086 and 286 ran in **real mode**: programs addressed the first megabyte of RAM directly, with no memory protection and no isolation between processes. That was the natural environment for DOS software.
Windows 3.1 on 386 systems ran in **386 Enhanced mode**, with virtual memory and segment-based protection. Every context switch between applications, or between a DOS session and the Windows environment, required a CPU mode switch. That cost cycles.
On the 286 things were worse. The processor could enter protected mode but had no instruction to return to real mode in software. Windows 2.x handled this by forcing a triple fault, essentially crashing the CPU in a controlled way to trigger a reset and get back to real mode. It worked, but it came with the timing and compatibility problems you'd expect from that kind of approach.
Technical reading: [Intel 286 Protected Mode and the Windows Real Mode Switch](https://www.os2museum.com/wp/286-real-mode-switch/)
## Cooperative Multitasking
Windows 3.1 used **cooperative multitasking**. Each application was responsible for voluntarily yielding control to the system by calling `GetMessage()` or `PeekMessage()` on a regular basis. If an application got stuck in a processing loop without doing that, the entire system froze, mouse, keyboard, everything.
DOS had no multitasking at all. The program had the CPU to itself for as long as it ran. No scheduler interrupting, no other application competing for attention. For games, number-crunching tools, or anything that needed consistent timing, that made a real difference.
## Memory and Swapping
The Windows 3.1 memory model was complicated, mostly for historical reasons. It used **moveable and discardable segments**: when RAM filled up, the memory manager moved segments around in the heap, compacted free space, and swapped to disk when needed. Anyone who ran Windows 3.1 on a machine with 4 MB of RAM knows what that looked like in practice, the disk grinding away for several seconds before an application responded.
DOS had none of that. If a program fit in available RAM, it ran without the system interfering.
## Questions people were asking at the time
**"Why does my DOS game run badly inside a DOS window in Windows 3.1?"**
Because Windows kept intercepting hardware interrupts even inside a DOS session, `INT 8` for the timer and `INT 9` for the keyboard. Games that relied on precise hardware timing, especially those driving the **OPL2/OPL3 chip on a Sound Blaster** directly via port I/O, would lose synchronization. The usual workaround was pressing `Alt+Enter` to switch to exclusive mode, which gave the program more direct hardware access. That didn't always fix it completely though.
**"Why was printing so slow in Windows 3.1?"**
The GDI rendered the entire page as a bitmap in RAM before sending it to the printer. At 300 DPI on an A4 page, that meant several megabytes of data to process at a time when 4 to 8 MB of total RAM was typical. On machines with less memory, part of that rendering ended up going through the swap file.
**"Why did Windows programs use so much more memory than DOS equivalents?"**
Every Windows application loaded the system DLLs (`GDI.EXE`, `USER.EXE`, `KERNEL.EXE`) into a shared memory space, on top of...