WARP-1

Documentation

Wilhelms Anachronistic Relay Processor 1

Copyright © 2010 Paul Wilhelm <paul at mosfetkiller dot de>

Main website:https://mosfetkiller.de/?s=warp-1
Documentation: https://mosfetkiller.de/warp-1/doc

Table of contents

1 Introduction

WARP-1 (Wilhelms Anachronistic Relay Processor 1) is a custom built and fully functional computer, constructed using only relays, diodes and a hell of a lot of wire. :-) It consists of a CPU and an external I/O/Stack Unit.

See the following sections for more specs.

Please contact me if you spot major (spelling/grammar) mistakes in this document. ;-) The same applies to feedback and critics of any kind.

All information presented here is preliminary; WARP-1 is still in construction phase.

1.1 Architectural overview

NamePropertiesDescription
Data bus6 bitsNumbers from 0 to +63 (unsigned) or -32 to +31 (signed)
Address bus12 bitsUp to 4096 words of program memory addressable
Internal memory7x 6 bitsAccumulator, flags register and 5 general purpose registers A..E
FlagsC,O,N,Z,S,HCarry, Overflow, Negative, Zero (ALU), Stack (switches port mode from I/O to stack), Halt (halts CPU)
Program memoryEEPROMShould really be replaced by a punch card reader
Stack memory24x 6 bits24 words of LIFO memory in external I/O/Stack Unit
Ports1x 6 bits I/OUsed to communicate with I/O/Stack Unit
User interface1x 6 bits I/OData written to the port in I/O mode is currently being output on LEDs, data read from the port is currently read from a set of switches accessible to the user on the I/O/Stack Unit
Clock speedmax. ??? HzTwo-phased clock, thus half an instruction per cycle

1.2 Electrical specs

Electrical specifications of WARP-1 are to be found below.

1.2.1 Power supply

The entire system runs on 24VDC. WARP-1's power supply can source about 8 amps. Current draw, of course, depends on the types of relais used.

1.2.2 Diodes

Wherever diodes without any further information on their type and maximum ratings are drawn, universal diodes like 1N4148 or 1N400x can be used. WARP-1 uses 1N4007.

1.3 Schematic conventions

In order to guard against confusion, some notes regarding the layout of schematics are to be found below.

1.3.1 Sections, notes

The CPU's schematic is divided into different sections, delimited by slight dotted lines. Some sections may contain additional information on their specific structure or task. This only serves the purpose of clarity and better understanding of the basic circuit. This entire document should be read for an in-depth explanation on how WARP-1 works internally.

1.3.2 Buses

Buses of different widths are used througout the design. Even though in circuit diagrams all of them are drawn as single lines, the colors they are drawn in indicate their width.

— (blue) 6 bit parallel data bus
— (orange) 4 bit parallel data bus
— (green) 3 bit parallel data bus
— (black) 1 bit data line

(A legend is also containted in the CPU schematic.)

Also, there is an eight bit data bus used in the ALU's internal circuit diagrams. (See 2.2.7 Arithmetic Logic Unit (ALU).)

— (purple) 8 bit parallel data bus

Buses may be split up into single lines they contain.

Example:  Extracting four flags C,O,N,Z from the 6 bits wide
flags bus and joining them into a new 4 bits wide bus.

Wherever a bus is being split up and no signal names but numbers are used, these indicate the bit significance of each individual line.

1.3.3 Connections, nodes

Wherever two or more buses are being connected to each other and thus creating a node, only their single lines with same bit significance must be interconnected inside the node.

Bit significances are specified in the internal circuit diagrams of the individual modules connected to that bus.

2 CPU

The CPU (Central Processing Unit) is WARP-1's main component where all the magic happens. The CPU consists of several modules connected to each other. Combined with the I/O/Stack-Unit it is a fully functional computer system.


2.1 Architecture

Information on WARP-1's architecture is to be found below. It consists of a very simple and straight-forward instruction set.

2.1.1 Registers

All registers are 6 bits wide and store numbers from 0 to +63 (unsigned) or -32 to +31 (signed). For the actual construction of register modules, see 2.2.3 Registers.

2.1.1a General purpose registers

One accumulator ACCU and 5 general purpose registers A, B, C, D, E are freely available to the programmer to store any 6-bit value.

The accumulator ACCU is always the first operand of any ALU operation. The E register is always the HIGH address for (conditional) far jumps.

