I have tested the latest USB drivers (from 2009-09-13) on my DOS computer now. The computer has two UHCI controllers, the first controlling the two rear USB connector and the second controlling two internal connectors. The BIOS has an option for mouse/keyboard "legacy support" but that never worked (showed error message during POST, didn't load DOS) so it's turned off. It might be important that I always used JemmEx during the testing. Here's what I noted:
- Using both USBKEYB and an Int15.4F based German keyboard layout driver ({J}KEYBGR from Japheth, the J one operates as JLM in Protected Mode, the other is a simple Real Mode TSR) types any "translated" key twice. Other layout drivers operating different work how they're supposed to (i.e. they translate the layout for all keyboards). With this bug, the key is still translated but gets to DOS twice. The bug even affects the PS/2-connected keyboard and is in effect when no USB keyboard is connected, too. USBKEYB uses Method 1 for emulating keystrokes from USB keyboards.
- I previously installed USBUHCI twice (for both controllers) and then went to uninstall it. I had to manually specify to uninstall the second instance first, otherwise the uninstaller found the first instance and complained that it couldn't uninstall it because of the interrupts hooked by the second instance. This raises two questions: Why doesn't the uninstaller search installed HCI drivers backward (avoiding this particular problem), and why can't it unhook the interrupt with another HCI driver instance on the same interrupt? Shouldn't this work with the interrupt sharing protocol (IISP)?
- I connected an 'internal' card reader to the two internal connectors (i.e. the second controller) which has two slots both for various card formats. USBDRIVES correctly found the device and assigned a DOS drive to the SD slot when I inserted a SD card. However, the access was very slow. Accessing a single sector with the WDE sector editor required a few seconds each time, even when only accessing the same two sectors (boot sector and first FAT sector) again and again. Executing "DIR" was slow too and stopped at the summary some minutes when computing the number of free clusters (it has to search all ~ 256 FAT sectors of the FAT16 drive). Executing "DIR" a second time was as slow, but notably the summary again took minutes. DOS usually buffers the number of free clusters in the DPB even for FAT16 drives, especially if no cluster allocation or deallocation happens inbetween. I uninstalled USBDRIVES and reinstalled with some other X settings. This didn't help the performance much. Single sector reads were definitively as slow as before. DOS usually only does single sector reads except maybe when reading via Int25/26 or from a file to the user buffer via Int21.3F. Notably, the card reader (or the card?) didn't like X settings 4 and 8 at first, but after retrying to read the first sector a few times, it accepted all further requests (and returned valid data). USBDRIVE S always showed the capacity under "DISK/LUN" as zero (Total Sectors being zero too), even when the card was detected and correctly assigned a DOS drive.
- Are your TSRs compatible with a DOS that moves the DOS data segment? (This really isn't necessary, I'm just interested.)
- You apparently use Int2F for dynamically (?) allocated multiplex numbers. Not to say this doesn't work, but it potentially could cause problems with other programs. Did you think about using AMIS? (It specifies the alternative multiplex interrupt as 2Dh. The most recent specification is completely in RBIL.)
- You can extend your FindInt code by two methods to find the interrupt handler in the chain: Add the 'uninstalled' IISP headers, which is created by iHPFS (simply 90h,EAh (nop, then jump far to the next handler) and the "KB" signature) on some (soft) Ints when uninstalling, and search through the interrupt lists provided by installed AMIS TSRs. The AMIS interrupt hook list might provide you another entry to the interrupt chain when it's blocked by an incompatible TSR installed later.
- Why do you prefer A86 over alternatives? I don't want to tell you what you 'should' use, again I'm just interested. (However, if you want to discuss assemblers..)
- Probably not many of the USB programs access files anyway, but do you support long file names? At least USBPRINT's COPY works with user-specified files, so LFN support might be useful to some.
- You have to close all handles (usually the Std handles 0..4) before issuing Int21.31; otherwise they'll stay open afterwards. This isn't critical for the default CON handle (because that's shared by all processes anyway) but could, for example, hold the destination file of an output redirection blocked.
- When a program installs resident and doesn't need to use files afterwards, its PSP can be deallocated. This is very easy to do for your auto-relocation code.
- Your memory allocation code is good, but still might create a memory hole when the environment is smaller than the resident code to install and there's no (or not enough free) UMA. Best results can be obtained by relocating the whole process to the top of the LMA (low memory area) before installing the resident part, then freeing the environment (as you already do), and then allocating a memory block for the resident part. (I initially wrote a lot more code for my TSRs to determine whether the process relocation would be useful, but after all, it's much simpler just to relocate the process always.)
- You currently leave some unnecessary bytes in memory that aren't used for anything. This is the description of the program at the start of the executable plus over half of the things in the PSP which DOS doesn't require for the process, such as the command line. Generally, all PSP fields from address 50h can be re-used for your own data or code.
Edit: Wait, the description is used by the multiplex interface, isn't it?
Christian