November 20, 2014
In 1959 IBM came out with the IBM 1401. It was a programmable data processor. It could read punch cards, process them, and punch new cards. It was spectacularly successful—they claim that at one point, half-way through the 1960's, nearly half the computers in the world were 1401s.
The local Computer History Museum has two running 1401s. A few weeks ago they ran an event where you got to manually punch your name into a card and they'd run it through the computer, which would print out a banner with your name on it. They also announced that if someone wrote a program for the computer, they'd run it. I thought I'd write a ray-tracer for it.
The computer is a decimal variable word-length machine. Decimal means that the internal representation is base-10. The number 1234 takes up four memory locations, one for each decimal digit. Each digit is represented in binary, with four bits each. (They waste values 10 through 15, which is odd for a time when memory cost $35 per byte in today's dollars.) Variable word length means that operations could work on operands of any length. Machine instructions worked directly in memory, not on registers like modern architectures, and the length of the operands was determined by an extra bit called the word mark. (Again odd that they would dedicate a bit ($4's worth!) to a value that was nearly always zero.)
There's a great assembler, emulator, and IDE called ROPE for the IBM 1401. I used it to develop the ray-tracer. The program can load a scene from punch cards but also has a built-in scene for easy deployment. It does lighting and shading, but not reflections or shadows. It sends its output in character art to the printer one line at a time using Floyd–Steinberg dithering. It takes about 30 minutes to generate a 100×100 image of two spheres. This is the output from the simulator:
You can browse the ray tracer's source code on
GitHub. The main
ray.aut. The machine doesn't support floating
point math, so the ray tracer uses fixed point math. There's a lot
of self-modifying code because the machine only supports three
pointers at a time. If you want more, you have to write the
address of the data into the instruction's data field. There are
a million quirky things about this machine. I definitely get the
sense that they were only starting to figure things out. Also
many of the architecture decisions were driven by compatibility
with older punch-card machines.
The crew at the Computer History Museum has been very helpful in getting my program to run on the real thing. Turns out it's a bit hard to get code onto it, with the I/O hardware often in a bad state. Last week I finally got it to work, but one of the columns in the printer was broken and one of the characters I had chosen for the art printed as a space. (This is pre-EBCDIC and the machine supported several interpretations of special characters.)
Ken Shirriff wrote a Mandelbrot Set program for the IBM 1401 and published a detailed description of how the machine works.