In the following instruction set description, the registers mentioned above are being referred to by individual 3-bit numbers:

r2 r1 r0Register
0  0  1ACCU
0  1  1A
0  1  0B
1  1  1C
1  1  0D
1  0  0E

2.1.1b Flag register

In WARP-1, 6 flags are present in the FLAGS register, which is freely accessible to the programmer. The flags register is being updated after every ALU operation, except for when the flags register is selected as destination register. In that case, the flags coming straight out of the ALU are being discarded.

Note: Each individual ALU operation may only affect some flags or even none of them. Please see 2.1.2b ALU operation on Accu w/ Register for a list of ALU operations and their flags affected.

The flags to be found in this register are listed below:

FlagBit in registerDescription
C0Carry flag. The carry flag is being set, if an addition produces a result too large to be stored in a 6 bits wide register. It is also a low active borrow in "subtract with carry" operations.
O1Overflow flag. (Useful in signed operation mode only.) Compares both input and output Zero flags (ALU). If they differ, an overflow (change in sign) occured and this flag is being set.
N2Negative flag. (Useful in signed operation mode only.) If the result of an ALU operation is positive, this flag is being set. (Bit 5 of result is just being copied into this flag.)
Z3Zero flag. This flag is being set if the result of an ALU operation equals zero or if two operands being compared are exactly equal.
S4Stack flag. (Only useful in combination with the optional, external I/O/Stack unit.) If cleared, the port is in I/O mode. If set, the port is in Stack mode.
H5Halt flag. If set, the CPU clock halts immediately until the user resets the machine.

In the following instruction set description, the FLAGS register is being referred to by an individual 3-bit number:

r2 r1 r0Register
1  0  1FLAGS

2.1.1c Port

One port PORT is accessible to the programmer. It behaves like a regular register; data can be written to and read from it. The port's main use is to connect it to an external I/O/Stack unit. In combination with this module, the port works in two different modes, determined by the status of the Stack flag.

Important note: The port may be accessed only once per instruction cycle if the external I/O/Stack module is being connected to it. (This is due to a design restriction of the I/O/Stack module.) That is, the port must not be source AND destination of any operation. See 2.3 Timing for more information on clock cycles.

In the following instruction set description, the PORT is being referred to by an individual 3-bit number:

r2 r1 r0Register
0  0  0PORT

2.1.1d Program counter

The program counter (in short: PC) holds the address of the instruction to decode next. The PC is 12 bits wide, thus consists of two 6 bits wide registers PCH (upper 6 bits) and PCL (lower 6 bits). These registers are not accessible to the programmer in ALU and "Copy Immediate to Register" operations, but they can be modified by performing jump operations. See 2.1.2d (Conditional) Short jump and 2.1.2e (Conditional) Far jump for more information.

2.1.2 Instruction Set

WARP-1 supports the following 5 basic instructions which can be customized by choosing the desired operation mode (ALU operations) or condition to check for (jump operations) and choosing the desired source and/or destination registers.

Every instruction is 12 bits wide and takes two clock cycles to complete (two clock cycles = one instruction cycle). See 2.3 Timing for more information.

2.1.2a Copy Immediate to Register

Copies the 6-bit word i to destination register d (see 2.1.1 Registers for register codes).

 Bit 11 10  9  8  7  6  5  4  3  2  1  0
 1  1  0 d2 d1 d0 i5 i4 i3 i2 i1 i0

2.1.2b ALU operation on Accu w/ Register

Performs ALU operation o on Accumulator as first operand and source register s as second operand. The result is being stored in destination register d (see 2.1.1 Registers for register codes).

Note: Not every operation uses both operands. Operations with only one operand always use operand B.

 Bit 11 10  9  8  7  6  5  4  3  2  1  0
 0  0 o3 o2 o1 o0 d2 d1 d0 s2 s1 s0

Following ALU operations are available:

