Open 16-bit Windows applications natively on 64-bit Windows using OTVDM/winevdm
In my previous post I described how to run 16-bit DOS applications on 64-bit Windows using NTVDMx64. This post will show you how to achieve the same for 16-bit Windows apps with OTVDM, also known as winevdm.
Unlike NTVDMx64 which is based on the leaked source code of Windows NT, OTVDM/winevdm is based on WINE and is totally open source. The repository can be found here and detailed usage instructions can be found here. With this, running 16-bit Windows applications on your modern computer is just a matter of passing the full path of your favorite program to the OTVDM executable:
Alternatively, you can also create a shortcut to OTVDM on your desktop and drag the application executable to this shortcut, which will effectively execute the same command without showing the OTVDM console window.
My first test is to install and run Visual Basic 3.0 on Windows 11 via OTVDM, which went pretty well. After installation, VB3 can be started by dragging C:\VB\VB.EXE to the OTVDM executable (the desktop shortcut doesn’t work). There is also a console window (which can be minimized if needed) which displays warning/error messages from OTVDM:
Visual Basic 3.0 help system originally used Windows Help (.HLP) format and pressing F1 would open the VB.HLP file. Starting from Windows 8 or later, Microsoft removed support for .HLP file but the component (WINHLP32.EXE) can still be downloaded from Microsoft website if needed. OTVDM also included this file in its download and will route all requests to open .HLP files to this executable. If pressing F1 does not work for you and you are using Windows 10 or 11, try this guide. In any case, you can simply open the .HLP file independently to look for the relevant topic.
To avoid conflict with your current Windows installation, OTVDM has its own WINDOWS\SYSTEM and WINDOWS\SYSTEM32 folder, and any requests to read/write Windows system file will be routed to this directory instead. If a software you want to run complains about missing DLL, try to copy the required DLL to these directory, instead of your Windows system directory.
Multimedia applications such as MPLAYER.EXE from Windows 3.1 works too, and is able to play a .WAV file from the C:\WINDOWS\MEDIA folder:
Word for Windows 2.0 works well too and is able to open an old document:
Although I must say there is really no reason to run Word 2.0 on OTVDM as the latest version of Microsoft Office (Office 2021) can still open Word 2.0 documents and maintain original formatting (except for OLE objects such as Equations or macros). Potentially you would only need to run Word 2.0 if you want to handle antique format such as Word for DOS. But then again, attempting to open a document that is not in either Word for Windows 2.0 or Rich Text Format will fail with error “Word cannot start the converter WORDDOS.CNV” (or name of the converter being used). I tried to copy the relevant .CNV file to the OTVDM Windows directory, which did not help. So I guess the only way to handle these formats is to install a proper virtual machine.
Through OTVDM, Word is able to see the list of printers available on the host and printing to Foxit PDF printer works fine:
In Borland C 3.1 I also tried to run a test program which asks the user to input a number and then prints it back. This works, but awkwardly:
In addition to the console window which started OTVDM, BCW has also started another console window. The default output of your C program (stdout via printf or cout) will be shown on the OTVDM console window whereas the default input stream (stdin via scanf or cin) still be on the BCW console window. With the above test program, you will need to type your inputs within the BCW console window and watch for outputs from the OTVDM console window. Debugging any console application like this will be a hassle. If your application is mostly graphics and only uses the console window for log messages, things would still work well enough. But then again, if Borland C is your favourite compiler, you should definitely try Borland Turbo C++ 4.5, which is a 32-bit application that can run natively without OTVDM.
There are no such issues with Borland Pascal for Windows and stdin/stdout remains on the BPW console window. The only error message in the OTVDM console window saying “SReg Load: segment is not a data segment or readable code segment” does not seem to affect operation.
If you get a runtime error 104 (File not open for input) or 105 (File not open for output), make sure to add uses WinCRT; to the beginning the code. Apparently, without the WinCRT unit initialization code, the console window will not be initialized and writeln/readln will fail. If you still have error, make sure to start BPW using OTVDM from a console window, and not by dragging shortcuts (which does not create the OTVDM console window). Also try to run OTVDM as an administrator if the problem persists.
Notepad for Windows 1.0 works fine too. This is a screenshot of a document being shown, and a modal File Open Dialog:
One thing I notice is that the dialog seems to show and handle long file names properly – files located under directories with long names can be opened. Windows 1.0 was released in 1985 when LFN was still a few years into the future. So what is happening here?
The Open File Dialog of Visual Basic 3.0, built for Windows 3.1, does not support LFN under OTVDM (as expected). However, BPW 7.0, designed in 1992, can show and open files with LFN in its Open File Dialog under OTVDM. Researching further, I realized that if a program is using the DirListBox control of VB 3.0, then LFN will be displayed properly. If a file with LFN is later accessed using standard Windows API (e.g. via OpenFile), then the API (emulated by OTVDM) will handle these LFNs automatically and transparent to the application, which only needs to operate on a handle value returned from the API. If however an application shows the Open File (or Save File) dialog using the Common Dialog API (COMMONDLG), then these dialogs may or may not support LFNs, depending on which versions of the COMMONDLG library these applications were originally built against. If the full path of the file with LFN is too long and exceeds the buffer allocated by the application, then there will be memory issues. So far I have not encountered such an issue with well-known apps, and long file names, once displayed, seemed to be handled properly.
The last test I performed is to run IE and Netscape on OTVDM and open a HTTP web page. Internet Explorer did not work and crashed OTVDM – I think IE relied on too many 16-bit Windows components that are not emulated. However, Netscape worked, which means that the Winsocks API and relevant networking layers are at least sufficiently emulated:
All in all, I believe OTVDM works satisfactorily for most purposes, partly thanks to the impressive backwards compatibility built into even the latest version of Windows. OTVDM reduces the hassle of having to start a separate virtual machine just to test a simple 16-bit app and is in no doubt very helpful to those who are still reliant on 16-bit apps (like me) for their day-to-day jobs.