The SIMPLEX Digital Computer
Version 0.75 (August, 2001)


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.) 

Description

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.

Architecture

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. 

Registers

There are a few special purpose registers in the SIMPLEX computer, these are:

The Accumulator

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.

Flags:

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.

Instructions:

    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

0

 No Condition
 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
accumulator.

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

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.

System Control (lights and switches)


A Graphic of the SIMPLEX Front Panel

Toggle switches shall control the following functions:

Displays

There are a number of displays on the hardware implementation of the SIMPLEX architecture, these are defined here.

Sample Program (untested)

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

The SIMPLEX FPGA

(this is out of date and needs to be reviewed)

The SIMPLEX computer is implemented in a single PGA the I/O pins are
as follows:
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.

Other Thoughts

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.

--Chuck