Going Generic...

by Roderick Klein

(Not update to date with the release of the driver of 24 december of 2000)

History of this driver and some background information.......
OS/2 is an operating system that provides great stability. One of the reasons its so stable is because applications don't have direct access to the hardware or the memory where the kernel of OS/2 runs. For sound support in WIN/OS2 and DOS sessions this however does bring some limitations. Even when a hardware manufacture has written a perfect sound driver, not all DOS games will run under OS/2, simply because some of them "talk" to your soundcard in a way that is not allowed under OS/2. This is however a very small portion of the DOS games that won't run in an OS/2 DOS session when sound is used.

The way in which OS/2's virtual DOS machines (VDM) are engineered automatically allows protected access to hardware from DOS without necessarily requiring a VDD. OS/2's DOS emulation kernel maps IRQ's, I/O ports and memory directly into the VDM, allowing a DOS application to access the hardware. Such accesses are mutually exclusive, however, i.e only one DOS session (VDM) can access the hardware at any one time. If the I/O is handle-based, however, access by more than one VDM at a time is possible (for example DOS INT-21 file requests are routed directly into the OS/2 file system, and these have to be shareable). Therefore, for block devices all that is necessary is to provide an OS/2 physical device driver for the service that appears as part of the filesystem. DOS sessions and OS/2 both then access the device using the standard filesystem calls for each operating system.

A VDD is required normally in two instances. If the I/O is not handle based and can not be accessed through filesystem calls, and it is also required that the service be shared across multiple VDMs, then a VDD is used to arbitrate access to the service. Secondly, if the time between a physical interrupt being received in an OS/2 physical device driver, and the DOS session being notified of the interrupt is critical, then a VDD can be used to communicate with the OS/2 physical device driver and ensure timely notification of interrupt to multiple VDMs.

Windows VXDs are not really similar to VDDs under OS/2. They do have the following in common. Both VxD and VDD are 32-bit modules running at Ring-0. This is largely where the similarity ends. VDDs can be used to provide services to a WinOS/2 session which approximate that provided by a VxD under Windows, but the mechanism is different. VxDs can talk directly to the hardware, whereas a VDD does not (it uses a corresponding OS/2 physical device driver). OS/2 provides no facility to load VxDs (look at the problems that badly-written ones cause for Win9x), but some of the services that would have to be provided by a VxD under windoze can be provided by a VDD under WinOS/2.

Supporting WIN/OS2 is even more work then providing DOS support besides the VDD driver for DOS, the WIN/OS2 driver is in many cases different compared to the normal Windows 3.1 driver. When running Windows 3.1 under normal DOS (so no OS/2 loaded) Windows can access all the hardware and memory area's. Under Windows 3.1 there are a kind of VDD's, so called VxD files,  they have the  extension 386 or sometimes vxd (these are however mostly found under Windows 9x). These Windows 3.1 VxD want to have straight access to the hardware and want to run on the same level as the OS/2 kernel. These files will normally not load under OS/2. There are for instance a few Windows 3.1 fax programs that install there own VxD file to speed up the serial port. Under WIN/OS2 these will not load. When you for instance install a Crystal driver on your OS/2 system, rem out the VDD driver in the CONFIG.SYS, reboot the machine and startup WIN/OS2 it will say that 386 file for the Crystal is not loaded. How manufactures do this is not clear to me, the can make the VDD in such a way that the is really 386 is loaded or in the VDD file there is some kind of an emulation to fake the driver. One thing is clear some effort is needed from a manufacture to add DOS and WIN/OS2 support.

The first Windows 3.1 soundcards did not have such a VxD so if you have a old soundcard there is change (if you have a PDD and VDD driver) that this driver may load. All though Windows 2000 is coming there is still support for Windows 3.1 around. All the manufactures that have made OS/2 drivers for PCI chipset, except Crystal Semiconductors, have not added WIN/OS2 support. There are also a few OS/2 programmers that are changing PCI drivers so that they will work with other chipsets of manufactures. More information on this can soon be found on the "PC I OS/2 homepage" (if I have time to put it together ).

To make this complex story a little bit easier to understand, the following diagram:

WIN/OS2 device driver /\ |     |  \/   VDD(Virtual Device Driver) /\ |     |  \/.   PDD (Physical device driver) /\  |      |   \/   Soundcard

