First post, by fsck100
UPDATED- Patched USBDDOS fork for 386/486/Pentium-era OHCI controllers- TESTERS NEEDED
Update to my earlier post. This is a maintained fork of crazii's USBDDOS (the only DOS USB driver suite I'm aware of that does HID + MSC and supports OHCI/UHCI/EHCI together), patched for the OHCI-era controllers most often found on 386-class through early-Pentium machines. Goal: a DOS USB driver that actually initializes on the silicon those machines shipped with, not just on modern QEMU.
TL;DR
Patched USBDDOS fork for OHCI controllers on 386/486/Pentium-era boards. alpha.3 release with 12 new patches since alpha.2. Real-silicon testers wanted, especially for ALi / AMD / SiS / early VIA / OPTi / NEC OHCI chipsets. Two known issues being worked on for a future release: post-TSR lockup (under active diagnosis) and an MSC sector-bounds bug on USB drives smaller than 1 GB. If you don't want to think about the setup, run USBDDOS.EXE under HIMEM/HIMEMX - works in nearly every config, no DPMI host needed. Download: usbddos-v1.0.0-alpha.3.zip (~370 KB).
What's new since the last release
Twelve patches landed on the fork between alpha.2 and the current alpha.3 build. The OHCI-side ones cover real chipset quirks that prevented init on period hardware:
- OHCI Legacy Support cleanup - disables Legacy Support emulation after BIOS handoff so the post-handoff state matches what Linux/BSD drivers expect.
- ALi M5237 fminterval - skip the HcFmInterval access that hangs ALi M5237 OHCI silicon (one of the more common ALi-era chips).
- SMM handoff timeout - bound the OHCI SMM-handoff wait loop so a non-cooperative BIOS doesn't trap us forever.
- INITRESET retry - matches the Linux QUIRK_INITRESET path for OPTi/SiS controllers that reject FmInterval writes in SUSPEND state.
- POTPGT wait - read POTPGT from HcRhDescriptorA and honor it instead of using a fixed delay; matters on root hubs that need real power-on-to-power-good time.
- Page-boundary-safe DMA - OHCI ED/TD structures cannot cross page boundaries (PCI/host bridge restriction on some chips); now enforced explicitly.
- Unrecoverable error recovery - HC UE bit no longer leaves the driver wedged; recovery path bounded.
- Hub support, port reset, ClearPortFeature spec compliance.
- Graceful skip for unsupported device classes (was a hang).
- HID boot-protocol-only handling - cleaner USB keyboard/mouse path; works around the EHCI ControlTransfer "no pending transfers" assertion that the prior toggle-on-IRQ SET_IDLE path tripped.
Plus visibility improvements - silent capacity rejects and MSC mount errors now log to COM1 in DEBUG builds so when something goes wrong you can actually see why.
Hardware I'd particularly like tested
Anything 386 / 486 / Pentium / Pentium Pro with an OHCI USB controller. The patches address specific chipsets, so coverage on these silicon families would be especially useful:
- ALi M1535 / M1543C / M5237
- AMD 756 / 768
- SiS 5595 / SiS 630
- VIA VT82C686A/B, VT8231, VT8233 (the early OHCI VIAs, not VT8237 which is later)
- OPTi (early OHCI controllers)
- NEC OHCI PCI cards on socket 7 / socket 5 boards
- Any add-in PCI USB card with OHCI on a real 486 or Pentium board
UHCI testing is also welcome (Intel PIIX3/4, VIA UHCI) but the new fixes are mostly OHCI-side.
Download
usbddos-v1.0.0-alpha.3.zip (about 370 KB)
Contents:
- USBDDOS.EXE - Open Watcom build. Embedded protected-mode switcher; no external DPMI host needed. Use this if you don't know what you have. Resident footprint ~4-12 KB.
- USBDDOSP.EXE - DJGPP build. Smaller, faster, but requires a DPMI host.
- CWSDPMI.EXE - bundled DPMI host for the DJGPP build.
- COPYING.txt - GPL-2.0 (inherited from upstream).
- README and BUILD-INFO files with full toolchain provenance.
Source: https://github.com/Netrunner01/USBDDOS - the tag is v1.0.0-alpha.3.
Known issues - please read before installing
This is an alpha release. There are real, known limitations. Most importantly:
Functional bugs being worked on
- Post-TSR lockup observed on real hardware after USBDDOS goes resident. At least one tester's machine has hit it; root cause under active diagnosis via a COM1-instrumented diagnostic build. Symptom is the system becoming unresponsive sometime after USBDDOS prints "TSR inited." Recovery requires a power cycle. If you see this, please grab a COM1 capture and the chipset/board details.
- MSC sector-bounds check is unreliable on USB drives smaller than 1 GB. The capacity-display routine clobbers the bounds value used by subsequent reads/writes. Workaround: use a USB drive 1 GB or larger, or run HID-only mode (omit /disk). Data integrity risk is real on small media - don't put your only copy of anything important on a sub-1 GB drive that this driver has touched.
Architectural limitations
- Hard cap of 4 USB devices total, including devices behind hubs. There's a latent upstream issue that prevents raising this safely in RELEASE builds without triggering a separate silent hang on certain controllers; investigation parked for now. If you have a kbd + mouse + thumb drive, you're at 3 and have headroom. If you have a USB hub with multiple devices, you can easily hit the 4-device cap and any further devices will be silently rejected with no log indication.
- RELEASE builds lack malloc OOM hardening. Several allocation sites assume the malloc succeeded and dereference the result. Manifests as a silent crash or hang under memory pressure - typically only seen on systems with under 8 MB RAM or constrained DPMI configurations. Fix is queued for a future release.
- No hot-plug after init. USBDDOS enumerates whatever is plugged in at load time; hot-plug events after TSR are not handled. Plug all devices before loading.
- Boot-protocol HID only. The driver intentionally uses USB HID boot protocol mode (the simple 8-byte keyboard / 3-byte mouse reports), not the full report-descriptor parser. Most modern USB keyboards and mice support boot protocol but a few don't, and gaming peripherals with custom HID layouts may not enumerate cleanly even if they do.
Scenarios not yet validated
These aren't known broken, they're known untested - which is part of why testers are needed:
- Real 386/486/Pentium silicon - QEMU and Bochs validation only goes so far. The whole point of this post.
- Multi-level hub topologies - tested with a single hub on a root port; chained hubs are not validated.
- Long-duration operation - the interrupt-polling stability test for sessions over ~30 seconds is deferred. If USBDDOS works on your board for the first minute it should keep working, but I haven't proven that over hours.
- NEC USBHC errata path - NEC OHCI has documented write-1-to-clear errata; the workaround is queued but not in alpha.3.
"This is alpha" caveats
Don't run it on a system you can't power-cycle remotely. Don't put your only copy of important data on a USB drive you've mounted with this driver. If you're in the middle of something else, save it before loading USBDDOS.
Memory manager guidance (read this before you load it)
USBDDOS needs an XMS host either way. The DPMI requirement depends on which binary you run.
USBDDOS.EXE (Watcom) - has its own protected-mode entry. No DPMI host needed. Cooperates with EMM386/JEMM386 if loaded but works fine without. The path of least resistance for most setups.
USBDDOSP.EXE (DJGPP) - needs a DPMI host. Acceptable hosts, best to worst:
- HDPMI32 (Japheth's) - pure DPMI, smallest footprint
- JEMM386 NOEMS (FreeDOS) - DPMI 0.9 from V86
- EMM386.EXE NOEMS (MS-DOS / DR-DOS) - same idea on commercial DOS
- CWSDPMI -p (bundled fallback) - works alone, but see the failure mode below
The CWSDPMI tight-XMS failure mode. If CWSDPMI is the only DPMI provider on a system with limited free XMS (under 8 MB total RAM, heavy V86 setup, lots of XMS-consuming TSRs already loaded), CWSDPMI will eat enough XMS that USBDDOSP startup fails with:
Failed allocating XMS memory, size: 2949120.
The driver exits without going resident. Fix: load JEMM386 NOEMS (FreeDOS) or EMM386 NOEMS (MS-DOS) before USBDDOSP - CWSDPMI then falls back to the V86 host's DPMI 0.9 services and the XMS competition disappears. Or just use USBDDOS.EXE.
Quick setup by DOS (the README in the bundle has the full table):
FreeDOS 1.3 / 1.4 USBDDOS.EXE: HIMEMXUSBDDOSP.EXE: HIMEMX + JEMM386 NOEMSMS-DOS 6.22 / 7.x USBDDOS.EXE: HIMEMUSBDDOSP.EXE: HIMEM + EMM386 NOEMSDR-DOS 7.x USBDDOS.EXE: HIDOSUSBDDOSP.EXE: HIDOS + EMM386 NOEMS (or HDPMI32)PC DOS 2000 USBDDOS.EXE: HIMEMUSBDDOSP.EXE: HIMEM + EMM386 NOEMS
If you don't want to think about it, just run USBDDOS.EXE under HIMEM/HIMEMX-class XMS and that's the whole setup. Do NOT load USBDDOS with LH / LOADHIGH - DPMI programs already execute above 1 MB and putting the PSP in UMB just causes fragmentation.
Basic load
USBDDOS.EXE (HID-only, default)USBDDOS.EXE /hid (explicit HID)USBDDOS.EXE /disk (MSC + HID; needed if you're booting from a USB drive)
Reporting issues
What helps me most:
- Hardware: motherboard / chipset (USB silicon specifically), CPU, total RAM, DOS version.
- DPMI/XMS setup: CONFIG.SYS and AUTOEXEC.BAT contents (or just the relevant lines).
- Symptom: does it hang, exit cleanly, fail to enumerate a device, work but slow? Was a device plugged in? Hub or root port?
- COM1 capture if you have a serial cable and a capture-capable host. USBDDOS DEBUG builds log a lot to COM1 at 9600/8-N-1 and that's by far the most useful single artifact for diagnosis.
The DEBUG-build USBDDOS.EXE is what's in the alpha.3 ZIP - it's already set up to log to COM1. If you have a working null-modem cable, point Tera Term or screen at the other end before booting and you'll capture the full init sequence.
File an issue on the fork's issue tracker. I am not able to check replies here frequently. Please file an issue for bugs.
Thanks for any time anyone can put on this. The 386/486/Pentium-era PCI hardware is exactly the gap upstream USBDDOS didn't cover well, and the fixes are real but they need real-silicon validation - QEMU, Bochs and 86box can only tell you so much.