retrowin32, two years in

September 12, 2024

This post is part of a series on retrowin32.

It's been just about two years since I left my job. The Saturday after my last day I opened up my laptop and, without before even considering this idea up to that point, spontaneously decided to try writing a Windows emulator to run an old program I loved.

I didn't know much of anything about how emulators work. I could read the occasional x86 assembly when debugging things but I had never written much of it. I worked with programming Windows a bit a few times over my professional career but I am far from an expert. But overall, how hard could it be, right?

The truth is that there is kind of a lot of detail to all of it. But also, detail ultimately just means it is a slog. x86 has a scrillion opcodes to implement, win32 has scrillion APIs, but the path from zero to a scrillion starts with a step like any other.

I picked up this project with the explicit intent to just follow my interest wherever it led. I was inspired in part by this thread: "Good things happen when I try hard to chase my sense of excitement, ignoring impulses to produce legible outcomes." I think that observation about legibility really reached me. I went through a period in the past where I found I was only reading books that I felt like I ought to be reading and had ultimately been killing my enjoyment of reading, and I was trying to recover that feeling about programming.

I haven't been employed since, in part due to having a hard time as a parent. This is a larger topic for another post, but my son has been a lot; there was even a period where his preschool was having me come in for two hours a day to help manage him. I remain mystified how parents manage careers and children simultaneously, even with easy children. I also try to rationalize that, to the extent I can afford it, if there was ever a time to be there for him it is now.

Does it really take two years to make a not particularly complete emulator? Looking over my commit logs it seems like I only even made commits for about 85% of the weeks I've been working on it, and many other weeks there's only been a few random touches. I have had plenty of other distractions, including video games (I beat Factorio's Space Exploration with some friends, which either means nothing to you or which will impress you a lot), other projects on the side (like my build system experiment, which has since been forked by Android!), vacations, and so on.

Two years in, one thing I have been reflecting on is where I am going with this project. At some point I ought to call it complete, or abandon it. As long as it remains interesting to tinker with I intend to tinker, but I also am well aware of the feeling an unending project that starts to feel like a burden. I am not there yet but I am watching for the signs.

When I first started I imagined the project would be somehow tying my WebAssembly experience into x86 emulation. It turns out that for various reasons JITting into Wasm isn't the most important piece (though the cheerpx people do it) and I never got there. Similarly, my memory of the demoscene — the above program that spawned the whole project is from that world — is from the 90s and I had kind of imagined there would be a rich collection of interesting 2d Windows programs from there. This turned out to not be true. I discovered there are a lot of 2d DOS demos but once Windows came around the demoscene started adopting 3d APIs relatively quickly, and I am not particularly interested in 3d graphics, in part because the look of 90s 3d demos hasn't aged well to my eyes. In other words, the demoscene I had thought I started this project for may have existed only in my imagination.

But at least for now I can say I accomplished something — I got at least the first scene of that original demo working! (Looking now I haven't updated the website to show this; maybe something to do after this post.) The very last bug fix was that I had flipped some math backwards in my MMX implementation. Also, had I known I would need to implement some of MMX, would I have even started this project? Not even sure. I have seen it observed that sometimes not knowing how hard something will be is an important help to actually just starting to try.

The other surprising accomplishment is that after nearly two years of working on it solo (though to properly credit, I've had some really great advice from Dean and Nico!) recently I have had a few contributors show up. In particular somehow the group behind this project found me because they want to run old Windows compilers on Linux cloud machines, but because of the particular thing they do they are also comfortable with disassembly. I have sometimes thought about this: what are the chances of someone having both the low-level skill set needed to usefully contribute, and also the need to emulate an old Windows program? This is to me one of the best things about the internet, where even if such a person is a one in a billion chance, we have a few billion people around on here. And this includes someone else who for whatever reason got Win95's solitaire.exe to run.