The PDD driver is the driver that really controls the hardware and the VDD driver makes access possible in DOS sessions, the WIN/OS2 communicates via the VDD driver with the VDD and PDD.

That the amount of OS/2 users has dropped is true, the manufactures that provide OS/2 support have reduced there drivers in many cases to native OS/2 drivers only. Some of them still come with a VDD, but a WIN/OS2 driver is not included in many cases. When IBM was working on OS/2 Warp 4 some soundcard manufactures also did not include WIN/OS2 drivers because of the extra cost. This is where the generic device driver comes in! IBM already had a kind of generic WIN/OS2 driver (another thing that never really got of ground, partly because of the famous IBM gray suites), the had a port of OS/2 to the PowerPC. Before the release of OS/2 Warp 4 for the PC Richard Gerant was working on a port of the general WIN/OS2 driver from the Power PC to Warp 4. (how it works is mentioned below and shown in the diagram). When you look at the diagram you could say that WIN/OS2 looks like a native OS/2 application in the eyes of the OS/2 audio services. In WIN/OS2 there is a Windows 3.1 driver that can be seen as translator that handles the calls to from Windows 3.1 Multimedia and then sends these data to the VDD of this and then sends these calls to the PDD driver!

The logical question is then asked "Well why have we never seen this driver", the answer is simple, it was never finished.

John Gow explains how it all went:
It all began way back in 1995, with the advent of OS/2 for the PowerPC. Some guys at IBM attempted to allow WinOS/2 to make use of the OS/2 audio resources, rather than require a separate, audio hardware vendor supplied driver for the WinOS/2 component, as had been required hitherto ever since OS/2 started supporting multimedia audio. Given the way that WinOS/2 is a layer running atop one of OS/2's virtual DOS machines, it seems sensible that WinOS/2 should use the audio resources of OS/2 itself, thus requiring hardware vendors to produce only one driver for their hardware - that for OS/2 itself.

In the PowerPC architecture, this was accomplished with the aid of a virtual device driver (VXXX.SYS file, or VDD) and a small stub Windows .drv file simply to provide the interface to Windows. All the hard work was done in the VDD, which in the PowerPC architecture had the ability to appear as an OS/2 application, and therefore could issue ring-3 calls from within the VDD. The presence of DART (direct audio routines) allowed for speedy access to the OS/2 audio device buffers for wave functions - and thus all that remained was for the VDD to grab buffers from WinOS/2 via the .drv file, massage them a little to get the data into the correct form, and then pass them directly to the DART API. Likewise buffers returned from DART could be subjected to the same treatment in reverse, in order that the data may be returned to WinOS/2. It worked, and apparently worked quite well. After all their hard work, IBM then decided to cancel OS/2 for the PowerPC. This left lots of lovely code, with no platform to run it on. Except maybe Warp 4 (Merlin) on Intel platforms. Unfortunately, the architecture of Warp 4 is such that VDDs can not call ring-3 API functions directly. To port the code to Merlin, a different approach was needed. A small ring 3 application was created, designed to run as a background process started from the CONFIG.SYS file (deamon). This de deamon contained very little actual processing, and was basically a vehicle to allow calls into the DART API. Although a ring-3 OS/2 application can call into a VDD without problem, a ring-0 VDD can not call into the application. However, with the aid of some ring-0 VirtualDevHelp functions the VDD can access 32-bit semaphores. Using this mechanism the daemon can call into the VDD and be blocked on a semaphore. When the VDD has news for the daemon the semaphore can be released and the call returns to the daemon with a modified parameter list. This way the VDD can call DART via the daemon. The changes of context involved with this data path did not add to the efficiency of the port.

This is how the driver worked first......

When the developer was working on this project at IBM he was taken off this project and he had to work on Voice Type for Warp 4. At the end of 1998 or the beginning of 1999 the source codes of the more or less unfinished project ended up on the DDK (device driver site for developers). The original IBM developer also "finished" the driver and added a small WIN/OS2 driver for wave play back, which works quite well.

