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.
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
).
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.
-9999
to
+9999
).
00-99
.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).
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.
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
.
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
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
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
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
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
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
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).