An IBM PC emulator

One day I was poking through an old book on 8086 assembly language and thought to myself, wouldn't it be interesting to try writing an emulator to interpret this stuff? As it turned out, it was very interesting, but while assembly language is quite interesting to interpret and process, it's useless by itself. Eventually I decided that I'd emulate the entire 8088 CPU (not 8086), but even that's not much worth without an interface to it.

Ultimately, I found this very helpful and informative Web site about the original IBM PC 5150 machine, including what was effectively the holy grail of my ideas: The Technical Reference Manual. It had circuit diagrams, a ROM BIOS listing, detailed external interface schematics... everything I could ever want to know about the IBM PC 5150. But not quite enough about the detailed operations of the various chips that make up the machine.

Web searches gave me datasheets describing fully the operations of such old but functional devices as the 8237A DMA Controller, the 8259A PIC, the 8255A-5 PPI, and the 8253-5 PIT. Unfortunately, there just wasn't enough detail about the 8088 CPU itself. My eventual solution was to buy a copy of the original 8086/8088 User's Manual (Programmer's and Hardware Reference) from Amazon.com. I'd never understood hardware on such an intimate level before, and I admit I was more than a little wild about my enthusiasm for awhile there.

Of course, I'm far from the first person to ever try emulating a 5150 PC, and it's been done more successfully than by me, but I wasn't doing it to be the first. I was doing it for fun, and in that I succeeded beyond all my hopes. It had been a long time since I'd had such an exciting raw learning experience, and no matter how corny it sounds, I loved it.

I completed quite a few of the simpler pieces of the emulator before finally hitting a lasting snag in implementing the Programmable Interval Timer. All the chips I'd dealt with up to that point weren't all that sensitive to exact timing details, so I'd been using a very relaxed way of controlling the emulation loop. That wasn't going to work for the 8253-5, not if I wanted the original BIOS, which has quite a bit of code that depends on exact clock cycles to function, to work. One particular example that comes to mind is the BIOS' POST, the very first thing it does. It tests the PIT by setting counter 0 to trigger, then waiting through a pair of NOP instructions and checking the number of times the timer fired. Obviously, it was only going to work right if the NOPs took the correct 2 cycles at 4.77MhZ and the PIT was running counter 0 at the correct 2.38MhZ, etc.

It didn't really matter if the 2 cycles took exactly 0.00000954 seconds of realtime to execute or the more likely 9.54 x 10-9 seconds that the operations would take on a modern CPU, but they did have to happen in the correct order in the emulated CPU with respect to the emulated PIT. I found that I didn't know any immediate answers to how to do this kind of timing. It sounds so simple, yet I couldn't make it come together in code. Multithreading would have been ludicrous, not to mention impossible to synchronize correctly, especially with so many devices. Besides, the real devices ran off clock pulses from a timing crystal modulated by a 8284A clock generator, and no emulated model was ever going to exactly simulate that.

As it turned out, I never solved the problem. My attention turned to other projects while I was pondering solutions to the timing issue - I could have looked to other emulators, but the entire point of this project had been to work out for myself the problems involved. At this point in time, the emulator remains a partially completed work. It does run, but the original IBM PC BIOS doesn't boot, and not enough of the devices exist to make a functional computer. I do intend to finish it someday.

Status

Complete
ROM controller
RAM controller
8088 CPU core - not timing-correct
8237-A DMA Controller
MDA and display - not efficient
Incomplete
8253-5 PIT
Unimplemented
8259-A PIC
8087 FPU
8255-5 PPI
Cassette tape interface
IBM Keyboard w/ 8048 microcomputer
5161 Expansion Unit
Printer interface
CGA and display
NEC µPD765 FDC
Fixed disk drive controller and interface
Game control adapter
IBM communications adapters

Source code

The code of the emulator will be posted as soon as I decide what license to put it under. Watch this space for further developments.

Screenshots

I'll post some simple shots of the MDA in action once I get it to compile again.