Homemade Graphic Card
The goal: building a 8-bit computer
Inspired by Ben Eater's videos where he explains how many things work in computers, I wanted to create my own computer from scratch. But as Carl Sagan said:
If you wish to make an apple pie from scratch, you must first invent the universe.
So here by "scratch", I mean integrated circuits from the 7400-series that is, basic logic gates, latches, counters, multiplexers, etc... The only complex components that I'm allowing myself to use are memory chips. So obviously I'll not use a micro microcontroller or an FPGA, because it doesn't feel "from scratch" to me. I really want to look at my computer and think "I built it". However, I'm not crazy to the point of building it with only transistors.
My goal is not just to build a demo computer, but a true computer that could have been sold in the 70s. This means that I'll not use 7-segment displays as an output and 2 or 3 buttons as an input. The computer should be able to interface with a monitor and a keyboard like any other PCs.
On the software side, again, my goal is to build something that looks and feels like a real PC. This means that I'll develop an OS with its own filesystem, shell and built-in utilities so that it will be possible to edit, compile, and run programs.
First step: building the graphic card
Why the graphic card first?
This is a big project, the kind of project that requires more than a year to complete. So where to start? I don't want to spend months designing the schematics and then spend as much time, if not more trying to find all the errors and bugs that I missed during the conception phase. To avoid that, I wanted to build a first module relatively quickly, so I could familiarize myself with all the tools that I need and also so I could quickly identify common errors so I don't commit them again.
The first module that I chose to build is the graphic card. To be fair, calling it a graphic card is a bit of an overstatement. It's closer to a VGA controller than an actual graphic card with a GPU.
I chose to start with the graphic card for multiple reasons:
- It's a simple module in the sense that it's a "one-way" module: it takes some inputs and displays them. There are no outputs that go back to the PC to take care of. This means that it's easy to plug the graphic card into an Arduino or a Raspberry Pi and dump some data to display for debugging purpose.
- There is visual feedback (the screen), so it's something interesting to work with.
- It's a quite small module (only 21 integrated circuits with my design).
- Ben Eater has multiple videos going really in depth on how VGA works.
A simplified overview
The principle of VGA is pretty simple: the graphic card sends pixels one after the other with a precise timing defined by the VGA specifications. A vertical synchronization pulse is also sent to indicate the end of a line, as well as a horizontal synchronization pulse to indicate the end of a frame.
With my graphic card design, the PC doesn't send the pixels to display, but the ASCII encoded text to display. This way, a position on the screen (line and column) can be encoded with only two 8-bit integers, while keeping a high enough resolution to display text. It's the job of the graphic card to divide one character into the 128 pixels to display.
As you can see below, the design is straightforward: there are different counters counting the pixels and the characters, and at each moment the pixel to display is fetched from the video RAM and font ROM. The video RAM contains the characters to display, and the font ROM stores the mapping between characters and pixels.
The outcome
After building the graphic card on breadboards and trying to debug this mess of wires, I was confident enough to design the PCB and order it. I was relieved to see it work on the first try. After that all the components were transferred to the PCB and soldered.
Here is what the full charset looks like when displayed:
Because I had the space to store two different fonts, I added a font that consists of different arrangements of big pixels. This way, it's possible to display actual raster graphics by switching to this secondary font, as you can see here:
What's next?
The graphic card is built, but the rest of the computer remains to be made... which is quite a lot.
As for now, I would estimate that about 80% of the computer schematics are done. So now I'll have to terminate them and start building the PC.
The mess of wire on the breadboards was just a hint of bigger headaches to come...