What is it?
This project allows the use of ISA extension cards on a modern computer over a USB interface.
The main project goal was to learn about the ISA bus, not to build a polished product.
USB has inherent limits to the minimum latency, defined by the frame timing in the USB specification.
This means that a USB 1.1 attached device will only ever be able to handle 1000 transfers per second.
USB 2.0 increases this limit to 8000 transfers per second (125μs frame time), which is still way to slow for most applications.
For practical use, a different interface, like PCIe, Thunderbolt/USB4, etc. needs to be used.
First prototype (Arduino Mega / AVR-based)
To get a feel for the ISA bus, an Arduino Mega 2560 was manually wired to an ISA slot. Little integrated switch-mode converters provide the -5V and -12V supply rails for ISA cards, a 74HCT32 OR-gate was used as a clock buffer for the 14.31818 MHz clock.
The Arduino uses a very simple serial protocol to accept transactions from a PC.
r - read from memory
w - write to memory
i - read from I/O space
o - output to I/O space
are all of the supported transactions.
The Linux utility “isapnptools” was used back in the 1990s to configure Plug & Play ISA cards. This utility normally uses outb/inb commands to directly talk to the I/O-registers of an x86 machine. It was modified to redirect all I/O accesses to a serial connection instead.
In this video, isapnptools runs on a Linux machine, detects and configures an Aztech ISA sound card connected to the Arduino Mega and then starts a simple OPL playback routine (which sends music data to the sound cards synthesizer registers):
STM32-based ISA-over-USB card
Because the performance of the Arduino Mega was limited by the available CPU performance, not the USB bus itself, a STM32-based ISA adapter card was designed. This card includes an STM32H743 with external SDRAM and a native USB 1.1 interface. The STM + SDRAM design was also used in the CMM2 clone project, so we were already familiar with the MCU.
The x86 emulator PCem was modified to redirect certain memory and I/O calls to the STM32 card. This allows a virtual machine to use real ISA peripherals like a sound card, video card or POST analyser card:
You can see the slow scrolling performance. This is a result of the maximum transfer speed of the USB interface. For scrolling, the entire screen content needs to be read and written back to a different address. With 1000 accesses per second in total, scrolling the entire screen takes a while.
STM32-standalone PC emulation
With the fast STM32H743 and external SDRAM, a port of PCem to the 32bit ARM inside the STM32 was attempted.
We were able to execute enough BIOS code to initialize the VGA card and get a first Award BIOS screen, but didn’t get any further.
PCem’s code does a lot of unaligned memory accesses (which aren’t possible on the 32bit ARM architecture).
A similar setup with a much faster, arm64 CPU like on a Raspberry Pi would be a good target platform for further experiments. This would also enable the use of the x86->arm64 JIT. The BCM2835 chips also have a SMI feature, which might be use for low-latency, high-speed bus interfacing. PCIe (either with an FPGA or WCH-IC converter) might also be an interesting target.