| Home | My Blog | Code / GitHub | My resumé (PDF) |
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.
| 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 |
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.
I'll post some simple shots of the MDA in action once I get it to compile again.