o3 o2 o1 o0 Operation Flags affected
0  0  0  0 Q = A + B Add without carry C O N Z
0  0  0  1 Q = A + B + C Add with carry C O N Z
0  0  1  0 Q = A - B     = A + /B + 1 Subtract without carry C O N Z
0  0  1  1 Q = A - B + C = A + /B + C Subtract with carry C O N Z
0  1  0  0 Q = A & B Logic AND - - - Z
0  1  0  1 Q = A | B Logic OR - - - Z
0  1  1  0 CMP A, B        (A - B) Compare (subtract w/o saving result) C O N Z
0  1  1  1 TEST A, B       (A & B) Test (logic AND w/o saving result) - - - Z
1  0  0  0 Q = B No operation - - - -
1  0  0  1 Q = /B One's complement - - - -
1  0  1  0 Q = B - A     = B + /A + 1 Subtract without carry C O N Z
1  0  1  1 Q = B - A + C = B + /A + C Subtract with carry C O N Z
1  1  0  0 Q = B >> 1 Shift right C - - -
1  1  0  1 Q = B << 1 Shift left C - - -
1  1  1  0 Q = A ^ B Logic XOR - - - Z
1  1  1  1 Q = A & /B Logic AND, one operand inverted - - - Z

2.1.2c ALU operation on Accu w/ Immediate

Performs ALU operation o on Accumulator as first operand and immediate value i as second operand. The result is being stored in the Accumulator.

Note: Not every operation uses both operands. Operations with only one operand always use operand B.

 Bit 11 10  9  8  7  6  5  4  3  2  1  0
 1  1  1 o2 o1 o0 i5 i4 i3 i2 i1 i0

Following ALU operations are available:

o3 o2 o1 o0 Operation Flags affected
0  0  0  0 Q = A + B Add without carry C O N Z
0  0  0  1 Q = A + B + C Add with carry C O N Z
0  0  1  0 Q = A - B     = A + /B + 1 Subtract without carry C O N Z
0  0  1  1 Q = A - B + C = A + /B + C Subtract with carry C O N Z
0  1  0  0 Q = A & B Logic AND - - - Z
0  1  0  1 Q = A | B Logic OR - - - Z
0  1  1  0 CMP A, B        (A - B) Compare (subtract w/o saving result) C O N Z
0  1  1  1 TEST A, B       (A & B) Test (logic AND w/o saving result) - - - Z

2.1.2d (Conditional) Short jump

Reads the flags register and checks for condition c. If the condition check is TRUE, PCL (see 2.1.1d Program counter for more information) is being loaded with immediate value i. If the condition check is FALSE, normal program execution continues.

Note: Please note that WARP-1 can only perform absolute jumps. Relative jumps are not implemented.

 Bit 11 10  9  8  7  6  5  4  3  2  1  0
 0  1 c3 c2 c1 c0 i5 i4 i3 i2 i1 i0

Following jump conditions are available:

c3 c2 c1 c0FlagsMnemonicArithmetic comparison/testLogical test
0  0  0  0don't careJMP---
0  0  0  1ZJE,JZA == BA equals BResult == 0 Result equals zero
0  0  1  0!ZJNE,JNZA !== BA unequals BResult !== 0 Result unequals zero
0  0  1  1O & !ZJLA < BA is less than B-
0  1  0  0O | ZJLEA <= BA equals or is less than B-
0  1  0  1!O & !ZJGA > BA is greater than B-
0  1  1  0!O | ZJGEA >= BA equals or is greater than B-
0  1  1  1CJC-CCarry flag is set
1  0  0  0!CJNC-!CCarry flag is not set
1  0  0  1!N & !ZJPResult > 0Result is positive-
1  0  1  0!N | ZJZPResult >= 0Result equals or is greater than zero-
1  0  1  1N & !ZJNResult < 0Result is negative-
1  1  0  0N | ZJZNResult <= 0Result equals or is less than zero-
1  1  0  1-----
1  1  1  0-----
1  1  1  1-----

The last three conditions are always FALSE if selected; a jump never occurs.

2.1.2e (Conditional) Far jump

Reads the flags register and checks for condition c. If the condition check is TRUE, PCL is being loaded with immediate value i and the value of register E is being copied to PCH (see 2.1.1d Program counter for more information). If the condition check is FALSE, normal program execution continues.

Note: Please note that WARP-1 can only perform absolute jumps. Relative jumps are not implemented.

 Bit 11 10  9  8  7  6  5  4  3  2  1  0
 1  0 c3 c2 c1 c0 i5 i4 i3 i2 i1 i0

See 2.1.2d (Conditional) Short jump for a list of available conditions to check for.

2.2 Modules

General note: When connecting a bus to a module, special care must be taken in terms of the order each individual bus line is connected to the module's terminals. See 1.3.3 Connections, nodes for additional information on connecting buses.

