Apparently talking about DOS Extenders is too hot for Twitter: AKA Phar Lap 386

I had a small twitter account, and I tried not to get dragged into anything that would just be basically wasting my time. Just stay focused and on topic. FINE. I just wanted to see if anyone ever saw it, if it was even worth the effort of doing WIP’s as I didn’t want to make it super annoying.

I logged on to post a fun update that I’d finally gotten a Phar Lap 386 version 4.1 app to do something halfway useful, the sairen AGI interpreter up and running in the most basic sense.

Talking about DOS Extenders is spammy and manipulation!

I don’t get what triggered it, but oh well there was a ‘have a review’ and yeah that was fine. Great. So I’m unlocked so I go ahead and post with the forbidden topic, as I’m clearly dumb, and forgetting that Twitter is for hate mobs & posting pictures of food, and cat pictures.

The Sairen AGI interpreter built with Watcom 386/7.0 & Phar Lap 386 4.1

So yes, that was a line too far, and now that’s it.

Now some of you may think, if you buy ‘the plan’ you’ll no doubt be exempt from the heavy hands of Twitter

3 squids a month

But I already was and had been for a while.

Your account is suspended

So that’s the end of that. I guess it’s all too confusing for a boomer like me.

Cancel me, cancel you

So needless to say I cancelled Twitter as well. Kind of sneaky they didn’t auto-cancel taking money.

So yeah, with that out of the way, let’s continue into DOS Extender land. I added just enough 386 magic, onto github: neozeed/sarien286. Yes I see now it really was a poorly named repo. Such is life.

There is 3 main things for porting old programs where they take care of all the logic, it’s going to be File I/O, Screen I/O, and timers. Luckily this time it was easier than I recalled.

Over on usenet (google groups link) Chris Giese shared this great summary on direct memory access from various methods:

