leecher1337 / ntvdmx64

Run Microsoft Windows NTVDM (DOS) on 64bit Editions
823 stars 81 forks source link

Please support hardware Vxd drivers. #203

Open ytrezq opened 2 years ago

ytrezq commented 2 years ago

The point is ntvdm already supports vxd loading like dsound.vxd for providing DirectSound support. On the other end, there are more and more hardware like Fax and hardware‑based sound synthesisers which only have legacy vxd or early ɴᴛ drivers like the ᴏᴘʟ3 card.

Would it be possible to get those vxd to pass low‑level data to such ᴘᴄɪ or even ɪꜱᴀ devices ? Of course, the hardware would only work with Windows 16‑bits applications.

cyberluke commented 2 years ago

This would be great also for my retrogaming project - a lot of joystick Win98 only devices with VxD driver and proprietary force feedback (InterAct Racing Wheel)

leecher1337 commented 2 years ago

Unfortunately, the VxD driver model is completely different than the NT driver model, there is a reason why this wasn't implemented by Microsoft into the NTVDM and there are only VDDs (NT replacement to VXDs). VXDs are very specific to Win9x (16 bit) Kernel and there are no comparable facilities in the NT kernel or the emulated Win16 kernel of NTVDM. I was playing around with them a bit recently, I submitted a patch to dos32ang to load them in DOS so that the realmode part can be loaded via a modified dos32ang (very hacky, but worked, can share patched dos32ang that loads a VXD, if someone is interested), but the protected mode part of VXD for Win16 still is complicated. iirc, even WINE doesn't support them and only has a stub loader. Any help getting them to run partly would be appreciated, though.

