VOGONS


First post, by ell1e

User metadata
Rank Newbie
Rank
Newbie

Dear forum,

I'm thinking of trying to write some software that runs on Windows versions going back to 98SE, mostly because it sounds like fun, and CPUs going back to something like Pentium 3 or around that time (still undecided what exact cut-off I should use, but I'm willing to require something slightly more modern in terms of CPU than in terms of software sack).

Where am I doing this: My main workstation where I'm working on this software is using Linux.

Past attempts: I've already tried targeting Windows XP which was fairly easy. I've noticed other than the code pages, my software doesn't really use anything already present on Win98SE, and for the code pages I might be able to just use the Win API's unicode conversion functions - or perhaps some other library I can track down - to convert it on-the-fly. Then my file path handling might not be able to handle all corner cases but it might be good enough for practical use. I got a working Win98SE VM around, with the usual patches for modern CPUs, and now I'm curious what I could reasonably do.

My question: Does anybody have experienced with modern Mingw-w64 versions in that regard, or are there any other compiler recommendations for doing this?

If preferable I don't want to use some old compiler like an older MinGW version, since I want to compile one single x86 exe that still runs on latest Windows 11, without having any issues of e.g. modern CPU mitigation considerations not being taken into account by the compiler. The compiler needs to be able to handle C89 with C11-like atomic 32bit+46bit ints (simply handling "volatile" correctly might be enough on Intel architecture so I've heard, so I could get away without the C11 annotations but I prefer to use them if available) and _attribute_((constructor)) or similar, and I need to be able to use LoadLibrary() on the usual common libraries like for example the kernel32.dll for features only present on newer versions of windows.

I don't really need any C99 or newer features, or anything else unusual. I don't use much of the more advanced stuff of the C library, e.g. I do string formatting myself.

Any suggestions, or any past experience worth sharing?

Reply 1 of 14, by xcomcmdr

User metadata
Rank Oldbie
Rank
Oldbie

Hi,

I don't think any modern compiler would support Windows 9X.

However, if you are willing to track down VS2019 Community for your dev environnement (requires Windows, or a Windows VM),

And track down for Windows 98SE the .NET Framework 2.0 runtime installer (it also requires Internet Explorer 5 or later and Windows Installer 2.0), and with a "SDK style" .NET Framework .csproj file project, multitarget via the "TargetFrameworks" element several versions : .NET Framework 2.0 (for Windows 9X or XP), 4.8 (shipped with modern Windows), and .NET 8 (for Linux and macOS), you can make something viable that runs on Windows 98SE, Windows XP, modern Windows, modern Linux, and modern macOS, with some effort.

On Linux and macOS you could even ship it *with* the .NET 8 runtime, making the installation of the .NET runtime at the OS level not required. (dotnet publish --self-contained true)

The installer for Windows 98SE would be the .NET Framework 2.0 ANSI variant (and there are variants depending on the OS language, ie. French, English, ...).
Most links give you the Unicode (Windows NT 5+) variant. Same for Microsoft Installer 2.0.

The standalone installer for Internet Explorer 5.0 (same - there are variants depending on the OS language, ie. French, English, ...) or later can still be found.

It's not going to be easy exactly, but I've already done it.

Projects like Polyfill can make it easier, as most modern features of the C# language are syntax sugar: https://github.com/SimonCropp/Polyfill

However, you'll have to use C# instead of C.

Matt KC even made .NET apps work with Windows 95:

https://github.com/itsmattkc/dotnet9x

.NET CLR 2.0 requires the following to be installed: […]
Show full quote

.NET CLR 2.0 requires the following to be installed:

Windows 95 B (OSR 2) or newer. Currently older versions will not work, however I am investigating ways to get around this requirement (see below).
Internet Explorer 5.01. The installer is packaged in this repository at bin/msie501. One day I plan to make it an automatic part of the installation process, however for the time being you'll have to run it manually.
Microsoft USB Supplement. The installer is packaged in this repository at bin/usbsupp or may be on your Windows 95 install disc at other/updates/usb. This is why 95 B is necessary, the USB supplement makes patches to VMM32.VXD that allow .NET to work, and it isn't available on RTM/A. I am currently investigating why this is necessary and whether it can be patched out.
Optional:
To allow sockets, install the Microsoft Windows Socket 2 Update.

