1974 - The Altair 8800

The Altair 8800 #

The Altair 8800 is perhaps the first commercial computer made for hobbyists. Released in 1974, it had an Intel 8080 CPU chip, 256 bytes of RAM, and a number of expansion slots for additional memory and peripherals. Here is the Jan 1975 edition of Popular Electronics (PDF) which introduced it to the world.

Original specifications:

  • Intel 8080 CPU, running at 2 MHz
  • 8-bit data bus, 16-bit address space
  • Motherboard with 4 slots (later: 18)
  • Altair bus: S-100 (2x 50 pins per slot)
  • Power supplies: +8V @ 8A and +/- 18V
  • Weight: 30 kg - Price: US$ 439 (Dec 1974)

Introduction #

This article describes a re-creation of this iconic machine of the 70’s, using a few modern components: a microcontroller, some memory chips, and a USB interface. It won’t look like an Altair computer, but it will be able to run its software and give an idea of the capabilities and limitations of such a system.

The emulation game #

Old processors such as the Intel 8080 can easily be emulated in software: a much faster CPU runs code which acts like the original CPU, reading machine instructions from memory, interpreting them, and performing the same steps as the original. The end result is effectively the same: programs will “run” in this emulated environment and input / output can be replicated to varying degrees of realism.

In this case, the iconic front panel of the Altair won’t be emulated. There are other builds for this (e.g. the Altair-Duino), but I’m more interested in how such a system can be used with a keyboard + screen.

Hardware choices #

For the hardware brains, I’ve picked the STM32G031F6 microcontroller, which runs at up to 64 MHz and has 8 KB of built-in RAM + 32 KB of ROM. This chip is the size of a fingernail and draws ≈ 5 mA @ 3.3V.

An 8-pin DIP chip will be used as “64K RAM memory expansion” and a second 8-pin DIP chip will provide around 16 MB of storage to emulate a couple of floppy disk drives plus a whopping 8 MB hard drive.

The resulting system can comfortably run CP/M 2.2, a widely used operating system, also from 1974.

What a difference 50 years of tech development makes, eh?

Software tools #

The software for this retro-computing emulation is written in C++ and uses the open source PlatformIO (aka “PIO”) wrapper for all the embedded software development involved. Once PIO is present, it takes care of everything needed to build, run, and debug a project. All the tools and :toolchains" required for this are automagically installed by PIO (this immensely simplifies all software development!).

A large part of my motivation for a project such as this, is that I want to fully understand how it all works deep inside. To the point of rebuilding almost all low-level code from scratch and dealing directly with the hardware registers in a µC such as the STM32G031. To this end, I’ve created a brand new runtime library called JeeH which acts as a Hardware Abstraction Layer between the application code (e.g. this emulator) and the raw hardware (e.g. an ARM Cortex chip from STMicroelectronics).

Getting started #

Modern µCs such as the STM32G031F6 come in very small SMT packages, but there are suppliers which place them on “breakout boards” with some extra (equally small) componenents to provide the rest of the essential circuitry, such as a crystal oscillator in the the case of a CPU.

The WeAct STM32G031F6P6 board from AliExpress is a good fit for this project. It can probably do about the same as an Altair computer.

There are 18 I/O pins (a few of these have very specific uses), 6 pins for power (5V in and 3.3V out from a tiny on-board voltage regulator), a few buttons, and a few LEDs. The size is about 25 x 20 mm.

As with all electronic components, half a century ago as well as today, the question is: how do you get these things to actually do something? It needs power, obviously, but also a way to communicate with it.

One solution for this is a USB-to-Serial interface board. There are many of these on AliExpress and elsewhere. Anything with a CH340, CP2102, or PL2303 chip on it will do. For this project, it’s useful if it can also supply 5V to the µC board. I picked a board I had lying around, based on an FT232 chip.

Wiring it up #

Many ways to go here. I like soldering things together on a small board. This makes it more or less permanent and more robust than using a breadboard with jumper wires, but that’s of course also an option.

This very first step needs just 4 wires to get things going: +5V & GND for power as well as TX & RX for serial communication. The key point here is that TX from one board is tied to RX on the other board, and vice versa: one sends, the other receives.

For reference: A2 on the µC board is TX and should be tied to RX on the USB interface. And A3 on the µC is RX, to be tied to USB’s TX pin.

This concludes the wiring for a first test, but now what? The next step is to get some code ready. As a first check, I want to get the on-board LED to blink. This is the µC’s equivalent of “Hello World”.

A blinking LED #

This can be done with two small text files: the application itself (app.cpp) and a project defintion file (platformio.ini). The app.cpp source file can be kept minimal for now:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <jee.h>
using namespace jeeh;

