If you haven't heard this one, you're probably wondering what it's about.
On 6600's you loaded and stored X registers by loading A registers with
the addresses; if you loaded A0, X0 got stored; if you loaded A1 to A4,
the corresponding X got loaded. To store an A register, you moved it to
a free X register; to load it, you got the address into an X register.
So X0 (I may have which registers did what a bit wrong; it's been ten years)
mostly had to be kept empty.
Now suppose you're writing an interrupt routine (not common; the
PP's took care of the I/O); you need to save the registers. But you have
no right to assume that any register is free. Later 6600's had the exchange
jump (XJ) instruction to deal with that case, but not the one at Courant.
How do you get X0 free so you can save registers? Answer:
Branch to A1 on X0 negative
store 0 at location c1
Branch to B1
A1 store 1 at location c1
B1 Shift X0 left
Branch to A2 on X0 negative
store 0 at location c2
Branch to B2
A2 store 1 at location c2
..... 58 more times.
Save the rest of the registers.
Reconstruct X0 from c1-c60.
This is my memory of what I was told by various friends. Anyone with more
direct knowledge, please correct me where I'm wrong.
Courant had vast sums of money from the Atomic Energy Commission (later
ERDA, then DOE). They ran a major computer installation which featured
one of the first CDC 6600's; in fact, serial number 3. Many wonderful things
were done on this machine, and many to it. Ever hear of the supercritical
Well, the CDC had a bad habit of crashing at 3:00 or so weekdays. It was
fairly regular about this; every few weeks, at 3:00, it would crash. The
repairman would come in, find one of the "cordwood" PC cards burnt out,
replace it, and things would be back to normal for a while. But everyone
worried about the mystery of the regular crash.
Turns out that, because the machine was number 3, the backplane had been
hand wire-wrapped. The technicians had left fingerprints all over the place.
A fungus was growing on the backplane, apparently fed by the oils in the
fingerprints. Most of the time, the air in the room was very dry, and the
fungus didn't grow. But when the operators came in on weekdays, the moisture
in their breath was enough for the fungus to grow a bit. Eventually it would
short a couple of pins (remember, the 6600's circuitry was run at the ragged
edge) causing something to burn out. Of course, that bit of fungus would
get incinerated too.
An application of spray fungicide cured the problem.
This machine is the subject of a bazillion stories, as are some of the people
around it. It's the machine that Ken Kesey and the merry pranksters threatened
to blow up (hence, despite programming on it for a year, I never saw it;
the floor it was on was locked up). Jacob Schwartz, my old boss, was famous
for inventing the first way to save one register when you couldn't touch the
rest: a long series of test and branch instructions (the Courant 6600 didn't
have an exchange jump instruction; that came later). Garabedian and Jameson
did the first numerical simulations of the supercritical wing on it; that idea
later resulted in 30% fuel savings for jet engines. Charles Peskin used it to
simulate blood flow in a dog's heart. I used UT LISP on it; the only LISP with
CONS, CAR, CDR, and CSR (cooser); addresses were 18 bits, words were 60 bits,
so they put another pointer in a CONS cell.
The above is sort of right, but here are the gory details, (taken from 20
years of CDC assembler experience, plus the old listing still stored next
to my desk!)
OK, there are 3 register sets:
B (18 bit index registers) 1 through 7. B0 is write-only, it always
reads as 0.
X (60 bit data registers)
A (18 bit address registers) Writing into A1 - A5 reads the contents of that
memory address into the corresponding X register. Writing into A6 or 7 causes
the contents of X6 or 7 into memory. Modifying A0 does not perform any memory
Now, note that the only way to store anything into memory is writing into (and
thus destroying the contents of) A6 or A7. But.. an Return Jump instruction
(used for calling subroutines) will write a return branch instruction into
memory. We now have the basis for setting memory flags depending on B
OK, so the sequence for freeing up 1 B register is:
PL B7,BRANCH1 (jump to BRANCH1 if B7 is positive)
RJ BRANCH1A (stores return in BRANCH1A and
starts executing at BRANCH1)
BRANCH1A DATA 0
BRANCH1 SB7 B7+B7 (sets B7 = B7*2, shifting the next
bit to the sign position)
. continue for all 18 bits.
B7 is now free to save A7, so X7 can be saved without loss, etc. BRANCH1A, etc.
contain indications of the previous values of the 18 bits of B7.
Whew! Register restore was handled by instruction modification. (Hey,
it worked. What can I say?) I might add that this register saving was
done very seldom; I have seen it used only in debugging packages.
Subroutines simply documented which registers were destroyed, and the
system monitor didn't have to worry about such trivia, since the
user's registers were already saved by hardware.
Lehigh University Computing Center
Ok. Here's the register scoop on a Cyber 170-state machine: it has 24
registers. 8 B registers, 8 X registers, and 8 A registers. The A and B
registers are address registers (B being called 'index' registers) and are
18 bits wide; X are data registers, and are 60 bites wide (one's complement,
yet...). B0 is hardwired 0 (very useful, actually), and A0 is a "normal"
register. A1-A5, however, are "load" registers, and A6,A7 are "store"
registers (loading, for example, 100 into A1 would cause X1 to be loaded
from location 100; loading 100 into A6 would cause X6 to be written into
Sean Eric Fagan | "Time has little to do with infinity and jelly donuts."
se...@sco.COM | -- Thomas Magnum (Tom Selleck), _Magnum, P.I._
(408) 458-1422 | Any opinions expressed are my own, not my employers'.