This page presents a machine definition and programming guide for Simon. The aspects of the machine definition left unspecified in the articles, as distinguished from the resolutions for them used here, are elaborated on the Gaps & Alterations page.
Much of the material presented here is new (2006), including the programming model diagram, assembly format definition and sample programs. Such material was not presented in the original articles.
Contents (this page):
Program instructions and data are input via a 5-level paper tape reader (5 bits or holes wide). (5-level paper tape was standard for use with teletypes before the advent of ASCII). Data may also be input manually via the front-panel switches during program execution.
Various registers are provided, some for general data storage, others for targetted purposes. The registers and busses are a mixture of 2- and 4-bits wide. The input register can be viewed as one 4-bit register (referred to as IR) or two 2-bit registers (IR1 and IR2). IR1 refers to the 2 lower-order bits of IR, IR2 to the 2 higher-order bits. Register CR4, which indicates the function to be performed by the ALU, is 4 bits wide. There is a 1-bit carry register (CRY) accessible only by the ALU. All other registers are 2 bits wide.
Note that IR and CR5 can not be loaded from the main bus. IR is only loaded from the tape or front panel, CR5 is restricted to registering the output from the ALU.
The ALU is also 2-bits wide. The functions which it performs are listed further below.
Output is via the 5 lamps connected to the Output Registers.
Comment: The mixture of 2 and 4 bit registers and busses makes for an awkward design. Presumably the designers made this choice for reasons of economy, particularly in reducing the size of the ALU. Nonetheless, I suspect a more fully 4-bit design where the existing 2-bit registers are simply combined into 4-bit registers and the ALU extended to 4 bits, would not require many more relays.
To program Simon one prepares a paper tape with the machine instructions and data. The paper tape is the program memory: Simon executes the program instructions as it reads the tape, it does not 'load' the program.
The tape reader reads in one direction only. All instructions on the tape are executed in sequence, there is no opportunity to skip instructions or branch. Some degree of conditional operation is provided for by the selective assignment function of the ALU. There is one opportunity to create a loop by forming the entire program tape into a loop.
A program may include programmed halts.
Program execution stops, and the machine waits for manual indication before resuming execution.
The output lamps can be observed at this point and/or a data value can be input from the front panel.
|Instruction Encoding and Execution|
At the tape level there is really only one type of instruction. In executing each tape instruction the machine performs the following sequence of actions:
This sequence obviously and directly provides the operation of moving data between registers. Other operations - specifically those involving the ALU - are accomplished by loading CR4 with an appropriate function code from Table 2. Loading CR4 results in CR5 and CRY being loaded with the function results from the ALU. This is detailed further in the programming examples below.
In the event of a programmed halt (h=1), reading of the tape stops immediately at the 2nd element of the tape triplet.
At this point, IR can be manually loaded with data from the front panel and execution resumed.
For clarity the operands have been reordered from their sequence in a tape triplet, so information movement is now consistently right to left.
It is possible to specify an instruction entirely in numeric form. To this end, numeric values may be in the range 0 to 31 to permit the direct setting of the 5th bit in a tape element. In practice, only values in the range 0 to 15 are typically used, with the 5th bit being handled by other specifications in the assembly instruction.
Specifying "IR" for register is equivalent to specifying "IR1", and is provided simply for clarity when performing a 4-bit transfer to CR4. Symbolic values for the ALU function codes may be used for clarity.
Specifying a third argument results in c=1 on the tape, to clear IR in preparation for receipt of the new value, unless "^" is present, which forces c=0.
Specifying "^" is typically done to get the second set of 2 bits from a previously loaded value.
Specifying "*" introduces a programmed halt (h=1).
The nice syntax eliminates the need for repeated specification of inherent aspects of instructions. While for the most part a program can be written entirely using this syntax, there are some limitations as to what can be expressed with it. Particularly, note that the nice syntax for data input implies the use of specific halves of the IR register.
HLT can be used to indicate a pause in a program when there is no interest in the data from the front panel, but note IR may be affected if the front panel switches are not all 0.
Figure 4 presents some examples of assembly instructions, showing the tape codes they produce and the equivalency between the different assembly syntaxes.
Following are several programs which exemplify some programming techniques for Simon.
By example, lines 0 and 1 of Program 1 load the value 13 (binary 1101) from tape into registers OR1 and OR2. The first instruction (line 0) specifies IR to be cleared, loads IR with the 4 bits from the tape and transfers two bits to OR1. The second instruction (line 1) refrains from clearing the previous data from IR and transfers the other 2 bits to OR2. OR1 will receive binary 01, OR2 will receive binary 11.
The same procedure applies for loading data from the front panel during a programmed halt as shown in lines 2 and 3.
The instructions are expressed in nice syntax this time, with IR1 versus IR2 implied by the use of "=*" versus "=^".
The order in which the loads occur is of consequence. CR5 and CRY will receive the result of the function but do not do so until CR4 is loaded. This means CR4 must be loaded for every function operation - even if CR4 already contains the desired function code - and the load performed after loading the desired operands into CR1, CR2 and/or CR3.
As an example, Program 2 adds two 4-bit values (13 and 5) and displays the 5-bit result in the output lamps.
Program 3 directs Simon to receive two manually-input 4-bit values and select the greater of the two for display.
During execution one value is subtracted from the other.
The difference result is ignored, but the carry register holds the borrow result of the subtraction.
The value in the carry register is moved to CR3 where it is used twice by SEL instructions to choose the value for display.
As instructions occupy 3 elements on the tape, when loading a tape onto Simon one must be careful to position the tape precisely at the first element of the program, to ensure that execution does not begin in the middle of an instruction. Starting execution at an arbitrary point in a blank leader is not acceptable. A suggested policy is to begin a tape with several instructions of the form "IR2 IR1 0" which results in a tape pattern of "10001 00000 00000". These are effectively NOPs, while the 'holes - no holes - no holes' pattern provides easy visual indication for positioning the tape correctly.
Blank portions of tape are effectively NOPs, so blank trailers are acceptable. The absence of tape presents an instruction with a programmed halt to the machine, so the end of tape will result in the machine halting.
| Relay Implementation