COMPASS
COMPASS stands for COMPrehensive ASSembler, and it was the language in which entire operating systems were written. Control Data Corporation used it across mainframes whose architectures had almost nothing in common, from the 3000 series to the 60-bit machines of the 6000 series, the 7600, and the Cyber 70 and 170 lines. These were very different machines underneath. Yet the same assembler could speak to all of them. How does one family of macro assembly languages stretch across hardware that disagrees so completely? And on a single 60-bit machine, why did programmers need not one COMPASS but two? The answers live in registers, in memory loads that happen the instant you name an address, and in a processor so simple it could not run a user's program at all.
Control Data's 3000 series sat at one end of the COMPASS family, and the 60-bit machines sat at the other. Between them stood the 7600 and the Cyber 70 and 170 mainframes, each a distinct design. The thread tying them together was not their wiring but their facilities. The macro and conditional assembly features stayed similar even where the architectures diverged. COMPASS itself worked as a classical two-pass assembler. It read the source twice, and it produced a full listing that placed the original assembly code beside the machine code it generated, with that machine code shown in octal. Almost everything in CDC's operating systems was written this way, in COMPASS assembly language rather than a higher-level tongue.
On the 60-bit machines, COMPASS split into two flavors that served two different processors. COMPASS CP targeted the Central Processor, the part of the machine that ran the user's programs. COMPASS PP targeted the Peripheral Processor, which ran only operating system code. The two were not minor variants of each other. Peripheral processor instructions were completely different from those of the central processor. A program written for one would have been meaningless to the other. This division reflected a machine built so that the work of running user code and the work of housekeeping lived on separate hardware, each with its own language to address it.
Twenty-four operational registers gave the central processor its working memory, grouped into three banks named A0 to A7, X0 to X7, and B0 to B7. The X registers were the widest, 60 bits long, and they held data. The B registers ran 18 bits and were meant mainly for addresses or for indexing, with one fixed rule: B0 was always zero. Programmers followed a convention of keeping the value positive one in B1, and sometimes in B7, so a common increment was always at hand. The A registers, also 18 bits, did the work of pointing into memory. Each A register paired with the X register that shared its number, a pairing that turned out to do far more than naming suggests.
Setting an address into one of the A registers could move data on its own. When a program loaded an address into any of A1 through A5, the hardware fetched the data at that memory location straight into the matching X register. The reverse held for A6 and A7. Placing an address there caused whatever sat in X6 or X7 to be stored out to that location in memory. A0 stood apart as the exception. It could hold any address without disturbing the contents of X0, making it the one address register free of this automatic load and store. The instruction form made the effect plain to read. Writing SA1 A0+B1 set address register A1 to the sum of A0 and the index register B1, and the hardware then began loading from that computed address into X1.
Peripheral processor hardware carried far less than the central processor it served. Its accumulator, the A register, was 18 bits. Alongside it sat a 12-bit Program Address register and a 12-bit Q register that the programmer could not see. A 22-bit R register handled address relocation during reads and writes to central memory on Cyber 180 systems. Writing for this processor came with a quirk of access. No special job validation was needed simply to assemble a peripheral processor program. Running one was another matter. Such a program had to be installed into the operating system through special system editing commands before it could execute, a gate that kept this code in the hands of those maintaining the system itself.
Common questions
What does COMPASS stand for in Control Data Corporation computing?
COMPASS stands for COMPrehensive ASSembler. It is a family of macro assembly languages used on Control Data Corporation's 3000 series and on the 60-bit CDC 6000 series, 7600, and Cyber 70 and 170 series mainframes.
What kind of assembler is COMPASS?
COMPASS is a classical two-pass assembler with macro and conditional assembly features. It generates a full listing that shows both the source assembly code and the generated machine code in octal.
What is the difference between COMPASS CP and COMPASS PP?
COMPASS CP is the assembly language for the Central Processor, which runs user programs, while COMPASS PP is the assembly language for the Peripheral Processor, which runs only operating system code. Peripheral processor instructions are completely different from central processor instructions.
How many registers does the COMPASS central processor have?
The central processor maintains 24 operational registers named A0 to A7, X0 to X7, and B0 to B7. The X registers are 60 bits long and hold data, while the A and B registers are 18 bits long.
How does setting an address register work in COMPASS?
Setting an address into any of A1 through A5 loads the data at that memory location into the corresponding X register, while setting an address into A6 or A7 stores the contents of X6 or X7 to that location. A0 can hold any address without affecting the contents of X0.
What language were CDC operating systems written in?
CDC's operating systems were written almost entirely in COMPASS assembly language. Peripheral processor programs could be assembled without special job validation but had to be installed into the operating system through special system editing commands before they could execute.