The OS/2 Museum has made available the first version of a display driver disk for Windows 9x running on VirtualBox. The driver uses a linear framebuffer and supports 8/16/24/32bpp modes with resolutions up to 1920×1200 pixels (see more below). The driver is not accelerated but tends to be very speedy on modern hardware.
I’d like to say that it was easy to adapt the existing Windows NT video miniport driver for Windows 9x… but of course it wasn’t. The Windows 9x display driver model is completely different and has nothing in common with NT. The Windows 9x display driver has much more in common with Windows 3.1 (and 3.0 and 2.x) drivers, and it has clearly directly evolved from those older drivers.
So what makes it a “minidriver”? A Windows 2.x/3.x display driver has to implement a very significant chunk of GDI. Bit blits, lines, text output. There is a lot of cases to handle and a great deal of complexity. To give some sense of the complexity, the Windows 3.1 DDK sample driver for Video 7 cards is about 1.6 MB (circa 60,000 lines) of assembler source code. And that’s just for 8bpp displays.
Windows 9x drivers still have to do all that. The difference is that Windows 95 introduced the “DIB Engine”, a large library that implements more or less all of GDI and that the display driver can “punt” to. The minidriver has to set modes and implement various housekeeping tasks, but all drawing can be handled by the DIB Engine. The minidriver can implement what it can do better than the DIB Engine, but doesn’t have to.
The DIB Engine in Windows 95 (DIBENG.DLL) is very similar to the DIB Engine that Microsoft released in September 1994 as part of WinG (WINGDE.DLL). I do not know the exact timeline and history. The WinG DIB Engine was designed to draw to memory bitmaps using GDI. DIBENG.DLL does exactly the same thing, but takes the idea one step further by making the video framebuffer itself a memory bitmap, optionally using the VFlatD VxD to present a bank-switched graphics card as a linear framebuffer.
The exact history of the WinG and Windows 95 DIB Engine is unclear. WinG was released in September 1994, when Windows 95 was already well underway. It is possible that the DIB Engine was planned for Windows 95 and repurposed for WinG—which also ran on Windows 3.1 and NT 3.5. Or perhaps the DIB Engine was first written for WinG and then adopted for Windows 95.
Minidriver in C
The OS/2 Museum Win9x minidriver is written almost completely in C (using Open Watcom C/C++), in part to show that not only it can be done, but it isn’t even too difficult, and the code is significantly easier to understand than the all-assembly DDK sample code.
Writing the driver in C was mildly challenging. The biggest challenge was the fact that the Windows 9x display driver is a 16-bit driver, which means it has to deal with segmentation. That’s actually something which is easier to deal with in C, because the C compiler provides a lot more sanity checks than assembler can.
A somewhat nastier problem was that although the Windows DDK documents all the functions which the driver needs to implement and the DIB Engine functions it can call, the DDK does not provide prototypes for those functions. Although the documentation does pretend to list the prototypes, it often omits return types, more or less always omits the calling convention, and sometimes is a bit sloppy with argument types.
I spent a good deal of time trying to figure out why the CreateDIBPDevice
function was failing. I kept looking for bugs in my initialization code, but in the end I discovered that even though CreateDIBPDevice
is a 16-bit function, it returns a 32-bit value not in the DX:AX register pair but rather in the EAX register. The Windows 95 DDK completely fails to mention this non-obvious yet crucial detail; I found it “documented” in U.S. Patent 6,525,743.
The driver also implements and calls a couple of undocumented functions. One of the functions it calls is AllocCStoDSAlias
, which Microsoft’s KB Article Q67165 admits is used in the Windows 3.0 DDK but says it “will not be supported in future versions of Windows”. In reality it was of course supported all the way to Windows Me…
Supported Resolutions
While the Windows DDK sample drivers are all hardcoded to support a small set of resolutions, the OS/2 Museum minidriver is not. It restricts the smallest resolution to 640×480 but not much beyond that. The maximum allowed is 5,120×3,840 pixels, but that is entirely untested.
The supplied .INF files sets up common resolutions up to 1,920×1,200 pixels, but users can edit the .INF file (or Registry) and add their own resolutions. Note that Windows 9x likely will have trouble if there are “too many” modes listed, and it is unknown what the highest resolution might be before funny things start happening.
Installation
The driver can be installed through the Display Properties dialog or through the Device Manager; the method used should not matter.
The driver works on Windows 95, Windows 98, and Windows Me. No attempt has been made to discover how far back it might work with Windows 95 betas.
Is it technically possible? Yes. Do I have any interest in doing that? Not really, no. Maybe in another 10 or 20 years 🙂
In my case, we are using our machine program on windows 98 so need help to installing of VGA after cloning the HDD
This simple virtualbox display driver does not support DirectX at all, which basically renders itself useless.
Don’t use it if you don’t like it. For me, it works very well.
What if this works on Windows 3.11 for Workgroups?
Not a chance. Windows 3.1 drivers work in Windows 95, but not the other way around.
There (still) is something weird going on. The RSS feed says that there are new comments here, about if a Win9x driver would work on Win 3.11 and an answer stating that it won’t.
However when actually viewing this page, the latest comment I see is from nov 2022.
A reload doesn’t help.
Btw this is the DNS response I get. Is the site hosted on some (questionable) could service that sometimes don’t propagate updates correctly? Or is there possible some configuration error where updates aren’t flagged as updates and thus only visible for some but not all viewers?
$ host http://www.os2museum.com
http://www.os2museum.com has address 188.114.96.1
http://www.os2museum.com has address 188.114.97.1
After posting I was able to see newer comment once, but then the comment from 20 nov 2022 by Tori wasn’t visible. After reloading the page everything new including my comment disappeared but Toris comment came back.
There is something weird going on with the blog.
Driver based on this one, but adding 3D acceleration (utilizing Mesa, etc.) – https://github.com/JHRobotics/softgpu
Yes, I heard of it. Anyone have any experience with it?
Usei o Virtual Box 7.0.12. com Windows 95. (Propriedades de video/configurações/Propriedades avançadas) A atualização funcionou perfeitamente em True color (32bits) e 1024×768 pixels.Parabens aos desenvolvedores e obrigado.
@MiaM Is there a “Newer Comments” link at the bottom of the comments section?
@Vikki:
In some cases that has been the explanation. But in other cases, like for the “OS/2 2.11 SMP Woes” post the RSS feed clearly shows a comment by Robert almost three hours ago, but that comment doesn’t show up when I view the post with its comments, no matter if I reload or not.
I think it’s a problem with propagation across multiple web servers, where the RSS feed gets updated before the actual page contents gets updated everywhere.
Commenting will obviously force all of the latest comments to show up when I comment something, but a reload again will hide my comment and any that also was hidden at the time.
It’s probably something I’ll have to live with. A bit weird that it happens on a site that runs on it’s own domain rather than at for example blogspot/blogger or some similar site where many blogs reside.
Also maybe I’m the only one in my part of the world that reads this blog, and thus propagating the content to servers near me has a really low priority?