This post describes our continuing efforts to restore a Xerox Alto.
We checked that the low-level microcode tasks are running correctly and the processor is functioning.
(The Alto uses an unusual architecture that runs multiple tasks in microcode.)
Unfortunately the system still doesn’t boot from disk, so the
next step will be to get out the logic analyzer and see exactly what’s happening. Here’s Marc’s video of the days’s session:
The Alto was a revolutionary computer, designed at Xerox PARC
to investigate personal computing, introducing the GUI, Ethernet and laser printers to the world.
Y Combinator received an Alto from computer visionary Alan Kay.
I’m helping restore the system, along with
Marc Verdiell, Luca Severini, Ron Crane, Carl Claunch and Ed Thelen
(from the IBM 1401 restoration team).
For background, see my previous restoration articles: day 1,
We started by checked that all the clock signals were working properly by connecting an oscilloscope to the wirewrap pins on the computer’s backplane.
This took a lot of careful counting to make sure we connected to the right pins!
The system clock signals are generated by an oscillator on the video display card, which isn’t where I’d expect to find them.
Since the clock signals control the timing of the entire system, nothing will happen if the clock is bad. Thus, checking the clock was an important first step.
At first, the clock signals all looked awful, but after finding a decent ground for the oscilloscope probes, the clock signals looked much better. We verified that the multiple clock outputs were all running nicely. We also tested the reset line to make sure it was being triggered properly – the Alto is reset by pushing a button at the back of the keyboard.
Next we looked at the running tasks. The Alto has 16 separate tasks running in microcode, doing everything from pushing pixels to the display to refreshing memory to moving disk words.
Keep in mind that these are microcode tasks, not operating-system level tasks.
The Alto was designed to reduce hardware by performing as many tasks in software as possible to reduce price and increase flexibility.
The downside is the CPU can spend the majority of its time doing these tasks rather than “useful” work.
Alto task scheduling is fairly complex. Each task has a priority. When a task is ready to run, its request line is activated (by the associated hardware). The current task can offer to yield by executing the TASK function at convenient points. If there is a higher-priority task ready to run, it preempts the running task. If there’s nothing better to run, task 0 runs – this task is what actually runs user code, emulating the Data General Nova instruction set.
The point of this explanation is that microcode instructions need to be running properly for task switching to happen. If the TASK function doesn’t get called, the current task will run forever. And if all the task scheduling hardware isn’t working right, task switching also won’t happen.
Below is a picture of the microcode control board from the Alto.
When you’re using 1973-era chips, it takes a lot of chips to do anything.
This board manages which task is running and the memory address of each task.
It uses two special priority encoder chips to determine which waiting task has the highest priority.
The board holds the microcode, 1024 micro-instructions of 32 bits each, using
eight 1K x 4 bit PROM chips. (PROM, programmable read-only memory, is sort of like non-erasable flash memory.) The board has 8 open sockets allowing an upgrade of 1K of additional microcode to be installed.
Note the tiny memory capacity of the time, just 512 bytes of storage per chip.
Since tasks can be interrupted, the board needs to store the current address of each task. It uses two i3101A RAM chips for this storage. The 3101 is historically interesting: it was the first solid state memory chip, introduced by Intel in 1969. This chip holds 64 bits as 16 words of 4 bits each.
Just imagine a time when a memory chip held not gigabits but just 64 total bits.
The control board has a 4-bit task number available on the backplane, indicating which task is running. We hooked up the oscilloscope so we could see the running tasks.
The good news is we saw the appropriate tasks running at the right intervals, with preemption working properly.
The following traces show the four task number bits. Most of the time the low-priority task 0 runs (all active-low signals high). Task 12 is running in the middle. Task 8 (memory refresh) runs three times, 38.08 microseconds apart as expected. From the traces, everything seems to be functioning correctly with the task execution.
Seeing the running tasks is a big thing, since it shows a whole lot of the system is working properly.
As explained earlier, since tasks are running and switching, the microcode processor must be fetching and executing micro-instructions correctly.
You may remember from the previous article that the Alto display was very, very dim and
we suspected the CRT was failing.
The good news is the display has steadily increased in brightness from its original very dim state, so we probably won’t need to replace the CRT.
We also managed to see some garbage on the screen along with a cursor, showing that RAM is storing something and the display interface is working.
Lots of things are working at this point. The minor 🙂 remaining problem is the system doesn’t boot.
Last time, we got the disk drive working: we can put a 14-inch disk cartridge (below)
in the drive, the drive spins up, and the heads load.
But looking at the backplane signals, we found nothing is getting read from the disk (which explains the boot failure).
The oscilloscope showed that the Alto isn’t sending any commands to the disk – the Alto isn’t even trying to read the disk. We checked for various hardware issues and couldn’t find any problems. My suspicion is the boot code in microcode isn’t running properly.
A bit of explanation on the boot process: On reset, microcode task 0 handles the boot. If backspace is pressed on the keyboard, the Alto does a Ethernet boot. Otherwise it does a disk boot by setting up a disk command block in RAM. The microcode disk sector task gets triggered on each sector pulse (which we saw coming from the disk). It checks if there is a command block in RAM, and if so sends the command to the disk. When the read data comes from the disk, the disk word task copies the data into memory. At the end, the block read from disk will be executed, performing the disk boot. So three microcode tasks need to cooperate to boot from disk.
Since we’re seeing no command sent to the disk, something must be going wrong between task 0 setting up the command block in RAM and the sector task executing the command block. There’s a lot that needs to go right here. If anything is wrong in the ALU or RAM has problems, the command block will get corrupted. And then no disk operation will happen.
The next step is to use a logic analyzer to see exactly what is running, instruction by instruction. By looking at the microcode address lines, we will be able to see what code is executing and where things go wrong. Then we can probe the memory bus to see if RAM is the problem, and look at the ALU to see if it is causing the problem. This is where debugging will get more complex.
I’ve studied the microcode and it is very bizarre.
(You can see the source here.)
Instructions are in random order in the PROM, what an instruction does depends on what task is running, branches happen when a device board flips address bits on the bus, and some bits in the PROM are inverted for no good reason (probably to save an inverter chip somewhere).
So looking at the microcode can be mind-bending.
But hopefully with the logic analyzer we can narrow the problem down.
We can also use the Living Computer Museum‘s simulator to cross-check against what microcode should be running.
For updates on the restoration, follow kenshirriff on Twitter.