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.
Maybe you could have put the download link somewhere in the article; it’s pretty hard to find otherwise.
DL link: https://www.os2museum.com/files/boxv9x.img
Yeah… I didn’t mean to publish the article yet. I added a download link and it is not the one you found.
Okay, sorry, yeah I was confused a bit by the short post π
Feel free to remove the link in my post (or the whole post) if it’s not correct anyway
No problem. I fixed your link and removed the old disk image.
Nice! Does this target the newer VMSVGA ? Or the older VirtualBox VGA device ?
Also: No source? π
I had problems writing (using Open Watcom) a mixed 32/16 VxD that would be dynamically loadable from Win9x, since the watcom linker seems to put some attributes in the VXD/LE section headers that 9x didn’t like. I’m curious to see if display VxDs are purely 16-bit (not subject to this problem), you found a workaround, or are using a different linker π
The VirtualBox mouse.drv I made for 16-bit Windows ( in Watcom too, see https://git.javispedro.com/cgit/vbmouse.git/about/ ) does load under 9x and actually works (if you do the manual installation via system.ini — a testimony to all the craziness Win9x had to do in order to preserve binary compatibility with win16) .
But just for fun I was considering making a native 32-bit 9x mouse miniport driver/vxd (in C).
It targets the VirtualBox (bochs heritage) video device because it’s super simple to program for. Basically VMSVGA would make the code more complicated with no upside.
I will release the source code when it’s cleaned up a bit.
There is no VxD in this driver. The last time I worked on a VxD was twenty years ago and I think that was with Microsoft tools. I’m pretty sure others have written VxDs with Open Watcom but I have no direct experience. The minidriver is a 16-bit DLL, at least if you don’t count all the 32-bit registers it uses here and there.
Windows 9x is a very strange beast. It preserves compatibility with DOS and Windows 3.1 by being DOS and Windows 3.1 on steroids. There’s a lot of 32-bit code in Win9x, but at the same time all the old 16-bit code is there too, and Windows can use either.
As far as display drivers are concerned, the Windows 3.1 DDK documentation is quite useful because the Windows 95 DDK was clearly written for people who already knew how Windows 3.x drivers worked.
Ah, interesting, since the win16 video drivers do have both the usermode DLL part as well as the 32-bit VxD part (for 386 windows). Mouse drivers were likewise also 16-bit DLLs in win16 , actually loaded by user.exe (and one could consider VKD/VMD as the “32-bit part of the mouse driver”).
I am curious how does 9x do it without the 32-bit graphics part. I guess it just assumes a VGA card for stuff like DOS fullscreen window switching.
I tried boxv9x / boxvmini.drv and it does work (also DOS boxes). Got stuck into a black screen when switching directly from VBEMP (which a full reboot fixed) , but that’s already an improvement from the existing drivers. Thanks a lot!
On screenshot there is “Desktop area – 1920Γ1200 pixels”, but screenshot image resolution is just only 1152Γ864 pixels ( https://www.os2museum.com/wp/wp-content/uploads/2022/06/boxv9x.png )
Could be there placed screenshot in 1920Γ1200 pixels, as it set in “Desktop area” settings?
Exactly, Microsoft supplied a VxD (VDD) with Windows 9x that handles fullscreen VGA support. Vendors could write a mini-VDD to support Super VGA. I don’t see any point in that, since DOS stuff is not really going to work better under Win9x.
The architecture all goes back to Windows/386 (1987). The “native” Windows drivers are 16-bit DLLs and the DOS compatibility/virtualization drivers are 32-bit VxDs.
Sure, the screenshot is of a 1152×864 desktop, showing the maximum resolution available in the dialog. I didn’t see the point of wasting space with so many boring pixels π
It is funny how AllocDStoCSAlias is documented but AllocCStoDSAlias is not.
This looks amazing! Are you able to publish the source code? I’m really interested in reading it and learning more about how Windows 9x drivers are built.
After I clean it up a bit, yes.
In general, Windows 9x display drivers are built much the same way as Windows 3.1 display drivers, and that is the case all the way to Windows Me. The big difference is the DIB Engine which makes it possible for the Win9x driver to be massively simpler and smaller than a Windows 3.1 driver.
Can I ask to put boot mark AA55h@1FEh in your boot images? It is not hard to do myself but will be better if it exists from the beginning.
Why? There is no requirement for floppy boot sectors to have the AA55h signature. DOS doesn’t need it, Windows 9x doesn’t need it, Windows NT doesn’t need it… so who does?
AFAIK WinG would use VFlatD on a supported (DVA compatible) device (they are mentioning Tseng and WD here http://archive.retro.co.za/CDROMs/DrDobbs/CD%20Release%2012/articles/1995/9513/9513g/9513g.htm ). I think this evolved from the need for a fast path to the graphics card for video (DCI, which was later dropped during the Chicago betas) and was finally replaced when DirectX appeared.
I’m confused. Does this mean that OS/2 can run Win 9x programs for a better Win 9x than Win 9x?
I’d be surprised if that was the case. I’d think that OS/2 would use it’s own video drivers and by-pass Windows’ drivers entirely.
Yes, OS/2 always used its own video drivers. That said, the old (pre-GRADD) OS/2 display drivers and Windows 2.x/3.x/9x drivers have common heritage. They’re far from interchangeable but their overall design is similar, and it’s clear that they were at least partially written by the same people.
The way that article describes VFlatD does not at all match what I know about VFlatD. But it’s certainly right that WinG does (can?) use VFlatD. I assume it’s for the same reason that Windows 95 does — the DIB Engine requires a linear framebuffer, which may be implemented in hardware but if it’s not, VFlatD can simulate one.
VFlatD is a pretty clever idea, it simplified the drawing code a lot and very likely made it faster, too.
>so who does?
Modern archivers, of course…
>DOS doesnβt need it, Windows 9x doesnβt need it, Windows NT doesnβt need it
I don’t remember well but AFAIK format puts this mark even on floppies.
Seems Windows 3.1 shipped with DIB.DRV which was the same core idea as WinG (a special “device” that handles generic memory bitmaps), except DIB.DRV had no way to blit to the screen and often didn’t perform terribly well.
Some later video cards actually came with DCI accelerated video drivers. It was mostly used by VfW and QuickTime to speed up video scaling and playback. WinG could use it too. Thing is all this came out right before Windows 95 and promptly got dropped, so little hardware or software exploited it.
It took some vendors forever to get proper working Windows 95 drivers too. I remember the Viper VLB suffering from this since the driver for its Weitek Power 9100 chip was way late. I’m still impressed that Windows 3.1 video drivers worked on 95 as well as they did.
I’m not that impressed π There is a very direct line from Windows 95 display drivers back to Windows 2.0 if not 1.0. In fact reading Windows 3.1 and 2.1 DDK documentation has proven quite helpful in understanding a number of weird details that the Windows 95 DDK does not bother explaining.
BTW, was such thing as DDK available for Windows 1.x?
How does it differ from the VBE9X driver (can be googled by “VBEMP 9x Project”)?
I believe it was, but it was probably called OEM Adaptation Kit or some such. It is possible that the DDK did not yet exist as a “packaged” product and Microsoft provided the necessary information to the tiny handful of OEMs who wrote any Windows 1.x drivers.
For Windows 2.x there definitely was a DDK (called OEM Binary Adaptation Kit), and in the same era DDKs for OS/2 also existed. With Windows 3.0, there was a product called DDK, except I don’t think anyone has a copy.
It differs by not using the VESA BIOS at all. So it won’t work on any real hardware, but it is not limited by the modes offered by the VirtualBox VGA/VESA BIOS.
One mystery to me was later Windows 3.1x drivers (those released roughly 1994 and later) liked to change the default color theme from the dark blue title bars to a light blue. Given that it is a common feature to just about every vendor’s driver, I kinda suspect they were all using some sort of “base” libary to develop video drivers.
Would make sense if a 3rd party marketed such a product given how difficult it seems to write a proper 3.x driver. It seems to be easier to write an emulation of a a whole video chip that has a supported driver vs. writing a generic Windows 3.1x driver!
Chris M:
I have no proof whatsoever, by my gut feeling was always that the lighter blue v.s. darker blue change just happened when you installed some software that included newer versions of some common DLLs. I might be totally wrong though. It would be really interesting to know which file is responsible for the change, but I lack the time and energy to do different tests to find out.
So, when you are saying about “reading Windows 3.1 and 2.1 DDK” do you mean Windows 2.1 DDK or OEM Binary Adaptation Kit? Or both existed?
This is not to be picky, just trying to understand what earliest version of something helping to write drivers was released π
Binary Adaptation Kit (BAK) = DDK for the purpose of this discussion. The product was called Binary Adaptation Kit in the Windows 2.x times, and it was essentially a superset of the later DDKs. The BAK included everything that OEMs needed to create their own customized OEM version of Windows 2.x. There were all the sample drivers that later appeared in the DDK, but where was also Windows setup, fonts, and various Windows components that OEMs could adapt.
In Windows 3.0 times, the situation was different in that a) OEM versions of Windows were less necessary because core hardware was more uniform, and b) vendors of hardware such as graphics cards needed to be able to write Windows drivers even though they had no desire to ship Windows. In the Windows 2.x era, graphics hardware vendors used the BAK to write display drivers for their hardware.
I don’t know what there was in Windows 1.x times — BAK, DDK, both, or something else.
The only base I know of was the DDK… that said, it would not at all surprise me if there had been some consulting company that no one ever heard of which actually wrote or co-wrote a lot of those drivers. The driver does have the default palette baked in, so it probably makes a difference.
And yeah, I think you’re right that writing an emulation is easier. In fact I would even say that writing a graphics chip emulation from scratch is possible given decent documentation, while writing a GDI driver from scratch almost certainly isn’t, at least not without inordinate effort.
I certainly found it easier to emulate graphics hardware rather than write a GDI driver from scratch, when I wanted to see what Windows 1 looked like in 256 colours.
One other avenue I’ve never explored but seems feasible is to use virtual DOS drivers to run real-mode Windows 1.x / 2.x in a DOS box under NT 4, with video / keyboard / mouse drivers that hand everything off to the host system’s GDI.
@Chris M:
Regarding the change from dark blue to light blue titlebar, from experimentation it the colors seem to switch as soon as you switch the color depth to 16-bit or higher. I haven’t tried with 256-color mode though, so it might switch then too.
-Wilhelm
Pingback: Windows 9x Video Minidriver Source Code | OS/2 Museum
Just in case anybody was wondering β it is possible to run Windows 98 in 5k:
https://eternallybored.org/imgs/compstuff/win98_5k.png
Wow, that’s a lot of screen real estate! Thanks for the screenshot, I was wondering if it actually works.
There are a few problems with redrawing (when I resized the almost full-screen Defrag window, it left trails everywhere), but seems to work fine otherwise. PrintScreen only captures black-and-white image at 5k 16-bit, but works fine at 8-bit colours or 4k 16-bit (VirtualBox’s View β Take Screenshot doesn’t work at all at 5k β just saves a blank image).
4k 24-bit is a bit broken, but I think this is a bug in VirtualBox, since View β Take Screenshot doesn’t capture the problem: https://eternallybored.org/misc/imgs/vbox/4k24bit.png
There’s almost certainly a lot of untested code paths involved on all sides. I’m surprised it gets that far at all.
Did a bit more testing, the highest resolution I can set is 5120×3840 β not sure where the limitation comes from (I have two 5120×2880 displays arranged horizontally).
It comes from the driver. The limits are 5*1024 horizontal and 5*768 vertical. It clearly works poorly enough already that there’s not much point in extending it.
Ah, too bad, I wanted to try Win98 in 8k π
Actually… it’s much simpler than I thought. The light blue titlebars are something the 256-color DDK sample driver (Video 7) does. I can’t check if the Video 7 driver shipped with Windows 3.1 does that too, but the DDK sample does it. So that’s where it came from. The color is called “cool blue” in the source code.
And it’s actually not the default palette but rather the default Windows color scheme that controls this. It’s stored in the driver’s resources.
I have a feeling a lot of developers just copy/pasted most of the 3.1 DDK drivers when they wrote their own. I’ll take a peek and see how much one would have to rewrite if the driver doesn’t expect to do any hardware GDI acceleration.
Microsoft’s own generic VESA SVGA.EXE drivers didn’t change the default color scheme. I remember having to install those because for some reason my old CL-GD542x drivers didn’t support something that WinG wanted.
They had to copy/paste most of it because not doing so would have been crazy. Among other things, Windows 3.1 display drivers had to fully implement rendering into 1/8bpp memory bitmaps, in addition to rendering into screen format bitmaps, including blitting between the different formats. There is also a lot of boilerplate functionality related to fonts, widgets, color schemes, and other things. I don’t mean all the files typically shipped with a driver but also the resources built into the driver module itself. It was almost impossible to not take one of the sample drivers as a starting point, and certainly the expectation was that people would do that.
The Windows 3.1 DDK Video 7 sample driver is about 1.5 MB of source code. I would estimate that hardware specific acceleration is less than 10% of the total source code size. In other words, the vast majority of code is what more or less everyone would need because it’s either generic fallback code or needed for memory bitmaps.
Of course there were “historical reasons” for that — when Windows started out, there were only device-dependent bitmaps (DDBs) and different display devices tended to use wildly different formats. By the time Windows 95 rolled out, DDBs were all but dead and device-independent bitmaps (DIBs) could handle everything. I believe Microsoft could have implemented a generic DIB Engine in Windows 3.1 but maybe they just hadn’t thought of it soon enough or couldn’t get it done in time, and by the time they had it, they didn’t really care about Windows 3.x all that much.
Thank you for your work, Michal! Is there a chance that you will publish a QEMU compatible variant of the driver?
I have no interest in doing that, sorry. But the source is available if someone else wants to have a go.
Pingback: Antique Display Driving | OS/2 Museum
@Michal Necasek, Great work!
Now that you almost reached the maximum backwards in time (Win 1.x Antique Display Driving), what about going in the other direction – 3D acceleration?
For host with VirtualBox 6.1.40/7.0.4:
– making VirtualBox 6.1/7 3D host-acceleration work in guest Vista (apparently even VBoxSVGA support was dropped after 6.1.0_RC1)
– making the above work in guest WinXP/2K (for VBoxSVGA or VBoxVGA ?) – official VBoxVGA 3D host acceleration was dropped from 6.1 or 4.2
– making the above work in guest Win9x (as WDM)
– expand support to DX1-DX7 versions via WINE/MESA/etc. (apparently official VirtualBox driver supports only DX8-DX11)
– making the above work in guest Win9x (as VxD)
– making the above work in guest WinNT (as Windows NT Driver Model)
– expand support to WinG
– making the above work in guest Win3x (as VxD)
Is some of that possible?
Use case examples:
– DX8 applications from the late 90s in Win9x that don’t work completely in XP (like Mechwarrior 3), especially those that don’t work well (or at all) with DirectX software rendering
– DX9, P4 1.4GHz, 256MB RAM, 2005 – Age of Empires III (one of the latest games that can work in Win9x)
– DirectX/OpenGL applications that do not work in Win7 or later
– https://github.com/joncampbell123/dosbox-x/issues/3405