return to main page

Esoteric Factoids

You hope you will never need to know ;-))
Table of Contents

1401 ALU Archeology
Subject: [1401_software] What you get when you add @ and #
From: Ken Shirriff < >
Date: Wed, Jan 28, 2015 10:51 pm

I was studying the ILD diagrams, trying to understand how the qui-binary adder works, when I noticed some puzzling circuitry to handle non-digit characters. I did some investigation to figure out what's going on and how addition works when you add things that aren't digits. The results are probably obvious to many of you, but hopefully they will still be of interest.

Qui-binary numbers are explained on the website, but I'll give a quick summary. A decimal digit is split into two parts. The first part is one of 0, 2, 4, 6, or 8. The second part is 0 or 1. It should be clear that any digit 0 to 9 can be expressed as one value from the first set and one value from the second set. For instance, 7 = 6+1 and 4 = 4+0. In the circuitry, each part has a control line associated: Q0, Q2, Q4, Q6, or Q8 for the first part, and B0 or B1 for the second part.

One motiviation for qui-binary is that it provides easy error checking of the sum. There should be exactly one Q line and one B line active in the result. If no Q lines are active, or more than one Q line is active, something is wrong. Likewise with the B lines. By checking for no lines set or more than one line set, an error in the adder can be detected and triggers an arithmetic check fault.

Page 25 of the ILD diagrams shows the circuit to convert the B register to qui-binary:

I've labeled in red which binary values go to which Q values. Q0 is set for values 0 (blank), 1, and decimal 10 (zero digit). Keep in mind that the digit 0 is represented as decimal 10 internally. Likewise, values 2 and 3 go to Q2. 4 and 5 go to Q4, 6 and 7 go to Q6 and 8 and 9 go to Q8. B0 and B1 are simply set from the low-order bit. But what happens when you have a character outside 0-9?

What caught my eye is the gate labeled x011 -> Q2, which sends 3 to Q2. Since the gate above it sends 001x to Q2, both gates send 3 to Q2, which is redundant. Why is x011 treated specially? Is there some reason that they added an extra gate to have binary 1011 (decimal 11) treated as 3 (i.e. Q2+B1) by the adder? (Anyone know how much an additional SMS card cost?)

To get to the bottom of this, I wrote a test program to add all 64 characters to all 64 characters. Stan was pretty dubious, saying I was wading into illegal, undefined operations, but he helped me try it out on the 1401. After a lot of blinking lights, I got my output. The digits 0 through 9 add as you would expect. A blank is treated just like 0, which is reasonable. The interesting part is the characters #@:>√ (stored as 11-15) are treated exactly like the digits 3 through 7, i.e. the top bit is ignored. To summarize, the internal values 0 through 15 are treated as the digits 0123456789034567. (Personally, I think 0123456789012345 would have been more logical.)

This explains the gate that puzzled me. Because 1010 is treated specially (going to Q0), 1011 also needs to be treated specially, to make it go to Q2. (If they used a single gate 101x, then decimal 11 would have ended up as Q0+B1=1, not 3.)

Note that significant additional logic is required to handle special characters. If they didn't include this logic, special characters could trigger more or less than one Q line, and trying to add them would trigger an arithmetic check fault - the illegal addition that Stan was worried about. But with this logic, special characters add just like regular digits.

Thus, to answer the question in my subject, @+# = 4+3 = 7.

I'll wrap up with the treatment of signs. Signs of special characters are treated the same as regular digits. The B zone bit indicates a negative number, and any other zone indicates a positive number. So
,%='" are treated as 34567, -$.);Δ are treated as negative 34567, and &⌑(<≡ are treated as positive 34567.

As the documentation says, adding a positive and negative number results in a complement add, subtracting the values. In this case, the adder generates the zone based on the sign of the result (B zone for negative or AB zone for positive). For a regular (non-complement) add, the zone bits from the B register are passed through unchanged. (The circuit for this is on ILD page 10 - data flow - and the zone bits are selected from the adder or B register by B REG ZONE INHIBIT and ARITH ZONE INHIBIT.) One consequence is that addition is non-commutative: 1 + C = D (i.e. 1 + positive 3 = positive 4). But C + 1 = 4 (i.e. positive 3 + 1 = 4).

For an example of signs with special characters, adding % + $ yields A (+1) since % is treated as 4 and $ is treated as -3. Since this is a complement add, the zone is set to AB (+) based on the result's sign.

Hopefully this is interesting, but let me know if it's too low-level for this mailing list.


From: Van Snyder < >	 	 
Date:	Thu, Jan 29, 2015 1:44 pm
To:	Ken Shirriff 
Bob Supnik (the author of the SimH i1401 simulator) wrote:

Very interesting! And the simulator seems to get it right:

const int32 bcd_to_bin[16] = {
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 4, 5, 6, 7

Or, as Ken says,

the internal values 0 through 15 are treated as the digits 0123456789034567

I'm glad to have confirmation of why this works.

I wonder if the 1620 works the same way...

From:	Keith Falkner < >	 	 
Date:	Fri, Jan 30, 2015 5:35 am
To:	Van Snyder 
Cc:	1401 Software Team <>

You ask if the 1620 added the same way the 1401 does.

Very very far from it. Wikipedia reminds us,
that the 1620 had addition tables in its memory,
so the process of addition was akin to table lookup,
and if a bug (or intentional prank) scrambled the addition tables,
a program could add 4 and 2, and get 7 with 1 to carry.

No wonder it was nicknamed CADET:
Can't Add Doesn't Even Try.

Many thanks for the compendium of tips. I cherish them.


return to main page