However, it appears that after the original authors left IBM, some further work was done on the driver. The original architecture of the data path made use of three linked lists containing buffers, and data was copied between them depending upon the state of the buffer. In the new version wave-in support was stripped out and the data path re-engineered in the form of a buffer, which could effectively break the link between the WinOS/2 context and the OS/2 context, and make for smoother data transfer. DART-based processing was transferred largely to the daemon, while WinOS/2 message and buffer handling was coded in the VDD. This code was deposited on the IBM device-driver kit site, and the binaries are available from various sources. It is here that I entered the scene. Frustrated with the apparent lack of vendor support for WinOS/2 for PCI sound cards (I know, except Crystal Semiconductor, but show me somewhere in the UK where you can easily buy a PCI soundcard with one of their chipsets!) I started to investigate this driver. I played about with the binaries, but about the only thing they were good for was to hear the 'ta-da' upon opening WinOS/2. Not much else worked properly. So, as an engineer with a love of low-level programming I started to look at the sources I found on the DDK. The source I found on the DDK certainly showed the correct concept, in my opinion, but the implementation was, frankly, both incomplete, and in places, horrible. There were a number of serious bugs in the code, especially in the WinOS/2 return path and in the data path itself. After a couple of months wading through the code I came to the conclusion that the data path would have to be completely re-engineered in order to both fix the bugs, and to permit the addition of wave-in support.

Rich Jerant, one of the original authors, has been extremely kind and helpful and sent me his original source using the linked-list method - I recompiled this and tested it for performance against the recompiled partially debugged DDK sources, and the buffer method seemed to perform consistently better under a variety of machine loadings and settings, and used significantly less CPU time (if that little WarpCenter system load graph means anything!) This seemed to vindicate my decision to re-engineer the driver using a buffered arrangement. So I set to, and during my odyssey of coding so far I have completely re-written the buffer handling to allow bidirectionality, improved the DART communication, added wave-in support and fixed a lot of bugs. Better support for some of the windows driver messages has also been added. Some functions required complete rewrites to achieve the desired level of functionality.

To give an example of the performance of the current driver, at present it allows me to run an interactive German course for WinOS/2 which relies heavily on wave out and wave in (it uses speech-recognition). It works quite well. RealPlayer 5 works fine with both sound and video when playing a file, but it currently does not function correctly with data streamed from the internet. From the debug dumps this appears to be a problem with DART, and not the driver (buffers are correctly written, but for some reason DART only sends the first few back!). Windows Sound Recorder now works completely for both replay and recording. Volume sliders also now work. Pause and resume processing is now implemented correctly. To see how the re-engineered driver works, see the figure. Data is passed through from WinOS/2 via a stub device driver (os2wave.drv) into the VDD, where it is queued. Depending upon the direction of the data flow, data is either ripped from the buffer to the queue, or from the queue to the buffer before the queued data is returned to WinOS/2 via the stub. Asynchronously to these events, in the OS/2 context, data is either ripped from the buffer to the DART buffer array, or passed in the reverse direction. The actual handling of DART buffers and the associated buffer management is performed in the daemon, with calls into the VDD simply to fill or empty DART buffers.

There is more to do, I intend eventually, if possible, to add MIDI out support, and maybe MIDI in, if I can. At this moment a closed beta is taking place (second week of december). A public release will be ready around the end of december or the beginning of the new year.. This project is freeware, so if you have a PCI sound card with no WinOS/2 support, there is hope in this driver!



There

This is how the driver works now.

ACKNOWLEDGEMENTS:
I must thank Rich Jerant for his generous assistance with source code and advice, and together with Joe Nord for coming up with the original concept. Without the code skeleton a working driver would have been a lot longer in the coming. Thanks, guys.

RELEASE SCHEDULE:
Release 1.0: The current offering from the IBM DDK, available from various sources. I have had nothing to do with this code. Release 2.0: This version you can download now (23 of december 2000). Wave-in and wave-out is be supported. Minor release numbers may contain bug fixes and improvements in functionality. Selection of Line in and Microphone is also included. Release 3.0: At this moment MIDI playback in WIN/OS2 is working more or less. I can play a MIDI file for about ten seconds and then the sound breaks up. This is still very experimental a public release may be released at the beginning of                 January 1999. (This was dropped) Release 4.0: The release now for download has the new datapatch in place. It supports WAVE in/out and MIDI playback. Release 5.0: Add support for Soundblaster emulation for DOS sessions.

Release 6.0: Add full duplex support for WIN/OS2 and a DLL for developers to use the fast interface in native OS/2.

© 1999/2000 Dr John A Gow developer of this project: j.a.gow@furrybubble.co.uk