CARDIAC: Cardboard Illustrative Aid to Computation

CARDIAC was an educational device developed at Bell Labs in 1968 to demonstrate the basic operating principles of computers. It was constructed out of cardboard, and the actual computations were performed by students using pencil and paper. Like all computers, CARDIAC possesses a control unit to execute programs, components for input and output, and a memory to store both data and programs.

This webpage describes the basic functioning of CARDIAC. It is intended to give the user sufficient background to operate the CARDIAC simulator.

Random Access Memory (RAM)

The Random Access Memory (RAM) of CARDIAC consists of 100 directly accessible memory cells. Each cell is referenced by a unique 2-digit address in the range 00 to 99, and each cell can hold a whole number in the range -999 to +999. In the simulator, the memory is arranged into a 10 x 10 array; 54 refers to Row 5, Column 4 (with row and column numbering starting at 0).

Registers and Control

The Central Processing Unit (CPU) is responsible for executing programs. To do this, the CPU makes use of memory cells called registers, each of which can contain a decimal number.

The Instruction Set

CARDIAC can only execute 10 basic instructions (listed below). Each instruction is exactly 3 digits long and can be broken into two parts. The leftmost digit is the opcode (operation code) and indicates which type of instruction is to be executed (e.g., the number 1 indicates the ADD instruction; 6 indicates the STORE instruction). The remaining 2 digits constitute the operand and indicate the address of a memory cell to be affected by the instruction.

For instance, the code 670 tells the computer to store the contents of the accumulator register to memory cell 70. Opcode 6 determines the instruction (STORE) and operand 70 indicates the memory cell affected. Since reading numerical codes is difficult for humans, we often write instructions in a shorthand called assembly language in which the opcode of the instruction is replaced with a string mnemonic (e.g., STO 70 instead of 670). The numeric form of the instructions are called machine code.

OPCODE MNEMONIC DESCRIPTION (Op indicates a memory cell.)
0 INP Input: Read a number from input and store it in cell Op.
1 CLA Clear and Load: Copy the value in Op to the accumulator.
2 ADD Add: Add the value in Op to the value in the accumulator. Store the result in the accumulator.
3 TAC Test Accumulator: If accumulator value < 0, then replace the contents of the program counter with Op.
4 SFT Shift: Shift the value in the accumulator X to the left, Y to the right, where Op = XY. A 4-digit window is used, and when digits move passed it, they are lost.
5 OUT Output: Output the value in Op.
6 STO Store: Store the value in the accumulator to Op.
7 SUB Subtract: Subtract the value in Op from the value in the accumulator. Store the result in the accumulator.
8 JMP Jump: Replace the contents of the program counter with Op.
9 HRS Halt: Stop execution.

Table 1: CARDIAC Instruction Set

Below are instructions to add two numbers stored in memory cells 70 and 71 and store the results the results in 73.

Assembly Code Machine Code
CLA 70 170
ADD 71 271
STO 73 673

Note about the accumulator: While memory cells hold signed 3-digit numbers, the accumulator holds signed 4-digit numbers. This is relevant to the ADD, SUB, and SFT instructions. When values from the accumulator are copied to memory cells, however, only the 3 least significant digits are stored (the 4th is not used).

The CPU Machine Cycle

CARDIAC operates in a sequential fashion, fetching one instruction from memory, decoding and executing it, and then moving on to the next instruction. This is called its machine cycle. This cycle is repeated until a HALT instruction is met. The program counter indicates which instruction is to be retrieved and executed, and it is incremented by 1 after an instruction has been fetched from memory. By default, the instruction pointer initially points to memory cell 00. The phases of the CARDIAC machine cycle are shown below.

  1. Fetch: Retrieve the contents of the memory cell indicated by the program counter and store it in the instruction register. Increment the program counter.
  2. Decode: Break the value in the instruction register into opcode and operand.
  3. Execute: Execute the instruction.

Negative Numbers and Arithmetic Overflow

CARDIAC can store negative whole numbers, and these are not (strictly speaking) valid instructions. In the simulator, we will deal with 'negative' instructions simply by ignoring the sign. E.g., the value -070 will be treated as if it were 070.

