Dos and Windows Emulation under Linux

Windows 95 in a window under Linux? Sure, using a program called bochs...

Here are some of the options for simulating older PC operating systems and programs...

DosEmu with FreeDos gets a lot of use on my system, with it I can run most of my old batch and qbasic software with the files mapped directly to my Linux file system. I can edit a batch or copy a program under Linux then immediately run it under FreeDos. DosEmu doesn't emulate the processor itself so it's fast, on my 1.4ghz Sempron machine my homemade math benchmark program rates it equivalent to a 486 running at 559 mhz.

DosBox includes a simple built-in dos and can map to Linux files, but emulates the processor as well so it is much slower, performing at ~12mhz according to my benchmark program. I mainly use it to run individual dos programs that won't run or are too fast under DosEmu.

Bochs and QEMU are recent arrivals on my machine. Bochs seems to simulate at a rate of ~33mhz but had to rewrite my bench program because of problems running programs compiled with FirstBasic. QEMU is much faster, running at ~133mhz to ~200mhz-equivalent depending on what's enabled, but comes with its own set of glitches and configuration details to figure out. That they work at all is amazing, for some things they work quite well. Unlike the dos emulators, these "PC emulators" require a disk image file to operate and cannot simply map files to the underlying host file system. The "dd" command can be used to copy real floppy disks and CD's to disk image files, the "bximage" program provided with bochs can be used to make empty hard-disk images that can be fdisk'd and formatted (QEMU includes a similar program). Image files can be mounted under Linux using "loop" commands provided in the bochs documentation, allowing files to be copied back and forth.

9-18-05 - QEMU seems to be the more useful PC emulator but I still need Bochs for some things... I had to access a CD using a boot floppy but found that my (real) boot floppy didn't recognize QEMU's cdrom, so used Bochs to copy the CD's files to a hard disk image which needs no driver to access. I often use really old software and in some cases QEMU's "hardware" is too new and I need to patch things using Bochs, which seems to simulate somewhat older hardware. Neither emulator is perfect (for the software I use), QEMU is usually the "best" PC emulator environment for me, but for old stuff designed when a 40mhz 386 was considered fast, then Bochs is sometimes a better choice. My very old copy of Win95 has problems with both emulators but in different areas, apparently due to buggy drivers. I'm still limited to 640x480 16 colors, in QEMU I can use the Cirrus emulation and select higher resolutions but they're buggy, screen doesn't update properly and bits of the background get stuck in the borders of windows. The PCI Cirrus driver seems a little better but Win95 doesn't seem to recognize the PCI version of the ethernet card.

