Programmierung des Relaiscomputers
Du kannst den Relaiscomputer auf verschiedene Art und Weise in Maschinensprache programmieren. Das geschieht ganz einfach über das Tastenbedienfeld oder über Jumper auf dem ROM Modul.

Einzige Bedingung ist, dass Dein Programm mit den 16 verfügbaren Maschinenbefehlen und den 16 verfügbaren Speicheradressen auskommen muss. Hier findest Du einige Beispiele für Maschinenprogramme.
Neben der Programmierung in Maschinensprache kannst Du sogar einige Maschinenbefehle durch umstecken von Drahtbrücken "erfinden" oder vorhandene Befehle ändern.
Inhalt
Aufbau der Maschinenbefehle im Relaiscomputer
Der Relaiscomputer unterstützt einen 4bit breiten Op-Code. Damit lassen sich insgesamt 16 Maschinenbefehle umsetzen. Jeder einzelne Maschinenbefehl ist durch eine eigene Baugruppe (Modul) im Rechner vertreten.
Auf dieser Baugruppe werden die bis zu 32 Steuerleitungen mit den maximal 8 Schritten zu Mikrobefehlen 1 im Befehlszyklus 2 verschaltet und repräsentieren damit den sogenannten Microcode 3.
Theoretisch hat so ein Modul bis zu 8 x 32 also 256 Speicherplätze, von denen aber je Maschinenbefehl nur ein Bruchteil benötigt wird, so dass die Verdrahtung und Anzahl der Bauteile im Gerät entsprechend sparsam ausgeführt werden konnte.
Der 32bit Steuerbus
Nachfolgende Tabelle listet alle 32 Steuerleitungen im Rechner auf, aus denen der Microcode der Maschinenbefehle zusammengebaut wird.
Nr | Name | Beschreibung |
---|---|---|
01 | RS | Schrittzähler zurücksetzen |
02 | MA | Adressregister MA laden |
03 | MR | Speicher M lesen |
04 | IL | Befehlsregister I laden |
05 | IR | Befehlsregister I lesen |
06 | PL | Programmzähler laden |
07 | AL | Register A laden |
08 | AR | Register A lesen |
09 | ML | Speicher M laden |
10 | DL | Register D laden |
11 | DR | Register D lesen |
12 | BL | Register B laden |
13 | BR | Register B lesen |
14 | AD | ALU Addition Register A + B |
15 | CY | ALU Addierwerk Carry In (Sum += 1) |
16 | NB | ALU Register B komplementieren (NOT B) |
17 | PR | Befehlszähler PC lesen |
18 | PI | Befehlszähler PC weiter zählen (+1) |
19 | HL | Zeitgeber / Takt anhalten |
20 | OL | Ausgaberegister O laden |
21 | CR | Indexregister C lesen |
22 | CL | Indexregister C laden |
23 | LC | ALU Konstante in Register B laden |
24 | SL | ALU Register A nach links schieben |
25 | SR | ALU Register A nach rechts schieben |
26 | SB | ALU Register B nach links schieben |
27 | AN | ALU Register A und B |
28 | OR | ALU Register A oder B |
29 | ER | Dezimaleingabe Register E zurücksetzen |
30 | EU | Dezimaleingabe Register E Einer lesen |
31 | ET | Dezimaleingabe Register E Zehner lesen |
32 | EH | Dezimaleingabe Register E Hunderter lesen |
Der Befehlszyklus
Der Befehlszyklus, auch Maschinenzyklus genannt, entsteht im Relaiscomputer durch das Versorgen des Schrittzählers mit dem Systemtakt. Dabei zählt der Schrittzähler bei jedem neuen Taktimpuls um eins weiter. Es sind maximal 11 Einzelschritte innerhalb eines Befehlszyklus möglich. Danach beginnt der Zähler erneut von Vorne.
Jedem einzelnen Schritt wird im System eine Maschinenoperation (Verschaltung über den Steuerbus) wie folgt zugeordnet:
- Schritt 1 bis 3 ist der sogenannte "fetch cycle", welcher den nächsten Maschinenbefehl holt und den Programmzähler weiterzählt. Dieser Teil ist für alle 16 Maschinenbefehle gleich und daher auf einem eigenen Modul gemeinsam mit dem Op-Code 0000 (NOP) untergebracht.
- Schritt 4 bis 11 ist der sogenannte "execute cycle" zum Ausführen des eigentlichen Befehls mit maximal 8 Einzelschritten.
- Schrittzähler auf Null (0) setzen, wenn keine weitere Maschinenoperation folgt.
Eine Besonderheit im Relaiscomputer ist die variable Länge des Maschinenzyklus, die es erlaubt den Schrittzähler mittels Steuerleitung RS während des "execute cycle" zurückzusetzen um Ausführungszeit zu sparen. Der kürzeste Maschinenbefehl ist NOP mit insgesamt 4 Schritten und der Längste ist INP mit insgesamt 11 Schritten.
kompletter Maschinenzyklus
Ein Beispiel für den Maschinenzyklus ist der Befehl INP zum Auslesen der Dezimaleingabe (Op-Code 1101).
Die folgende Tabelle zeigt den vollständigen Microcode für den Maschinenbefehl INP inklusive "fetch cycle" Schritte 1-3 und "execution cycle" Schritte 4-11.
S | 1 | 2 | 3 | 4 | 7 | 10 | 11 | 12 | 14 | 17 | 18 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
RS | MA | MR | IL | AL | DL | DR | BL | AD | PR | PI | ER | EU | ET | EH | |
1 | x | x | |||||||||||||
2 | x | x | |||||||||||||
3 | x | ||||||||||||||
4 | x | x | |||||||||||||
5 | x | x | |||||||||||||
6 | x | x | |||||||||||||
7 | x | x | |||||||||||||
8 | x | x | |||||||||||||
9 | x | x | |||||||||||||
10 | x | x | x | ||||||||||||
11 | x |
S | Beschreibung Microcode |
---|---|
1 | lese Programmzähler (PR) und lade mit diesem Wert Adressregister (MA) |
2 | lese von Speicheradresse (MR) und lade mit diesem Wert Befehlsregister (IL) |
3 | Erhöhe Programmzähler um Eins (1) (PI) |
4 | lade Register A (AL) mit Wert von Register E Hunderter (EH) |
5 | lade Register B (BL) mit Wert von Register E Zehner (ET) |
6 | addiere (AD) Register A und B und lade mit diesem Wert Register D (DL) |
7 | lese Register D (DR) und lade mit diesem Wert Register A (AL) |
8 | lade Register B (BL) mit Wert von Register E Einer (EU) |
9 | addiere (AD) Register A und B und lade mit diesem Wert Register D (DL) |
10 | lese Register D (DR) und lade mit diesem Wert Register A (AL) und lösche Register E (ER) |
11 | setze Schrittzähler auf Null (0) |
Und so sieht der verdrahtete INP Befehl ohne "fetch cycle" aus. Steuerleitungen, die gar nicht benötigt werden, wurden auch nicht verdrahtet.

