Native Adressierungsarten

Der Prozessor verfügt über 2-Adreß-Befehle mit folgenden Adressierungsarten:

Register

Der Prozessor verfügt über insgesamt 16 Register (je Interrupt-Ebene) mit einer Breite von 16 Bit. Sie werden mit R0 bis R15 bezeichnet. Jeder Maschinenbefehl besitzt mindestens ein Register als Operanden.

Beispiele:

0234    MOVE R2, R3
8705    LBI R7, #5
3880    MOVE $100, R8

Immediate 8-Bit

Bei den Befehlen für ADD, SUB, SET, CLR, CTRL sowie für LBI (Load Byte Immediate) läßt sich ein Immediate-Wert angeben.
Besondere Beachtung muß der Addition/Subtraktion geschenkt werden! Der Bereich im Opcode für den Immediate-Wert beträgt $00 bis $FF, also ganze 8 Bit. Interpretiert wird er jedoch um 1 erhöht, d.h. wenn im Opcode für die Immediate-Addition bzw. Subtraktion der Wert $00 steht, bedeutet dies 1; bei $FF entsprechend 256! Man kann damit keine 0 addieren oder subtrahieren, dafür aber ganz einfach das High-Byte im 1 verändern. Wie gesagt: Das gilt nur für die Addition und Subtraktion!

Beispiele:

A51F    ADD R5, #32
FC00    SUB R12, #256
82C1    LBI R2, #'A'
B420    SET R4, #$20
9F01    CLR R15, #$01

Direkt 4-Bit

Bei den I/O-Befehlen wird immer eine Geräteadresse benötigt, die sich im Bereich von $0 bis $F befindet (siehe Geräteadressierung)

Beispiele:

0D5E    GETB R5, $D
ED6F    STAT R6, $D
4E78    PUTB $E, (R7)
107B    CTRL $0, #$7B

Direkt 8-Bit

Der Prozessor ist in der Lage, bei den 16-Bit MOVE-Befehlen einen 16-Bit Direktzugriff mit 8-Bit Wortadresse auszuführen. Die Byteadresse ist demnach 9-Bit, wobei Bit 15 (Vorsicht: IBM-Bitnumerierung) gleich 0 ist.

Beispiele:

2850    MOVE R8, $A0          $A0 = 2 * $50
2056    MOVE R0, $AC
39A0    MOVE $140, R9

Register-Indirekt

Bei den Befehlen MOVE, MOVB, GETB und PUTB läßt sich als Quelle bzw. Ziel eine Adresse indirekt über ein Register angeben. Wahlweise läßt sich noch ein Postinkrement oder Postdekrement um 1, 2, 3 oder 4 Bytes angeben.
Für die byteorientierten Befehle lauten die Inkrementoperatoren +, ++, +++ sowie ++++, beim Dekrement entsprechend -, --, --- und ----.
Da bei den Wortbefehlen der Registerwert um die gleichen Werte verändert werden kann, wurden die Operatoren entsprechend der Wortbreite ausgelegt. Daher werden für halbe Worte die Inkrement- bzw. Dekrementoperatoren ' bzw. ~ benutzt.

4D80    PUTB $D, (R8)+        erhöht R8 um 1
EDF4    GETB (R15)-, $D       erniedrigt R15 um 1
D236    MOVE R2, (R3)-~       erniedrigt R3 um 3 (1,5 Worte)
7542    MOVB (R4)+++, R5      erhöht R4 um 3 (3 Bytes)
DBC8    MOVE R11, (R12)

"Pseudo"-Adressierungsarten

Neben den oben aufgeführten Adressierungsarten lassen sich durch Verwendung anderer Befehle bzw. durch "Tricks" die Modi Immediate 16-Bit und PC-relativ implementieren.

Immediate 16-Bit

Um ein Register komplett mit einem 16-Bit Wert zu laden, gibt es zwei prinzipielle Möglichkeiten, die auch die IBM-Programmierer benutzt haben. Zum einen kann man beide Bytes (Low- und High-Byte) nacheinander wie folgt laden:

; Laden von R5 mit dem Wert $120E
8512    LBI R5, #$12        ; Lade Low-Byte
055D    MLH R5, R5          ; Low-Byte -> High-Byte
850E    LBI R5, #$0E        ; Lade Low-Byte
Dies ist unschön und lang zudem (insgesamt 6 Bytes), muß aber bei Programmen, die im ROS ablaufen, benutzt werden.
Die zweite, elegantere Möglichkeit besteht darin, die Konstante direkt hinter dem Befehl im Code abzulegen, der sie lädt. Man muß nur den Programmzähler entsprechend erhöhen, um die Konstante zu überspringen. Dies funktioniert aber nur bei Programmen, die im RWS ablaufen, da Datenzugriffe immer das RWS adressieren.
D501    MOVE R5, (R0)+      ; R0 zeigt danach auf das Wort hinter der Konstanten
120E    DW $120E
        ...
Wie man sieht, hat man dadurch 2 Bytes eingespart. Aus diesem Grund erhielt dieses Konstrukt ein eigenes Mnemonic LWI (Load Word Immediate); im obigen Beispiel hieße es dann LWI R5, #$120E.

PC-relativ

Wie man in der Opcode-Tabelle sieht, gibt es keine besonderen Sprungbefehle (Die Jump-Befehle gemäß IBM-Notation sind die bedingten Testbefehle). Entweder man lädt den Befehlszähler R0 mit dem Wert eines anderen Registers bzw. aus dem Speicher (über MOVE R0, ...), oder man springt direkt über den Befehl LWI R0, ... (s.o.) zum Ziel, wobei in beiden Fällen das Programm nicht verschiebbar ist.
Um relativ zum aktuellen Befehlszähler vor- oder zurückzuspringen, benutzt man einfach die Addition bzw. Subtraktion. Damit läßt sich eine Distanz von +/- 256 Bytes überwinden. Das ganze sieht dann so aus:

850A    LBI R5, #5
8601    LBI R6, #1
C50B    SNZ R5
A005    ADD R0, #6        ; Springe zum HALT
0668    ADD R6, R6
F500    SUB R5, #1
F009    SUB R0, #10       ; Springe zurück zum SNZ
0000    HALT