Also, since CARDIAC cannot represent values less than -9999 or greater than 9999 in the accumulator, it is possible for an arithmetic operation to yield a value that is out of bounds. In such cases, the values will rollover like the odometer on an automobile, so that, for instance, 9999+002 = -9998 and -9999 - 001 = 9999.

Cardiac: Sample Programs

Swapping Two Numbers

This program swaps the contents of two memory cells (50 and 51). It first reads in two numbers to the cells. The value in cell 50 is then copied to the accumulator, and then to the temporary cell 40. The value in cell 51 is copied to the accumulator and then to cell 50 (overwriting the original value). Finally, the value in cell 40 is copied to the accumulator and then to cell 51.The third cell (cell 40) is needed to hold a copy of the contents of cell 50.

INP 50
INP 51
CLA 50
STO 40
CLA 51
STO 50
CLA 40
STO 51
HRS 00

Adding Two Numbers

Two numbers can be added together using the accumulator. Here, the numbers to be added are read from input and stored in memory cells 10 and 11. The result is stored to memory cell 12 and then written to output.

INP 10
INP 11
CLA 10
ADD 11
STO 12
OUT 12
HRS 00

An Infinite Loop

A value (the number 001) is read from input and stored in cell 50. The value in cell 50 is then added to the value in the accumlator, and the result is stored to cell 51. The value of cell 51 is then written to output. Afterwards, the program jumps to the instruction in cell 01. The effect is to output an increasing sequence of integers.

INP 50
ADD 50
STO 51
OUT 51
JMP 01

Comparing Two Numbers

Here we input two numbers and use subtraction and the conditional jump instruction TAC to determine the larger number. If the contents of 91 is larger than the contents of 90, then subtracting the contents of 91 from 90 will yield a negative number in the accumulator. If the value in the accumulator is negative, then the contents of cell 91 is written to output. If not, then the contents of 90 are written.

INP 90
INP 91
CLA 90
SUB 91
TAC 07
OUT 90
JMP 08
OUT 91
HRS 00

Fibonacci Numbers

Using techniques similar to those in the previous examples, this program computes the first 17 Fibonacci numbers. The number 14 and the first two Fibonacci numbers (0 and 1) are written on input. The 14 is used as a counter. The program begins by storing the values in input to memory cells, outputing the original two Fibonacci numbers, and then entering a loop. The program halts when the value in the accumlator becomes negative (which happens when the counter is decremented beyond 0).

INP 40
INP 50
INP 51
OUT 50
OUT 51
CLA 51
STO 30
CLA 50
ADD 51
STO 41
OUT 41
CLA 51
STO 50
CLA 41
STO 51
CLA 40
SUB 30
STO 40
TAC 20
JMP 07
HRS 00

Multiplication

Cardiac does not have a separate instruction for multiplying two numbers x and y. This can be accomplished by repeated addition (that is, add y x times). In the below program, two values are read from input and the result written to output. The accumulator is used to hold both the temporary sum and the number of times left to add y. The value 001 at the end of the program is used in counting the number of times left to add y.

INP 90
INP 91
CLA 90
SUB 12
STO 90
TAC 10
CLA 92
ADD 91
STO 92
JMP 02
OUT 92
HRS 00
001 

Bootstrapping programs.

The instructions below load a program which, when executed, prints out the numbers 1-5. The interesting thing is how the program is loaded. In the original CARDIAC, memory cell 00 has a fixed value 001. This, together with the instructions in yellow, initiates a loop to load the program (this is called bootstrapping). The load loop works as follows: when 001 in cell 00 is executed, INP 01 is written to cell 01. When that cell is executed, JMP 00 is written to cell 02 . Subsequent input instructions are interleaved with the program to run. CARDIAC enters a loop repeatedly executing cells 00-02, loading the program to cells 10-14 and the data used by the program to cells 20-24. The last instruction, JMP 10, breaks out of the loop and transfers control to the first instruction of the program.

INP 02
JMP 00
INP 10
520
INP 11
521
INP 12
522
INP 13
523
INP 14
524
INP 15
HRS 00
INP 20
001
INP 21
002
INP 22
003
INP 23
004
INP 24
005
JMP 10

The CARDIAC simulator implemented here does not force cell 00 to hold 001, but some examples are provided which demonstrate this bootstrapping process (two of the examples are taken from another site dedicated to the CARDIAC).