The University of Iowa's DEC PDP-8Restoration Log
Part of
the UI-8 pages
|
This is a chronological log of the progress restoring the University of Iowa's PDP-8 computer. Entries are added at the end as work progresses. Click on any thumbnail image to see full-sized image.
![]() |
![]() |
Backplane rows B and D | |
---|---|
![]() | |
Backplane wiring, as found |
Several details are omitted here, notably, there were 7 wires from the data
inputs to the
R203 flipflops
in backplane slots B29 through B31 to an unpopulated backplane slot, D29.
These were all wires added by the Psychology department, and on careful
tracing their function, they all carried raw data from the tape reader.
Our best hypothesis is that these wires part of an unfinished project.
![]() |
Type 750 controller, as found |
---|
The thing that was most apparent in reverse engineering this interface is that
it contains a number of features typical of shotgun debugging. The control
system is close to twice as complex as required for the Tally reader, and some
of the changes make this interface unnecessarily incompatible with the
documentation for the interface in the
PDP-8 Users Handbook
(Digital Equipment Corporation, 1966).
![]() |
![]() |
Rows B and D cleaned up |
---|
DEC's backplane wire-wrap pins in the pre-TTL era were designed for 22 or
24 AWG wire using Kynar (polyvinylidene fluoride) insulation. Some of the
wire we removed had plain vinyl insulation, which is too soft for use among
the sharp corners of wire-wrap pins, and some was 28 or 30 AWG (we did not
measure it, but it was definitely too fine.) The blue wires visible in the
photo of row D above are examples of this problem that remain in place, for now.
![]() |
![]() |
The improved test rig |
---|
We broke the first small core we tried to use, ferrite is quite
brittle. To protect our second attempt, we mounted the core on a small circuit
board to isolate stresses on the windings from stresses imposed by test leads
and handling. Our core had with 3 identical 3-turn windings made of
30-gauge wire-wrap wire. One wining connected to the signal generator, one
to the input of the G007 board, and the final winding was used as a scope
input to monitor the input to the G007 without perturbing it. Driving the
core with a square wave produced nice spikes for testing the sense amplifier.
![]() |
Pins E & F of problem board. |
---|
![]() |
Pins E & F of good board. |
With our test rig producing clean 20mV spikes as input, the collectors of Q5 produce complementary and somewhat stretched spikes with an amplitude close to 0.25V. At first glance, it is very difficult to see any difference between the good board and the problem board. Note that the complementary outputs were recorded separately and then combined here. Small horizontal differences between the two red traces are the result of jitter in the signal generator output and not evidence of amplifier problems.
A closer look shows that the outputs of the good board are just shy of 0.25V,
while th outputs of the problem board are closer to 0.24V. A second detail
we noticed only on close inspetion was that the differential
amplifiers are not perfectly balanced on both boards. We did our best to
balance all of the amplifiers by adjusting
the trimmer potentiometer R4 to minimize the DC voltage between pins E and F,
as measured with an analog volt meter. The slight imbalance remaining shows up
as a slightly different peak amplitudes for the positive and negative spikes.
![]() |
Pin J of problem board. |
---|
![]() |
Pin J of good board. |
The scope traces to the right show how the output of the slicer (shown in red) depends on the amplitude of the input pulses (shown in blue). We ramped the input pulse amplitude up from 30mV to 50mV. Note how, on the good sense amplifier, output pulses start to appear as the input amplitude rises from 30mV to 34mV, while on the problem board, output pulses only appear when the input amplitude rises from 38mV to 42mV. We used AC coupling for these measurements.
According to the writeup on the sense amplifiers on page 4-7 of the PDP-8 Maintenance Manual (Digital Equipment Corporation, 1966), the nominal amplitude of the input pulses to the sense amplifiers is 50mV.
Before we really thought this through, we replaced Q9 on the problem board.
While it is possible that insufficient gain in this transistor would lead to
problems here, it seems far more likely that what we are seeing is either
insufficient select current — leading to a low amplitude in the input to
the sense amplifier, or a slice voltage that is too high — leading to an
excessive threshold. The apparent big difference between the good sense
amplifier and the problem one can be explained by what we thought was
an insignificant difference between the two amplifier gains.
Bug 66: Having concluded, on July 3, that the most likely problem with our "bad" G007 sense amplifier board is simply that it has a lower gain than our "good" board, we set out to compare all 12 G007 boards. To help keep track of which board is which, we scratched an identifying letter on each board, from A to L, starting with the one we had considered bad. The following table relates board labels and bit numbers to backplane positions, as seen from the handle end of the board:
ROW A | 30 | 29 | 28 | 27 | 26 | 25 |
---|---|---|---|---|---|---|
10 | 8 | 6 | 4 | 2 | 0 | |
B | C | D | A | E | F | |
ROW B | 30 | 29 | 28 | 27 | 26 | 25 |
11 | 9 | 7 | 5 | 3 | 1 | |
G | H | I | J | K | L |
Note that, on the PDP-8, bit 0 is the most significant bit and bit 11 is the least significant bit. The bit numbers were taken from DEC drawing BS-D-BM-0-15 Sense Amps, Inhibit Drivers and Memory Control (page 10-51 of the 1966 Maintenance Manual).
With board A (the problem board) on the same test rig we used on July 3, we adjusted the slice voltage so that board A began to respond when inputs from the sense line had an amplitude of 34mV. In our July 3 tests, the good board (now labeled board J) had begun to respond at this voltage. (The slice voltage controls the threshold against which the differential amplifier output is compared, it is adjusted by changing the setting of the trimmer potentiometer R3 on the G008 Master Slice Control board; the schematic is immediately below that for the G007.)
We had adjusted the static balance of the differential amplifiers on all of the boards using the volt-meter techniqe recommended in the PDP-8 Memory Tuning Procedure (also available here) on page 9. We realized that our test rig offers a much more effective way to adjust the sense amplifier balance, so we adjusted the sense amplifier input to 50mV and then adjusted the sense amplifier balance so the output peaks on pin J were of equal height for both positive and negative input pulses. (Note that perfect balance was impossible because the balance adjustment, a 10Ω trimmer potentiometer (R4), changes the balance in discrete steps as the adjusting screw is turned.)
The following table shows the pulse height we measured on pin J for input 50mV input pulses on every board:
Board | Pulse Height |
---|---|
A | -2.7V |
B | -3.8V |
C | -3.6V |
D | -3.6V |
E | -4.0V |
F | -3.7V |
G | -3.7V |
H | -3.6V |
I | -3.9V |
J | -3.9V |
K | -3.7V |
L | -3.8V |
The data here makes it very clear that our problem board has an unusually low gain. We may need to replace on or both of Q2 and Q5, although it is also possible that the gain, although sub-par, will be tolerable after completing the memory tuning procedure.
Bug 64 and bug 66: On Jul 8 we speculated that our changed slice voltage might allow memory to work sufficiently reliably to allow us to try writing programs. So, we moved the G008 Master Slice Control (see schematic immediately below that of the G007) from our sense amplifier test rig back to slot B31 in the backplane and tried toggling things into memory.
Bug 43: It worked, so we tried writing a little program (all code here is shown in PAL-8 assember listing format):
0000 7001 L, IAC / increment AC 0001 5000 JMP L / iterate
Not a very exciting program, using just the IAC and JMP instructions, but it ran, with all the front panel lights for the accumulator AC blinking too fast to see, except the link bit L, a condition code bit that toggles with each carry out of AC. You could just see that L was flickering. We wanted to see what was happening, so we slowed the program down:
0000 7001 L, IAC / increment AC 0001 7000 NOP / no opertion 0002 7000 NOP / no opertion 0003 7000 NOP / no opertion 0004 7000 NOP / no opertion 0005 7000 NOP / no opertion 0006 7000 NOP / no opertion 0007 5000 JMP L / iterate
Adding NOP instructions slowed the program down enough that we could see that the top 3 bits of the accumulator were counting in binary.
With this success, we tried to make a program to run
chase lights
in the accumulator display:
Again this worked when we single stepped the code, but when we ran it,
it was too fast, nothing was visible on the front panel lights.
The
CLA, CLL
and
CML
opcodes all combine as a single microcoded instruction.
To slow it down, we tried adding a delay loop using the
ISZ
instruction:
This did not work. It hung in the delay loop, and when we single stepped the
code, we found that the carry was not propagating from bit 7 to bit 6 of the
delay loop counter X. Looking at the
CPU flow diagram, drawing
BS-D-8P-0-7 (page 10-55 of the 1966 Maintenance Manual),
we found that IAC and other addition functions on the accumulator
use a different incrementor than is used by the ISZ instruction.
The latter directly increments the memory data register, and according
to drawing
BS-D-8P-0-5 (page 10-35 of the Maintenance Manual),
carry propagation for that increment is done using a pair of
R181 boards.
We did not bother with reverse engineering, but simply pulled the board
from backplane slot PD19 (this
handles the carry from bit 7 to bit 6) and checked all the diodes. Two were
bad, so we replaced them and tried again.
With this fix, the program worked, but it was still too fast,
so we rewrote it as:
This program worked nicely, repeatedly moving a single one bit left through
the 13 bits [L,AC] slowly enough that you could follow it. We left it
running for several minutes, which is to say, many million instruction cycles.
Our attempts to write code that did load and store, or rather
TAD and DCA instructions
failed. We need to do more CPU debugging. We left
the chase light programm in memory before we turned the machine off because
it is good for quick demos.
Bug 43:
Continuing our work from
July 10,
we wrote more code. We were curious about taking input from the switch
register using
OSR.
At the same time, we experimented with writing code in
a higher
page
of memory, leaving our chase-light code from
July 10
in page 0:
This code worked. All it does is continuously display in the accumulator
whatever value is on the front-panel switches. This allowed us to quickly
verify that the data paths from all of the switches worked correctly. At the
same time, it demonstrates that the "current page" addressing mode works, at
least for
JMP
instructions.
We left that code in page 1 (which starts at 02008), and moved on
to page 2 (starting at 04008) for a test of load and store,
or rather
TAD and DCA instructions.
This program worked:
As written above, the front panel lights for the accumulator always show the
one more than the value in the switch register. Changing the final
JMP L to JMP M (52018) changes the
program's behavior to a simple binary counter.
From this experiment, we know that the DCA and IAC
instructions are referencing memory. Furthermore, they appear to be referencing
the current page, or at least, the chase-lights program we left in memory on
July 10
still worked correctly after running this program.
We left the following program in memory:
This program was somewhat fun becaue the value on the switch register
is the amount by which the counter is incremented for each iteration of the
outer loop, so by playing with the switch register while the program is
running, you can change the rate at which the higher bits of the counter blink.
We tried to load code in page 3 (starting at 06008 and had
difficulties. We tried to run larger programs and had difficulty. We tried
running programs with subroutines and had difficulty.
In some cases, these programs ran for a visible fraction of a second before
hanging, and when they hung, the code had been changed. This suggests that
there is something nondeterministic either in the call or return instructions
or dependent on memory addresses outside the first few addresses in a page.
We also noticed that setting the program counter to an odd address from the
switch register was difficult. It was easier to start with an even address and
then increment the program counter with the examine key.
0000 7320 CLA CLL CML / initialize AC=0,L=0,L=~L
0001 7004 L, RAL / circular left shift [AC,L]
0007 5001 JMP L / iterate
0000 7320 CLA CLL CML / initialize AC=0,L=0,L=~L
0001 2005 L, ISZ X / increment X and skip if zero
0002 5001 JMP L / iterate delay loop
0003 7004 RAL / circular left shift [L,AC]
0004 5001 JMP L / iterate
0005 0000 X, .-. / delay loop counter
0000 7320 CLA CLL CML / AC=0,L=0,L=~L
0001 2011 L, ISZ X / increment X and skip if zero
0002 5001 JMP L / iterate first delay loop
0003 2011 M, ISZ X / increment X and skip if zero
0004 5003 JMP M / iterate second delay loop
0005 2011 N, ISZ X / increment X and skip if zero
0006 5005 JMP N / iterate third delay loop
0007 7004 RAL / circular left shift [L,AC]
0010 5001 JMP L / iterate
0011 0000 X, .-. / delay loop counter
Jul 15, 2025, More programming
0200 7604 L, CLA OSR / AC=0,AC|=SR (in sum, AC=SR)
0201 5200 JMP L / iterate
0400 7604 L, CLA OSR / AC=0,AC|=SR (in sum, AC=SR)
0401 3210 M, DCA X / X=AC,AC=0
0402 7001 IAC / AC+=1 (so AC=1)
0403 1210 TAD X / AC+=X (eventually increment X)
0404 2211 N, ISZ Y / increment Y and skip if zero
0405 5204 JMP N / iterate delay loop
0406 5200 JMP L / iterate
0410 5200 X, .-. / value from SR or counter
0411 5200 Y, .-. / delay loop counter
0400 3210 L, DCA X / X=AC,AC=0
0401 7604 CLA OSR / AC=0,AC|=SR (in sum, AC=SR)
0402 1210 TAD X / AC+=X (eventually X=X+SR)
0403 2211 M, ISZ Y / increment Y and skip if zero
0404 5203 JMP N / iterate delay loop
0405 5200 JMP L / iterate
0410 5200 X, .-. / counter visible on AC lights
0411 5200 Y, .-. / delay loop counter
Jul 17, 2025, Test and replace some diodes
![]() |
The chase light test |
---|