If you want to support real hardware which is connected to Host Windows and already has a driver working there, I suggest to write a VDD driver and a corresponding 16bit driver that interacts via BOPs with the VDD (that's the recommended way to implement NTVDM drivers). For interacting from DOS, this usually works fine.

leecher1337 commented 1 year ago

Here is an example on how to write your own VDD driver extensions to replace the VXDs: https://github.com/leecher1337/antzvdd

ytrezq commented 1 year ago

Here is an example on how to write your own VDD driver extensions to replace the VXDs: https://github.com/leecher1337/antzvdd

I have the reverse problem as the code I need to run is in the vxd, and the vxd I m talking about contains many register settings for the real hardware. Not running the vxd can t be avoided unless finding how to run 32 bits .sys on 64 bits Windows.

leecher1337 commented 1 year ago

First step is to reverse engineer the .sys driver, then you can try to write a 64bit driver based on your reverse engineering results.

ytrezq commented 1 year ago

First step is to reverse engineer the .sys driver, then you can try to write a 64bit driver based on your reverse engineering results.

Something very hard as the userland interface is standard but hardware isn t. Those who attempted it never completed it. This is also why the Linux driver is stripped down in important features (especially the signal generator).

Getting the vxd or the .sys to send the unknown and receive those unclear irq seems not be that much more difficult.

leecher1337 commented 1 year ago

Of course, it's very hard, but I see no other way. You cannot make a Ring 3 usermode application like NTVDM to acccess hardware directly, which would require Ring 0. I/O Permission bitmaps on Windows are only supported in 32bit mode, not in Long mode, so you cannot pipe through I/O like it is i.e. done for fullscreen graphics of NTVDM to directly access the VGA card. And the whole architectore of the WOW16 isn't laid out to supoprt VXD-drivers, so this is also a dead-end.

In case it is a scanner driver, I recommend the appliction VueScan which has a very wide list of supported Scanners where no 64bit driver from the vedor exists. But "Signal generator" doesn't sound like a scanner.

ytrezq commented 1 year ago

Of course, it's very hard, but I see no other way. You cannot make a Ring 3 usermode application like NTVDM to acccess hardware directly, which would require Ring 0. I/O Permission bitmaps on Windows are only supported in 32bit mode, not in Long mode, so you cannot pipe through I/O like it is i.e. done for fullscreen graphics of NTVDM to directly access the VGA card. And the whole architectore of the WOW16 isn't laid out to supoprt VXD-drivers, so this is also a dead-end.

In case it is a scanner driver, I recommend the appliction VueScan which has a very wide list of supported Scanners where no 64bit driver from the vedor exists. But "Signal generator" doesn't sound like a scanner.

The other way is to behave in a ndiswrapper like manner by wrapping the required abi endpoints which unlike the driver are partly documented. The extreme difficulty for reverse engineering doesn t make wrapping more difficult (the fm generator require huge mathematical knowledge for being controlled). Otherwise, the user mode driver framework indeed allows to send irq to pcie from ring 3 on modern Windows.

leecher1337 commented 1 year ago

giveio64 has some weird tricks to access I/O ports directly also on 64bit Windows, from what I know, so it might become handy for porting the driver.

Still, the problem remains to get a VXD running, as WOW16 architecture is lacking all the stuff that is required for running VXDs, as its kernel is different from Win 3.x/Win9x kernels, even though it uses part of the Win 3.x sourcecode. If there would have been a possibility to make it work, M$ most likely would have implemented it. I extended dos32a-ng PM extender code with the ability to load a VXD file to memory for research purposes, if you want to play around with the VXD. But as the DOS and Win16 sessions have their own memory, how do you solve i.e. the problem of global variables that are used in the V86 and the PM-routines? In my driver example, the common VDD in 32bit land uses a shared section for that, but there the VDD-DLL is just a re-implementation of the original VXD which makes this possible. If you just load the VXD to memory on DOS and on WOW16, you can do that but then you're basically stuck.

ytrezq commented 1 year ago

giveio64 has some weird tricks to access I/O ports directly also on 64bit Windows, from what I know, so it might become handy for porting the driver.

Still, the problem remains to get a VXD running, as WOW16 architecture is lacking all the stuff that is required for running VXDs, as its kernel is different from Win 3.x/Win9x kernels, even though it uses part of the Win 3.x sourcecode. If there would have been a possibility to make it work, M$ most likely would have implemented it. I extended dos32a-ng PM extender code with the ability to load a VXD file to memory for research purposes, if you want to play around with the VXD. But as the DOS and Win16 sessions have their own memory, how do you solve i.e. the problem of global variables that are used in the V86 and the PM-routines? In my driver example, the common VDD in 32bit land uses a shared section for that, but there the VDD-DLL is just a re-implementation of the original VXD which makes this possible. If you just load the VXD to memory on DOS and on WOW16, you can do that but then you're basically stuck.

In my case, the driver job is to translate the very complex handling of the card to the simpler standard Windows api. From there, I was able in 98SE to run standard 32 bits Windows Media Player or vlc to use the card (and even relatively recent versions of Firefox through the vista compatibility layer for 98 and ME until I had to switch to a computer with a Xeon without full 32 bits support). The win.ini was showing it was the vxd driver being used.

Though, I agree to accept running Windows 16 bits version of vlc if it can fix my problems.

Nable80 commented 1 year ago

Something very hard as the userland interface is standard but hardware isn't. Those who attempted it never completed it. This is also why the Linux driver is stripped down in important features (especially the signal generator).

So, there is some Linux driver already (and some reverse-engineering efforts), it sounds interesting to extend. Could you provide more details about this device, please? Btw, there's an option to try dosemu/dosemu2 (VDM for Linux) or Win9x in KVM. It won't be an easy way (e.g. compared to working with real hardware from DOS in OS/2 MVDM) but it's not so painful IMHO as struggling with NT internals and tools.

ytrezq commented 1 year ago

Something very hard as the userland interface is standard but hardware isn't. Those who attempted it never completed it. This is also why the Linux driver is stripped down in important features (especially the signal generator).

So, there is some Linux driver already (and some reverse-engineering efforts), it sounds interesting to extend. Could you provide more details about this device, please? Btw, there's an option to try dosemu/dosemu2 (VDM for Linux) or Win9x in KVM. It won't be an easy way (e.g. compared to working with real hardware from DOS in OS/2 MVDM) but it's not so painful IMHO as struggling with NT internals and tools.

The over 20 years old Linux driver only does provide pcm signal conversion (using the card as a digital to analog converter which many more modern and any sound card provide). It doesn t handle the configuration of the signal generator which behave like a separate piece of hardware on the same chip (it also trigger a kernel panic if you try to use pcm input despite being in tree). There are however incomplete abandoned reverse engineering works on https://vogons.org on that part that still can t be used into any software (they just identified the code addresses in the vxd responsible for handling the registers of the card and identified most of them without understanding fully how they behave).

Also my computer is a special 6Tib of ram one: it is controlled through an on board arm computer (the bmc) and the bios run os through virtualization (allowing to expose some of the arm hardware as direct x86 equivalent through virtualization). You can run userland 32 bits programs but can t run 32 bits oses. You also can t do nested virtualization (I had to disable HyperV security on Windows) and are supposed to run multiple os through the firmware s vendor web interface (the default is to have all sata and pcie hardware as pass through). I m using ntvdmx64 through the cpu emulation mode.

leecher1337 commented 1 year ago

Naming the card name and linking the Vogons-threads about it may be helpful for readers that are interested in the issue.

Nable80 commented 1 year ago

The over 20 years old Linux driver only does provide pcm signal conversion (using the card as a digital to analog converter which many more modern and any sound card provide). It doesn t handle the configuration of the signal generator which behave like a separate piece of hardware on the same chip (it also trigger a kernel panic if you try to use pcm input despite being in tree). There are however incomplete abandoned reverse engineering works on https://vogons.org on that part that still can t be used into any software (they just identified the code addresses in the vxd responsible for handling the registers of the card and identified most of them without understanding fully how they behave).

Well... Is it possible to provide the name of this device? And which application/driver could use its full capabilities under which OS? Kernel panic isn't surprising, I guess there were no maintainers who had this hardware to test before accepting the driver. But it shouldn't be hard to fix, at least it provides much more information than BSoDs.

ytrezq commented 1 year ago

Naming the card name and linking the Vogons-threads about it may be helpful for readers that are interested in the issue.

(I m using the pci variant through a pcie adapter and the card is identified as VEN_125D&DEV_1969&SUBSYS_8888125D&REV_01 on Windows 11). https://www.vogons.org/viewtopic.php?p=738552#p738552. Since Windows 11 still support .sys sound drivers of the Windows Driver Model along it s virtual Roland driver, I managed to reanable hardware midi support (tested through late pcie SoundBlaster card with SoundMap loading through Linux). Given even the official 32 bits driver (but not the os/2 1) lacks the code to set up the default sound bank for midi playback (leaving only the rare games who made a custom use of it) and the less interesting fact that the generic Microsoft vxd opl3 driver which provided midi playback through a The Fat Man soundbank is still awaiting a wdm .sys port along the fact I'm still awaiting the result from the professional to whom I paid and lended the card during last August, that a midi playback driver which is able to recreate the original sounding of the default sound bank with it s pitch control per op instead of per pair can be forgotten.

I m interested in fm synthesis not as a way to generate poor unrealistic results, but as a way to create unsual sounds. Though just buying a Yamaha fs1r might be a larger but more straightforward computer controlled option.

leecher1337 commented 1 year ago

The project https://github.com/pachuco/ESSPlayMid looks active to me, does the demo player work with your card?

ytrezq commented 1 year ago

The project https://github.com/pachuco/ESSPlayMid looks active to me, does the demo player work with your card?

As it uses assembly, it lacks 64 bits support. It also doesn t attempt to replicate the original sound bank and thus the quality. Though, he use nt4 driver but there is an official wdm 32 bits only driver providing custom game compatibility.

leecher1337 commented 1 year ago

Using asm isn't really a problem, also for 64bit driver. Just the IN/OUT stuff needs to be replaced with 64bit driver doing the port access (or giveio64.sys may also work), so this wouldn't be a real issue. So the code in the .asm file isn't taken from vxd driver, but it's just an asm representation of the original NT4-driver which can be disassembled and ported easily anyway, it it has full symbols etc. I wonder what's the point of the ESSPlayMid project then, just porting the 32bit driver to 64bit? You can see that it is able top load custom banks. So loading custom banks isn't all you need then?

If it's just for the banks to be used, this could be exchanged in the resource segment of the Usermode MIDI-driver AUDDRIVE.DLL easily without even needing to reimplement this driver

ytrezq commented 1 year ago

Using asm isn't really a problem, also for 64bit driver. Just the IN/OUT stuff needs to be replaced with 64bit driver doing the port access (or giveio64.sys may also work), so this wouldn't be a real issue. So the code in the .asm file isn't taken from vxd driver, but it's just an asm representation of the original NT4-driver which can be disassembled and ported easily anyway, it it has full symbols etc. I wonder what's the point of the ESSPlayMid project then, just porting the 32bit driver to 64bit? You can see that it is able top load custom banks. So loading custom banks isn't all you need then?

If it's just for the banks to be used, this could be exchanged in the resource segment of the Usermode MIDI-driver AUDDRIVE.DLL easily without even needing to reimplement this driver

Essplaymid is just for doing the reverse engeeniering work (check prior versions of the readme). You have to test ideas to check is they are true. https://www.vogons.org/viewtopic.php?p=738552#p738552 says said bank (registers) is in the kernel driver.

After all, the card has in hardware opl3 compatibility. If it s just for basic midi, a more documented way would be to port the old vxd opl3 Windows driver which used adlib sound banks.

leecher1337 commented 1 year ago

The tables are both in the usermode MIDI driver:

Table Origin
bnk_NT4.bin AUDDRIVE.DLL
bnk_common.bin ESFM.DRV

Or which tables do you mean? So using the MIDI userland driver AUDDRIVE.DLL with the bnk_common.bin table does not give the expected sound output? (To test it, one can simply patch the table in AUDDRIVE.DLL and try it out on 32bit Windows where NT driver usually works, I guess). As far as I understand, the ESFM.DRV is the Usermode MIDI driver, as the AUDDRIVE.DLL is the MIDI usermode driver on NT (well-knowen dispatch function modMessage for MIDI output driver) and these are communicating with the kernelmode driver via IOCTLs (ES1869.VXD on Win 9x, AUDDRIVE.SYS on NT).

ytrezq commented 1 year ago

The tables are both in the usermode MIDI driver:

Table Origin bnk_NT4.bin AUDDRIVE.DLL bnk_common.bin ESFM.DRV Or which tables do you mean? So using the MIDI userland driver AUDDRIVE.DLL with the bnk_common.bin table does not give the expected sound output? (To test it, one can simply patch the table in AUDDRIVE.DLL and try it out on 32bit Windows where NT driver usually works, I guess). As far as I understand, the ESFM.DRV is the Usermode MIDI driver, as the AUDDRIVE.DLL is the MIDI usermode driver on NT (well-knowen dispatch function modMessage for MIDI output driver) and these are communicating with the kernelmode driver via IOCTLs (ES1869.VXD on Win 9x, AUDDRIVE.SYS on NT).

A third thing: on Windows 11 kernel dll need to be in 64 bits.

leecher1337 commented 1 year ago

Kernel DLL? The MIDI driver DLL is always user mode, the .SYS driver is kernel mode, when using the Installable Driver concept that also goes with the NT4 driver. The installable DLL driver (AUDDRIVE.DLL) is always 32bit, regardless if running under 32bir or 64bit Windows afaik (check default wdmaud.drv, it's always 32bit). So to install the AUDDRIVE.DLL, it's just needed to place it in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Drivers32 in the midi-keys, afaik (used to be the "Multimedia" control panel item under NT4).

The kernel mode driver AUDDRIVE.SYS mostly consists of a lot of functions from the well-known Soundlib where source is known, so there are just some ES1868 specific functions to reverse-engineer and implement and then compile it as a 64bit driver to be compatible with the IOCTLs that the DLL driver sends. But as mentioned, you said that the NT driver doesn't give the required sound output (possibly only compatible with OPL3 emulation, did I understand that correctly?), so just putting in the Bank information from bnk_common.bin wouldn't help?

leecher1337 commented 1 year ago

So I had a look at the drivers: 1) The NT4-Usermode driver does its custom commands for MIDI playback. It has the table mentioned above in its resource segment. 2) The Win2k/XP+ driver uses Miniport driver approach and has the code running in the kernel .sys driver. It checks, if the Soundcard is OPL3-capable. If yes, it resorts to default OPL3, if not, it does the same as the Windows NT usermode driver (the stuff that has been tested by the ESSPlayMid project)