Last edited by xcomcmdr on 2026-03-05, 19:14. Edited 5 times in total.

Reply 2 of 14, by gerry

User metadata
Rank l33t
Rank
l33t

My question: Does anybody have experienced with modern Mingw-w64 versions in that regard, or are there any other compiler recommendations for doing this?

If preferable I don't want to use some old compiler like an older MinGW version, since I want to compile one single x86 exe that still runs on latest Windows 11, without having any issues of e.g. modern CPU mitigation considerations not being taken into account by the compiler.

a challenge indeed. I'd normally take two routes with this, neither quite being the one you want 🙁

1) Write it on a modern dev tool but consciously keeping things as simple and 'old school' as possible, then re-compile same project with an earlier version of the modern tool that still targets 98se, then fix all the compatibility issues with either conditional compilation or some other means
2) Write it on the 'last version' of a tool still targeting win 98se, likelihood of working on windows 11 will be fairly high, higher if the application isn't doing anything very (old)platform specific or using old libs

otherwise the excellent .NET suggestion can work

The success of any attempt depends on what you are building and how strict you're going to be about tools etc

Reply 3 of 14, by ott

User metadata
Rank Member
Rank
Member

Sorry for offtop, but what about Delphi?

Delphi 7 apps can run on Windows 9x/NT/XP and even Windows 10/11.

This is good example, but I think there are a lot of hacks inside to cover compatibility with all supported OS:
ASTRA32 - Advanced System Information Tool for Windows

Reply 4 of 14, by digger

User metadata
Rank Oldbie
Rank
Oldbie

The Open Watcom compiler should allow you to cross-compile Windows 9x applications from a Linux or modern Windows (and perhaps even DOS?) host.

It can even cross-compile Windows 3.1 applications.

And the v2 fork is still maintained on GitHub.

Reply 5 of 14, by ell1e

User metadata
Rank Newbie
Rank
Newbie

OpenWacom seems like a fascinating suggestion, I'll look into that!

So has anybody tried MinGW? It can still target XP, I don't know about 98SE. I've found post suggesting that it can that are quite old.

The suggestions of different languages aren't that interesting to me, for various reasons anything but C89 isn't really feasible for my stack.

Reply 6 of 14, by gerwin

User metadata
Rank l33t
Rank
l33t
ell1e wrote on Today, 00:17:

OpenWacom seems like a fascinating suggestion, I'll look into that!

So has anybody tried MinGW? It can still target XP, I don't know about 98SE. I've found post suggesting that it can that are quite old.

The suggestions of different languages aren't that interesting to me, for various reasons anything but C89 isn't really feasible for my stack.

I often use MinGW v10.3 under Windows XP x86 to make Windows XP compatible executables from open source game projects.
The main Windows XP incompatiblity in MinGW v10.3 is libwinpthread-1.dll. But it can be fixed by using an older libwinpthread-1.dll, both for MinGW binaries and also for any executable build with it, in case it requires it.
Windows 98 is not normally on my radar, but I did make some notes about it here:

eDuke32 for Win95
It says a MinGW v8.4.0 build executable fails in Windows 98 because of a call to __mb_cur_max_func in msvcrt.dll.
I suppose MinGW v7 and earlier are safe in this regard. MinGW 5.4.0 definitely is.

Under Windows it is easy to use multiple compiler installations. Like MinGW v4, 5, 6, 7, 8, 10, 12 and some MSVC versions. Then switch from one compiler to the other and rebuild a project. In case of a CMake project I can select a compiler by setting the PATH environment variable. Code::Blocks IDE has compiler settings in the GUI.
It is not just the compiler that matters, of course, it is all the libraries and headers that a project may require. Any lib has the potential to include an API call that breaks legacy OS compatibility. SDL2 is not Windows 98 compatible, and it is everywhere...

At the bottom of my "backports" section on my website https://gb-homepage.nl/ there are some links and packages related to the above.

Last edited by gerwin on 2026-03-06, 01:32. Edited 2 times in total.

--> ISA Soundcard Overview // Doom MBF 2.04 // SetMul

