Use real ISA cards in an emulator

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.

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.

ISA backplane, soldered with lots of individual wires to an Arduino Mega ISA backplane, Arduino Mega and an ISA sound card Clock input, using a 74HCT32 logic IC Protoboard with 2x 5V isolating converters

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

ISASTM PCB ISASTM backside ISASTM board, installed into an ISA backplane ISASTM board, installed into an ISA backplane with different cards

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).

ISASTM board, installed into an ISA backplane, with Segger J-Link attached Monitor, showing the VGA BIOS message from a graphics card

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.