So getting the Win2k/XP driver to use the same method as the NT4 driver is relatively easy, just patch the routine that checks for OPL3 to return FALSE and - if needed - patch the appropriate sound bank into the driver (bnk_NT4.bin is present, can be swapped with bnk_common.bin).

So as I understand, the sole problem then is that there is no x64 version of the driver, thus not working on Win11, so driver es1969.sys needs to be ported to x64, OPL3 support turned off and maybe functionality to add custom table added?

ytrezq commented 1 year ago

So I had a look at the drivers:

  1. The NT4-Usermode driver does its custom commands for MIDI playback. It has the table mentioned above in its resource segment.
  2. The Win2k/XP+ driver uses Miniport driver approach and has the code running in the kernel .sys driver. It checks, if the Soundcard is OPL3-capable. If yes, it resorts to default OPL3, if not, it does the same as the Windows NT usermode driver (the stuff that has been tested by the ESSPlayMid project)

So getting the Win2k/XP driver to use the same method as the NT4 driver is relatively easy, just patch the routine that checks for OPL3 to return FALSE and - if needed - patch the appropriate sound bank into the driver (bnk_NT4.bin is present, can be swapped with bnk_common.bin).

So as I understand, the sole problem then is that there is no x64 version of the driver, thus not working on Win11, so driver es1969.sys needs to be ported to x64, OPL3 support turned off and maybe functionality to add custom table added?

