hardware, restoration, software

Fixing 40-year-old Software Bugs, Part One

The museum had a big event a few weeks ago, celebrating the 45th anniversary of the 1st “Intergalactic Spacewar Olympics.”  Just a couple of weeks before said event, the museum acquired a beautiful Digital Equipment Corporation Lab-8/e minicomputer and I thought it would be an interesting challenge to get the system restored and running Spacewar in time for the event.

As is fairly obvious to you DEC-heads out there, the Lab-8/e was a PDP-8/e minicomputer in a snazzy green outfit.  It came equipped with scads of analog hardware for capturing and replaying laboratory data, and a small Tektronix scope for displaying information.  What makes this machine perfect for the PDP-8 version of Spacewar is the inclusion of the VC8E Point Plotting controller and the KE8E Extended Arithmetic Element (or EAE).  The VC8E is used by Spacewar to draw the game’s graphics on a display; the EAE is used to make the various rotations and translations done by the game’s code fast enough to be fun.

The restoration was an incredibly painless process.  I started with the power supply which worked wonderfully after replacing 40+ year old capacitors, and from there it was a matter of testing and debugging the CPU and analog hardware.  There were a few minor faults but in a few days everything was looking good, so I moved on to getting Spacewar running.

But which version to choose?  There are a number of Spacewar variants for the PDP-8, but I decided upon this version, helpfully archived on David Gesswein’s lovely PDP-8 site.  It has the advantage of being fairly advanced with lots of interesting options, and the source code is adaptable for a variety of different configurations — it’ll run on everything from a PDP-12 with a VR12 to a PDP-8/e with a VC8E.

I was able to assemble the source file into a binary tape image suited for our Lab-8/e’s hardware using the Palbart assembler.  The Lab-8/e has a VC8E display and the DK8-EP programmable clock installed.  (The clock is used to keep the game running at a constant frame-rate, without it the game speed would vary depending on how much stuff was onscreen and how much work the CPU has to do.)  These are selected by defining VC8E=1 and DKEP=1 in the source file

Loading and running the program yielded an empty display, though the CPU was running *something*.  This was disappointing, but did I really think it’d be that easy?  After some futzing about I noticed that if I hit a key on the Lab-8/e’s terminal, the Tektronix screen would light up briefly for a single frame of the game, and then go dark again.  Very puzzling.

My immediate suspicion was that the DK8-EP programmable clock wasn’t interrupting the CPU. The DK8-EP’s clock can be set to interrupt after a specified interval has elapsed, and Spacewar uses this functionality to keep the game running at a steady speed — every time the clock interrupts, the screen is redrawn and the game’s state is updated.  (Technically, due to the way interrupts are handled by the Spacewar code, an interrupt from any device will cause the screen to be redrawn — which is why input from the terminal was causing the screen flash.)