/* 32-bit Watcom C with CauseWay DOS extender */
int main(void) {
char *screen = (char *)0xA0000;
*screen = 1;
return 0;

/* 32-bit Watcom C with DOS/4GW extender
(*** This code is untested ***) */
int main(void) {
char *screen = (char *)0xA0000;
*screen = 1;
return 0;

/* 32-bit Watcom C with PharLap DOS extender
(*** This code is untested ***) */
#include <dos.h> /* MK_FP() */
int main(void) {
char far *screen = (char far *)MK_FP(PHARLAP_CONVMEM_SEL, 0xA0000);
*screen = 1;
return 0;

/* 16-bit Watcom C (real mode) */
#include <dos.h> /* MK_FP() */
int main(void) {
char far *screen = (char far *)MK_FP(0xA000, 0);
*screen = 1;
return 0;

It is missing the Phar Lap 286 method:

/* Get PM pointer to text screen */

But it’s very useful to have around as documentation is scarce.

Which brings me to this (again?)

Phar Lap 386|Dos-Extender 4.1

Years ago, I had managed to score a documentation set, and a CD-ROM with a burnt installed copy of the extender. I didn’t know if it was complete, but of course these things are so incredibly rare I jumped on the chance to get it!


Unfortunately, I didn’t feel right breaking the books apart, and scanning them, then add in some bad life choices on my part, and I ended up losing the books. Fast forward *years* later and Foone uploaded a document set on GREAT! As far as I can tell the only difference in what I had is that I’ve got a different serial number. Thankfully I was smart enough to at lest email myself a copy of the CD-ROM contents! And this whole thing did inspire me to gut and upload the Phar Lap TNT 6.0 that I had also managed to acquire.

Although unlocking the video RAM wasn’t too bad, once I knew what to do, the other thing is to hook the clock for a timer. ISR’s are always hell, but at least this is a very simple one:

void (__interrupt __far *prev_int_irq0)();
void __interrupt __far timer_rtn();
int clock_ticks;
#define IRQ0 0x08
void main()
   //get prior IRQ routine
   prev_int_irq0 = _dos_getvect( IRQ0 );
   //hook in new protected mode ISR
   _dos_setvect( IRQ0, timer_rtn );

/* do something interesting */
   //restore prior ISR
   _dos_setvect( IRQ0, prev_int_irq0 );

void __interrupt __far timer_rtn()
    //call prior ISR
    _chain_intr( prev_int_irq0 );

The methodology is almost always the same, as always, it’s the particular incantation.

So yeah, it’s super simple, but the 8086/80286 calling down to DOS/BIOS from protected mode via the int86 just had to be changed to int386, and some of the register structs being redefined. I’m not sure why but the video/isr code compiled with version 7 of Watcom, but crashes. I think its more drift in the headers, as the findfirst/findnext/assert calls are lacking from Watcom 7, so I just cheated and linked with Watcom 10. This led to another strange thing where the stdio _iob structure was undefined. In Watcom 10 it became __iob, so I just updated the 7 headers, and that actually worked. I had to include some of the findfirst/next structures into the fileglob.c file but it now builds and links fine.

Another thing to do differently when using Watcom 7, is that it doesn’t include a linker, rather you need to use 386LINK. Generating the response file, as there is so many objects didn’t turn out too hard once I realized that by default everything is treated as an object.

Another fun thing is that you can tell the linker to use the program ‘stub386.exe’ so that it will run ‘run386’ on it’s own, making your program feel more standalone. From the documentation:

386 | LINK has the ability to bind the stub loader program, STUB386.EXE, to 
the front of an application .EXP file. The resulting .EXE file can be run by 
typing the file name, just like a real mode DOS program. The stub loader 
program searches the execution PATH for RUN386.EXE (the 

386 | DOS-Extender executable) and loads it; 386 | DOS-Extender then loads 
the application .EXP file following the stub loader in the bound .EXE file. 

To autobind STUB386.EXE to an application .EXP file and create a bound 
executable, specify STUB386.EXE as one of the input object files on the 
command line.

So that means I can just use the following as my linker response file.

words.obj,picview.obj stub386.exe
-exe 386.exe
-lib \wat10\lib386\dos\clib3s.lib \wat10\lib386\math387s.lib
-lib \wat10\lib386\dos\emu387.lib

It really was that simple. I have to say it’s almost shocking how well this went.

So, this brings me back, full circle to where it started, me getting banned for posting this:


I thought it was exciting!

For anyone who feels like trying it, I prepped a 5 1/4″ floppy disk image.

running on 86box, 386DX-40 CGA graphics

One interesting observation is that the 386 extender is actually smaller than the 286 one. And being able to compile with full optimisations it is significantly faster.

16bit on the left, 32bit on the right.

I ran both the prior 16bit protected mode version (on the left), and 32bit version (on the right), on the same IBM PS/2 80386DX 16Mhz machine. You can see how the 32bit version is significantly faster!.

I really should profile the code, and have it load all the resources into RAM, it does seem to be loading and unloading stuff, which considering were in protected mode, we should use all ram, or push the VMM386 subsystem to page, and not do direct file swapping, like it’s the 1970s.

Phar Lap’s 286/DOS-Extender: why nobody used it for games

Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.

-Ian Malcolm

Ever since I got my first 286 board way back in the early 90’s (1990? 1991?) I have been intrigued by the whole protected mode of operation. Unfortunately, in the era the required tools were way out of my reach, and of course were not available at retail. But now I live in the future where I have all the parts! Let’s look at the needed parts

I have to once more again thank my patrons, and people tolerating the google ads as it made all the difference in being able to buy all this stuff. And now is as good a time as any other to put it all together.

I stumbled upon this repo on sourceforge, Sarien. It included a Turbo C++ port, which is pretty exciting! So, this became my goal, get Sarien running on Phar Lap 286.

Installing Microsoft C 6.0a

Installing Microsoft C requires you to pick and choose both hosting, targeting environments, along with what the preferred libraries are. In the business we call this foreshadowing as this can be such a giant PITA. At least virtual machines are fast, plentiful, and cheap. In addition I had been using MS-DOS player to host the tools on Windows 11. This of course proved weird later.

The first step was getting it running on MS-DOS using Microsoft C 6.0a. This was actually pretty easy, the hard part was working out the makefile, as some files don’t compile with optimisations. And overall, the project doesn’t seem to work with /Ox at all. I haven’t spent enough time mixing and matching settings to find what actually doesn’t work, but I’m in a hurry, and /Os seems to work just fine.

In no time I had both the CGA & VGA drivers up and running and verified working on my PS/2. Great!

Now comes the fun, getting it ready to run on Pharlap.

The magic!

Phar Lap’s 286|DOS-Extender is pure magic. A DOS extender is a special program that can load a protected mode program into memory on a 286 or better computer and run it. At it’s heart, it can proxy MS-DOS functionality from protected mode to real mode, allowing you to use a lot of methodology and code from traditional real mode code. Phar Lap, goes beyond that by providing a pseudo OS/2 1.2 environment on MS-DOS, including advanced features like DLL’s, and being able to use ALL the RAM in your computer. Of course on the 286 there is a massive caveat:

The 286 has no built-in function for switching from protected mode to real mode. This makes programs that rely a LOT on MS-DOS potentially very slow. You can absolutely feel the difference between the real mode and the protected mode version of Sarien.

Phar Lap does include a test program, swtest which can benchmark the switching methods, so let’s run it and get some scores.

Switch code version = 1.14
BIOS signature: BA66CC86
BIOS date: 02/13/87

Machine ID = 0, A20 method = PS2, Reset method = Standard
Starting test for Switch Mode 3 (SLOW) ... Test complete.
Avg switch time (usecs): To prot = 34, To real = 101, Total = 135
Min switch time (usecs): To prot = 32, To real = 98, Total = 130
Max switch time (usecs): To prot = 35, To real = 103, Total = 138

Machine ID = 0, A20 method = PS2, Reset method = Standard
Starting test for Switch Mode 2 (AT) ... Test complete.
Avg switch time (usecs): To prot = 34, To real = 86, Total = 120
Min switch time (usecs): To prot = 33, To real = 83, Total = 116
Max switch time (usecs): To prot = 36, To real = 88, Total = 124

Machine ID = 0, A20 method = PS2, Reset method = Standard
Starting test for Switch Mode 1 (SURE) ... Test complete.
Avg switch time (usecs): To prot = 34, To real = 70, Total = 104
Min switch time (usecs): To prot = 32, To real = 68, Total = 100
Max switch time (usecs): To prot = 35, To real = 72, Total = 107

For those of you wondering what the timing is like on a 386, here is my 16Mhz PS/2 Model 80 board (now with fully 32bit memory)

Switch code version = 1.14
BIOS signature: 039D2DB4
BIOS date: 03/30/87

Machine ID = 0, A20 method = PS2, Reset method = Standard
Starting test for Switch Mode 5 (386) ... Test complete.
Avg switch time (usecs): To prot = 31, To real = 22, Total = 53
Min switch time (usecs): To prot = 30, To real = 20, Total = 50
Max switch time (usecs): To prot = 32, To real = 23, Total = 55

I’m honestly surprised the 286 switches from protected back to real so quickly! Although as you can see from the 386 timings it’s significantly faster than the 286.

Here is a quick video, real mode on the left, protected mode on the right. Yes I need to get a VGA capture card. Sorry.

Real mode on the left, Protected on the right. Running on the 386

Being a DOS extender it does have built in functions for things like hooking interrupts like this:

    /* install our new timer tick routine */
    DosSetPassToProtVec(IRQ0, (PIHANDLER)new_prot_timer_tick,
        &old_prot_timer_tick, &old_real_timer_tick);

Unlike some kind of OS/2 method which would involve creating a thread and or timers.

Setting video modes via the video BIOS is also supported, using the built in int86 style calls:

    r.h.ah = 0; = 3;
    int86(0x10, &r, &r);

Using pointers into things like video ram do require ‘asking for permission’ but it’s not too involved:

    int rseg;
  /* Get PM pointer to text screen */

with the segment mapped, and a pointer to the segment, and now I can read/write directly into video RAM!

  /* save text screen */

Just like that!

I’m not sure what I screwed up on the VGA graphics, as it doesn’t work correctly, but oddly enough CGA does work.

And now this is where everything goes off the rails.

Sairen running on Qemu & DOSbox

It ran fine on emulation. So all excited I fired up the PS/2 and….

General protection fault

This lead me to more fun in how on earth to debug this. Of course Phar Lap 286 version 2.5 requires me to have Microsoft C/C++ 7.0. I shamelessly downloaded a disk set from You actually need to install it, to copy out the files required:

  • 28/05/1991 05:37 pm 47,216 CFIG286.EXE
  • 26/11/1991 11:19 am 13,531 GORUN286.EXE
  • 19/03/1992 04:00 am 42,720 shw0.dll
  • 19/03/1992 04:00 am 105,039 eew0cxx.dll
  • 19/03/1992 04:00 am 410,112 cvw4.exe
  • 19/03/1992 04:00 am 91,118 eew0can.dll
  • 19/03/1992 04:00 am 74,400 emw0w0.dll
  • 03/08/1992 09:34 pm 2,649 INT33.DLL
  • 03/08/1992 09:40 pm 2,718 MSG.DLL
  • 03/08/1992 09:40 pm 1,702 NAMPIPES.DLL
  • 03/08/1992 09:42 pm 2,073 NLS.DLL
  • 03/08/1992 09:43 pm 5,184 PTRACE.DLL
  • 03/08/1992 09:45 pm 2,320 SESMGR.DLL
  • 03/08/1992 09:50 pm 1,508 WIN87EM.DLL
  • 05/08/1992 12:04 am 3,100 KEYBOARD.DLL
  • 05/08/1992 06:33 pm 270 TOOLHELP.DLL
  • 14/08/1992 07:38 pm 7,891 KERNEL.DLL
  • 14/08/1992 09:40 pm 14,545 USER.DLL
  • 09/09/1992 10:59 pm 209,922 RUN286.EXE
  • 09/09/1992 10:59 pm 229,046 RUN286D.EXE
  • 14/09/1992 11:01 pm 14,024 TLW0LOC.DLL
  • 17/09/1992 07:26 pm 34,152 CVP7.EXE

While CVP7 does come with Phar Lap, you have to run it via run286. As you may have noticed there is a mixture of OS/2 and Windows DLL’s in here, as at this point CodeView was a Windows protected mode debugger. The divorce was in full swing, and Microsoft C/C++ 7.0 had amputated the majority of OS/2 support. I’m sure all this is in the manuals, however all I have is disk images. There was no C 6.0a supported hosted debugger. Maybe it’s in the v1/v2 of Phar Lap 286, but I only have 2.5. There is version 3 files on the internet but I wanted to stick to 2.5.

Exception #13

And this is all I got. Yes, I did recompile with ‘/Od /Zi’ along with using cvpack on the executable. Yes, after copying the source to the PS/2 I was able to see the source line mapping, but it immediately jumps to assembly and GP Faults. All this is fine, but IT RUNS UNDER EMULATION.

What is going on?!

I asked around on discord, and found someone willing to test on their 286. It also crashed. I tried VMware and .. it crashed too! So did 86box! Ok now we’re going somewhere!

Since I had been using MS-DOS player to run the tools, I had an issue with the linker in C 6.0a crashing, so I tried the one from C/C++ 7. It also didn’t work. I tried the one from Visual C++ 1.5. It also failed. Almost giving up on the entire thing, since I had copied the source code to the PS/2, I tried something really silly, I compiled it using the /qc or QuickC flag. I wasn’t too worried about sizes as again I’m going to run in protected mode. It took some 20-30 minutes to compile, as 10Mhz machines are not the best for building software in this modern age. Much to my surprise it actually ran.

First run!

This was kind of shocking as I’m not sure what I screwed up to not get this to work, but it worked! I went ahead and changed the build to not use QuickC, but rebuild with /Os (Optimize for space). It took about an hour. And it too worked.

Phar Lap 286 running on OS/2 2.00 on VMware

Shockingly it runs! I’m not sure what on earth is up with the linking. I did find it easier to just rebuild on Qemu since it can easily map into my source directory and copy everything over and re-build very quickly.

Later I did try copying over compiled objects built using the MS-DOS Player, and linked them natively, and they ran fine.

What is it with the LINK?!

It all fits! Stacker rules!

One weird thing on 86box is my pre-built machine I was using has a 5 1/4″ 1.2Mb floppy for the A: drive. It’s too small to fit MS-DOS, the game data and Phar Lap 286 all on there. Although Stacker to the rescue and it fits!

It can save and even load those saves!

I removed a lot of Unix quality of life, to make it more MS-DOS dumping everything in the same directory so you can save & load games.

Assuming anyone is interested in this at all, I have the source up on github. I’ll follow up with some performance videos showing how much slower real vs protected mode is, along with some binaries/demos. A 5 1/4″ floppy disk image can be downloaded here for any suitable emulator.

Zork for the PDP-11 / RT-11 recreated

I know this is a weird one, but I’ve always wanted to run Infocom games from ever since I found out it was a thing.

The cover of the RT-11 Zork that sold on ebay for $2,348.31

I know you maybe thinking of the FORTRAN port of the full Zork game, which does run on the same system. But this is NOT the FORTRAN reverse engineered game, rather it’s a port of the Z-Machine to the RT-11 / PDP-11.

Also this is NOT a 3rd party reverse engineering effort, it is the official Infocom Z-Machine source.

;       Proprietary documentation of:
;               Infocom, Inc.
;               55 Wheeler St.
;               Cambridge, MA 02138
;       Copyright (C) 1982, 1983 Infocom, Inc.  All rights reserved.

Yes it’s the real deal!

Ok so what or where to do this?! First you need SIMH or any other good PDP-11 emulator, a copy of RT-11, and of course the source to the interpreter oddly enough named PDP11.ZIP. Just keep in mind that this is NOT a pk-zip file, it’s a text file. It’s Macro-11 assembler source.

First you need a very simple config/type in to the SIMH PDP-11 emulator:

attach rk0 rtv4_rk.dsk
attach ptr
boot rk

All being well you should boot into RT-11.

Now we copy the source into the machine through the paper tape reader. Just type in ‘COPY PC: ZIP.MAC’

 Files copied:
PC:            to DK:ZIP.MAC


This will create a .mac or macro assembler source file. The extension matters as it will tell the compiler what file it is and what to do. But luckily this is a single file, and assembles quite easily. As a tip to Unix folk, I found that making the assembly source in MS-DOS CR/LF made life easier.

Compiling & linking is very straightforward




Now we need to import a game file. I usually test with Planetfall, so I grabbed the data file, and placed it into the working directory and then attached it to the emulator

Simulation stopped, PC: 152644 (BR 152622)
sim> att ptr planetfa
sim> c

 Files copied:
PC:            to DK:PLANET.IML


Notice the filenames are short, very 8.3 for some strange coincidence! Also I named it planet.iml, as that is what the interpreter is expecting. Now we can just run the zip and point it to the game data file!

Line width (default is 80, end with LF for status line):
File name (current default is DK:$GAME$.IML) *dk:planet.iml
Infocom interactive fiction - a science fiction story
Copyright (c) 1983 by Infocom, Inc. All rights reserved.
PLANETFALL is a trademark of Infocom, Inc.
Release 37 / Serial number 851003

And there we go! We are now running Planetfall on our simulated PDP-11!

There is quite a few great 80’s systems in the github repository, I have no doubt the rest can be built, but I thought I’d tackle a system that was another bigfoot, a thing of pure legend!

Knights of the Old Republic PowerPC

I just scored a G5 iMac for £20 with a damaged panel. It doesn’t bother me at all as I’m not going to use it for anything serious, I’m just wanting something mainstream.

I did want one thing which was KOTOR.

So I looked up eBay, and yeah turns out it’s a collectors thing?

£147!! No way!

I saw this for far less, the Star Wars Mac Pack!

vBut at the flip side had this ominous warning….

Intel only

I thought I’d just try the disc anyway.. nothing to lose?


and yeah, not only is KOTOR is PPC, but yes it does run on OS X 10.4!


granted it’s on steam, gog and of course available for pretty much anything modern. And sure yeah, it was originally PC/Xbox, but for some odd reason I’m feeling nostalgic for that last gen PPC.

Stadia controllers can be re-flashed to generic PC controllers

Stadia controller

So I saw this controller for sale for 20. I figured that there ought to be a way to hack it to do something useful so it may be fun. Turns out all it needs is a re-flash of new firmware and it’ll become a generic controller.

All you need to do is peer it to your computer, go to and follow the prompts.

You might be slightly scared that the browser can talk directly to bluetooth devices, including the unlock, and re-programming the controller.

And yeah after that it’s all unlocked and good to go!

Not sure if it matters all that much, but for anyone wanting either a controller on the cheap, or if you bought into Stadia when it was a thing (did anyone remember other than the announcement and the expected cancellation?).

I guess it’s nice that google is providing an unlock service but I’m sure that won’t be around forever, so yeah. yay.

Today is Starfield day!

And there is a map of all the locales and when the launch. I was busy working and didn’t notice that Hong Kong had already launched.

many geo zones!

Thankfully I did get a payment voucher which fully covered the super fancy edition. Sadly there was no option for GPU’s so I’m going to try this with an OG 6GB GTX Titan.

It was a bit weird to figure out if I could run the game or not but I did get a pop up that today was the day so I guess so.

0% verified

I’ll have no choice but to update as it goes, so nothing yet to report.

I’m just hoping it’s not the hollow world experience of Fallout 76.

After all that downloading, turns out it doesn’t like my video card at all.

So yeah GTX 1070ti minimum. wow.

So I abused a work machine that ironically has a decent mobile GPU. swapped some storage and booted into the game, played a few hours.. And yeah

Old tyme Bethesda quality

When |I could, I took a detour to Earth’s moon, and went out for a walk. Naturally there was a base less then half a click away, and naturally it had 30 insurgents automatically hostile. What a vast but populated world. And then the NPC following me around suddenly took off her space suit, and broke the whole thing. I wanted to maybe get an ARC but apparente it doesn’t run at all on ARC. Seems kinda fishy to me tho. NVIDIA released a new driver like today for the special launch. I don’t know if there will be any fallout.

SimCity for Unix Liberated

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

In early 90s DUX Software ported SimCity classic UNIX. They provided downloadable demo versions for SunOS, Solaris, HP-UX, SGI IRIX, OSF/1, Digital Unix, OpenDesktop, UnixWare, Linux and BSD.

SimCity SGI IRIX screenshot from DUX website

In the winter break wave of nostalgia I wanted to play SimCity on my vintage HPUX workstation. Unfortunately the 5 minute demo just wouldn’t cut it. Back in 1993 you could simply purchase a license key and unlock the demo to a full version. However even if I could find an old license code, these keys were “Host ID” locked, so you could not easily use it on a different machine anyway.

In 2008 SimCity Classic has been open sourced under a new name Micropolis for the OLPC project. This was truly epic endeavor, many thanks to everyone involved. Unfortunately for vintage computer enthusiasts, the source code been updated to compile on a modern Linux, before it was released to the public. It will no longer build on any old Unix system. Typically, when a developer decides to free up their obsolete version, they just toss out some licenses codes. Sadly this time no one ever bothered.

The only option left was to bypass the license checking code. Fortunately, modern binary analysis tools make patching old apps relatively straightforward. In just minutes I was able to get the game started in a full multiplayer mode. A few hours later I got it patched on all the vintage Unix platforms!

SimCity on Solaris 7 (also works on 8 and 9)
SimCity on HP-UX 9 (doesn’t work on 10 or 11 due to TCL/TK issues)
SimCity on OSF/1 aka Digital Unix aka Tru64
SimCity on IRIX 5.3 on MAME (doesn’t work on never IRIX due to COFF binary)
SimCity on SunOS 4.1.4 on QEMU
SimCity on SCO OpenServer / OpenDesktop (ODT)

UPDATE: patched IRIX as well! Special thanks to Mr^Burns for providing a preinstalled IRIX 5.3 MAME image!

UPDATE: patched SunOS version as well. Special thanks to Daghdha for preinstalled SunOS 4.1.4 QEMU image!

UPDATE: patched SCO Unix/ODT version as well.

You can download the demo versions and patches here. Happy gaming on your vintage Unix Workstation!

If you just want to try the game without bothering with an ancient unix, you can simply sudo apt install micropolis && micropolis on a modern Linux – it’s identical except for multiplayer