If this true, yes. Previous reverse engineering on Vogons.org told that the midi functionality was working only in opl3 compatibility mode instead (leaving only the modern pcm playback working normally) of the advanced one, leaving only some games being able to use the ess functionality. So if the 32 bits drivers just have the advanced sound bank disabled but still there, yes.

The second problem is my bios run oses in virtual machine mode while disabling vm inside vm acceleration thus only allowing 64 bits os to run unless some customs modes like yours is used (Windows 98 inside a browser based Javascript vm indeed works but without access to the hardware).

leecher1337 commented 1 year ago

Does your 64bit Windows generally support the soundcard? So, you just want to play MIDI with the advanced sound bank and leave the rest as-is? Or does your 64bit Windows not support the card at all and thus, you need a full driver?

ytrezq commented 1 year ago

Both things are true. I have no internal on board sound card. Computer can t generate nor read any sound including pcm unless on Linux (If care is made to stay on command line), but I m interested in hearing midi files I modified, even if it s restricted to vlc compiled for 16 bits Windows.

ytrezq commented 1 year ago

Though if creating a new port, a general midi level 2 driver which can understand the sysex message for controlling harmonics effects would be great too (General midi level 2 was made in 1999).

I meaning partial support. Though I think a 1 rule fit all like ndiswrapper would be the best thing.

ytrezq commented 1 year ago

https://github.com/pachuco/ESSPlayMid/issues/4

leecher1337 commented 1 year ago

Here is the driver that you requested, x64 driver for ESS soundcards with ESFM support: https://github.com/leecher1337/es1969 I verified that is uses its native ESFM implementation and not the OPL3 mode. Driver is based on Win 2k driver. Still nobody knows what would be different in the Win 9x driver.