Pin led ("A4","P");

int main () {
    while (true) {
        led.toggle();
        for (volatile auto i = 0; i < 1'000'000; ++i) {} // approx 0.5s delay
    }
}

The platformio.ini file determines what gets built and uploaded (it will be extended later):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[platformio]
src_dir = .

[env]
platform = ststm32
framework = cmsis
board = disco_g031j6
build_flags = -std=c++17
lib_deps = jcw/jeeh
upload_protocol = serial

[env:hello]

That’s enough to build the firmware using this command: pio run

The upload puzzle #

Embedded µCs contain permanent memory in the form of “flash memory”, an easily programmable and eraseable form of ROM. This didn’t exist in 1974, which is why the Altair - like most early computers - had a front panel with many toggle switches. Getting the first program into the computer was tedious, but it could be a small “bootstrap” program which knew how to get the rest of the code into memory from a terminal, cassette, paper tape, or disk. A few bytes is doable … thousands of bytes is not!

But the problem still remains: how do you get data into flash memory?

Luckily, chip vendors solved this riddle with a separate (non-erasable) part of flash memory containing a flash-specific bootstrap loader. It scans for incoming requests on a few built-in peripherals and then copy the incoming data to flash: problem solved. But wait … how do you activate that bootloader?

One more trick is used: when a µC comes out of reset, it checks the value of one or more “boot pins”. Normally, you’ll just want to start running your app. But to change the firmware in flash memory, or to get it there in the first place, you have to pull a certain pin high or low to enter the vendor’s bootstrap.

This is where the STM32G031F6 chips pose a serious problem: they come off the factory with the boot pin(s) disabled. If flash memory is completely empty, the µC will enter its bootstrap anyway. But the WeAct board is normally delivered with a little test program already pre-loaded. Whoops!

Another way in #

There is a second mechanism to control any ARM µC: SWD, which is a variant of JTAG. It uses two pins (PA13 and PA14 on STM32 µCs) along with GND, which is always needed, plus the RESET pin. This offers a way to control the µC regardless of what it’s doing (if anything). Keeping the RESET pin low holds the µC “in reset”, i.e. doing nothing at all. While in this state, the SWD pins are nevertheless active (SWD and JTAG operate independently of the CPU and its peripherals).

SWD can erase and re-program flash memory. This is in fact the usual way of uploading firmware to a µC during software development. The problem with the STM32G031F6 chip is that it has very few I/O pins, so this access mode is provided by STM but without the extra pin to enter bootloader mode.

Unfortunately, SWD requires extra hardware (a JTAG programmer), whereas this project already has a serial port connection. The irony is that the µC’s bootstrap knows perfectly well how to upload over serial, if only it could be coaxed into doing so! There are various solutions to this chicken-and-egg problem, but that’ll be a topic for another day. For now, this article assumes that the µC can be placed in bootloader mode with the following sequence on the WeAct board:

Bootloader mode: while holding down button "A14", briefly press "NRST", then release "A14".

While the board is in boot loader mode, it will accept firmware uploads: pio run -t upload and if all is well, the LED will now blink once every second. PlatformIO did all the work: compiling the code and uploading it to the µC.

The steps described so far are the crux of embedded software development. Everything else is simple …

The BASICs #

Altair’s “4K BASIC” is a famous implementation of the BASIC language by Bill Gates and Paul Allen. It (just barely) fits in 4 KB of RAM: with 6 KB it should be quite usable. The G031 needs some memory for emulation, but 6 KB can easily be allocated as emulated RAM. There is also ample room to store a copy of 4K BASIC in flash memory and then copy it to ram on power up.

Altair BASIC has very few requirements: it polls an input port for key presses, and it sends characters to an output port as text output. These need to be emulated, so the code must catch these “I/O” requests and translate them to requests for the serial port, which is managed via the JeeH library.

Going from a blinking LED to an emulated Intel 8080 CPU with serial I/O will require quite a bit of code:

  • the 8080 CPU instuction emulator, which was adapted from #T#B#D#
  • a copy of 4KBAS, converted to a header file for inclusion as source code
  • intercepting in/out calls and passing them on to JeeH’s serial driver
  • copying 4KBAS from flash memory to emulated RAM memory on startup
  • a main program to combine all the pieces needed for a complete build
  • a serial port terminal program to communicate with the emulated system

The good news is that “it’s just code”. The embedded hardware has already been verified to work.

Running 4K BASIC #

Extended BASIC #

Adding 64 KB RAM #

Testing memory #

RAM performance #

Adding 1..16 MB storage #

Writing to flash #

Disk performance #

A complete CP/M setup #

Booting from disk #

Another upload puzzle #

End of the road #