It's a miracle emm386 managed to squeeze out more memory as UMBs than it needed to do its job.
Consider: It scans for holes in the memory map. It switches to protected mode, then v86 mode, sets up page tables, and is basically more of an OS than DOS, if you look at the CPU. It monitors IO ports and rewrites DMA access from random programs to translate the UMBs to their physical addresses. It implements VCPI to cooperate with e.g. windows and dos4gw. It switches A20 on and off when translation needs to happen.
And all that to gain memory from segments C000,D000,E000, if nothing else sits there. So 192K max.
Looking back, it's insane what contortions we went to, just to keep dos alive.
It's a shame that VM86 mode wasn't able to be nested. I don't remember the specifics, but as I recall there are instructions that don't trap and prevent nesting VM86 within itself. I know Intel rectified this in later CPUs-- I believe that's the VT extensions.
The VT extensions also unfortunately didn't "fit in" with the VM86 model either, needing their own special instructions and data structures (and AMD and Intel also did slightly different things, further complicating the situation.)
sgdt/sidt/sldt are some of these instructions. Don't know if there are others.
They give linear adresses of the processor's descriptor tables. Code running with paging enabled can't even read these locations, so they are pretty useless for user mode. But they allow user mode to get forbidden info from the kernel, and virtualizing lgdt/lidt/lldt becomes impossible because non-privileged code can see the values given to the cpu changed, and a save state/restore state is impossible under virtualization.
Under newer processors, flag CR4.umip makes them trap, so virtualization becomes possible.
This is why I've suggested an inverse EMM386 to the FreeDOS team: a 32-bit app that has a single purpose -- start 1 DOS VM.
That is the only way I can imagine to create a form of DOS that could be booted on UEFI computers, and without that, soon FreeDOS will be confined to VMs and old kit.
The idea is, start a very very simple 32-bit binary that creates 1 V86-mode VM, maps some DOS resources into it (disk, screen, keyboard, mouse, etc.), then loads the DOS kernel into it.
In DOS a stub EMM386.EXE could create some UMBs and LIM EMS if you want it.
I doubt it will ever be possible to support sound cards, network cards, etc. this way but most modern ones don't work on DOS anyway so nothing of importance is lost.
The big achievement of DOS and the 8088 was relocation during loading. For .COM files, this was easy: the program was segment register relative, you pretty much had virtual memory. For .EXE files, MS-DOS relinks all of the absolute segment addresses during the load process.
So this means you could have multiple programs loaded at once: often done with TSRs (terminate and stay resident programs), but it also allowed things like shell windows in Lugaru Emacs (Epsilon) to exist. Languages like Turbo-C had system().
Also the OS was well decoupled from the application programs (it could be independently updated). This was not true for many of the other home computers of the time, but some pulled it off: all CP/M systems and TRS-80. I think the main exception to this was the video system- many programs made assumptions about the address of the screen buffer.
If I remember correctly, even with a color card, applications switching to a monochrome video mode was possible if a bit rare. Creating UMBs in vram segments A000, B000 or B800 was always considered a suicidal configuration, and EMM386 would not do it unless forced.
Designing a debugger like SoftICE is unnecessary now: modern processors support virtualization, which means you can run the entire OS inside a VM and debug it from your hypervisor.
I don’t know about that sorry. It did let you suspend Windows totally, not sure how different that is than today. I had to take over responsibility for a device driver in windows 95/98 era and SoftICE offered a better debugger than microsoft for the task under Windows at that time.
a.k.a. Intel, who also designed USB "Full Speed" vs "High Speed"
("Full Speed" was the maximum speed of USB 1.0, 12 Mb/s, which also had "Low Speed", 1.5 Mb/s which is used by keyboards and mice. "High Speed" was introduced in USB 2.0, and is 480 Mb/s)
Joke's aside, I have empathy for the pain of naming in protocols and systems that get extended and remain backwards compatible. Intel was the king at this.
(BTW this is a paraphrase of on my favourite gags from the early Steve Martin film Dead Men Don't Wear Plaid for reasons that I hope, in context, are obvious.)
The 8086 was a stopgap, to have something to sell until the 432 was finished. Maybe they wanted it to be an evolutionary dead end, and 16MB address space was too dangerous? Notice also how the 80186 was PC incompatible.
The article mentions those at the bottom: "And that’s it for today folks. I intentionally did not touch on DPMI—the technology that truly allowed DOS applications to break free from the 1 MB memory limitation—because I’m saving that for the next article. So, make sure to come back for more!"
[Original author here.] Exactly! That (DPMI) is the thing I originally wanted to talk about but I realized I had to clarify many more thoughts first! And I still have to do the research on DPMI to be able to talk about it :)
I was almost amazed when instead of launching windows 3.1 running win.com one could run Borland DPMI host (that they used in their own 32-bit compiler toolchain), that stayed resident offering its API, and then one could run windows' KRNL386.EXE, that hooked with the DPMI host and booted windows.
None concrete I can think about, apart from understanding better the innards of windows boot with a whacky experiment. DPMI was an open spec, so this validated that in principle you could write your own DPMI host to make windows think it was running on top of a protected mode whose view to clients you could control and customize. But again can't answer to what avail.
CauseWay DOS Extender was released open source to public domain in 2000, and the source is on GitHub, if you're curious about the implementation. It supports builtin EXE (LE) packing as well.
It would be interesting to understand the Quarterdeck products and how they fit together: the separation between QEMM and QDPMI, and how DESQview worked to enhance DOS with multitasking.
DOS/4GW was memorable because it advertised itself while loading games made with it, usually late 386/486 era 32-bit games from before gaming on Windows had its act together.
Phar Lap was more ubiquitous throughout the 286 and 386 DOS days. Microsoft distributed a light version of it with their compiler for a while.
They also had DOS/16M which targeted 286 protected mode. The company I worked for used it when moving the Clipper programming language to protected mode.
The big problem is that 64-bit x86 long mode removes the V86 mode that made DOS 386 memory managers possible.
This is why the DOSemu project has been doing a multi-year rewrite: to create a new, full-VM-based DOSemu2 that can run DOS without emulation on x86-64 machines.
If memory serves, I had a neighbor who bought that 4MB Emulex card.
It was for an 80286 clone that had a 10MB HDD. His rational for buying this card was "I can make a big RAM drive out of it and run everything from memory"
I can't recall the price of the thing, but I want to say it ran in the thousands. Couldn't run most games on it because of copy protection so we never got to take advantage of it. In fact, I don't think the extra memory was usable at all in most software -- I recall we couldn't run a game on his machine due to having 512MB of onboard memory, but it had no issue in my ancient 8088 with 640K installed (in bizarre CGA colors).
CGA was the worst. EGA and VGA were huge improvements because CGA only had 4 ugly colors, while EGA had 16 (good), and VGA had 256 (much better). VGA also supported pallets I think (a way of allowing an application to use 256 colors out of 16 million supported colors).
16 colors, technically. But only four at a time, and three of those were selected from two preset palettes, both of which were hideous (one green/red/brown, one cyan/magenta/white).
And EGA had 64, because while its display output pins where still TTL, there was no longer a single intensity bit (RGBI) like in CGA but individual intensity bits wired for each color component (rRgGbB)
I remember the palette choices in CGA were downright bizarre; they'd be 4 colors that you couldn't possibly use to make anything look right. At the price of the card and the display, you're like "wait ... that's it?"
[0] Ignoring all of the interesting things coming out of the 8088 demo scene, nothing that I'm aware of from the 80s was capable of anything close to that.
I was avoiding EMM386 as much as I could on my slow 386SX25: there was a huge performance hit.
There was the Unreal Mode aka Flat mode. With few lines of assembly code, an memory allocation using HIMEM.SYS, it was possible to access all the memory: the segment limit is 4GB instead of 64KB in this "mode". Of course it was not compatible with Windows, so the unreal mode was more for fun than anything else.
Ehh! I wonder, when somebody remember, ms-dos was NOT first to use such tricks.
- All these stuff was REimplemented on PC IBM's technology of overlays, created as marketing technology, to widen line of IBM mainframes, as top models have enough RAM to work with programs directly, but cheapest models have to use something like virtual memory and swap on magnetic drum, to use same software.
And sure, when IBM PC achieved wide adoption, people also sought, some things could be done on PC, what before done on mainframes or mini-computers, but much cheaper.
I exactly seen revolution in approx 1993-1994, when prices on RAM dropped and become possible to equip PC with 1M or even more.
Unfortunately I myself believed, to talks of older colleagues, that all these PC tricks are not serious, and IBM is strong and will return with something much more powerful :)
I even not imagined, about current 64-bit PCs and what opportunities they opened.
Thank you for this article. It reminded me how I was profitable in DOS memory optimization. To run game like Mortal Kombat, Doom, Dune, Dune 2 or others I got very good in optimizing. I remember now how I wrote my own config.sys and autoexec.bat files or run MemMaker. This is a piece of history for part of us
I landed two jobs in the 1990s on the strength of my DOS memory-optimsation skills.
I didn't use Memmaker, or Quarterdeck Optimise or anything. I did it by hand. I got as much free base memory, with shorter more readable config files, and they were more maintainable.
When I worked on my Commodore 65xx computers, I intimately understood their hardware architecture, the Page Zero layout, the general layout of RAM/ROM, PEEK/POKE registers that mattered, CPU operations, and I had a general knowledge of assembly language. And most of this was documented in the user manuals themselves; the only other stuff I read was "Compute!'s Gazette".
When I received my first IBM PS/2 in 1989, I hardly knew any of this stuff. I didn't know any x86 assembly, I didn't know how DOS laid out memory or how the INT routines accessed devices. My computer overnight turned into a black box. I didn't program it in BASIC, I just loaded games and applications on it.
This sort of system opacity drove me rather crazy, and soon I was in college studying Unix and systems architecture again. I didn't waste any time deleting DOS/Windows and replacing it with Minix.
To be fair my background is similar but the system isn’t really more opaque. I remember having the same books for the PC as (in this case my slightly older mentors) had for the C64. Undocumented PC and Undocumented DOS stand out. However you mentioned games , I too was distracted with such things (like the ABCs, alcohol, babes and cars). And had a nerd break until the web era. With maybe a little play around with VGA graphics and DJCPP or whatever it was called along the way.
I thought I was a MS-DOS 6 expert. But I had never heard of MemMaker. Probably because when it appeared I was already an expert at tweaking CONFIG.SYS and AUTOEXEC.BAT for gaming (I made a boot floppy with menu for each game that setup memory and launched the game), and MemMaker wasn't compatible with the menu system.
Consider: It scans for holes in the memory map. It switches to protected mode, then v86 mode, sets up page tables, and is basically more of an OS than DOS, if you look at the CPU. It monitors IO ports and rewrites DMA access from random programs to translate the UMBs to their physical addresses. It implements VCPI to cooperate with e.g. windows and dos4gw. It switches A20 on and off when translation needs to happen.
And all that to gain memory from segments C000,D000,E000, if nothing else sits there. So 192K max.
Looking back, it's insane what contortions we went to, just to keep dos alive.