[queued] MCL86+ - Drop-in 8088 CPU Emulator/Accelerator for the IBM PC

I wanted to share my latest project, the MCL86+, which is a drop-in 8088 replacement board for the IBM PC/XT and clones. It can run in cycle-accurate as well as accelerated modes.

It uses a Teensy 4.1 to run the 8088 emulation and a small and inexpensive PCB to perform the voltage shifting.

Early testing shows that it can boot multiple versions of DOS, run various applications and games, and pass a number of tests including the SuperSoft Diagnostic ROM.

More info on my Wordpress Blog: https://microcorelabs.wordpress.com

And all of the project files are on GitHub: https://github.com/MicroCoreLabs/Projects/tree/master/MCL86%2B

MCL86_Plus.JPG
 
Impressive low level work inside the emulator code!

Impressive low level work inside the emulator code!

Thank you for noticing/recognizing! Yes, it was difficult to get the Teensy 4.1 to work consistently and make timing on the 8088's 4.77Mhz local bus!

I need to:
- disable interrupts while a bus cycle was in progress - otherwise 8088 clocks would get lost.
- Use GPIOx reads and writes to access the Teensy's IO's at the register level in a more parallel and faster fashion to make timing.
- I used a few array tables to map the 8088 address and data bus to the correct blend of GPIOx signals, rather then isolating and shifting bits.
- For additional margin I am running the Teensy 4.1 overclocked at 800Mhz which doesn't need cooling (says GUI) and runs reliably.

I think getting this microcontroller to basically bit-bang the 8088's local bus at-speed was one of the more challenging and fun aspects of this project!
 
I used a few array tables to map the 8088 address and data bus to the correct blend of GPIOx signals, rather then isolating and shifting bits.
Yep, I do that, too, to get a somewhat parallel bus, except I need a 16 or 18-bit bus :(. (I need several arrays.)

An additional trick I like to use, is the GPIOn_DR_TOGGLE register: update only the subset of pins that change state.

That is, if curword represents the current state of the bus, and newword is the desired state of the bus, using GPIOn_DR_TOGGLE = BUS_TO_GPIO[curword ^ newword]; curword = newword; gives just about the fastest possible way to update the GPIO pin states, assuming BUS_TO_GPIO[] is the array mapping the 8/16-bit bus to the 32-bit GPIO mask. This does not affect any of the other GPIO pins in the same bank, and does not need a read either; only keeping the bus bits in a global variable.
 
Yep, I do that, too, to get a somewhat parallel bus, except I need a 16 or 18-bit bus . (I need several arrays.)

The 8088 address bus is 20 bits! I broke it into two 10-bit (1K) arrays for each of the GPIOx registers that were involved.

I also tried to do as little read-modify-write of these registers as possible, so I just performed writes rather than check and write only bits which changed.
 
Back
Top