2.2.1 Logic gates

The basic logic gates NOT, XOR, OR and AND are used to generate control signals throughout the CPU and I/O/Stack Unit.

Note: Different kinds of logic gates are used throughout the design. Single inputs and/or outputs may be inverted and the number of input lines may vary. Not all actually used logic gates are to be found below.

NOTORXORAND
(Inverter) (two inputs) (three inputs) (two inputs,
output inverted)
(two inputs) (two inputs,
output non-buffered)
(two inputs) (three inputs) (two inputs,
one inverted)

2.2.2 Bus switches

Bus switches are used for selective interconnection of buses. Since these modules only consist consist of relays (analog components) they are bidirectional. Each bus switch has three sets of data lines (A,B,C) and one select input, which when LOW connects A to B and when HIGH connects A to C. Either of data line sets A or B may be left unconnected.

Note: Different kinds of bus switches are used throughout the design. Number of bus lines may vary. The basic structure of a bus switch remains the same, though.

The schematic of a three bits wide bus switch is shown below.


2.2.3 Registers

Registers are used for storing and reading 6 bits of data simultaneously. The bits in one register can be interpreted as a number between 0 and +63 (unsigned) or -32 and +31 (signed). These modules are actually transparent latches, but in the context of this project we refer to them as registers. The logical levels of data lines 0..5 are latched on the rising edge of LOAD and can then be read back during LOAD low state.


2.2.4 Adders

Two half-adders are used for incrementing the program counter (PCL and PCH). These modules each have one input bus IN and one output bus OUT, each 6 bits wide. Since there is only a carry input CIN used as second addend, only 0 or 1 can be added to the input. Several of these modules can be cascaded using the carry output COUT.

The schematic of one one-bit half-adder is shown below.



One complete half-adder module consists of six of these, cascaded through CIN input and COUT output lines. The entirety of A and B lines is the input bus IN and OUT respectively.


2.2.5 (De)Multiplexers

Multiplexers (mux) have a set of data inputs, one data output and a select input bus. The selected input signal is being forwarded to the data output. Since these modules are designed using only relays (analog components) every multiplexer is also a demultiplexer (demux) which forwards one data input signal to one of several data outputs. The number of possible selectable data inputs/outputs depends on the number of select input lines (2^n).

Note: Different kinds of (de)multiplexers are used throughout the design. Number of select inputs and data inputs/outputs may vary. The basic structure of a (de)multiplexer remains the same, though.

Note: Not only single data lines, but entire buses may be (de)multiplexed. See 1.3.2 Buses for additional information on buses.

The schematic of a (de)multiplexer with 3 select inputs and thus 8 data inputs/outputs is shown below.


2.2.6 Condition Check Unit (CCU)

The Condition Check Unit (CCU) is used by the Instruction Decoder (ID) in case of a conditional jump. The module has two input busses FIN and COND which take four flags (C,O,N,Z) and a condition code respectively. Result output Q goes HIGH if the condition is complied with.

The CCU consists of two (de)multiplexers and a 16x16 diode matrix consisting of 112 diodes in total.
See 1.2 Electrical specs for additional information on diodes.


2.2.7 Arithmetic Logic Unit (ALU)

The Arithmetic Logic Unit (ALU) performs simple arithmetic (ripple carry) and logic operations on one (B) or two (A and B) 6 bits wide operand values, thus generating a 6 bits wide output value Q. The desired operation mode depends on the value of the 4 bits wide OP bus. A set of 4 input flags FIN affects the operation and a set of output flags FOUT is being generated. The active low signal /RSAVE tells the CPU whether the result Q shall be saved or discarded (this will be the case whenever a CMP or TEST operation is being performed.)

2.2.7a Core

The ALU core is shown below. It is a 1 bit ALU slice capable of performing all supported operations except for shifting right. Eight control lines CTRL have to be set correctly for the individual operation to be performed. Operands are A and B, result is Q.



Six of these modules are being cascaded via CIN and COUT lines, thus creating a 6 bits wide ALU core.


2.2.7b Periphery

Since, as mentioned above, the ALU core cannot perform the shift-right operation all alone and no special flags logic is present, additional circuitry is needed in order to create a fully-featured ALU. This periphery also decodes the operation number OP into the control signals CTRL mentioned above.


2.2.8 Instruction Decoder (ID)

