erste Schritte im SIMH

Wie können die nur 16 Instuktionen des RIM Loaders den Lochsreifen verarbeiten und erst die Startsequenz (leader), dann Adressen und Daten und schliesslich die Schlusskennung (trailer) verarbeiten?

Register

Die PDP-8 hat nur ein einziges universelles Register in der CPU, den AC (Akkumulator). Ausserdem gibt es das sogenannte Link Bit (L).

Die DEC Dokumentation zeigt normalerweise den AC die Bitpositionen aufsteigend (links ist das höherwertigste Bit “0”, rechts dann das niederwertigste), was bei mir für einige Verwirrung gesorgt hat. Drum hier mal die für mich logischere Notation mit dem Link bit als dreizehntes Bit “ganz links” (da wir später nach links schieben):

  1 1
L 1 0 9 8 7 6 5 4 3 2 1 0

So weit – so gut…

Erste RALly…

Eine weitere Hürde ist die Bedeutung der Mnemonics und der damit verbundenen Aktionen zu verstehen. Ich habe als ausführlichste Quelle das “PDP-8 Programming Manual MACRO-8” zu Rate gezogen. Da wird RAL wie folgt erklärt:

Rotate AC and L left. C(AC) and C(L) are rotated left one place.

C(ACi) => C(ACi-1)
C(AC0) => C(L)
C(L) => C(AC11)

Die Rotation erfolgt über das Link Bit. Unklar ist für mich, ob das L als dreizehntes Bit fungiert, oder eine Kopie des (im Falle von Links-Schieben) höchstwertigen Bits im AC ist. Ich vermute folgendes:

   1 1
 L 1 0 9 8 7 6 5 4 3 2 1 0
 a b c d e f g h i j k l m

Nach RAL:

   1 1
 L 1 0 9 8 7 6 5 4 3 2 1 0
 b c d e f g h i j k l m a

Lass uns das testen! 🙂

Tests in simh

simh (github) ist ein Programm, welches viele alte Minicomputer teilweise inklusive Peripherie emulieren kann. Nach der Installation des simh Pakets kann ich den PDP-8 Emulator mit pdp8 starten und lande dann am simh Prompt.

Für den Test brauchen wir diese 4 Instruktionen:

 CLL CLA 7300 / L=0 AC=0
 IAC 7001     / AC++
 RAL 7004     / Rotation nach links
 HLT 7402     / Halt

Und für simh folgende Kommandos:

  • id – interactive deposit: Werte im Speicher deponieren, akzeptiert auch Mnemonics
  • ex – examine: Register, Flags, Speicherinhalte anzeigen
  • go – Programm starten

Testlauf:

PDP-8 simulator V3.8-1
 sim> id 20-30
 20: cll cla
 21: iac
 22: ral
 23: ral
 24: ral
 25: hlt
 26: sim>
 sim> ex l,ac,20-26
 L: 0
 AC: 0000
 20: 7300
 21: 7001
 22: 7004
 23: 7004
 24: 7004
 25: 7402
 26: 0000

Das Programm liegt also ab 0020 im Speicher, und wir springen es an:

sim> go 20

HALT instruction, PC: 00026 (AND 0)
 sim> ex l,ac
 L: 0
 AC: 0010

Wie erwartet ist der Wert im AC jetzt 000 000 001 000, also (1<<3). Wir können jetzt einfach wieder irgendwo ins Programm reinspringen um den AC weiter zu schieben:

sim> go 22

HALT instruction, PC: 00026 (AND 0)
 sim> ex l,ac
 L: 0
 AC: 0100
 sim> go 22

HALT instruction, PC: 00026 (AND 0)
 sim> ex l,ac
 L: 0
 AC: 1000
 sim> go 22

HALT instruction, PC: 00026 (AND 0)
 sim> ex l,ac
 L: 1
 AC: 0000
 sim> go 22

HALT instruction, PC: 00026 (AND 0)
 sim> ex l,ac
 L: 0
 AC: 0004

Hier ist gut zu sehen, wie das gesetzte Bit vom AC ins L geschoben wird und von da wieder in den AC zurück. Passt!

Analyse des RIM Laders

Schauen wir uns kurz die ersten Progrmamzeilen des RIM Laders an:

  • Das erste Kommando (KCC) löscht L und AC,
  • dann wird die erste Lochreihe eingelesen (KRB). Channel 1..8 landen im AC 0..7.
  • Mit den Schiebe-Operationen und erneutem Laden liegen schilesslich die beiden 2×6 Bit “Nutzdaten” im AC,
  • die schlussendlich im Speicher abgelegt werden.

Ich habe die 8 Kanäle des Lesegeräts mit den ZIffern 8…1 im AC/L eingetragen und beobachte die Schiebeaktionen:

         L  1 1
ACCU     L  1 0 9 8 7 6 5 4 3 2 1 0
         -  -----------------------
KCC      ?  0 0 0 0 0 0 0 0 0 0 0 0
KRB      ?  0 0 0 0 8 7 6 5 4 3 2 1
CLL      0
RTL      0  0 0 8 7 6 5 4 3 2 1 0 0
RTL      0  8 7 6 5 4 3 2 1 0 0 0 0
...
RTL      7  6 5 4 3 2 1 0 0 0 0 0 8
            ^ ^ ^ ^ ^ ^
KSF      7  0 0 0 0 8 7 6 5 4 3 2 1
                        ^ ^ ^ ^ ^ ^

Damit haben wir aus den zwei Lochsteifen-Reihen 4×3 Bits eingelesen, die abhängig von den beiden “header”-Bits entweder als Adresse oder Daten behandelt werden:

     11 10 9 8 7 6 5 4 3 2 1 0
AC    addr1  addr2 addr3 addr4