SUBLEQ (SUbtract and Branch if Less than or EQual to zero) is a type of OISC (One Instruction Set Computer) / URISC (Ultimate Reduced Instruction Set Computer) architecture. It has only one instruction of the form:
A B C
This is equivalent to the following pseudocode:
Compound instructions, such as addition, can be formed from sequences of these
simple SUBLEQ instructions. For examples of these, see the source
files - most compound instructions include a comment about their function.
Indirect addressing (pointers) can be emulated through self-modifying code,
where operations are performed on the instructions themselves.
See ,,,, for further information.
This project (download) consists of four main parts:
A recent version of Logisim is required to simulate the CPU. Simulation
instructions are provided below.
There are three main buses in the CPU:
A bus: contains the address of the current memory location
B bus: contains the output of the ALU
D bus: contains the data read from memory
The CPU has six control signals:
MAR: the Memory Address Register should be updated with the value of the D bus at the end of this cycle
PC: the Program Counter should be updated at the end of this cycle
JMP: the PC should be loaded with the value of the D bus at the end of this cycle if the LEQ flag has been set by the ALU, otherwise PC is just incremented if either JMP or LEQ are false
RD: the value of MAR should be loaded onto the A bus, otherwise it is loaded with the value of PC if RD is false
WR: the value of the B bus should be stored to memory at the end of this cycle, and the value of the LEQ flag should be updated
A: signals that the "A" operand is currently on the D bus, so the A register should be updated at the end of this cycle
These signals are controlled by a 5-microinstruction microprogram which runs in
a continous loop. The signals enabled by each of these microinstructions are:
MAR, PC: load mem[PC] (address of A operand) into MAR, increment PC
RD, A: load mem[MAR] into the A register
MAR, PC: load mem[PC] (address of B operand) into MAR, increment PC
RD, WR: load mem[MAR] onto the D bus, then write the value of the B bus (equal to the value of the D bus minus the value of the A register) into mem[MAR]
PC, JMP: if the LEQ flag is set (the result of B-A was less than or equal to zero) then set PC to mem[PC] (the C operand) i.e. jump to C, otherwise increment PC
Input/output is performed through memory-mapped I/O, with the I/O driver mapped
to address 0xffffffff (-1). If the A signal is enabled, then reading from this
address returns the negation of the next input character. If the A signal is
not enabled, then the value 0xffffffff is returned. Writing to this address
prints the character obtained by performing a bitwise NOT on the value of the B
bus. This behaviour allows the following I/O instructions to be performed:
(-1) X: add the input character to X (X -= -input)
X (-1): output the character in X (subtracting X from 0xffffffff gives NOT X, then performing a NOT on this yields the original X)
Jumping to address 0xffffffff (-1) disables the clock signal, effectively
halting the CPU.