Reply 7 of 14, by DosFreak

User metadata
Rank l33t++
Rank
l33t++

The last time I touched any of the below was 2021 so likely a bit out of date but here is my info:

For Mingw already compiled binaries you are good for >i686 and NT3.50/95+
For Mingw-w64 win32 thread I last tested NT3.50/95+ with Mingw-W64 v7.3.0 in 2018 and it worked fine
For Mingw-W64 win32 thread XP compatibility verified on 10-9-2021 using Ubuntu 20.04.3 and gcc 9.3-win32 20200320 (GCC) with static dependencies
Mingw-w64 is compiled for i686+ so if you want less than that you'll need to recompile it.
If you need/want to use the posix version of mingw-w64 and want to run on older operating systems less than what the corpos want you to use then you'll need to find ways around pthread being incompatible.
For Mingw-W64 on older operating systems you need to make sure you are using the latest msvcrt. See the links below.

Around 2021 Mingw-w64 on WSL2 and regular Linux was win32 straight from the repos by default w/ no dependency issues, haven't checked since.
Re: eDuke32 for Win95
Re: DOSBox Compilation Guides
Re: DOSBox Compilation Guides

As of 2018 Mingw-w64 posix 7.3.0 XP+
As of 2018 Mingw-w64 win32 dwarf is NT 3.50+/95+

MSYS - MINGW w/GCC v6.3.0 (i386+) w/ MINGWRT 5.0.2 (Supports NT3.50+ and 95+)
https://sourceforge.net/projects/mingw/files/ … up.exe/download

Mingw-w64 win32 dwarf (old build for windows I know works)
https://sourceforge.net/projects/mingw-w64/fi … ev0.7z/download

The environments I setup back in 2018 are here:
DOSBox Compilation Guides

Last time I worked on the above MSYS/MSYS2 was pretty terrible as far as tooling and slooooooooooow and also pacman defaults to posix which causes issues when you update.. Just use WLS2 or the Linux terminal to cross compile to Windows.

Last edited by DosFreak on 2026-03-06, 11:27. Edited 8 times in total.

How To Ask Questions The Smart Way
Make your games work offline

Reply 8 of 14, by DosFreak

User metadata
Rank l33t++
Rank
l33t++

Rust9x
Re: Rust ported to Windows 95 (and NT)
https://github.com/rust9x/rust

SDL 2 on DOS
https://github.com/libsdl-org/SDL/pull/13906# … ment-3267729953

SDL3Lite
https://github.com/JordanCpp/SDL3Lite

LDL
https://github.com/JordanCpp/LDL

Mingw-Lite
MinGW-w64 GCC distribution. Fast and flexible build scripts; minimal dependencies; works on NT 4.0 and 98. Inspired by w64devkit
https://github.com/redpanda-cpp/mingw-lite

https://github.com/enlyze/EnlyzeWinCompatLib
Let MSVC v141_xp/Clang targeted applications run on even older Windows versions

https://github.com/DibyaTheXPFan/LLVM-for-Win … Saphire-Dragon-
LLVM and Clang for Windows XP

Last edited by DosFreak on 2026-03-06, 15:17. Edited 5 times in total.

How To Ask Questions The Smart Way
Make your games work offline

Reply 9 of 14, by ell1e

User metadata
Rank Newbie
Rank
Newbie

Thank you so much for all the detailed info!!

MinGW libwinpthread-1.dll introducing an XP problem sounds kind of concerning. Maybe that would be worth reporting? What do I need to reproduce that, just get the POSIX threading version of MinGW and compile a minimal program, while statically linking MinGW's included libwinpthread-1.dll? Or do I need to actually be using threading in some way? (I typically just use the WINAPI threading calls.)

I'm generally happy to use MinGW's win32 threading version, which I understand is apparently the variant that has basically no useful threading built-in. However, I've recently had an interaction with a MinGW developer and it kind of sounded like they were considering to not support that much anymore. On some distributions you can't even install that variant as a cross-compiler, it can be a rare find. Perhaps that would be my best choice?