The instruction decoder controls all modules inside the CPU. A twelve bits wide instruction word (IH and IL) is being decoded and a set of control signals is being generated, depending on the instruction word itself, current clock cycle and the condition check result.

Bits 5..0 of the instruction word represent a 6-bits wide immediate value, which is being connected to the data bus in CK_EXECUTE cycle in all jump and ALU operations except for ALU operation on Accu w/ Register (which does not require an immediate value).

PR (Port Read) signal is HIGH during one full instruction cycle whenever any ALU operation with PORT selected as source register is selected. Otherwise, PR is LOW.

PW (Port Write) signal is HIGH during one full instruction cycle whenever any ALU operation with PORT selected as destination register is selected. Otherwise, PW is LOW.



The table below shows the statuses of the REGISTER SELECT bus and the REGISTER ENABLE line, depending on current instruction and clock phase.

InstructionClock phaseREGISTER SELECTREGISTER ENABLEDescription
Copy Immediate to RegisterCK_EXECUTEdon't care *LOW(No register selected)
Copy Immediate to RegisterCK_STOREInstruction word bits [8..6]HIGHDestination register
ALU operation on Accu w/ RegisterCK_EXECUTEInstruction word bits [2..0]HIGHSource register
ALU operation on Accu w/ RegisterCK_STOREInstruction word bits [5..3]HIGHDestination register
ALU operation on Accu w/ ImmediateCK_EXECUTEdon't care *LOW(No register selected)
ALU operation on Accu w/ ImmediateCK_STOREHardwired ACCU register: 0b001HIGHDestination is ACCU
(Conditional) Short jumpCK_EXECUTEdon't care *LOW(No register selected)
(Conditional) Short jumpCK_STOREdon't care *LOW(No register selected)
(Conditional) Far jumpCK_EXECUTEdon't care *LOW(No register selected)
(Conditional) Far jumpCK_STOREdon't care *LOW(No register selected)

* This means REGISTER SELECT value does not matter because REGISTER ENABLE is LOW. Nevertheless, using the schematic below, REGISTER SELECT does have a definite value of 0b100.



The table below shows the statuses of the ALU OPERATION and CCU CONDITION buses, depending on current instruction.

InstructionALU OPERATIONCCU CONDITIONDescription
Copy Immediate to RegisterHardwired ALU op. Q=B: 0b1000don't care *Pass unchanged immediate through ALU
ALU operation on Accu w/ RegisterInstruction word bits [9..6]don't care *One of all 16 ALU operations
ALU operation on Accu w/ ImmediateInstruction word bits [8..6]don't care *Only one of the lower 8 ALU operations
(Conditional) Short jumpdon't care **Instruction word bits [9..6]Conditional jump
(Conditional) Far jumpdon't care **Instruction word bits [9..6]Conditional jump

* This means CCU CONDITION value does not matter because the state of CONDITION CHECK RESULT signal does not influence the execution of the current instruction. Nevertheless, CCU CONDITION does have a definite value, namely the value of instruction word bits 9..6.

** This means ALU OPERATION value does not matter because during jump instructions REGISTER ENABLE is always LOW, meaning that ALU result is not being stored in any register. Nevertheless, ALU OPERATION does have a definite value of 0b1000 (ALU operation Q=B).



The table below shows the statuses of lines LOAD PCL W/ CONSTANT, LOAD PCH W/ E and LOAD PC W/ PC++, depending on the type of current jump instruction and status of CONDITION CHECK RESULT line during CK_STORE cycle. During CK_EXECUTE cycle or if the current instruction does not imply any conditional jump, all three lines are LOW.

Jump typeCONDITION CHECK RESULTLOAD PCL W/ CONSTANTLOAD PCH W/ ELOAD PC W/ PC++
SHORTFALSEFALSEFALSETRUE
SHORTTRUETRUEFALSEFALSE
FARFALSEFALSEFALSETRUE
FARTRUETRUETRUEFALSE

Note: TRUE = HIGH level; FALSE = LOW level.



2.2.9 Read Only Memory (ROM)

The ROM is a non-volatile memory unit with one data bus and one address bus, both 12 bits wide. This allows a maximum of 4096 words to be addressed. For reasons of simplicity and compactness, integrated EEPROM circuits are being used in the current version of WARP-1. Additionally, level shifters are neccessary in order to connect the EEPROMs' low-voltage inputs/outputs to the rest of the system.

