Building MS-DOS 2.11

I thought I’d slap together some github thing with MS-DOS 2.11 that’s been made buildable thanks to a whole host of other smart people. The default stuff out there expects you to build it under MS-DOS using the long obsoleted ‘append’ utility which can add directories to a search path. Instead I created a bunch of makefiles that take advantage of MS-DOS Player, and let you build from Windows.

dos211: just the MS-DOS 2.11 sources, I re-aranged stuff and made it (slightly) easier to rebuild on Windows. (

building should be somewhat straightforward, assuming you have the ms-dos player in your path. JUST MAKE SURE YOU UNZIP as TEXT mode. If you are getting a million errors you probably have them in github’s favourite unix mode.

msdos ..\tools\masm ibmbio.asm ibmbio.obj NUL NUL
The Microsoft MACRO Assembler , Version 1.25
 Copyright (C) Microsoft Corp 1981,82,83

Warning Severe
Errors  Errors
0       0
msdos ..\tools\masm sysimes.asm sysimes.obj NUL NUL
The Microsoft MACRO Assembler , Version 1.25
 Copyright (C) Microsoft Corp 1981,82,83

Warning Severe
Errors  Errors
0       0
msdos ..\tools\masm sysinit.asm sysinit.obj NUL NUL
The Microsoft MACRO Assembler , Version 1.25
 Copyright (C) Microsoft Corp 1981,82,83

DOSSYM in Pass 2

Warning Severe
Errors  Errors
0       0

   Microsoft Object Linker V2.00
(C) Copyright 1982 by Microsoft Inc.

Warning: No STACK segment

There was 1 error detected.
msdos ..\tools\exe2bin.exe IBMBIO IBMBIO.COM < 70.TXT
Fix-ups needed - base segment (hex): 70
del -f ibmbio.obj    sysimes.obj   sysinit.obj ibmbio.exe


As an example building the bios by running make. For the impatiend you can download, which includes a bootable 360kb disk image, and a 32Mb vmdk!

Bill Nye, the Microsoft C 6 guy

So, a while back I had found this up on eBay. As much as I’m trying not to buy old stuff I just couldn’t resist. And the price was just too good, I’d just have to forego going out to dinner for a week.

While looking around for something on Microsoft C, I stumbled upon this promo video for Microsoft C 6. Naturally I had to share it!

I had been using it to mess around with a poorly ported Hack 1.03, although I haven’t done much with that in a while.

One thing is for sure, that the old MS-DOS memory limits were becoming more and more of an issue. Sadly, they didn’t include the QuickC for Windows product which had the benefit of building in protected mode for access to far more memory, nor did they include any DOS Extender to even allow larger runtime access. Obviously you were expected to run this under MSOS/2 1.2 in this era. Although targeting OS/2 protected mode allowed easier integration with PharLap’s 286 based DOS Extender.

Since this was the OS/2 era, the Windows 3.0 SDK was a separate product.

There was another release, the 6.00ax version which included a DOS Extender, allowing the compiler to access 16MB of ram, as reported in this leaflet in a combined Microsoft C & Windows 3.0 SDK package.

The followup Microsoft C/C++ 7.0 addressed many of these shortcomings, but of course famously removed targeting OS/2. There was a later update that at least provided OS/2 compiled version of the binaries allowing you to run it under OS/2. I never tried to see if it could be paired with the OS/2 SDK, and manually made to generate OS/2 executables. I suspect not.

The larger thing is that Microsoft C 386 remained a ‘hidden’ product on Xenix, and the 32bit OS/2 and NTOS/2 betas.

Re-visiting VM/386

So years ago I had won an eBay auction for 3 disks:


But pretty much everything I threw at it emulation wise came up with NOTHING but green bars when trying to enter a virtual machine. I’d always thought it was a video ROM thing but VGA type ROM I put in Qemu it’s always the same thing, green jail bars.

VM/386 in action

However, I tried it again on 86box, and YES it runs!

VM/386 VM status

You can see VMs running, where they are in memory and all that other fun stuff.

And even better you can run graphical PC programs on your advanced 80386, and seamlessly multitask them all, using the hotkey ALT+PRINTSCREEN to toggle between them all. Surprisingly creating and terminating VMs didn’t really mess with overall system stability. I have to imagine that had this program had a 32bit API, it would have killed OS/2 before it ever got a chance. Considering that version 1.2 is from 1988 there very well could have been a larger possibility.

It does have the ability for individual profiles to specify RAM or even where or how to boot, it has disk drivers for sharing of files (think file locking). It also has the ability to boot from floppy, or even ROM!

MS-DOS 3.30A booted under VM/386

Indeed there is a rather good review from PC Magazine: January 1988, that goes into many features, and compares it to other contemporary multitaskers of the era.

The one big drawback is there is no data exchange facilities. The one thing that Windows/386 had bridging the gap between MS-DOS & Windows applications.

So many products like VM/386 ended up finding their niche’s in attaching dumb terminals, and turning 386 classed machines into ‘micro mini’s’ witthout the power of Unix. It’s even out of this environment Citrix was born.

But there was so much potential here to be something so much larger, but sadly that was not to come. Perhaps 1988 was just a little too early in the sense of GNU GCC/GAS/LD and some Xenix COFF help. The world would have been a lot more stranger had Microsoft lost that second vital platform war.

Anyone crazy enough to want to try it in 86box, I uploaded my images on

Looking back at MS-DOS 4.00M, or in the beginning before there was OS/2

With the pre-christmas release of the Microsoft OS/2 betas 1.00, 1.01, 1.02, 1.03 & 1.05 on, and helping Ncommander with an upcoming video, it seemed like a good place to start, not with OS/2 but rather with MS-DOS 4.0.

From the book INSIDE OS/2 ( ISBN 1-55615-117-9 )

Microsoft started work on a multitasking version of MS-DOS in January 1983.  At the time, it was internally called MS-DOS version 3.0. When a new version of the single-tasking MS-DOS was shipped under the name MS-DOS version 3.0, the multitasking version was renamed, internally, to MS-DOS version 4.0. A version of this product–a multitasking, real-mode only MS-DOS–was shipped as MS-DOS version 4.0. Because MS-DOS version 4.0 runs only in real mode, it can run on 8088 and 8086 machines as well as on 80286 machines. The limitations of the real mode environment make MS-DOS version 4.0 a specialized product. Although MS-DOS version 4.0 supports full preemptive multitasking, system memory is limited to the 640 KB available in real mode, with no swapping.2 This means that all processes have to fit into the single 640 KB memory area. Only one MS-DOS version 3.x compatible real mode application can be run; the other processes must be special MS-DOS version 4.0 processes that understand their environment and cooperate with the operating system to coexist peacefully with the single MS-DOS version 3.x real mode application.     

Because of these restrictions, MS-DOS version 4.0 was not intended for general release, but as a platform for specific OEMs to support extended PC architectures. For example, a powerful telephone management system could be built into a PC by using special MS-DOS version 4.0 background processes to control the telephone equipment. The resulting machine could then be marketed as a “compatible MS-DOS 3 PC with a built-in superphone.” Although MS-DOS version 4.0 was released as a special OEM product, the project–now called MS-DOS version 5.0–continued. The goal was to take advantage of the protected mode of the 80286 to provide full general purpose multitasking without the limitations–as seen in MS-DOS version 4.0–of a real-mode only environment. Soon, Microsoft and IBM signed a Joint Development Agreement that provided for the design and development of MS-DOS version 5.0 (now called CP/DOS). The agreement is complex, but it basically provides for joint development and then subsequent joint ownership, with both companies holding full rights to the resulting product.

As the project neared completion, the marketing staffs looked at CP/DOS, nee DOS 5, nee DOS 4, nee DOS 3, and decided that it needed…you guessed it…a name change. As a result, the remainder of this book will discuss the design and function of an operating system called OS/2.

– Inside OS/2.

Although MS-DOS 4.00M disk images have been floating around for quite some time, either a 2 360k disk set, or a single 720k disk image, I don’t think anyone (including me) really tore into it that much. It does have the ability to freeze DOS 3 programs, giving the illusion of running more than one. The session manager is pretty sparse but hitting left alt twice will pop it up giving you the ability to toggle through programs with ease.

MS-DOS 4.00M

There is a FDISK, FORMAT & SYS command making it straight forward to setup a hard disk, and copy the files over, I didn’t see any installer.

there is a PS command to show running processes. Also there is a DOSSIZE to show the memory partitioning and how much is available. Although there is a SWAPPER program I’ve been unable to get it to actually fun.


Another interesting thing if you run the unix ‘strings’ command against all the EXE’s you’ll find the string:

C Library - (C)Copyright Microsoft Corp 1985

Implying that not only was DOS 4.00M a ‘new’ DOS, but it was also written in C. No doubt this contributed to a larger file size than DOS 3, however it would also give that holy grail of portability, at least to new CPU modes. Also many files have the name of the source files baked in such as:

@(#)append.c    1.1 85/10/09
@(#)assign.c    6.1 85/10/23
@(#)attrib.c    6.1 85/10/24
@(#)fdisk.c     1.1 85/10/09
@(#)fddata.c    1.1 85/10/09
@(#)fdlow.c     1.1 85/10/09
@(#)fdsub.c     1.1 85/10/09
@(#)joinsbst.c  6.3 85/11/08
@(#)sysvar.c    6.2 85/11/08
@(#)cds.c       6.2 85/11/08
@(#)dpb.c       6.1 85/11/08
@(#)label.c     6.1 85/10/24
@(#)newdef.y    6.2 85/10/14
@(#)ms4bnr.c    1.1 85/10/15
@(#)mode.c      6.2 85/10/24
@(#)getkey.c    6.1 85/10/25
@(#)pifmes.c    6.1 85/10/25
@(#)advpscrn.c  6.1 85/10/25
@(#)advescrn.c  6.1 85/10/25
@(#)usrscrn.c   6.1 85/10/25
@(#)rangers.c   6.1 85/10/25

Okay so far, so good. But we’ve all seen this before, and scratched this OS about this far, because what else can you do? It’s not like there is any dev tools to do anything fun!

Well the tool hidden in plain sight is LINK4, which in retrospect is specific for MS-DOS 4.00M.

Microsoft (R) 8086 Object Linker  Version 4.01
Copyright (C) Microsoft Corp 1984, 1985.  All rights reserved.

Object Modules [.OBJ]:

There is no SDK for MS-DOS 4.00M, but they were kind enough to leave the linker in place. A quick check of the Windows 1.01 SDK shows that it also includes LINK4:

Microsoft 8086 Object Linker
Version 4.00  (C) Copyright Microsoft Corp 1984, 1985

Object Modules [.OBJ]:

It appears that if the dates and versions are to be trusted they are of the same vintage, but the Windows linker is older, and that they both output to a NE or New Executable. So to start the experiment I created a simple hello world exe from a simple:

void main(){
  printf("Hello from MSC 3\n");

To compile this I used Microsoft C 3.0 (more on why later), and used LINK4 to create an EXE:

C:\dos\msc3>cl /c hello.c
Microsoft C Compiler  Version 3.00
(C)Copyright Microsoft Corp 1984 1985

C:\dos\msc3>msdos dos4m\link4 hello.OBJ

Microsoft (R) 8086 Object Linker  Version 4.01
Copyright (C) Microsoft Corp 1984, 1985.  All rights reserved.

Run File [HELLO.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
Definitions File [NUL.DEF]

Okay, everything looks fine so far. Attempting to run this under MS-DOS just results in the error:

Program too big to fit into memory

Well now that’s odd. Checking the EXE with the Linux ‘file’ command reveals:

HELLO.EXE: MS-DOS executable, NE (unknown OS 0) (EXE)

So obviously it’s a NE, but it is an older/unknown version to the file map database. There is no stub so I suppose that is why MS-DOS is getting confused.

Now let’s try MS-DOS 4.00M


Well now isn’t that interesting?!

Excited with the ability to create special MS-DOS 4.00M programs, I get my favorite vintage ’87 Infocom interpreter, InfoTaskForce 87, and get it building on MSC 3.0. However instead of using the MS-DOS 4.00M linker, I thought I should try to use the Windows 1.01 linker and libraries for the exe:

C:\dos\msc3\infocom>msdos ..\win101sdk\bin\LINK4.EXE

Microsoft 8086 Object Linker
Version 4.00  (C) Copyright Microsoft Corp 1984, 1985

Definitions File [NUL.DEF] INFOW.DEF;

And for those interested this is my .DEF file:

NAME    Infocom

DESCRIPTION 'Infocom 87 interpreter for Planetfall(83)'


HEAPSIZE    1024        ; Must be non-zero to use Local memory manager
STACKSIZE   4096        ; Must be non-zero for SS == DS
                        ; suggest 4k as minimum stacksize


One thing to save you the horror is that between MS-DOS 2 & 3 the way command line arguments changed. I forget the details but no matter what I tried I was unable to parse the CLI or the environment in this setup. I suppose if I had documentation of the product there would be some hint as to what tools or setup to use. Instead, I took the easy way and hard coded to load Planetfall.

InfoTaskForce compiled with MSC 3.0, using Windows 1.01 libc / LINK4

Unfortunately, this success would prove to be the exception to the rule. I took trek, converted it to K&R C, as Microsoft C 3.00 from 1985 is well. old, and sadly it just won’t run. Likewise, I took Hack 1.03 and although it runs on MS-DOS it will not run on MS-DOS 4.00M. I am sure there is some fundamental reason why it’s not working, and probably tied to creating a proper DEF file. I’m sure it was all written down somewhere but I don’t know. And yes I tried specifying either floating point emulation via library or inline, and it made no difference.

Looking at OS/2 1.00

Loading up the infamous $3,000 OS/2 1.00 beta, and hitting ctrl+escape you are greeted with session manager!

Session Manager for OS/2

Notice the R for real-mode. With the obvious implication that everything else is protected mode. Going one step further on the excellent site there is OS/2 betas SIZZLE and although there is no OS/2 development bits on there, the directory DOS3TOOL reveals that the C compiler for this era for at least MS-DOS is MSC 3.0. Also included is our friend LINK4.

I create a simple def file that contains the single word ‘PROTMODE’ which should give me my OS/2 binary.

So let’s run that through hello world:

msdos sizzle\DOS3TOOL\link4  hello.OBJ,hello,,,hello.def;

Microsoft (R) Segmented-Executable Linker  Version 5.00.21
Copyright (C) Microsoft Corp 1984, 1985, 1986.  All rights reserved.


However attempting to run this just crashes amazingly.

Real mode LIBC in Protected mode:

No doubt it’s because the real-mode libc is using interrupt 21 calls, which OS/2 sure wouldn’t like. I’m pretty sure it requires an OS/2 libc that uses DOSCALLS.DLL to function, which I just don’t have any pre-release versions, nor any libc source code to really make it possible. And attempting to port one to OS/2 pre-releases just doesn’t seem so worth the time.

So for the heck of it I point the LIB variable to the OS/2 1.00 SDK’s libs and re-run the link:

C:\dos\msc3>msdos sizzle\DOS3TOOL\link4  hello.OBJ,hello.exe,,C:\86box\100\x\MSC\LIB\slibc5.lib \86box\100\x\LIB\DOSCALLS.LIB,hello.def;

Microsoft (R) Segmented-Executable Linker  Version 5.00.21
Copyright (C) Microsoft Corp 1984, 1985, 1986.  All rights reserved.

By default it’s trying to link in EM.LIB, SLIBFP.LIB, SLIBC.LIB. Trying to add them all in the command line link just hangs LINK4 maybe a response file is better suited. Anyways:

Hello from MSC 3.0 in protected mode.

It does run on OS/2 1.00, which I guess isn’t surprising as the LINK4 & libraries are from/for this version.

As an interesting note, OS/2 links against doscalls library/DLL to interface to the OS. While MS-DOS 4.00M doesn’t have a seperate DLL, rather it’s baked into IBMDOS.COM


Noticeably absent is file I/O, No doubt allowing programs to use the standard int21 interface to the kernel for file I/O. No doubt this is in its primordial state, as the OS was going to evolve a bit more until it became OS/2. Unfortunately I have no idea how to link or call into this. Without any SDK it’s impossible to say. And even then is developing for a real mode OS worth the effort?

So what have we learned? LINK4, aka the MS-DOS 4.00M Linker, probably should have been called LINKNE for the NE format. Also there is references to it having it’s own virtual memory paging system, and being able to link larger EXE’s than the traditional link command. Sadly I was unable to get any non trivial programs running. I don’t think it was a memory model thing, although the C compiler has issues with InfoTaskForce and the large memory model for some reason, but small & medium work fine. I’d like to think that DOS 4.00M could support massive EXE’s much like Windows 1.01, however despite being from the same company and using the same tools, the memory manager for DOS 4.00M & Windows is fundamentally different.

With all these exiting OS/2 betas now available I’ll have to take some more time to explore them in more detail.

But until then I thought this genesis of DOS 4.00M was worth the look. turns 20 years old today!

Stiletto had dropped on by to share this amazing milestone!

Today is the 20th anniversary of I was there helping to brainstorm it into existence in June 2000 at @bravenet on vladr’s VDMSound forums before @zetafleet hosted it, I registered for it on July 1st, and I helped give it its name and “theme”!

Follow the twitter thread here!

For the longest time VOGONS was the place to get information about VDMsound the sound blaster emulator for NTVDM, allowing a far more rich gaming experience on NT, DOSBox, the ubiquitous PC/MS-DOS emulator that is simply everywhere, and of course where I was ‘discovered’ via ‘Quake1 with WATTCP built with DJGPP on DOSBox‘ some 10+ years ago!

So happy 20th to VOGONS!

Citrix South Beach: aka the missing link from text to graphics

A long long time ago, in a distant continent I once interviewed at this small company called Citrix. It was some QA position, they didn’t need programmers. I’d passed the interviews easily as I’d been programming serial TSR’s so I was hip to the 8250/16450. Citrix was an interesting but troubled company. They had incredible contacts and more importantly a deal from Microsoft that gave them access to OS/2. Sadly OS/2 1.0 had been a dud, and by the time OS/2 2.00 saw even a limited release, Microsoft had pulled out of OS/2. Citrix was a company that had lost twice in what should be a big market. -Multi user commodity systems.

Citrix Multiuser 1.0 was based on OS/2 1.21, and was limited to 16bit protected mode apps. Citrix Multiuser 2.0 was based on the Limited Availability version which means that it cannot run “GA” or General Availability programs. So no 32bit programs here. Instead it can run the same 16bit protected mode applications, however it can also run MS-DOS based programs. DOS4/GW programs run so oddly enough the only real commercial stuff that can be run is MS-DOS.

So here we were 1994. Citrix had struck out twice, but this time it was going to be different, but the deal had to be re-struck again. I have no idea how they managed to secure this lucrative deal again, but Citrix was able to get access to the source access Windows NT, after the 3.1 release to 3rd parties (when they got DEC involved). By now the world had gone Windows, Office 4.2 was a thing, and on the high end side, NT had SQL & SNA, and there was most defiantly a market for multiuser systems as there had been from the old days of Unix, with the old mix of ASCII and network graphical terminals.

The CD looks like a normal-ish NT 3.5 Server CD although there is no MIPS or Alpha builds, as expected everyone at Citrix would be working and targeting the larger established i386 market.

As you can see this is Beta build 101.

In the text mode setup it looks like a normal setup program. No doubt they had better things to do than skins, wallpapers and themes. HOWEVER there is a silent IDE bug that many people will no doubt run into:

Although it works okay in short bursts, the IDE driver will send a command 28 zero byte and then shut down the controller. From this point it hangs. So that means we either need to generate all the floppy disk images (not going to happen!) or do the MS-DOS cross install. Yeah I’m doing that instead.

When setting up under Qemu, use the AMD PCNET card. It’s much easier. I set it to Twisted Pair, and PCI bus. I’m not sure if those matter all that much, but it works for me!

If you are going to use Hyper-V, you’ll need the GF100 NIC driver, but use the Windows NT 3.1 driver, as this is technically a beta of NT 3.5 and the production 3.5 driver will blue screen.

I set the driver to autosense.

I also had both Qemu and Hyper-V bluescreen when doing DHCP. I don’t know what the issue is, and I’m too old to care as I don’t have source code to South Beach, and even if I did I’d probably regret posting fixes. So static IP address it is!

Ready to login

Honestly again the air in the office when I was there is that everyone was running around like crazy to QA the product, and get ready to expand client support. While I was too much of an OS/2 fan boy, they certainly knew that from now on everything was going to be about Windows NT.

Logging into the Citrix the first fun thing to do is to define some remote terminals, using the WinStation app.

The first interesting thing is that async terminals are supported. Along with using either NetBIOS or Winsock protocols for connecting clients. Isn’t that great! TCP/IP built in!

Now for the crazy part. The only client that works is MS-DOS based. Yes there is no Win16, no Win32, no Java, no protected mode DOS, no Linux, SunOS, Solaris, DG/UX, AIX, HPUX, Xenix, UnixWare or SYSV i386ABI. ONLY Real Mode MS-DOS. Despite the connections being able to be ICA version 2 or 3, they are incompatible with newer Windows based clients from Win Frame.

This it the following list of supported protocols. Although I had Novell Lan WorkPlace and used it before for Desqview X, I can’t find it at the moment. good luck finding FTP TCP/IP, in retrospect it’s a terrible name, and for all intents and purposes it’s disappeared from the earth. So that leaves Microsoft TCP/IP. Now all the LANMAN clients have it, although this isn’t what it wants. It wants the MSCLIENT found in the “\CLIENTS\MSCLIENT\NETSETUP” path from a retail version of NT Server 3.5

The DOS client is.. very touchy. Deleting profiles can lead to a corrupted profile. Altering existing profiles well yeah can lead to a corrupted profile. I thought it was EMM386 causing issues but it locks up on it’s own.

Revenge of text mode UI

One interesting thing I found is that the text mode UI didn’t die. It’s still very much alive. As mentioned above you can connect async terminals, or even connect over the network!

Text mode does bring up a Program Manage analogue, but all my programs are graphical so it’s kind of moot. But rest assured text mode stuff works great.

PowerStation Oregon Trail

So 32bit Fortran stuff works great, what about MS-DOS?

Here is MS-DOS / Qbasic editor. Running on Citrix South Beach! Great, what about OS/2?

OS/2 F2C Dungeon

And here we go running the f2c translator through Dungeon to get an OS/2 text mode app. As you can see forcedos reveals that this isn’t a bound executable, instead it only runs on the OS/2 subsystem.

As you can see the os2.exe/os2srv components of the OS/2 subsystem

And of course it looks better on the graphical client to mix and match them all.

Win32/Win16/OS/2 all at once!

Indeed Word & Excel for NT work great alongside everything else.

Obviously somewhere post South Beach the text mode stuff dropped off. I’ll have have to dig for more, but it’s kind of neat the idea of a real text mode NT. Sadly South Beach doesn’t seem to like VMware. I haven’t dug too far, as I like WSLv2 so I’m stuck with Hyper-V. It may work fine on ESX I haven’t tested. Obviously you need the appropriate drivers, ill try to update links later, if anyone cares.

No doubt that finally Citrix was no positioned to realize the dream of multiuser commodity based hardware along with commodity applications. Of course it wouldn’t be all sunshine and rainbows, and no doubt there was a toll needing to be paid between Windows NT 4.0 and on the way to Windows 2000. But back in 1994, things were looking good!

Conventional RAM aka that old foe

640K ought to be enough for anyone. Well I’ve been poking around with an old beta that I had a long long time ago, lost, found, lost again, recovered, lost and found while looking for something entirely different again. I’ll spoil it later but anyways while messing around I needed a MS-DOS client, and it needs the MSNET TCP/IP stack, not to be confused with the LANMAN TCP/IP stack, and it doesn’t work with the Windows for Workgroups stack either. So yes I setup all 3, and of course found out that it really was the worst of the 3, the MSNET one.

Anyways convential memory is below 1MB. Back when the PC was new, it seemed that going from an Intel 8080 processor that could addresses a mere 64kb of RAM to the IBM PC that could address a whopping 1MB it seemed unlimited. A decision was made to segment the machine into 640kb for user programs reserving 384kb of RAM for hardware.

MSD memory map

And then something happened where drivers became user programs, and suddenly loading a mouse driver, CD-ROM driver, audio driver, networking stack and you have not enough memory available. Welcome to the living hell that was 1988-1995. In this virtual machine although it has 64MB of RAM in MS-DOS the largest free space with everything loaded is 366KB.

Microsoft Windows and DOS (among other products) started to include this fun tool MSD, Microsoft Diagnostics that would let you explore your memory, to see what was actually in use.

Imagine the absolute frustration here. 64MB of RAM, and yet there isn’t enough free to run a simple program. HOW ANNOYING!!!

Looking back at the MSD memory map, you may noticed from the map there is memory available, and possibly available. What does that mean? It means that there is no ROMS, or device RAM in use currently using that hardware reserved memory. Sadly for the 8088/80286 users they either don’t have a MMU, or one that only really works for protected mode segmentation. The 80386 however had a MMU sophisticated enough to let you map whatever you wanted where by booting MS-DOS into a protected mode environment and using v86 mode to map whatever you wanted where, by using the included program emm386.exe I’m sure plenty of others have touched on this program, and I’m going to just make a quick glance at it.

Typical PC memory map

If you look at a typical PC memory map you’ll find that location A000-AFFF is actually reserved for graphics memory. Since we are using VGA that also means B000-B7FF is also available. that means for text mode programs we can open up all this RAM for smaller program & driver use, along with the memory after the VGA BIOS, until the ROM BIOS of the computer that’s CC00-CFFF in my case, with D000-DFFF and E000-EFFF also being open. Obviously the fun comes in that not every PC has the same peripherals ROMS installed so this isn’t guaranteed to work in every instance.

In my case I don’t need EMS emulation at all I want to map it all to UMB or upper memory blocks for drivers and TSR’s. So I load emm386.exe into the config.sys like this:


I didn’t put in any exclusionary ranges as EMM386 figured it out all on it’s own in MSD, but you may need to specify ranges to leave alone.

This gives me 519KB of free conventional RAM. Oddly enough a lot of the networking stack moved itself into UMB without me having to do anything. It’s probably more so a function of the MSNET I used from a Windows NT 3.5 Server CD-ROM being dated 1994, so I didn’t have to play with the load high command.

Back when the PCem forum was up I had this config, although keeping in mind that although it was far more aggressive!

DEVICE=C:\DOS\EMM386.EXE 4096 frame=d000 x=a000-afff i=b000-b7ff x=b800-bbff x=c000-c7ff i=c800-cfff i=e000-efff ram
PATH C:\DOS;c:\windows

This got me a whopping 619Kb free in MS-DOS, along with 4MB of EMS, and 12MB XMS (on a 16MB config).

In the spirit of the old ‘Linking the linker‘ (I’m not certain that this is the actual article but it does certainly read the same way, didn’t Tim have 2 blogs?), I went ahead and claimed the video memory for the heck of it.

Using range A000-AFFF (64KB EGA/VGA Graphics RAM)

Obviously you cannot run graphical programs, but 605kb of conventional RAM, wish some 206Kb worth of network drivers! Not bad. I could probably squeeze a 32kb EMS frame in there, and get what would be an incredible 1-2-3 machine for the era. But I’m not such a big Lotus 1-2-3 fan anymore.

As always it’s 2021, and normal people will glance and WTF, you have 64MB of ram how can you be fighting for kilobytes. Anyone that used MS-DOS based networking will cringe and look the other way. These were not happy times.

In other news the client ran, sadly it’s too new for the server.

All in the Family

One of the more interesting things about OS/2 1.x is how it had this interesting idea of how to strattle the bridge between old and new, and it was a very common bridge tactic where you can have a shipping program that can simply run in both the older operating system, and the new one. Naturally there is trade offs, you can’t fully take advantage of all kinds of features on the new side, you will be largely held back on the old side, but all is not lost, there is space for things that fit in the ‘same but bigger’ world where you have an overlap between old and new.

For OS X, this was the Carbon era, for Windows this was the famous Win32s extensions, and for OS/2 it’s the Family API.

As a quick example, allocating memory under MS-DOS may be limited to 640kb, but under OS/2 you have access to so much more memory, the entire capacity of an IBM AT class machine. And this also got OS/2 tools into a lot of MS-DOS developer’s hands as the early compilers and tools were built around the Family API and were able to run on so called legacy environments. Although it was far better to run on OS/2, the advantage 30+ years later is that MS-DOS emulation is more common and prevalent than OS/2, especially on non x86 processors.

Ages ago I had done a very simple video memory dump of the Microsoft Programmer’s Library giving me electronic access to the old documents, and a few queries give these as the Family API building blocks:


  • DosAllocHuge
  • DosAllocSeg
  • DosBeep
  • DosBufReset
  • DosCaseMap
  • DosChDir
  • DosChgFilePtr
  • DosCLIAccess
  • DosClose
  • DosCreateCSAlias
  • DosDelete
  • DosDevConfig
  • DosDevIOCtl
  • DosDupHandle
  • DosEnumAttribute
  • DosErrClass
  • DosError
  • DosExecPgm
  • DosExit
  • DosFileLocks
  • DosFindClose
  • DosFindFirst
  • DosFindFirst2
  • DosFindNext
  • DosFreeSeg
  • DosGetCollate
  • DosGetCtryInfo
  • DosGetDateTime
  • DosGetDBCSEv
  • DosGetEnv
  • DosGetHugeShift
  • DosGetMachineMode
  • DosGetMessage
  • DosGetVersion
  • DosHoldSignal
  • DosInsMessage
  • DosMkDir
  • DosMove
  • DosNewSize
  • DosOpen
  • DosPutMessage
  • DosQCurDir
  • DosQCurDisk
  • DosQFHandState
  • DosQFileInfo
  • DosQFileMode
  • DosQFSInfo
  • DosQPathInfo
  • DosQVerify
  • DosRead
  • DosReallocHuge
  • DosReallocSeg
  • DosRmDir
  • DosSelectDisk
  • DosSetDateTime
  • DosSetFHandState
  • DosSetFileInfo
  • DosSetFileMode
  • DosSetFSInfo
  • DosSetPathInfo
  • DosSetSigHandler
  • DosSetVec
  • DosSetVerify
  • DosSizeSeg
  • DosSleep
  • DosSubAlloc
  • DosSubFree
  • DosSubSet
  • DosWrite


  • KbdCharIn
  • KbdFlushBuffer
  • KbdGetStatus
  • KbdPeek
  • KbdSetStatus
  • KbdStringIn


  • VioGetBuf
  • VioGetConfig
  • VioGetCurPos
  • VioGetMode
  • VioGetPhysBuf
  • VioGetState
  • VioReadCellStr
  • VioReadCharStr
  • VioScrLock
  • VioScrollDn
  • VioScrollLf
  • VioScrollRt
  • VioScrollUp
  • VioScrUnLock
  • VioSetCurPos
  • VioSetCurType
  • VioSetMode
  • VioSetState
  • VioShowBuf
  • VioWrtCellStr
  • VioWrtCharStr
  • VioWrtCharStrAtt
  • VioWrtNAttr
  • VioWrtNCell
  • VioWrtNChar
  • VioWrtTTY

I’m sure this is not exhaustive by any stretch. I got the list from a simple query like this:

grep -i 'family api' os2dev.txt | awk '{print $2}' > fam.txt
grep -i 'family api' prgmr[34].txt| awk '{print $3}' >> fam.txt
sort fam.txt | uniq > family.txt

As an added bonus you really don’t have to mess with the API at all, as the LIBC will use it no doubt.

At any rate, using Microsoft C 6.00 (I can’t get the syntax right for 5.1 to save my life, I suspect I need to run it UNDER OS/2 to build for OS/2 properly), you can compile a typical stdio compliant program, and get an OS/2 executable.

The real fun is from the bind program which will convert that OS/2 program to a full Family mode app with the bind program.

And now on MS-DOS (Under OS/2) you can see very quickly that the OS/2 app won’t run, however the family mode one does!

So this is what let’s me run the older SDK tools as I’d simply forgotten about this great mode, letting you run programs in either environment.

Of course the added fun is the 3rd party product Phar Lap’s 286|Dos-Extender that provides some OS/2 services under MS-DOS in addition to greater memory but DLL’s! But that’s for another story.

**EDIT Oh and another edit, here is how to make the OS/2 program ‘window’ compatible with a link time definition file:

OS/2 2.00 via telnet

and then on the console:

Window mode

And there we go with some magical flags & def file it’s now marked as being compatible with window mode. So no full screen VIO tricks for you!

Fun with VP/ix under INTERACTIVE UNIX 3.0

(This is a guest post by Antoni Sawicki aka Tenox)

This is a continuation of the vintage DOS/Windows hypervisors and emulators for Unix series. So far I have covered things like Merge, MergePro and Wabi. This time I’m taking a closer look at VP/ix. This early DOS hypervisor was developed by Interactive Systems Incorporated (ISC). Initially released and included with their INTERACTIVE UNIX System V/386 operating system it was also available for SCO Xenix 386, Sun 386i, AT&T WGS as Simul-Task 386. The last two versions were significantly enhanced to allow DOS/Windows graphical apps run in windowed mode, which unfortunately is not the case with IX and Xenix, where graphical apps can only run on the console. VP/ix was released around the same time as Merge in 1987 and it was its main competitor. Both products are early hypervisors, they use Virtual 8086 mode and require 386+ to run on. This is in contrast to SoftPC which is a full x86 emulator that can run on different CPU/architecture hosts.

VP/ix comes with ISC INTERACTIVE UNIX that is covered in my previous article. The product was installed as part of the 50 floppy disk set. You run it with an icon in Looking Glass environment or invoke from terminal or console via “vpix” command.

VP/ix comes with it’s own custom version of MS-DOS 3.30. It allows a variety of cross unix/dos enhancements such as shared disks, automatic dos/unix file format conversion, listing unix attributes from dos as well as running unix commands from dos and vice versa. One of super cool features is that you can pipe output of DOS commands to Unix command, for example:

C:\> dir | wc -l

…will do a DOS dir and pipe it to Unix wc command. You can map Unix paths to DOS drives:

VP/ix has an interactive Menu invoked by SYSRQ + ‘m’ key:

You can load floppy disks, turn sound on/off, restart/quit or run unix shell.

As for running normal text mode apps it’s business as usual:

Multiple instances of DOS can be launched and files shared between them. Also if you are a different user on different terminal or connected remotely. Remote terminal also supports mapping dos line characters to ASCII.

The same however cannot be said about graphical DOS or Windows apps. Under INTERACTIVE UNIX and Xenix you need to run them from the text mode console:

One day I will probably want to look at VP/ix on Sun 386i or AT&T WGS as they solved this problem. Newer versions of Interactive Unix (4.x) and VP/IX also need to be investigated.

According to the documentation, you can run Windows 3.x in real mode using win /r however I did not have patience to install this.

INTERACTIVE UNIX 3.0 with VP/ix preinstalled can be downloaded here for 86Box or VBox OVA, however the later does not have networking and resolution is only 800×600. Login as root/root. When importing OVA in Vbox you may need to disable import as VDI. For 86Box version please read readme on how to circumvent licensing error.

Also VP/ix for SCO Xenix is available here.

Have fun with virtualization!

Fun with OpenServer 6 and MergePro

(This is a guest post by Antoni Sawicki aka Tenox)

In a recent post about OpenServer and Merge I covered OpenServer 5 and Merge 5.3. Thanks to a comment from Uli I have learned about MergePro which looks like is a rebranded Win4Lin. Intrigued I wanted to try it especially that you can download it from SCO ftp server as Uli pointed.

I’m going to be using VMware Fusion on Mac, which is now free for personal use. They call it Fusion Player, however unlike Workstation and Player, it has exactly same features as non-free Fusion version. For the OS I’m going to use Xinuos OpenServer 6 Definitive, however you can easily download OpenServer 6.0.0Ni from the ftp. I also have copies in my archive.

Installation is straightforward. You can skip licensing and use evaluation license, however for convenience you can use following keys:

Xinuos OpenServer 6D2M1: SCO053269 / ejcaagmy
SCO OpenServer 6.0.0Ni: SCO398943 / ysloudwl

If you are installing 6.0.0Ni you will also need MP4 update. 6D2M1 is already patched.

To install MergePro you need to copy this package to the host os and install like so:

# pkgadd -d /tmp/

In the following step, mount Windows 2000 or XP SP1 or SP2 ISO and run:

# loadwinproCD

Once Windows is loaded you need to install it as a non-root user using:

$ installwinpro

After it’s installed, to run you type:

$ winpro

Unfortunately I have failed to install Windows XP with variety of errors and blue screens. Windows 2000 works fine, however it feels bit sluggish and mouse click doesn’t always register. It looks like there are some sort of Windows Guest Additions being injected in to the OS so one would expect this to work just fine.

During startup I have noticed that MergePro installs and uses KQEMU kernel module. Also this screen looks suspiciously familiar… where did I see this before?

The BIOS and VGABios look definitely stolen from Bochs. HDD controllers look like Win4Lin. I’m not going to go in to deeper analysis of what MergePro is made of at this time. Looks like a topic for another article or even better – your comments 🙂

Also if you want to license the copy of Merge use following key:

MergePro 6.3.0f: SCO138318 / bhtecusg

Finally for the lazy here is fully installed OVA, password is root/root and tenox/tenox for the regular user.

UPDATE: Thanks to reader Larbob we now know that you can install any guest OS, on MergePro not only Windows! Use installwinpro -c /dev/cdrom/cdrom1 -w winxppro to boot the cdrom without checking what OS is actually on it. Here is a screenshot of Solaris x86 being installed on MergePro on UnixWare:

So.. you could install UnixWare as a guest VM under OpenServer or vice versa??

Thank you!