Abb: Modul für Op-Code 1101 INP ohne "fetch cycle"
Der variable Maschinenbefehl
Bei einigen Op-Codes wie 0110 (6), 1001 (9) und 1010 (10) kann durch umstecken von Drahtbrücken und Jumpern der Befehl und die Anzeige geändert werden.
Bspw. kann der SRA Befehl in einen SLA Befehl und der AND Befehl in einen OR Befehl umkodiert werden.
Der Op-Code 1010 (10) verfügt zudem über 8 mögliche Mikroschritte und eröffnet weitere Möglichkeiten neue Befehle mit dem Steuerbus zu verdrahten.

Abb: Modul für Op-Code 1010 im Relaiscomputer, frei definierbar, ohne Verdrahtung
Op-Codes aller Maschinenbefehle
Übersicht aller OP-Codes der möglichen Maschinenbefehle und deren Varianten:
- Sym: symbolischer Name des Befehls
- Code: 4 bit Maschinencode bit4 - bit7
- Param: Adressparameter bit0 - bit3
- Anz: Leuchtanzeige auf dem Computer
- S1 .. S3: Schritt 1 bis 3 im Maschinenzyklus - "fetch cycle"
- S4 .. S11: Schritt 4 bis 11 im Maschinenzyklus - "execute cycle"
Sym | Code | Param | Anz | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
--- | --- | --- | FI | PR MA | MR IL | PI | --- | --- | --- | --- | --- | --- | --- | --- |
Sym | Code | Param | Anz | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 |
---|---|---|---|---|---|---|---|---|---|---|---|
NOP | 0000 | ohne | FI | RS | |||||||
LDA | 0001 | aaaa | LA | IR MA | MR AL | RS | |||||
ADD | 0010 | aaaa | AD | MR BL | AD DL | DR AL | RS | ||||
SUB | 0011 | aaaa | SU | MR BL | NB AD CY DL | DR AL | RS | ||||
JMP | 0100 | aaaa | JP | IR PL | RS | ||||||
JPX | 0101 | aaaa | JX | IR PL | RS | ||||||
JPC | 0110 | aaaa | JC | IR PL | RS | ||||||
JPN | 0110 | aaaa | JN | IR PL | RS | ||||||
JPZ | 0111 | aaaa | JZ | IR PL | RS | ||||||
STA | 1000 | aaaa | ST | IR ML | AR ML | RS | |||||
SLA | 1001 | ohne | SL | SL DL | DR AL | RS | |||||
SRA | 1001 | ohne | SR | SR DL | DR AL | RS | |||||
SLA | 1001 | ohne | SL | SB DL | DR AL | RS | |||||
AND | 1010 | aaaa | AN | AN DL | DR AL | RS | |||||
OR | 1010 | aaaa | OR | OR DL | DR AL | RS | |||||
LDX | 1011 | aaaa | LX | IR ML | MR CL | RS | |||||
DCX | 1100 | ohne | DX | AR BL | AL CR | AD LC CL | AL BR | RS | |||
INP | 1101 | ohne | IN | EH AL | ET BL | AD DL | DR AL | EU BL | AD DL | DR AL ER | RS |
OUT | 1110 | ohne | OU | AR OL | RS | ||||||
HLT | 1111 | ohne | HL | HL | RS |
NOP 0000 - No Operation
Keine Operation
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | NOP | 0000 | keine Operation |
01 | HLT | 1111 | halte Programm an |
LDA 0001 - laden Register A
Lade Register A (akku) mit Wert aus Adresse aaaa
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
01 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0001 1111 | Zahl (31) |
STA 1000 - Store Register A
Speichere den Inhalt von Register A (akku) in den RAM auf Adresse aaaa.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
00 | STA 14 | 1000 1110 | speichere Register A auf Adresse 14 |
01 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0000 0000 | initial (0) |
15 | var | 0000 0010 | Zahl (2) |
ADD 0010 - Add Register B
Addiere Register B mit Wert aus Adresse aaaa. Das Ergebnis steht in Register A.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | ADD 15 | 0010 1111 | addiere Wert von Adresse 15 zu Register A |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0000 0100 | 1. Summand (4) |
15 | var | 0000 1110 | 2. Summand (14) |
SUB 0011 - Subtract Register B
Subtrahiere Register B mit Wert aus Adresse aaaa. Das Ergebnis steht in Register A.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | SUB 15 | 0011 1111 | subtrahiere von Register A den Wert von Adresse 15 |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 1100 1000 | Minuend (200) |
15 | var | 0001 0100 | Subtrahend (20) |
JMP 0100 - Jump
Sprung, setze den Programm Counter auf Adresse aaaa.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | ADD 15 | 0010 1111 | addiere Wert von Adresse 15 zu Register A |
01 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
02 | JMP 00 | 0100 0000 | springe auf Adresse 0 |
.. | |||
15 | var | 0000 0001 | Zahl (1) |
JPX 0101 - Jump while Register C not null
Sprung solange Register nicht ZERO (0) ist. Setze dann den Programm Counter auf Adresse aaaa.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDX 14 | 1011 1110 | lade Register C mit Inhalt von Adresse 14 |
01 | ADD 15 | 0010 1111 | addiere Wert von Adresse 15 zu Register A |
02 | DCX | 1100 | dekrementiere Inhalt von Register C (-1) |
03 | JPX 01 | 0101 0001 | springe auf Adresse 01 wenn Register C nicht Null (0) ist |
04 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
05 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0000 0011 | 1. Faktor (3) |
15 | var | 0010 0101 | 2. Faktor (37) |
JPC 0110 - Jump if Carry
Sprung wenn CARRY Flag gesetzt ist. Setze dann den Programm Counter auf Adresse aaaa (opt. NEG Flag)
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
01 | ADD 15 | 0010 1111 | addiere Wert von Adresse 15 zu Register A |
02 | JPC 06 | 0110 0110 | springe wenn Carry Flag auf Adresse 6 |
03 | STA 15 | 1000 1111 | speichere Register A auf Adresse 14 |
04 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
05 | JMP 00 | 0100 0000 | springe auf Adresse 0 |
06 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0001 0000 | initial (16) |
JPN 0110 - Jump if Negative
Sprung wenn NEG Flag, setze Programm Counter auf Adresse aaaa (opt. CARRY Flag)
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | SUB 15 | 0011 1111 | subtrahiere Wert von Adresse 15 von Register A |
02 | JPN 04 | 0110 0100 | springe wenn Negativ Flag auf Adresse 4 |
03 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
04 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0001 0000 | Minuend (16) |
15 | var | 0001 0010 | Subtrahend (18) |
JPZ 0111 - Jump if Zero
Sprung wenn ZERO Flag gesetzt ist. Setze dann den Programm Counter auf Adresse aaaa (opt. NEG Flag).
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | SUB 15 | 0011 1111 | subtrahiere Wert von Adresse 15 von Register A |
02 | JPZ 04 | 0111 0100 | springe wenn Zero Flag auf Adresse 4 |
03 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
04 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0001 0000 | Minuend (16) |
15 | var | 0001 0000 | Subtrahend (16) |
SRA 1001 - shift right Register A
Schiebe den Inhalt von Register A (akku) um ein bit nach rechts
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
01 | SRA | 1001 | schiebe Inhalt von Register A ein bit nach rechts |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0100 0000 | Zahl (64) |
SLA 1001 - shift left Register A
Schiebe den Inhalt von Register A (akku) um ein bit nach links
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
01 | SLA | 1001 | schiebe Inhalt von Register A ein bit nach links |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0010 0000 | Zahl (32) |
AND 1010 - AND Register A
logische UND Verknüpfung von Register A (akku) mit Wert aus Adresse aaaa. Das Ergebnis steht in Register A.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | AND 15 | 1010 1111 | verknüpfe UND mit Wert von Adresse 15 und Register A |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0000 0100 | Zahl (4) |
15 | var | 0000 0110 | Maske (6) |
OR 1010 - OR Register A
logische ODER Verknüpfung von Register A (akku) mit Wert aus Adresse aaaa. Das Ergebnis steht in Register A.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 14 | 0001 1110 | lade Register A mit Inhalt von Adresse 14 |
01 | OR 15 | 1010 1111 | verknüpfe ODER mit Wert von Adresse 15 und Register A |
02 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
03 | HLT | 1111 | halte Programm an |
.. | |||
14 | var | 0101 0101 | Zahl (85) |
15 | var | 1010 1010 | Maske (170) |
LDX 1011 - laden Register C
Lade Register C (counter) mit Wert auf Adresse aaaa.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDX 15 | 1011 1111 | lade Register C mit Inhalt von Adresse 15 |
01 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0001 1111 | Zahl (31) |
DCX 1100 - Decrement Register C
Decrement Register C (counter), Schützt Inhalt von Akku Register A in Register B.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDX 15 | 1011 1111 | lade Register C mit Inhalt von Adresse 15 |
01 | DCX | 1100 | dekrementiere Inhalt von Register C (-1) |
02 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0000 0011 | Zahl (3) |
INP 1101 - laden decimal Input
Einlesen einer Dezimalzahl aus den Dezimal Hilfsregistern für Einer (U), Zehner (T) und Hunderter (H). Ergebnis in Register A.
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | INP | 1101 | lade Dezimaleingabe von Tastatur in Register A |
01 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
02 | HLT | 1111 | halte Programm an, weiter mit run |
03 | JMP 00 | 0100 0000 | springe auf Adresse 0 |
OUT 1110 - Output
Ausgabe von Inhalt Register A nach Register O(ut)
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | LDA 15 | 0001 1111 | lade Register A mit Inhalt von Adresse 15 |
01 | OUT | 1110 | lade Register O mit dem Inhalt von Register A |
02 | HLT | 1111 | halte Programm an |
.. | |||
15 | var | 0000 1100 | Zahl (12) |
HLT 1111 - Halt Program
Stoppt bzw. unterbricht die Programmausführung durch Anhalten des Zeitgebers
Adr | Befehl | Code | Beschreibung |
---|---|---|---|
00 | HLT | 1111 | halte Programm an, weiter mit run |
01 | JMP 00 | 0100 0000 | springe auf Adresse 0 |
Der Programmspeicher
Du kannst im Relaiscomputer ein Maschinenprogramm sowohl im ROM durch Stecken von Jumpern programmieren als auch ein Programm über das Bedienfeld eingeben und im RAM abspeichern.
Beide Speicher sind unabhängig, können jedoch nicht gemeinsam genutzt werden. Vor dem Start des Programms muss der Speicher über eine Taste im Bedienfeld ausgewählt werden. Das Programm wird also entweder aus dem ROM oder aus dem RAM ausgeführt.
ROM

Abb: 16 Byte ROM Modul in Relaiscomputer
RAM
Der Rechner benötigt 16 Stück folgender RAM Module. Ein solches Modul speichert genau ein Datenwort von 8bit Breite.

Abb: 1 Byte RAM Modul in Relaiscomputer