CGA Output to IBM Enhanced Color Display (Model 5154) from Teensy 3.1

A while back, while hunting for an IBM PC AT Model F keyboard, I came across a Craigslist ad that said something like "IBM Model 570 computer for sale with monitor and keyboard, $50". I realized that it was probably a typo and that they meant Model 5170, which was the IBM PC AT. To make a short boring story shorter, the keyboard with the system was a 1986 Model M instead of Model F, but by itself was worth more than $50 anyhow so I lugged the whole thing home and sold the keyboard to cover the cost. I set the PC and monitor aside for a while until I became curious if you could drive the monitor with a microcontroller, and I came across this post on hackaday.com .

Research

The aforementioned post featured a project by a hacker who was able to get a signal from his Arduino Uno to show up on a CGA monitor. His demonstration only had horizontal lines, which is much easier than sending individual pixels. Still, his proof of concept project was very encouraging and gave me a great jumpstart on the timing calculations that I would need. Here's some quick notes regarding the scanning:

CGA Protocol Timing

Scan Frequencies

Pixel Clock: 14.31818 MHz
H Sync Freq: 15.75 KHz
V Sync Freq: 60 Hz

Horizontal Scanning

Pixels: Duration: Pixel Range:
Left blanking: 56 3.91104 μs 816 through 872
Left Overscan: 40 2.7936 μs 872 through 912
Visible Period: 640 44.6976 μs 0 through 640
Right Overscan: 72 5.02848 μs 640 through 712
Right Blanking: 40 2.7936 μs 712 through 752
Horizontal Sync: 64 4.46979 μs 752 through 816

Vertical Scanning

Top Blanking: Rows 228 through 239
Top Overscan: Rows 239 through 261
Visible Period: Rows 1 through 200
Bottom Overscan: Rows 200 through 223
Bottom Blanking: Rows 223 through 225
Vertical Sync: Rows 225 through 228
 

Implementation

For the implementation of this project, I chose the following materials:

Teensy 3.1
96 MHz ARM Cortex M4 for $20... what's not to like about that? Bought mine from Adafruit because fast and awesome.
74AHCT125 - Quad Level-Shifter (3V to 5V)
The Teensy 3.1 board uses 3.3V logic, and the monitor 5V TTL. I found out the hard way that the output directly from the Teensy's pins was not going to cut it. I needed 2 of them. Also from Adafruit.
D-Sub 9 pin connector
I got mine from RadioShack and soldered it to some perfboard to make an ugly and completely amateurish breakout board... it worked though.

The code is up on Github so I won't go too in depth... get it here:

http://github.com/bgould/teensy-cga

Just a few key points:

Conclusion

This was an educational project for me, and I am happy with the way it turned out. There are certainly things that I would like to tweak, but if I do I will likely only do that if/when I revisit this project, for instance to use a Teensy to create a composite video signal or something like that. In the meantime, feel free to use this code to build off of if it is useful for you, and if you have any questions just comment on the Youtube video or create an "issue" in Github and I'll try to get back to you as quick as I can. If you have any improvements I'll be glad to accept Github pull requests.

Thanks, and happy hacking!