2.2.9a EEPROMs

Two Atmel AT28C64B 8 kiB EEPROMs are being used. The upper 4 kiB of the address space are not being used. Only the lower 6 bits of each byte are being used.


2.2.9b Level shifters

INPUT   An input level shifter is a two-resistor voltage divider which limits a high input voltage (+24V) to a CMOS/TLL voltage level (+5V). The resistor connected to ground also pulls down the level shifter's output, thus creating a logic LOW level when no input signal is present. Because relay coils are connected directly to the input bus, free-wheeling diodes are neccessary in order to protect the ICs input circuitry.



OUTPUT   An output level shifter consists of an emitter follower (BDW93C) in combination with an additional driver transistor (BC550C) which, when turned on by a CMOS/TTL-compatible input signal, will connect the level shifter's output line to +24V, thus transforming any CMOS/TTL signal into an open-emitter (relays do not have emitters, of course) signal able to drive further relay's coils. Since the additional driver transistor inverts the input signal, the CMOS/TTL signal is first being inverted by an HC4049 inverter. Because relay coils are connected directly to the output bus, free-wheeling diodes are neccessary in order to protect the transistors.

2.2.10 Clock Generation Unit (CGU)

The CGU generates both CK_EXECUTE and CK_STORE signals. See 2.3 Timing for more information on clock timing. Four cascaded non-retriggerable monoflops trigger each other in a circular manner. A startup circuit initiates the oscillation by generating a very short pulse and feeding it to the input of the first stage when the button "GO!" is being pressed. Pressing the button again after that will have no effect. The first stage generates the CK_EXECUTE signal, the second stage generates a pause (1), the third stage generates the CK_STORE signal and the fourth stage generates another pause (2), then triggers the first stage again. The switches A and B at each stage can be used to adjust the duration time of each stage, thus optimizing the overall clock signals and pause periods for speed. When the enable input EN is low, the clock is being halted on the first stage (CK_EXECUTE) until EN goes HIGH again.


2.3 Timing

Each instruction takes two clock phases to complete: CK_EXECUTE and CK_STORE. Both signals are being generated by the Clock Generation Unit (CGU). After both signals have been emitted, one instruction cycle is complete.

2.3.1 EXECUTE cycle

Clock signal name CK_EXECUTE.

The 12 bits wide instruction word at the current programm counter address is being latched and immediately sent to the Instruction Decoder (ID) in this cycle.

Depending on the individual instruction, either a source register is being selected (= connected to the data bus) or an immediate constant value is being fed directly from the instruction word to the data bus.

If the instruction implies an ALU operation on Accu w/ Register or ALU operation on Accu w/ Immediate, the specific operation mode is being fed to the ALU. Otherwise, the operation "Q = B" is being selected, which means that the ALU's input passes right through to its output. The result and flags are being latched to temporary registers immediately in this cycle.

If the instruction implies a jump, the specific condition code is being fed to the Condition Check Unit (CCU).

Two temporary registers PCH++ and PCL++ are being loaded with the value of the program counter incremented by one.

2.3.2 STORE cycle

Clock signal name CK_STORE.

The ALU's temporary result register is being connected to the data bus in this cycle. If the instruction does not imply a comparison or bit test (ALU operations 0110 or 0111), the destination register is being selected (= connected to the data bus) and loaded with the temporary result register's value. If the the instruction does imply a comparison or bit test, there is no destination register and the temporary result register's value is being discarded (= not used).

If the destination register is not the FLAGS register, the ALU's output flags stored in another temporary register are being loaded into the FLAGS register.

If the instruction implies a jump and the condition fed to the CCU is being met (CCU result TRUE), PCL is being loaded with the immediate address value which has passed from the instruction word through the ALU into the temporary result register in CK_EXECUTE cycle and is now present on the data bus.

Additionally, if the instruction implies a far jump, the value of register E is being copied to PCH immediately if the CCU result is TRUE.

Otherwise, or if the instruction does not imply a jump at all, the program counter is being incremented by loading it with the values of registers PCH++ and PCL++ mentioned above.

3 I/O/Stack Unit

The I/O/Stack Unit is an optional module that provides It connects to the CPU's port, Instruction Decoder (ID), FLAGS register and Clock Generation Unit (CGU).

3.1 Use of the Unit

The I/O/Stack unit can operate in two different modes which are to be explained below.

