Copyright © 2001 by Chuck McManis
The SIMPLEX digital computer is a computer educational tool for teaching basic concepts in computation. It has a very easy to understand architecture, a small instruction set, and can be programmed to do several simple computations.
It was inspired by the CARDIAC, a cardboard illustrative aid to computation. That machine is implemented in card stock as you might imagine and it operated by manually moving a pointer through memory and writing and erasing values on the memory sheet. It was written by David Hagelbarger and Saul Fingerman. The copyright on mine is 1968.
The desire to build it originated with trying to teach my then 8 year old daughter the principles of computation, we learned quite a bit with the PDP-8 and the CARDIAC but I thought I might be able to improve on it (the jury is still out.)
The SIMPLEX computer shall consist of a box with various knobs and switches for controlling it. My plan is to implement it in an FPGA when I'm satisfied with the architecture, who knows, maybe I could sell kits to schools.
The computer consists of three rotary switches that can be set to the values 0 through 9. I would like them to look like the digital selectors on the front of the IBM 360 series machines. Above them is a 3 decimal digit display that is used for "display output". To one side are LEDs that indicate different machine states (fetch, execute, overflow, etc). In an ideal world the output display would be three nixie tubes on the top but that will be difficult to achieve.
The SIMPLEX is a decimal computer, digital architecture (base-10 being easier to understand than base-2) The store (or memory) consists of 100 independently addressable locations, addressed as 00 through 99, each of which can hold three decimal digits (e.g. 000 through 999).
SIMPLEX has two digits of precision, or to put it another way it deals with whole numbers between the values of 0 and 99. Whenever an arithmetic operation such as add or subtract causes the upper digit of the accumulator to become non-zero, overflow is indicated.
There are a few special purpose registers in the SIMPLEX computer, these are:
This is a three digit register that is the destination for arithmetic operations. It is also the "transfer" point between other registers and memory. On reset this register is set to the value 000.
The Program Counter
This is a two digit register that holds the address of the memory location where the next instruction will be fetched from. On reset this register is set to the value 00. It can be displayed when the MP/PC switch is in the "PC" position (see below)
The Memory Pointer
This register is not directly accessible to programs but it holds the address of the memory location that will be affected by the examine and deposit front panel operations. It is displayed when the MP/PC switch is in the "MP" position.
The Status Register
This register is not directly accessible, however it has three status flags (visible on the front panel) that indicate arithmetic overflow/underflow. Sign of the accumulator, and whether or not the accumulator is currently holding zero.
There are two Input/Output registers defined, they are:
The Switch Register (I/O location 00)
This register holds the value of the three digit selector knobs on input, and writes to the three display digits on output. The value of the display register is shown when the AC/SW switch is in the "SW" position, the input register is self displaying as there are lights that shine through the digits that are currently selected (see the image below)
The Console Register
This register holds the last character typed on the console (value between 0 and 127), and writes to this register are sent as serial data to the console, values 0 through 127 send ASCII characters and values 200 through 299 write the contents of memory location 00 through 99 as a three digit string to the console. The special code 999 will dump all state to the console.
There are a number of flags that SIMPLEX maintains, two of which can be tested programmatically. The flags are defined as follows:
The Zero Flag
This flag is set to true whenever the contents of the accumulator are zero. It is a synchronous flag in that it changes when the accumulator does.
The Overflow Flag
This flag is set to true whenever the accumulator's upper digit becomes non-zero after an arithmetic operation. It is reset by loading the accumulator with a new value. If the accumulator is loaded from memory with a value greater than 99 this flag is not set, but will be set the next time an arithmetic operation occurs.
The Run/Halt Flag
This flag is set to true when the SIMPLEX is executing instructions. It is not directly settable by the user program, however a branch to the same address is effectively a software halt.
The I/O Wait Flag
The I/O waiting flag indicates that the SIMPLEX is waiting for an I/O value. This can be thought of as a user prompt to either hit a key on the console or enter a value into the switch register. To continue press the step switch after setting the input switches to the desired value.
0 TSKIP Test and Skip
Test the accumulator for a specified condition and skip the next instruction if the condition is true/not true
Second Digit is Test Condition
No Condition 1 Accumulator Not Zero 2 Accumulator Is Zero 3 Overflow (from 99 to 100, or 0 to 999) Occurred. 4 Overflow did Not Occur. 5 - 9 Reserved
Third digit is number of instructions to skip, where 0 is zero instructions up through 9 which is 9 instructions. Since the program counter is already incremented by one when this instruction executes, this will skip 1 through 10 instructions.
Also Note: By this definition 000 is Test no condition skip no
instructions (ie NOP)
1 ADD Add Accumulator
Add the contents of memory referenced in the instruction into the accumulator.
Example: 122 - Add contents of location 22 to the
Note: There is no LOAD instruction, instead loading the accumulator from memory is accomplished by setting it to zero and then adding in a memory location.
2 SUB Subtract Accumulator
Subtract the contents of memory from the accumulator leaving the result in the accumulator.
Example: 222 - Subtract the contents of memory
location 22 from the accumulator.
3 STORE Store Accumulator to Memory
Store the contents of the accumulator into the referenced memory location.
Example: 340 - Store the contents of the accumulator
into memory location 40.
4 INIT Initialize Accumulator
Set the lower two digits of the accumulator to the value in the instruction, set the upper digit to 0. Then reset the flags to reflect the current state (overflow to false, sign to positive, and zero to true).
Example: 400 - clears the state of the machine.
5 BRANCH Load program counter
Load the Program Counter with the number in the two least significant digits of the instruction
Example: 505 - Cause the next instruction fetch to come
from memory location 5.
6 BRANCHI Branch Indirect
Load the Program Counter from the contents of memory referenced by the instruction
Example: 604 - Cause the next instruction to
be fetched from the location stored in
memory location 04.
7 READ Load accumulator from I/O Register
Read the contents of an I/O Register into the Accumulator Like the x80 series of machines and others the SIMPLEX has a separate I/O space from memory space. Location '00' in I/O space is the switch register and location 00 as an output
is the display. Plans include a drum like I/O device that could be used to load programs into memory.
Example: 700 - Read the contents of the switch register
and store them into the accumulator.
8 WRITE Store the Accumulator into an I/O Register
Write the contents of the accumulator into an I/O Register. The analog of read but of course the other direction, this instruction copies the accumulator into I/O "space."
Example: 800 - Write the contents of the accumulator
to the display.
9 CALL Store PC in Memory Location 99 and Branch
Copies the Program Counter (which points past the instruction) into the least significant digits of memory location 99 (whose initial digit is always '5' thus rolling into location 99 will execute a return branch to where the call came from. Then the program counter is loaded with the value in the last two digits of the instruction.
Note that there is no stack, thus recursion requires some care.
Example: 950 - Store the current PC into address 99 and
branch to location 50.
Note: The "return" instruction is simply a BRANCHI 99 or simply 699. .
Memory is addressed as 00 through 99. Each location holds three digits. I'm on the fence about forcing an initial value into either 0 or 99 to allow for self bootstrapping. For now memory is loadable through the switch register when the system is in the "HALT" state.
A Graphic of the SIMPLEX Front Panel
Toggle switches shall control the following functions:
There are a number of displays on the hardware implementation of the SIMPLEX architecture, these are defined here.
Add all of the numbers from 1 to 100:
COUNT DEF 75 ; One word for the count TOTAL DEF 76 ; One word for the total DEC DEF 77 ; And one to hold our decrement constant ORG 00 INIT 99 ; Load accumulator with 99 STORE COUNT ; Store it in COUNT STORE TOTAL ; Store it in TOTAL INIT 1 ; Load accumulator with constant 1 STORE DEC ; Store it in DEC LOOP: INIT 0 ; Clear ACC ADD TOTAL ; Load it with the value in TOTAL ADD COUNT ; Add in the current COUNT STORE TOTAL ; Save that in TOTAL INIT 0 ; Clear ACC again ADD COUNT ; Get the current COUNT SUB DEC ; Decrement by 1 STORE COUNT ; Remember the count TSKIP ZERO,1 ; Test for zero, SKIP if true BRANCH LOOP ; Else loop INIT 0 ; Clear ACC ADD TOTAL ; Load it with TOTAL WRITE 0 ; Display it on the output BRANCH * ; halt END
(this is out of date and needs to be reviewed)
The SIMPLEX computer is implemented in a single PGA the I/O pins are
4 bits -> Digit select
8 bits -> Display data
7 bits -> Memory/IO address
12 bits ->memory/IO data
0 bits -> switch register data (muxed on mem bus)
1 bit -> RD
1 bit -> WR
1 bit -> *IO
2 bits -> deposit / deposit next
2 bits -> examine / examine next
2 bits -> load address / clear all
2 bits -> run/halt
1 bit -> single step
1 bit -> clock
44 bits of I/O resources needed.
One of the thoughts that would be interesting would be to do a Turing version of this architecture where all of the instructions were relative +/- 50 units of memory for example and then implement the Turing "tape" in a static RAM chip.