I dug out the DK8-EP diagnostics and loaded them onto the Lab-8/e.  The DK8-EP passed with flying colors, but Spacewar was still a no go.  I decided to take a closer look at the Spacewar code, specifically the code that sets up the DK8-EP.  That code looks like this (with PDP-12 conditional code elided):

   CLSK=6131      /SKIP IF CLOCK
   CLLR=6132      /LOAD CONTROL
   CLEN=6134      /LOAD ENABLE
   CLSA=6135      /BIT RESET FLAGS

   CLA CLL        /JUST IN CASE   
   TAD (-40       /ABOUT 30CPS
   CLAB           /LOAD PRSET
   TAD (5300      /INTR ON CLOCK - 1KC

The bit relevant to our issue is in bold above; the CLLR IOT instruction is used to load the DK8-EP’s clock control register with the contents of the 8’s Accumulator register (in this case, loaded with the value 5300 octal by the previous instruction).  The comments suggest that this sets a 1 Khz clock rate, with an interrupt every time the clock overflows.

I dug out the a copy of the programming manual for the DK8-EP from the 1972 edition of the “PDP-8 Small Computer Handbook” (which you can find here if you’re so  inclined).  Pages 7-28 and 7-29 reveal the following information:

DK8-EP Nitty Gritty


The instruction we’re interested in is the CLDE (octal 6132) instruction: (the Spacewar code defines this as CLLR) “Set Clock Enable Register Per AC.”  The value set in the AC by the Spacewar code (from the octal value 5300) decodes as:

  • Bit 0 set: Enables clock overflow to cause an interrupt.
  • Bits 1&2 set to 01: Counter runs at selected rate.
  • Bits 3,4&5 set to 001: 1Khz clock rate.

(Keep in mind that the PDP-8, like many minicomputers from the era, numbers its bits in the opposite order of today’s convention, so the MSB is bit 0, and the LSB is bit 11.)  So the comments in the code appear to be correct: the code sets up the clock to interrupt, and it should be enabled and running at a 1Khz rate.  Why wasn’t it interrupting?  I wrote a simple test program to verify the behavior outside of Spacewar, just in case it was doing something unexpected that was affecting the clock.  It behaved identically.  At this point I was beyond confused.

But wait: The diagnostic was passing — what was it doing to make interrupts happen?

DK8E-EP Diagnostic Listing

The above is a snippet of code from the DK8E family diagnostic listing, used to test whether a clock overflow causes an interrupt as expected.  The JMS I XIOTF instruction at location 2431 jumps to a subroutine that executes a CLOE IOT to set the Clock Enable Register with the contents in AC calculated in the preceding instruction.  (Wait, CLOE?  I thought the mnemonic was supposed to be CLDE?)  The three TAD instructions at locations 2426-2430 define the Clock Enable Register bits.  The total sum is 4610 octal, which means (again referring to the 1972 Small Computer Handbook):

  • Bit 0 set: Enables clock overflow to cause an interrupt
  • Bits 1+2 unset: Counter runs at selected rate, and overflows every 4096 counts.
  • Bit 3, 4+5 set to 110: 1Mhz clock rate
  • Bit 8 set:  Events in Channels 1, 2, or 3 cause an interrupt request and overflow.

So this seems pretty similar to what the Spacewar code does (at a different clock rate) with one major difference:  Bit 8 is set.  Based on the description in the Small Computer Handbook having bit 8 set doesn’t make a lot of sense — this test isn’t testing channels 1, 2, or 3 and this code doesn’t configure these channels either.  Also, the CLOE vs CLDE mnemonic difference is odd.

All the same, the bit is set and the diagnostic does pass.  What happens if I set that Clock Enable Register bit in the Spacewar code?  Changing the TAD (5300 instruction to TAD (5310 is a simple enough matter (why, I don’t even need to reassemble it, I can just toggle the new bits in via the front panel!) and lo and behold… it works.

But why doesn’t the code make any sense?  I thought perhaps there might have been a different revision of the hardware or a different set of documentation so I took a look around and finally found the following at the end of the DK8-EP engineering drawings:

The Real Instructions

Oh hey look at that why don’t you.  Bit 8’s description is a bit more elaborate here: “Enabled events in channels 1, 2, or 3 or an enabled overflow (bit 0) cause an interrupt request when bit 0 is set to a one.” And per this manual, setting bit 0 doesn’t enable interrupts at all! To add insult to injury, on the very next page we have this:

More Real Info

That’s definitely CLOE, not CLDE.  The engineering drawings date from January 1972 (first revision in 1971), while the 1972 edition of the PDP-8 Small Computer Handbook has a copyright of 1971, so they’re from approximately the same time period.  I suspect that the programming information given in the Small Computer Handbook was simply poorly transcribed from the engineering documentation…  and then Spacewar was written using it as a reference.  There is a good chance given that this version of Spacewar supports a multitude of different hardware (including four different kinds of programmable clocks) that it was never actually tested with a DK8-EP.  Or perhaps there actually was a hardware change removing the requirement for bit 8 being set, though I can find no evidence of one.

So with that bug fixed, all’s well and our hero can ride off into the sunset in the general direction of the 2017 Intergalactic Spacewar Olympics, playing Spacewar all the way.  Right?  Not so fast, we’re not out of the woods yet.  Stay tuned for PART TWO!


The Xerox Alto Part 2: Microcode

The Alto, Part 2:  Microcode

These two boards contain the logic for the Alto’s main processor

The Alto proposal was a bold one, with a short time-frame and lofty goals.  In a few short months, Chuck Thacker and the rest of the crew had designed and implemented a complete computer encapsulated in just a handful of circuit boards.  The processor was comprised of two small boards (approximately 7″x10″) containing a mere 138 integrated circuits.

Peripheral controllers were similarly simple — single boards of the same size for each of the Display, Ethernet, and Disk.

How was such economy of hardware possible?  Microcode.

Microcode and you:

In many computers from the Alto’s era, the architecture of the processor was hard-wired into the circuitry — there was dedicated hardware to fetch, decode, and execute each instruction in the processor’s repertoire.  This meant that once designed and built, the computer’s instruction set could not be modified or extended, and any bugs in the hardware were very expensive to fix. It also meant that the hardware was more complicated — involving more components and longer development cycles.  As processors became more and more advanced these limitations became more pressing.

Microcode and micro-programming helped solve these problems by replacing large swaths of control logic with software.

So What *is* microcode?

Microcode is software.  It’s very low-level software, and it’s written in a language tailored to a very specific domain — the control of a specific set of hardware — but it’s software all the same.  Let’s look at a small snippet of a program from the highest level, down to a microcode representation.

At the highest level, we have human language:

      Add 5 to 6 and give me the result.

Which, if you’re able to read this blog, you are likely to understand the meaning of.

In a somewhat-high-level programming language, like C, this translates roughly to:

      i = 5 + 6;

This isn’t too much different from the English statement above and if you’re familiar with programming or math at all, you can figure out that the above statement adds 5 to 6 and stores the result in the variable i.

In Nova assembly language, the above C program might look something like:

     FIVE:  5
     SIX:   6
     I:     0
            LDA 0,FIVE
            LDA 1,SIX
            ADC 0,1
            STA 0,I

Now we’re starting to get a little bit further from the source material.  This code consists of three memory locations (containing the operands and the result) and four instructions.  Each of these instructions performs a small part of the “i=5+6” operation.  “LDA” is Nova for “Load Accumulator” and loads 5 into Accumulator 0, and 6 into Accumulator 1.

ADC” is Nova for “ADD with Carry.”  It adds Accumulator 0 and Accumulator 1 together and stores the result in Accumulator 0.  “STA” means “Store Accumulator” and puts the contents of Accumulator 0 (the result of 5+6) into a location in memory (designated as “I” in this example.)

In Alto microcode, a direct analog to the Nova instruction sequence above could be implemented as:

       MAR← FIVE
       T ←MD

       MAR← SIX
       L ←MD+T    

       MAR← I
       MD← L

The number of instructions is larger (9 vs 4) and the microcode operates at a lower level than the equivalent Nova code.

In English:

  • The “MAR← FIVE” operation tells the Memory Address Register hardware to load a 16-bit address. The subsequent “NOP” here (and after every MAR← operation) is necessary to give the memory hardware time to accept the memory request.  If this is omitted, unpredictable things will happen.
  • The “T← MD” operation puts the Memory Data register — the contents of the memory at the loaded location in the previous instruction — onto the ALU bus.
  • The “L← MD+T” instruction puts the memory data onto the ALU bus and tells the processor’s ALU to add the T register to it; and finally it causes the result to be stored in the L register.

What you may notice in the above examples is that the Nova machine language instructions tell the computer as a whole what to do (i.e. load a register, or perform an addition) whereas the Alto microcode instructions tell the computer how to go about doing it (i.e. “put this data on the memory bus,” or “tell the ALU to add this to that.”)  It directs the individual components of the processor (the memory bus, the ALU, the register file, and the shifter) to perform the right operations in the right order.

So what components is the Alto processor made of?  Here’s a handy diagram of the Alto CPU:

Block diagram of the Alto processor

The nexus of the processor is the Processor Bus, a 16-bit wide channel that most of the other components in the Alto connect to in order to transfer data.  The microcode controls who gets to read and write from this channel and at what time.

The R and S registers are 16-bit register sets; the R bank contains 32 16-bit registers, and the S register bank contains up to 8 sets of 32 16-bit registers.  These are general-purpose registers and are used to store data for any purpose by the microcode.

The L, M, and T registers are intermediate registers used to provide inputs and outputs to the ALU and the general-purpose registers.

The ALU (short for Arithmetic Logic Unit) hardware takes two 16-bit inputs (A and B), a Function (for example, ADD or XOR) and produces a 16-bit result.  The A input comes directly from the Processor Bus (and thus can operate on data from a variety of sources) and the B input comes from the T register.

The Shifter applies a shift or rotate operation to the output of the ALU before it gets written back to the R registers.

The MAR (Memory Address Register) contains the 16-bit address for the current operation (read or write) to the Alto’s Main Memory.   Data is transferred to and from the specified address via the Memory Data Bus.

Each of the components above and their interactions with each other are carefully controlled by the microcode.  Each microcode instruction is a 32-bit word consisting of the following fields:

Alto microcode word format

RSEL selects the general-purpose Register to be read from or written to.

ALUF selects the Function the ALU should apply to its A and B inputs.

BS selects what source on the Processor Bus should be sent to the ALU.

F1 and F2 are Special Functions that control the shifter, memory, branching operations, and other operations.

T and L specify whether the output from the ALU should be written back to the T and L intermediate registers.

And the NEXT field specifies the address of the next Microinstruction.  Unlike most conventional machine language where by default each instruction follows the last, Alto microcode must explicitly specify the address of the next instruction to be executed.

The Alto is similar to many other computers of its era in that it uses microcode to interpret and execute a higher-level instruction set — in this case an instruction set very similar to that of the Data General Nova minicomputer (which was popular at PARC at the time).  The Alto’s microcode was also directly involved in controlling hardware — more on this later.

This means the earlier microcode example is contrived — it shows what an addition might look like in microcode, but not what the execution of the equivalent Nova assembly code example actually entails.  So as to provide full disclosure, here’s the microcode instruction sequence the Alto goes through when executing a single Nova instruction, the “LDA 0,FIVE” instruction from the earlier code sequence:

       START:       T← MAR← PC+SKIP
       START1: L← NWW, BUS=0
       :MAYBE, SH<0, L← 0+T+1
       MAYBE: PC← L, L← T, :DOINT
       DIS0: L← T← IR← MD
       G1: T← PC -1, :DOINS
       L← DISP + T, TASK, :SAVAD
       SAVAD: SAD← L, :XCTAB
       FINLOAD: NOP;
       LOADX: L← MD, TASK

Whew.  That’s 13 micro-instructions to execute a single Nova ADC instruction.  (Keep in mind that each micro-instruction executes in 170 nanoseconds, meaning that these 13 micro-instructions execute in about 2.2 microseconds, which is within spitting distance of the instruction time on a real Nova.)

The above sequence takes the current instruction, decodes it as an LDA instruction and performs the operations needed to execute it.  If it doesn’t make a whole lot of sense at first glance, this is entirely normal.  For the hardcore hackers among us, the above code sequence is taken directly from the microcode listing available on Bitsavers, the hardware manual is here and if you want to explore it in depth, you can use the ContrAlto emulator to step through the code line by line and see how it all works.

The Alto used microcode to simplify implementation of its processor.  This was state-of-the-art at the time, but not altogether novel.  What was novel about the Alto is its use of the processor’s microcode engine to drive every part of the Alto, not just the CPU.  The display, disk, Ethernet, and even the refreshing of the Alto’s dynamic RAM was driven by microcode running on the Alto’s processor.  In essence, software replaced much of what would have been done in dedicated hardware on other computers.

The Alto was also unique in that it provided “CRAM” (Control RAM) – a microcode store that could be changed on the fly.  This allowed the processor’s behavior to be extended or modified at the whim of the programmer – while the Alto was running.


To allow the devices in the Alto to share the Alto’s processor with minimal overhead, the Alto’s designers developed very simple cooperative task-switching hardware.

Conceptually, the processor is shared between sixteen microcode Tasks, with a priority assigned to each one:  Task 0 is the lowest priority task, and Task 15 the highest.  Each device in the Alto has one or more tasks dedicated to it.  To make task switching fast and cheap to implement in hardware, the only state saved by the task-switching hardware for each Task is that task’s program counter — the MPC (“Micro Program Counter”).

Only one task is running on the processor at a time, and at any time the microcode for a task may invoke a “task switch” function (named, strangely enough, TASK).  When a TASK instruction is executed, the processor selects the highest priority task that needs to run (is “Requesting Wakeup”) and switches to it by jumping to the instruction pointed to by that Task’s MPC.

The Emulator Task (Task 0)  is always eligible for wakeup but runs at the lowest priority and which can be interrupted at any time by hardware that needs attention.  As suggested by the name, this task contains microcode that “Emulates” the Nova instruction set — it fetches, interprets, and executes the instructions for the user software that runs on the Alto.

The Disk Word Task (Task 14) is the highest priority task implemented in a standard Alto.  It needs to run at the highest priority because its main job is pulling in words of data off the Diablo 30 disk drive as they move under the read head.

The Display Word Task (Task 9) is responsible for picking up words out of the Alto’s memory and painting them on the display as the CRT’s electron beam moves across the screen.

Since the Alto’s Task system is cooperative (meaning that task switches only happen when microcode explicitly requests them) the microcode for each task must be careful to yield to other tasks every so often so that they don’t get starved of time.  If the Disk Word Task is late in execution, data from the disk is corrupted. If the Display Word Task doesn’t get enough time, the display will flicker or display glitches.  And since the Alto hardware saves only the MPC for each task, each task’s microcode must make sure that any important state is saved somewhere (for example, the 32-general purpose R registers) before the task switch happens.

This puts some interesting constraints on the microcode (and results in much hair-pulling on the part of the micro-coder) as you might imagine.  But despite these limitations, and despite the extremely low-level details the microcode has to deal with, the wizards behind the Alto’s design managed to fit microcode implementing the basic Nova instruction set (with extensions for graphics operations), disk controller, Ethernet controller, display, and memory tasks into a 1,024 word microcode ROM.  With three words to spare.

The Task-based microcode architecture, in tandem with the writable microcode Control RAM (CRAM) made the Alto a very flexible computer — new hardware could be quickly implemented and added, and the microcode to drive it could easily be loaded and debugged.  Entirely new instruction sets were devised, experimented with, and revised quickly.  Applications could load custom microcode to accelerate graphics rendering.

In the next article, we will go into depth on the rest of the Alto’s hardware.

hardware, software

The Xerox Alto: An Introduction

In this series of articles I’ll go into the Alto in detail — the low-level hardware implementation and microcode, the software and languages and ideas that this hardware made possible, and the environment at Xerox PARC where the Alto was designed and used.  But before we dive down to the bedrock, let’s start with a bit of background.

Alto History

In the early 1970s, Alan Kay, a computer scientist at PARC, had a vision of a personal portable computer that he called the Dynabook.  In many ways, Dynabook was similar to modern laptops or tablets – it weighed under two pounds, contained a keyboard, display, and pointing device, and had a tablet form-factor.  The goal of the Dynabook was to be “a personal computer for children of all ages,” a portable educational computer.  Kay’s vision wasn’t technically feasible at the time – but the vision behind it was a driving force for the research he lead both during his tenure at PARC and beyond.

Alan Kay's Dynabook. Image courtesy of Wikipedia.
Alan Kay’s Dynabook. Image courtesy of Wikipedia.

In 1972 Kay proposed the idea of building a small personal computer (which he termed “KiddiComp”) to allow experimenting with the kinds of ideas he envisioned for the future Dynabook – in particular user interface design, education and computer-literacy for children.  This was centered around a programming language he called “Smalltalk” which made use of unique hardware for the time:  A high-resolution bitmapped display with a pointing device.  Unfortunately, when Dr. Kay submitted a proposal to the management at PARC to get a few KiddiComp systems built, he was denied funding.

Enter Butler Lampson and Chuck Thacker.  When PARC’s request for the purchase of a DEC PDP-10 for their research work was turned down in 1971 these two brilliant engineers figured they could design and build their own PDP-10 within eighteen months.  And they did – MAXC (pronounced “Max”) was a microcoded recreation of the PDP-10 architecture using semiconductor memory rather than core, and a pair of them were used at PARC for the next decade.  By 1972 Lampson and Thacker were both itching for a new project.

From Alan Kay’s “Early History of Smalltalk”:

In Sept [1972] … Butler and Chuck came over and asked: "Do you have any money?" I said, 
"Yes, about $230K for NOVAs and CGs. Why?" They said, "How would you like us to build 
your little machine for you?" I said, "I'd like it fine. What is it?" Butler said: 
"I want a '$500 PDP-10', Chuck wants a '10 times faster NOVA', and you want a 'kiddicomp'. 
What do you need on it?" I told them most of the results we had gotten from the fonts, 
painting, resolution, animation, and music studies. I asked where this had come from 
all of a sudden and Butler told me that they wanted to do it anyway, that Executive "X" 
[the executive who shot down Kay’s KiddiComp request] was away for a few months on a 
"task force" so maybe they could "Sneak it in", and that Chuck had a bet with Bill Vitic 
that he could do a whole machine in just 3 months. "Oh," I said.

Thacker and crew started the skunkworks project on November 22, 1972 and by April of 1973 the first Interim Dynabook (aka Alto) was up and running and displaying graphics:

The first Alto. From Alan Kay's
The first Alto. From Alan Kay’s “Early History of Smalltalk.”

The Alto featured a bitmapped display of 606×808 pixels with the approximate dimensions of an 8.5”x11” sheet of paper, 64KW (in 16-bit words) of semiconductor memory, a microcode clock rate of 170ns (approximately 6Mhz) and local storage of 2.5MB on a removable pack.  In 1974 the design and implementation of Ethernet networking was completed, and became standard Alto hardware.  All of this was implemented in a couple hundred ICs and fit under a desk.  Over the next 10 years, approximately 2,000 Altos were manufactured for use within PARC and at research labs and universities around the world.

The Alto was designed as a research vessel for efforts within PARC, and in that regard it was an astounding success.  Over the next decade, the Alto was involved in experiments in:

  • Human/Computer interaction
  • Education
  • Programming languages (BCPL, Smalltalk, Lisp, and Mesa)
  • Networking and distributed computing
  • Desktop publishing, word-processing and laser printing
  • The Graphical User Interface (GUI)
  • Computer-generated music and audio
  • Computer-generated graphics and animation
  • Computer-aided circuit design

Most famously, the Alto (running Smalltalk) served as the inspiration for the modern Graphical User Interface.  As the story goes, in 1979 teams from both Apple and Microsoft saw what PARC had been working on and were inspired, integrating aspects of what they saw into the Macintosh and Windows, respectively.

Smalltalk was important in early computer education and HCI studies and lives on to this day in the Squeak programming language.

The Mesa programming language originated on the Alto and was instrumental in the development of the Xerox Star desktop environment.

The Bravo word processor introduced WYSIWYG editing to the world and is in many respects the great-grandfather of Microsoft Word – Bravo’s author Charles Simonyi took what he’d learned from Bravo with him to Microsoft when he left PARC in the early 1980s.

The Ethernet networking research done with the Alto at PARC lead to the definition of Ethernet as an industry standard and was a major influence on the design of TCP/IP and associated networking protocols.

The Alto’s success was due in no small part to its clever, minimalist hardware design.  This design made the Alto extremely flexible and easily adaptable to whatever crazy idea or experiment that needed to be investigated.

In the forthcoming articles in this series, I will go into detail about the Alto’s hardware and demonstrate how the Alto achieved this flexibility.