9-21-05 - After a few iterations of "hardware" changes and redetection, my Win95/QEMU setup has stable 800x600x256 video and for most things works well. Just no network, joystick or floppy disk images (which used to work but now it doesn't). I've been rediscovering old PC games and doing things I wouldn't dare do to a real installation of Windows, but under sim if I'm worried about something I can just tar.gz the disk image. Duke-Nukem 3D, Raptor, The Need for Speed and other '95-'98-era games run quite well, possibly better than they do on my real 133mhz Win95 machine, plus the convenience of being able to instantly shove them aside to do something else. Later games and things that depend on hardware accelleration tend to not do so well, not surprising as the video in the host system is sub-par to begin with but not a problem, no time to "get into" those complicated new games anyway.

9-24-05 - Some of the games didn't like only 256 colors so switched my Win95/QEMU setup to 16-bit color, no change in emulation speed. When I installed DirectX 5 it said it "found" a more up-to-date driver for the simulated Cirrus card, ok, whatever. Finally I have a capable and convenient platform for running the "new" Elite games, found and installed Frontier and JJFFE along with various doc files. Along the way I wrote a MKINDEX batch file for turning the Frontier docs into a single html index for my the desktop, and a CLEARFRE batch to overwrite free disk space with spaces to allow the disk image file to be more compressable. To select different CD images I use a bash script with an extension I set up to cause it to run in Konsole. My main "Win95" script at the moment contains just the qemu command without the -cdrom option, presently set up to run in a "dangling" shell without a window by marking executeable and just clicking it in KDE. Adding the "&" after the command to allow the launching shell to immediately exit causes instabilities, something should be there to receive the status messages from qemu even if it doesn't go anywhere visible. To see the messages I add konsole -e in front of the qemu command line. Other systems might require use of xterm, rxvt or some other bash terminal window.

My current scripts for mounting disk images under Linux are not suitable for sharing, basically the idea is to cd to the directory containing the disk image, make a directory (say imagefiles) to serve as a mount point then using sudo for root access run losetup /dev/loop6 disk.img -o 32256 followed by mount /dev/loop6 -o loop imagefiles (mount dir made previously). The files appear in imagefiles but I have to be root to do anything with them. Before running qemu on the image it MUST be unmounted, using sudo I umount imagefiles then losetup -d /dev/loop6. Failing to unmount will cause disk errors, when I did it I couldn't see the files I just added so shut down Win95, unmounted, after restarting ScanDisk found size errors but no serious problems. That time... I probably got lucky. I need to figure out the command for allowing read/write access for all so I don't have to sudo emelfm to access the files, probably a few simple commands I don't know.

Getting this stuff working is tricky and requires use of not-so-obvious command lines and scripting and digging through cryptically-written doc files. Some things just won't work depending on what one tries to do on what platform with what software. Different emulators have different strengths and weaknesses for doing particular things, at different times I need them all even though there's some overlap in function. For basic dos stuff I like the convenience of DosEmu/FreeDos because it maps the files to my normal file system. Some stuff doesn't run under FreeDos, so I use DosBox instead and take the performance hit. Wine is convenient at times for running Windows programs stored as ordinary files. QEMU does amazing things but it's its own world, a strength that allows it to run almost any PC software but copying files to and from disk images can be tricky. Then there's Bochs, with cdrom and floppy emulations that actually worked with my existing Win95 software allowing it to be installed on a disk image to begin with, hard to install something from a CD that can't be accessed due to lack of a "modern" driver to kickstart it with. I don't use bochs much anymore but who knows what might come up.

My present simulated Win95 desktop under QEMU under Knoppix...

11-11-05 - QEMU 0.7.2 is hanging in there and quite useful but I've all but given up on network and joystick support. Actually, not having the net available for Windows is probably a good thing :) I'm pretty sure QEMU itself can handle it just fine if the underlying OS is properly set up for doing that... but the chance of improper setup (by me) keeps me from mucking around too much. Rather if I need software for the simulated Win95 I D/L it in Linux, mount the disk image using a script containing the losetup and mount stuff, copy it over and unmount the disk image using another script. Ditto for getting stuff back out of Win95, it's all a few clicks. Still haven't solved the permissions problem preventing anything but root from accessing the disk image but I have EmelFM set up as root with favorate locations including my Win95files mount point, a sudo chmod -R 777 * takes care of resetting permissions of files copied back to Linux. Besides goofing around with Old Computer sims and driving the Need for Speed demo with cursor keys, I was using QEMU extensively to run SIMetrix Intro (a node-limited but very nice spice simulator), using a PDF print driver to package the results, but now there's a native Linux version of SI which pretty much nixes running it under emulation. ExpressPCB should get its own extensive use shortly.... hehe this is great not having to reboot the machine for stuff like this.

Recently I re-figured out Wine enough to effectively run LTSpice, a free spice simulator from Linear Technologies for Windows but is written to be compatible with Wine, an effective cross-platform solution. Provided one can get Wine itself to work... the one installed by Knoppix 3.7 worked fine when it worked at all (except for those ugly default fonts but didn't use enough to inspire me to change them) and was fairly well-integrated into the KDE environment (no direct click-execution, but could right-click and run wine). Then one day around August I updated Wine (as I frequently do with emulators when trying to make them run something they're not running) and it all changed. All KDE entries vanished and winesetup no longer did anything useful since the file it accessed (.wine/config) is no longer used and now is part of the incomprehensible registry. My existing wine scripts all still worked correctly so this wasn't a big deal until I started trying to actually use stuff under Wine then I knew those all-capital fonts would have to go or else. No problem I thought, but the new winecfg that's supposed to be used doesn't do fonts. RTFM but darn it still spoke of the dead config file. Dumped the installed docs and useless winesetup program, D/L'd the corrected manuals and finally found the very simple answer... copy Windows/Fonts from an existing Windows setup to the same fork under ~/.wine/fake_windows, problem solved, looks fine now. There is no setup which is why I couldn't fine one. Re-integrating into KDE was easy, I created an application-WinExe filetype and associated *.exe files to it, with wine as the default app and wineconsole as an alternate choice. Everything works ok now, except for not running half the things I try on it like ExpressPCB. This might be a matter of copying over real dll's into the fake Windows/System directory. It appears quite possible for an app to be installed that also installs an incompatible dll possibly causing other installed programs to break. Haven't seen it happen but I see many real dll's in System but they're dated by the file date of the original file so not obvious at all just by looking if a file is needed, junk left over from attempting to install something that didn't work, and in that case if a 0-byte dummy dll needs to be there instead. Stand-alone uninstall programs aren't always provided, no "control panel", and those things rarely restore system files anyway. I can see now I'm going to have to compress and archive the entire ~/.wine directory before running or installing any new program under wine. Hmmm... same can be said about running anything under Windows, emulated or not, but at least with the real thing there's less chance the "os" won't understand the code causing standard-issue redistributable dll's to fail.

11-15-05... Associating Files to Emulated Programs. It's fairly easy to set up a program under Wine, DosEmu, or DosBox to run when an icon is clicked, usually a matter of specifying the program name on a command line along with any other emulator parms needed to make it go. To run Redmaker under DosEmu/FreeDos I only need 'xdosemu redmaker' in a script, with a batch in a dos path directory named redmaker.bat which changes to the correct directory and runs redmaker.exe. DosBox is only a little more complicated, the program's directory needs to be mounted first using a command line like...

Running a program under Wine is usually easy, 'wine [/path/]program.exe' generally does it. If the program is "installed" to typically "Program Files" (under ~/.wine/fake_windows), the program path/name must be quoted to appear as a single parameter to Wine. Note that the "~" shortcut to home doesn't work inside quotes, either spell out the full path or do something else. It's easy to include command line parameters for the program, the trick is giving it something it can understand - Windows programs do not understand Linux filepaths making it not so easy to say associate *.hlp files to WinHelp under Wine. I solved this problem by creating a bash script which converts the Linux path into something a Windows program can understand...

The command line has to be edited to specify the location of the (real) winhelp.exe file with winhlp32.exe in the same directory. Note for WinHelp the $winpath on the command line cannot be quoted, however for other programs it has to be quoted, as in wine "...prog.exe" "$winpath". To be able to click on Windows Help files and view in WinHelp, I created a new Application WinHelp type, associated it with *.hlp and *.HLP files, and added the name of the script as the program to run. In my case w95help, no path needed because I put it in /usr/local/sbin, otherwise specify the full path/name of the script. The script of course has to be marked executeable in the file's properties. The same technique (with $winpath quoted) works for other programs installed under Wine, I have *.asc files associated to scad3.exe so clicking on a schematic file opens it in LTspice.

How it works... the script first checks to see if there is a parameter, if there is it checks to see if it contains "/" and if it does it changes all "/" characters to "\" and prepends Z: to the front, which Wine sees as the local Linux file tree. If there isn't a "/" character then it leaves the parameter alone, wine preserves the current directory allowing use from a command prompt without having to specify the path if the file is in the current directory. The good stuff happens after the && (which means if no error, in this case if grep found "/"), the ${winpath//\//\\} which expands to the contents of winpath with all the "/" characters changed to "\". The usage is ${stringvar//find/replace} so "//\/" specifies "/" for the find string ("\" is an escape) and "/\\" specifies "\" as the replacement.

Back to OldComp page