3.1.1 I/O mode

The I/O mode is especially designed for user interaction. The user can read values from and write values to the I/O port. Please note that the CPU acts as master, whereas the I/O/Stack Unit acts as a slave. Values to be read from the I/O port are always being polled; there is no way for the user to asynchronously force the CPU to read any value.

I/O mode is active, when the Stack Flag is LOW.

3.1.1a Write operation

Any data written to the port by the CPU through any ALU operation - except for "ALU operation on Accu w/ Immediate" - or "Copy Immediate to Register" instruction is being displayed on six lamps/LEDs to the user.

Since this data is present only in CK_STORE cycle of the instruction cycle (which is most certainly too short for a human to accurately read the result), the data is being latched until another "write to port" operation occurs (O/LATCH register). Additionally, a "data out" clock pulse DOUTCK is being generated which can be useful when connecting a printer to the I/O port.

In order to completely halt the CPU whenever a "write to port" operation occurs, the switch DOUTHALT must be closed. This way, the user can take his time reading the data and must then press the switch DOUTRESUME in order to resume normal CPU operation.

3.1.1b Read operation

The "ALU operation on Accu w/ Register" may read data from the port during CK_EXECUTE cycle. The data to be read into the CPU (in binary format) can be set by the user using six switches.

Since the data has to be present right before the end of CK_EXECUTE cycle, the CPU can be halted automatically everytime user input is required. This way, the user can take his time to respond to the request. To do so, the switch DINHALT must be closed. In order to resume normal CPU operation, the switch DINRESUME must be pressed after setting the correct data on the input switches.

In case an automatic (= non-user operated) data source (e.g. an external analog to digital converter) is to be connected to the port, all user input switches have to be open in order to not interfere with the automatic data source's output. A clock signal DINCK is being generated everytime user input is required.

3.1.2 Stack mode

Stack mode is active, when the Stack Flag is HIGH.

3.1.2a Write operation

Any data written to the port by the CPU through any ALU operation - except for "ALU operation on Accu w/ Immediate" - or "Copy Immediate to Register" instruction causes the Stack Pointer SP to be incremented by one during CK_EXECUTE cycle, thus selecting the next stack cell. The data is being written to the currently selected stack cell during CK_STORE cycle.

If SP exceeds a value of 63 (dec), an overflow occurs and SP is set to it's minimum value, 0 (dec).

3.1.2b Read operation

The "ALU operation on Accu w/ Register" may read data from the port during CK_EXECUTE cycle. The currently selected stack cell's value is being fed to the port for the CPU to read in and process during CK_EXECUTE cycle. During CK_STORE cycle SP is being decremented by one, thus selecting the previous stack cell.

If SP is being decremented below 0 (dec), an underflow occurs and SP is set to it's maximum value, 63 (dec).

3.2 Modules

Most of the modules to be found in the I/O/Stack Unit circuit diagram are also used in the CPU. Please see 2.2 Modules for details on these modules. All other modules to be found in the I/O/Stack Unit only are to be explained below.

3.2.1 Multi-diode module

This small module consists of six diodes with their anodes connected to an anodes bus and cathodes connected to a cathods bus. This module is used to keep HIGH levels on a bus from flowing into another part of the circuit.

3.2.2 Multi-switch module

This small module consists of six switches, each connected to a SWITCH OUTPUTS bus with one end. The switches' other end is connected to a common terminal. This module can be used by the user to manually set a specific binary value and feed it to the DATA INPUT bus.

3.2.3 Multi-display module

This small module consists of six lamps (which can be replaced by LEDs and corresponding resistors), each connected to a LAMP INPUTS bus with one end. The lamps' other end is connected to a common terminal. This module can be used to display binary values on the DATA OUTPUT bus to the user.

3.2.4 Incrementer/Decrementer

This module takes any 6-bit value IN and increments it by one if the INC input is HIGH, or decrements it by one if the INC input is LOW. The output value is present at OUT output. The unit uses ripple carry, thus it takes a minimal amount of time for the unit to generate valid output.

The Incrementer/Decrementer consists of three types of smaller modules.

Module type 1 is for bit 0 of the IN value.




Module type 2 is for bits 1..4 of the IN value.




Module type 3 is for bit 5 of the IN value.




As shown below, the complete Incrementer/Decrementer consists of six of these modules being cascaded via CIN and COUT lines.