I'm also wondering if there's anything known about OpenWatcom and how they deal with these new speculative CPU bugs and such. I'm guessing the operating system will sufficiently ensure process isolation at least, so as long as I don't expect threads to be safe from each other I might be fine, even if I compiled something like OpenSSL...? I wonder what their project policy is with such issues. I think potential security angles would be one of the main reasons for me to not use the community fork OpenWatcom V2 instead of MinGW.

I generally don't care about fancy features like C99 or threading. I just care about C11 atomics since e.g. for ARM64, they seem kind of needed for e.g. using a volatile int in an atomic way, which I can't really work around well otherwise. And for threading I just use the win32 APIs directly, from my research it seems like Win98SE has everything I need in that regard.

Reply 10 of 14, by ell1e

User metadata
Rank Newbie
Rank
Newbie

Update: it seems like most recent MinGW with the POSIX threading model is at least intended to still support Windows 98: https://github.com/mingw-w64/mingw-w64/issues … ment-4010782047 (While the minimal Win32 threading model variant of MinGW apparently no longer exists, and it's different now with higher requirements.) I will try this out soon. The reason I haven't yet is that I still have to fix some other things before I dive deep into this. I hope somebody finds this useful nevertheless.

Reply 11 of 14, by Ringding

User metadata
Rank Member
Rank
Member
ell1e wrote on Today, 09:32:

I'm also wondering if there's anything known about OpenWatcom and how they deal with these new speculative CPU bugs and such.

They don’t, I would assume. Why would anyone working on a retro compiler care about that?

And why should everyone running software on their own systems suffer from this? As you can tell, I am slightly annoyed by this topic.

Reply 12 of 14, by digger

User metadata
Rank Oldbie
Rank
Oldbie

Indeed, it seems a bit weird to worry about things like speculative execution exploits on CPUs when you are targeting an OS that was already known to be horribly insecure even back when it was still maintained, decades ago. 😅

Reply 13 of 14, by the3dfxdude

User metadata
Rank Oldbie
Rank
Oldbie
Ringding wrote on Today, 15:40:
ell1e wrote on Today, 09:32:

I'm also wondering if there's anything known about OpenWatcom and how they deal with these new speculative CPU bugs and such.

They don’t, I would assume. Why would anyone working on a retro compiler care about that?

And why should everyone running software on their own systems suffer from this? As you can tell, I am slightly annoyed by this topic.

Why would the compiler solve this issue? Generally it is solved by the kernel. It would be another app attacking the protected memory of another. You'll have a vulnerable system if the kernel doesn't mitigate it (at the very least, there are multiple ways to look at it), simply because some other app would not be hardened against it because it used some other compiler, but really, that is what would contain the exploit, through clever execution methods. It won't be coming from what you are doing.

Also, speculative execution is really only a modern day issue. The attack surface making the system vulnerable are multi-user, multi-core systems. Older systems under which the problem started, were not used that way, Win98 is case in point. This is why Intel got away with breaking the security model to make their chips (Not sure, it started somewhere between P2 and P3M), and essentially cheating because the GHz wars were such snake oil, they resorted to cheap tricks that broke the barriers between applications, cause the limitations imposed by the system of the day, no one thought it would be an issue.

So I wouldn't expect Win98 to be secure, but to be used in a way that also causes you to be exploited, is also very unlikely. In fact, there are many CPU that are not actually vulnerable that are Win98 capable too, so if anything, Win98 PCs may actually be more secure on this subject than PCs were when this was discovered.

Reply 14 of 14, by cyclone3d

User metadata
Rank l33t++
Rank
l33t++

You coming ld always spin up a Windows VM on your Linux box.

In the past, I found that it was a huge pain to cross-compile, but I was trying to maintain a program that would work in Windows and Linux.

I was also trying to cross-compile for Linux using MinGW and compile for Windows using Visual Studio.

The main problems I ran into is that some of the basic math functionality simply didn't exist in MinGW.

I also ran into issues where enabling optimization in MinGW would end up with the program crashing, while when compiling with Visual Studio with optimizations enabled would work perfectly fine.

Maybe it has gotten better by now, but it was not worth the hassle at the time.

Yamaha modified setupds and drivers
Yamaha XG repository
YMF7x4 Guide
Aopen AW744L II SB-LINK