What I remember about assembly language programming the CDC6600 was how beautifully simple the machine's principles of operation were at the register and instruction level.

In 1974 I learned CDC6600 assembly language in grad school. In comparison to IBM360 assembly language programming I had previously done, the CDC 6600 was so straightforward. It took perhaps one day to learn all of it. I still have the small book that I learned from, Assembly Language Programming for the Control Data 6000 Series and the Cyber 70 Series by Ralph Grishman.

Addressing: The machine had unusual data layout, it was word, not byte addressable and each word was 60 bits long, not 16 or 32 bits long.

Data Format: Text was stored in six-bit fields, ten per word and so the characters weren't directly addressable. Furthermore, integers were stored in 1's complement, not the more common 2's complement or sign-magnitude format. There was a single 60-bit floating point format (1-bit sign, 11-bit exponent, and 48-bit coefficient).

Speed: Floating point multiplication took 1000ns, but the 6600 could do two floating point multiplies, a floating point add, and an integer add simultaneously if coded carefully.

Memory: The memory of the 6600 was stored in a ferrite core memory and it had a maximum size of 128K words. Later, there were slower, larger memory tiers as options.

I/O: This was handled by peripheral processors that had access to the main memory and could offload data transfers to devices so that the central processing unit didn't have to handle expensive interrupts (expensive because the out-of-order execution of instructions meant that saving and restoring the state of the CPU was relatively time-consuming).

Registers: There were 8 X-registers. These are 60-bit registers that are used as the operands in the assembly language instructions. There are also 8 18-bit A-registers that are used for addressing and an additional 8 18-bit B-registers for use as loop indexes, etc.

Instructions: Opcodes are always 6 bits, there are only 71 instructions (one of the 64 possibilities in the 6-bit op code is further divided into 8 instructions). The instructions were simple:

IX4 X5+X6 ; Integer sum of X5 plus X6 goes into X4

Such an instruction takes 15 bits, six for the opcode, three each for the three registers.

This was all a lot less to understand than the intricacies of the IBM360 principles of operation. The IBM360 of the time had instructions like TRANSLATE-AND-TEST or the SHIFT-AND-ROUND-DECIMAL. Here for example are the first four paragraphs explaining the TRANSLATE-AND-TEST instruction from the IBM 360 Principles of Operation:

> The eight-bit bytes of the first operand are used as arguments to reference the list designated by the second operand address. Each eight-bit function byte thus selected from the list is used to determine the continuation of the operation. When the function byte is a zero, the operation proceeds by fetching and translating the next argument byte. When the function byte is nonzero, the operation is completed by inserting the related argument address in general register 1, and by inserting the function byte in general register 2.

> The bytes of the first operand are selected one by one for translation, proceeding from left to right. The first operand remains unchanged in storage. Fetching of the function byte from the list is performed as in TRANSLATE. The function byte retrieved from the list is inspected for the all-zero combination.

> When the function byte is zero, the operation proceeds with the next operand byte. When the first operand field is exhausted before a nonzero function byte is encountered, the operation is completed by setting the condition code to O. The contents of general register 1 and 2 remain unchanged.

> When the function byte is nonzero, the related argument address is inserted in the low-order 24 bits of register 1. This address points to the argument last translated. The high-order eight bits of register 1 remain unchanged. The function byte is inserted in the low-order eight bits of general register 2. Bits 0-23 of rcgister 2 remain unchanged. The condition code is set to 1 when the one or more argument bytes have not been translated. The condition code is set to 2 if the last function byte is nonzero.

> ... [There's a lot more]