Restoring support for 16-bit applications in modern Windows versions
Windows has some pretty amazing backwards compatibility. In many cases, you can run ancient 32-bit Win32 applications just fine on your current system.
However, there’s one issue: If you ever tried to run a 16-bit application from the Windows 3.x days, any 64-bit Windows version (starting from Windows XP) will refuse to run the application with an error message indicating that you should ask the vendor for a compatible version.
On the other hand, the modern 32-bit versions of Windows run these applications just fine.
Thanks to two amazing open-source projects, you can bring back 16-bit compatibility to the 64-bit Windows era.
Why did Microsoft drop support for 16-bit applications?
Back in the old days, things were rather simple. Up to (and including) Windows ME, all consumer versions of Windows ran on top of MS-DOS, so support for 16-bit applications was basically built-in (Windows 98 for example even includes the Program Manager
PROGMAN.EXE from Windows 3.x). For the NT series, Microsoft had to pick a different route because it didn’t have any MS-DOS kernel to rely on. This led to the invention of NTVDM, the NT Virtual DOS Machine.
NTVDM was first introduced with the release of Windows NT 3.1 back in 1993. The NTVDM subsystem provides a runtime environment replicating a system running on MS-DOS 5.0 including all required BIOS calls, the Windows 3.1 kernel and the Win16 API itself. Since NTVDM doesn’t provide real hardware emulation, it still relies on the CPU being able to run the original 16-bit code natively.
Microsoft removed the NTVDM in all 64-bit Windows release, so running DOS- and Win16-based applications is not possible anymore.
This removal was not a deliberate choice made by the Windows developers. Instead, the lack of 16-bit support is caused by the design of the x86_64 architecture itself.
CPUs based on the x86_64 architecture can run in two modes: Long mode and Legacy mode.
In Long mode, the CPU executes 64-bit code natively, while 32-bit applications run in a special compatibility mode. Long mode doesn’t provide support for the VM86 CPU code required by NTVDM in order to enable 16-bit segments for addressing, so it had to be removed in all x86_64 versions of Windows.
When the CPU runs in Legacy mode, it provides full support for both 32-bit and 16-bit applications.
Unfortunately, the only way to switch between both operating modes is a hard-reset of the CPU itself, making a seamless integration of both operating modes impossible without restarting the whole system. Because booting a 64-bit Windows system will always force the CPU to run in Long mode, there is no way to get back to a mode that allows native execution of 16-bit applications at runtime.
In fact, even switching to the 32-bit compatibility mode within Long mode itself (and not the legacy mode) requires an additional abstraction layer. Every time you launch a 32-bit application on your 64-bit Windows installation, the operating system invokes the WoW64 subsystem that acts as a compatibility layer providing the interface required to run the 32-bit application on a 64-bit system.
Like fine WINE
Considering the limitations the x86_64 architecture imposes, the only way to get 16-bit code running is introducing an emulation layer that is able to replicate a CPU with the proper instruction set. Additionally, we need some software which provides a runtime environment for the Win16 applications.
Combining a 80386 emulator and a Win16 runtime environment - that’s exactly what otya128 accomplished with their winevdm project. winevdm uses the 80386 emulator developed by the MAME project and combines it with the well-known Windows runtime environment WINE.
Installing winevdm is incredibly easy and provides a seamless integration in your current Windows installation.
First, you have to download the current version from GitHub’s release page.
I recommend extracting the contents of the .zip archive you just downloaded to
C:\otvdm since this directory is available for all users on the system and also not protected by UAC. The latter is important because in order to save DLLs in the virtual WINDOWS folder provided by winevdm, write access to the otvdm directory is required.
All you have to do to get winevdm added to your system is clicking on the
install shortcut. The installer tool adds numerous keys to your Windows registry, so administrative access is required. After a couple of seconds, the installer window closes and the installation is complete.
That’s it. Now, each time you want to launch a Win16 application, your system detects it and passes the program to winevdm which in turn is able to run it. In theory, winvdm also provides native DOS emulation as well, but since it is rather limited, a solution like 86Box or PCem might be a better choice for MS-DOS applications.
You don’t have to start winevdm manually after booting up your system or in case you want to launch a Win16 application. Thanks to the installed registry keys, it will automatically kick in as soon as it detects a Win16 application.
Updating winevdm is pretty easy too: Just download the new release, replace all files (but do not delete the contents of the
WINDOWS directories) and run the installer again.
Pretty incredible, if you ask me. And a great example why the open-source community is so important for software preservation. But that’s a topic for another day.
Do you have any comments or suggestions regarding this article? Please drop an e-mail to firstname.lastname@example.org!