I’ve decided to write a 16-bit Windows emulator. It’s a bit of crazy idea, but hear me out…
A couple of weeks ago I upgraded my partner Jen’s PC to 64-bit Windows. It all was going well until she went to play some Windows 3 card games that she enjoys when we realized that 16-bit programs don’t work on Windows x64.
So I installed a copy of 32-bit Windows on a VM and that works, but it got me thinking…
What would it take to write an emulator with just enough support to run these old games?
I’ve written a couple of emulators before and while they’re a ton of work, they’re also a great learning experience and the kind of challenge I really enjoy.
I particularly like the idea of this project because:
- it’s different enough that I’ll learn something new,
- it’s got some really tricky challenges,
- it’s not been done before (that I’m aware of) (and don’t care if it has) and
- there’s a slim chance it might actually be useful — even if only for Jen.
Besides, who doesn’t love a fairly pointless super geeky side project?
How would it work?
The basic idea is to write a program that can read a 16-bit Windows executable file, run it on an emulated CPU and map any 16-bit API calls that it makes onto the x64 equivalents.
- It’s like DosBox in that it’s emulating the CPU — but unlike DosBox in that it’s not emulating other low level hardware.
- It’s like Wine in that it’s emulating the Windows API — but unlike Wine in that the CPU is emulated instead of running on a physical processor (remember Wine stands for “Wine Is Not an Emulator”).
- It’s not like VirtualBox or VMWare or other virtualization software as it’s not emulating or virtualizing low level hardware.
In other words, even though it’ll include an emulated CPU to execute the 16-bit code this is more about emulating the operating system than the hardware.
The nice thing about this approach is that the 16-bit program will appear just like a regular Windows program — it’ll get its own entry in the task bar and you’ll be able to Alt-Tab to/from it just like any other program. It won’t be constrained to the walls of a virtual machine.
The down side is that the Windows API is massive (but I should only need to implement a subset of it).
Proof Of Concept
So far I’ve managed to get a proof of concept working that can run two really simple 16-bit programs. The first simply displays a message box and exits.
The second is essentially the “HELLOWIN.C” program from Chapter 1 of Charles Petzold’s classic book Programming Windows. It creates a window with a title, draws some text, can be resized, maximized, minimized and shuts down cleanly when closed.
Here’s how it looks on Windows 3:
And here’s the exact same .exe file running under the emulator on Windows 10 x64 with emulated CPU instructions being logged in the background.
That doesn’t look like much but there’s a fair bit going on there — enough for me to realize that this might actually work.
I’m still a fair way from getting those old games up and running, but I thought a series of articles about it would be interesting. If you remember the joys of segment arithmetic, MakeProcInstance and LocalLock you’ll especially appreciate this project.
What do you think: have I lost my mind or is this something worth pursuing?