I’ve recently wanted to get some programs compiled for Windows 95 running on a Pentium and faced the typical challenge of finding a compiler that will emit an executable suitable for a 25-year-old computer. While I knew which MS compilers would allow me to do it (Visual Studio .NET 2003 or Visual Studio 2005 SP1 with some exe patching, you can read more on Visual Studio versioning and compatibility), I didn’t want to install a copy of Visual Studio 2005 only to get the compilers (the standalone Visual Studio Build Tools weren’t available back then), I also skipped trying Microsoft Visual Toolkit 2003. But lets start with describing the target system.
The machine I wanted to compile for is a 1996 PC with a 200 MHz Pentium (non-MMX) CPU on an Intel Advanced/AS (Atlantis) motherboard with the 430FX (Triton) chipset, with 64 MB RAM and Windows 95 OSR2. I did install some updates:
- Internet Explorer 3.02. OSR2 comes already with IE3 integrated, this is just an update, since some programs specify this as a minimum. On vanilla Windows 95 many programs will complain about missing SHLWAPI.DLL until you install IE3.
- Visual Studio C runtime (MSVCRT.DLL) version 6.00.8797.0. This is the DLL Visual C++ from version 4.2 to 6.0 compile against. This version is included in (vc6redistsetup_enu.exe). Apparently you can find a more recent one in a Windows 2000 update (Q932590.exe), but I haven’t checked it out. This is also the DLL required by MinGW.
- Common Controls Library (COMCTL32.DLL) version 5.80.2614.3600. Many programs expect these controls to be installed on your system and some will not work or look buggy with earlier versions. Windows 95 ships with 4.00.950 by default. Version 5.80 is included in vc6redistsetup_enu.exe linked above (it’s inside the 50comupd.exe file).
- No IE4 Shell Update. The IE4 shell (the one integrated in the OS with Windows 98) is not as efficient as the classic 95 one, especially on a Pentium. I don’t see any good reasons to run 95 with the Shell Update instead of Windows 98.
I found it difficult to run programs even from the late 90s without these updates, so I consider these necessary for any box with Windows 95 installed.
What are the requirements to run programs on this system?
- They must not be linked against KERNEL/USER/GDI functions introduced in later versions of Windows. I wanted something that works out of the box, with only necessary updates installed, with no DLL imports patching, no KernelEx.
- They must not use instructions unavailable on the original Pentium in libraries. Even if you compile your program targeting the Pentium, if the libraries were targeting a newer CPU, your program won’t work when linked with them.
I’ve tested several GCC distributions: MinGW.org, MinGW-w64 and TDM-GCC in several versions. To check them I build some test programs. I found the wxWidgets samples to be quite good for testing, since they contain quite a bit of non-trivial code. I’ve also tested the CodeBlocks OpenGL template.
Here are the results:
version | distribution | type | result |
4.9.2 | TDM-GCC | posix-sjlj | PASS |
5.1.0 | TDM-GCC | posix-sjlj | PASS |
5.3.0 | MinGW-w64 | i686-posix-dwarf | FAIL – illegal operation |
9.2.0 | MinGW.org | PASS |
wxWidgets 2.8.12 samples tests, which require threads:
version | distribution | type | result |
4.7.1 | TDM-GCC | win32-sjlj | PASS |
4.8.1 | MinGW-w64 | x32-win32-sjlj | FAIL KERNEL32.DLL: InterlockedCompareExchange |
4.8.2 | MinGW-w64 | i686-posix-dwarf | FAIL KERNEL32.DLL: SetCriticalSectionSpinCount |
4.9.2 5.1.0 | TDM-GCC | posix-sjlj | FAIL KERNEL32.DLL: InterlockedExchangeAdd |
6.3.0 | MinGW.org | win32-dwarf | PASS |
9.2.0 | MinGW.org | FAIL – Compilaton error | |
9.2.0 | TDM-GCC | FAIL – illegal operation |
And last a quick test with wxWidgest 3.0.5, since 2.8.12 samples won’t with newer GCC distributions.
version | distribution | type | result |
9.2.0 | MinGW.org | fail GDI32.DLL: SetLayout |
The GCC distribution most compatible with Windows 95 on a Pentium is the MinGW.org one, as it is still compiled targeting the first Pentium and has a version with Win32 threads.
Any distribution linking with winpthreads will fail on a Windows 95 machine, because winpthreads use APIs not available on Windows 95. This makes TDM-GCC versions newer than 4.7.1 unusable for any program using threads.
MinGW-w64 since version 5.3.0 need at least a P6 class CPU, unless you compile it yourself targeting the Pentium (haven’t tried this myself). The same is true for TDM-GCC 9.2.0. These errors manifest themselves as “Illegal operations”.
If you want to use wxWidgets, then wxWidgets 2.8.12 being quite old and no longer updated fails compiling on newer GCC versions. wxWindgest 3.0.5 started using APIs not available on Windows 95. So, unless you want to patch wxWidgets 2.8 yourself, you have to use an older toolchain.