USB flash drives on 8-bit ISA bus using CH375 ISA to USB adapter
I purchased the CH375 ISA to USB adapter from Taobao, hoping for an easier way to transfer files to my PC XT clones. At a cost of 145 Chinese yuan (around US $23) per card, or approximately US $30 per card with shipping, this seems to be a very good price. Although the Taobao web interface is available in Chinese only, it works well when translated to English using Google Chrome and accepts payment via Mastercard, so I was able to make the purchase with no issues.
The card arrived after 2 weeks, and looked like this:
In the above photo, the ISA bracket has been removed. It is however recommended that you always connect the ISA bracket, to prevent inserting the card in reverse (the ISA connector is just 8-bit and will fit in either way), which may destroy both the card and the motherboard.
First I want to say a few words on the CH375. It was originally released as a USB interface module specifically designed for mass storage devices such as USB thumb drives. There are several variants of the module available on eBay allowing interface via SPI or a proprietary serial protocol. As for the CH375 USB to ISA adapter, it is originally designed by lo-tech and makes uses of the CH375 chipset to allow connecting USB mass storage devices to machines with only 8-bit ISA slots.
Using USB flash drives under DOS
Although lo-tech’s design places the card’s IO port at addresses 2C0-2C8h with a 32KB BIOS at either C800h or D800h, my card’s default IO port is at address 260h instead, configurable via jumpers. Getting the card to work in DOS simply involves connecting a USB flash drive containing a single FAT16 partition that is 512MB or less in size, and followed by adding these lines to CONFIG.SYS:
LASTDRIVE=Z DEVICE=C:\CH375\CH375DOS.SYS @260 #07
where 260 is the address of the card and 07 is the software interrupt for the card. You should select an available interrupt, otherwise there will be weird issues when reading/writing to the card. If you are using the PCI version of the card, pass 0 as the address. The driver also accepts a third optional parameter that can be anything between 0 to 255, specifying the read/write speed. The higher the value, the faster the speed. Default value is 2.
With the above configuration, I was able to create a new DOS drive letter for my USB thumb drive and access it with no issues. The throughput is around 8KB/s on a PC XT running at 12MHz. I guess the speed should be much higher on 386 and 486 machines.
Take note that loading CH375DOS.SYS will freeze the system if the USB drive is larger than 512MB, not formatted as FAT16, or contains multiple partitions. Also, only USB thumb drives are expected to work. USB hard disks will most likely not work as intended, unless used with an external power supply.
Configuring BIOS boot ROM
There is a socket on the card for a 27C64 EPROM for booting. 28C64 ROMs might work too, but I haven’t had the time to try yet. Finding the right boot ROM might also be an issue. There are at least a few versions of the ROM available for download at various sites, none of them seem to work out of the box:
- ROM v1.3 from lo-tech. This ROM simply prints “Start CH375 v1.3 …” in an infinite loop after POST, followed by repeated beeps, and you’ll have to reset the machine.
- ROM v1.5 with Ctrl prompt. This ROM adds a message “Press Ctrl to start E-Disk” during POST. The window for pressing Ctrl is less than 1 second. Pressing too early and it would cause the BIOS to report keyboard error. Pressing it late and your machine would have already booted normally. I could not get this ROM to work.
- ROM v1.5 (modified) without Ctrl prompt but hard-coded strange disk geometry taken from this discussion thread. This ROM removes the Ctrl prompt and attempts to boot directly from USB but assumes a disk geometry of 0x20 sectors per track and 0x40 heads, which would not work with most thumb drives.
I decided to start my analysis from version (3) of the ROM, using IDA Pro and information from the above discussion thread, together with my Minipro USB programmer. If you want to try, the first thing to do is learning how to properly prepare the ROM file. For the CH375, the board accepts a ROM size of 8KB, but various downloads only provide ROM sizes of 2KB or 4KB. If that is the case, use a hex editor and append zero to the end of the file until the size is exactly 8192 bytes before programming. There might also be another issue with the ROM checksum, which is the last byte of the ROM calculated by taking the byte value of last 8 bits of the sum of all bytes in the ROM (including the checksum bytes). Depending on the firmware of your ISA to USB card, the card will either recognize the ROM as long as the checksum matches, or will recognize the ROM only if this checksum byte is zero. To cater for this, if the ROM you attempt to flash does not have zero as the last byte, you will need to modify existing bytes to get a checksum of 0. This can be done by modifying the padded zero bytes, or one of the displayed ASCII characters.
The next thing to do is patching the BIOS to reflect the correct address for the CH375. On v1.3 of the BIOS, this address is located at 0x38 – 0x39. However, on v1.5, the address is located at 0x36 – 0x37. The next byte is the address of the emulated hard disk which defaults to 80h for the primary master channel. A pair of 2 bytes (3F FF) on the right provides the hard-coded geometry of the USB drive:
In the above screenshot, the card is located at 260h and the BIOS assumes a USB drive having 63 sectors per track and 255 heads (approximately 528MB), the usual limitation for older BIOSes. With these settings, any modern USB drive should work, albeit at a much smaller capacity.
There is still a step that needs to be done before you can use your USB thumbrive with this BIOS. Even though the CH375 recognizes the USB thumb drive, you must first get your DOS system files on it first before the machine can boot. And you can’t do that from a DOS boot disk, nor from Windows, due to the need to have the BIOS loaded first and the hard coded disk geometry. The only way I could get it to work is to create a DOS virtual machine in VirtualBox with a hard disk containing a single active partition of 500MB, then follow this tutorial to convert the disk image to DD format, and finally use Rufus to write the DD image to the thumb drive. Once then, my XT machine could boot using the thumb drive connected to the CH375 to USB adapter.
You can see in the following video my 80286 running at 12.5MHz booting from a USB thumb drive via the CH375 adapter. Disk throughput when using the CH375 BIOS is around 12KB/s:
Disassembling the BIOS source code
There are still a few issues with this BIOS. First, I think the code is not optimized and the throughput can be faster. Secondly, FDISK and several other disk utilities do not detect a fixed disk when using this BIOS. As a result, formatting the disk is impossible and I have to resort to using the above DD method. Also, this BIOS does not provide a way to boot from floppy disks, so I had to resort to using System Commander for floppy disk boot selection, resulting in the lengthy boot delay.
You can download here the IDA project which I used to study this BIOS. The link also contains a partial disassembly of the BIOS code. I have also given all identified functions sensible names, renamed several labels, and added comments to illustrate the communication protocol with the CH375 module:
I started off by using IDA to disassemble the BIOS as 16-bit 8086 code and relying on IDA comments, auto-comments, list of text strings as well as the datasheet to identify various code segments. Most notably, there is a function which I named CHS2LBA in the code, responsible for converting the assumed geometry of the thumb drive to LBA sectors to be passed to the CH375 module:
seg000:0372 CHS2LBA proc near ; CODE XREF: seg000:067Ap seg000:0372 mov al, cs:CHS_SECTORS seg000:0376 mul dh ; Unsigned Multiplication of AL or AX seg000:0378 mov dl, ch seg000:037A mov dh, cl seg000:037C and cx, 3Fh ; Logical AND seg000:037F dec cx ; Decrement by 1 seg000:0380 add cx, ax ; Add seg000:0382 shr dh, 1 ; Shift Logical Right seg000:0384 shr dh, 1 ; Shift Logical Right seg000:0386 shr dh, 1 ; Shift Logical Right seg000:0388 shr dh, 1 ; Shift Logical Right seg000:038A shr dh, 1 ; Shift Logical Right seg000:038C shr dh, 1 ; Shift Logical Right seg000:038E mov al, cs:CHS_SECTORS seg000:0392 mov ah, 0 seg000:0394 mul dx ; Unsigned Multiplication of AL or AX seg000:0396 mov dl, cs:CHS_HEAD seg000:039B mul dx ; Unsigned Multiplication of AL or AX seg000:039D add ax, cx ; Add seg000:039F adc dx, 0 ; Add with Carry seg000:03A2 retn ; Return Near from Procedure seg000:03A2 CHS2LBA endp
As can be seen, there are several bit shifts in this function. I leave it as an exercise for the reader to find out what this function is exactly doing, and perhaps write its C equivalent. It is also worth noting that IDA fails to identify several pieces of code for interrupt 13H and did not disassemble them but instead identify those as data. I saw several of these in IDA Pro and renamed them properly:
To force IDA to disassemble these functions, select the area which you think has been misidentified as data, right click and select Code. You should see the INT 13H function being disassembled nicely:
NEW_INT13H: ;New interrupt 13H to replace BIOS INT 13H to emulate USB hard drive seg000:0519 cmp dl, cs:HDD_DISK_NUM ; Compare Two Operands seg000:051E jnz short NEW_INT13H_GO0 ; Jump if Not Zero (ZF=0) seg000:0520 cmp ah, 2 ; AH=2, Read Sector seg000:0523 jz short NEW_INT13H_RD9 ; Jump if Zero (ZF=1) seg000:0525 cmp ah, 3 ; AH=3,Write Sector seg000:0528 jz short NEW_INT13H_WR9 ; Jump if Zero (ZF=1) seg000:052A cmp ah, 4 ; AH=4,Verify Sector seg000:052D jz short NEW_INT13H_SVC ; Jump if Zero (ZF=1) seg000:052F cmp ah, 8 ; AH=8, Read Drive Parameter seg000:0532 jz short NEW_INT13H_08H ; Jump if Zero (ZF=1) seg000:0534 cmp ah, 1 ; AH=1, Get Last Operation Status seg000:0537 jbe short NEW_INT13H_SVC ; Jump if Below or Equal (CF=1 | ZF=1) seg000:0539 cmp ah, 40h ; '@' ; Compare Two Operands seg000:053C jb short NEW_INT13H_GO ; Jump if Below (CF=1) seg000:053E cmp ah, 41h ; 'A' ; AH=41H, Check Extension Present seg000:0541 jz short NEW_INT13H_SVC0 ; Jump if Zero (ZF=1) seg000:0543 cmp ah, 42h ; 'B' ; AH=42H, Extended Read Sectors seg000:0546 jz short NEW_INT13H_RDX1 ; Jump if Zero (ZF=1) seg000:0548 cmp ah, 43h ; 'C' ; AH=43H, Extended Write Sectors seg000:054B jz short NEW_INT13H_WRX1 ; Jump if Zero (ZF=1) seg000:054D cmp ah, 44h ; 'D' ; AH=44H, Verify Sectors seg000:0550 jz short NEW_INT13H_SVC ; Jump if Zero (ZF=1) seg000:0552 cmp ax, 572Ah ; Compare Two Operands seg000:0555 jz short NEW_INT13H_ID ; Jump if Zero (ZF=1) seg000:0557 mov ah, 1 seg000:0559 stc ; Set Carry Flag seg000:055A jmp short NEW_INT13H_RET ; Jump
One last thing that I want to mention is that, this BIOS ROM does not map itself into the 8086 memory address space. Therefore it is not possible to dump the ROM contents from software, for example, by using DEBUG.EXE or any ROM dump utility.
Download the entire set of files that I have for the CH375 here. The ZIP file contains complete documentation (circuit schematics, datasheet) for the CH375 and similar modules, PCB/PLD designs, DOS tools, BIOS collections, as well as sample application. Some of the README.TXT files were originally in Chinese but have been translated by me to English using Google Translate – these files are given an .ENG extension. I hope these files will be useful for those who want to explore the adapter more and perhaps write a better BIOS for it.
See also
Integrating FatFs FAT filesystem module with CH375/CH376 USB controller
The good old days: cracking 16-bit DOS games
This is the single most comprehensive, useful, technical, well-written (English) article on this (these) CH375-based ISA-to-USB adapter(s).
I recently ordered the exact same card on TaoBao and is waiting for its arrival. This particular adapter is sold without the EPROM (https://imgur.com/a/zGpVpc8).
I have a few questions:
1) Since none of the sellers on TaoBao provide any technical information in their listings for this product and that I can’t make out all the parts from their blurry images, can I assume that this card will (obviously) not work w/o the EPROM chip? Is a 27C64 currently being used on your card?
2) > “As for the CH375 USB to ISA adapter, it is originally designed by lo-tech …”
Even from visual inspection, we can see that this card and lo-tech’s card have different designs. How are they similar & different? With what program can I open “CH375X86/PCB /CH375ED.DDB” to peruse the PCB design?
3) Have you since worked on improving the throughput performance? (~12KB/s is slower than that of 1.44 floppy)
4) At quick glance, the manufacturer’s CH375 BIOS supports mass storage devices and network devices. What other USB device classes (E.g. HID, like mice, keyboards) have you tried connecting to this adapter?
5) What/who is ToughDev[.com]? Is this a personal tech blog or is this a community? (It looks to me there is only one contributing editor, ToughDev)
6) Can you point me to where I can meet other folks who are also working on this/these adapter(s)?Perhaps, a forum or an IRC channel?
7) Is ToughDev on any IRC network?
I’d like to make a small donation for your work. Not only have you shared specific details from your findings but you have compiled code, schematics, datasheets and even IDA project files for the vintage community. I look forward to working on this adapter this coming Christmas holiday.
Thanks!
Hi,
Thanks a lot for your comment.
The DDB and most the PCB design files can be opened with Protel PCB designer software. Some other files can be opened with KiCad and Altium. Although several variations of the PCB design exist, the main difference between them is mostly about component positioning. The PCB design I provided is still a good reference.
The CH375 ISA to USB card (or at least mine) will work fine without the EPROM chip. You will only need the 27C64/28C64 if you want your BIOS to boot directly from USB drives via the CH375. The 8K ROM image has the 0x55 0xAA signature which tells your BIOS at boot time that a valid boot sector is present and allows the BIOS to transfer the boot process to the CH375 ROM. Without the EPROM, you can still use the card in DOS by loading the CH375DOS.SYS driver in your CONFIG.SYS file. The BIOS also contains 80286 code and will not work on an XT, so on an XT you can only use the card via CH375DOS.SYS.
The throughput was measured by copying files from USB to an IDE hard disk drive using Norton Commander running on MS-DOS 6.22. After writing this article, I figured that the limited throughput was probably due to several delays in the code for the BIOS and the DOS driver. There is a 2 micro-second delay after reading/writing every byte, executed in 2 successive calls to delay_1uS. If you want to try, edit CH375DOS.SYS, patch one of these calls with NOP to reduce the delay to 1 micro-second to see if the speed increases. If that works, the same can be done to the BIOS ROM to improve the speed.
I remember connecting a USB keyboard to the CH375 and the CAPS LOCK key could toggle the LED, but nothing else could be achieved as no suitable drivers were available. Correctly emulating a USB keyboard under DOS using the CH375 is certainly non-trivial. Writing a DOS driver to map a USB mouse to a serial mouse on the CH375 might be easier, although this is still something requiring substantial efforts. You can try posting on the VCFED thread that I linked from this article. Among the posts, somebody mentioned that he contacted the author of the CH375 BIOS ROM and was given some useful advice.
ToughDev was started as a personal blog and is currently maintained by a small team, aiming at posting articles to share useful knowledge about in-depth technical topics. Articles are posted by several members but are always signed under the same team name, as you have observed, since we strongly believe in the power of working as a team and sharing knowledge to help the community
Thanks again for your comment and I will appreciate any contribution. You can write to me directly at minhdanh at toughdev.com to keep in touch