Im Herzen des JOYCE

Teil 2: Kommunikation ist alles

Nachdem wir beim letzten Mal schon einige Einblicke in die "Tiefen" des BIOS, speziell in die Bedeutung der Restart-Funktionen, erhalten haben, wollen wir uns in dieser Folge den Kommunikations-Treiber (Communication Driver) etwas näher anschauen.

Dieses Programmsegment des BIOS (Basic Input Output System) hat, wie der Name schon vermuten läßt, die Aufgabe, die Kommunikation zwischen CP/M Plus und der Hardware, also den Ein- und Ausgabegeräten, zu ermöglichen. Nebenher verwaltet der Communication Driver auch noch die Ein-/Ausgabe für die serielle Schnittstelle des JOYCE (CPS 8256) und gibt auf Anfrage Informationen über die vorhandene Hardware zurück.
Aber alles der Reihe nach. Zunächst einige generelle Informationen:
1. Die hier beschriebenen Einsprungadressen beziehen sich ausschließlich auf die Routinen der BIOS-Version 1.4 (J14GCPM3.EMS). Die Adressen der etwas älteren Version 1.2 können von den hier aufgeführten Werten abweichen. Einige Routinen sind sogar in der Version 1.2 gar nicht implementiert.
2. Für den Aufruf der folgenden Routinen und Systemeinsprünge vom Anwenderprogramm aus, muß zunächst in die Bank #0, die Systembank, umgeschaltet werden, um dann den Aufruf durchzuführen. Diese Umschaltung der Speicherbänke läßt sich am einfachsten über die BIOS-Funktion # 30 (USERF) mit der Befehls-Sequenz
CALL 0FC5AH
DEFW ROUTINE
durchführen. ROUTINE ist dabei die Adresse der Programmroutine, die nach der Speicherumschaltung ausgeführt werden soll. Da alle Register während der Umschaltung der Speicherbänke gesichert werden, ist die Übergabe und Rückgabe von Parametern kein Problem.
3. Da über die im folgenden beschriebenen Systemroutinen meiner Kenntnis nach keine "offizielle" Dokumentation zu erhalten ist, mußte ich die Bezeichnungen für die Routinen zum Teil "erfinden".

Verschiedenes

Entsprechend der Adresslage im Speicher beginnen wir mit der Rubrik "Verschiedenes".
Hier gibt es drei Einsprünge, die dem Anwender von Nutzen sein könnten:

CD INFO $0178
kann auch über den XBIOS-Jumpblock erreicht werden (vergleiche Folge 1) und gibt Informationen über die Hardware-Konfiguration des Rechners, zum Beispiel Anzahl der Laufwerke, Anzahl der Speicherblöcke etc. zurück (siehe Tabelle 3).
CD JUMP (BC) $0187
führt einen Sprung zur im BC-Register spezifizierten Adresse durch. Das Ergebnis ist ähnlich dem Z80-Befehl JP (HL), nur daß hier die Adresse im BC-Register übergeben wird.
CD VERSION $0189
übergibt die Versionsnummer des BIOS und die Rechner-Identifikation. Für die PCW-Rechner sollten Sie hier den Wert $01 erhalten.
Möchten Sie vor dem Start Ihres Programms die Systemmeldung ausgeben lassen? Falls ja, sollten Sie die Adresse $0192 aufrufen. Parameter werden für diesen Aufruf nicht benötigt.
Die weiteren Routinen dieses Adreßbereichs werden nur während der System-Initialisierung (BOOT) aufgerufen und dürfen zum Teil anschließend auch nicht mehr aufgerufen werden, da sie die Initialisierung der Pufferbereiche und Interrupt-Header durchführen. Speziell für die Kommunikation mit CP/M stehen die I/O-Module für die Zeichenein-/-ausgabe zur Verfügung:
CD CHAR INPUT (?CI) $0230
liest ein Zeichen von einem spezifizierten Eingabegerät.
CD CHAR OUTPUT (?CO) $023C
gibt ein Zeichen an ein spezifiziertes Ausgabegerät aus.
CD INPUT STATUS (?CIST) $024E
prüft, ob ein Zeichen von einem Eingabegerät vorliegt.
CD OUTPUT STATUS (?COST) $025B
prüft die Ausgabebereitschaft eines Ausgabegeräts.
Bei diesen Funktionen wird das entsprechende Ein- beziehungsweise Ausgabegerät durch eine Nummer spezifiziert, die beim Aufruf im B-Register übergeben wird. Zulässige Werte sind hierbei:
-0für Monitor und Tastatur
-1für den JOYCE-Drucker
-2für den seriellen Port und
-3für den Centronics-Ausgang.
Interessant für den Anwender dürfte auch eine Routine sein, die über die Adresse $02B7 erreicht werden kann: Sie wandelt Kleinbuchstaben in Großbuchstaben um. Das umzuwandelnde Zeichen wird dabei im A-Register übergeben und zurückgegeben, alle anderen Register werden bei der Umwandlung nicht verändert.

Serielles

Die serielle Schnittstelle des JOYCE wird ebenfalls vom Kommunikations-Treiber "versorgt". Diese Schnittstelle verfügt neben der SIO auch über einen parallelen Ausgang.
Daher sind diverse Routinen für die Initialisierung und die Zeichenein-/-ausgabe vorhanden. Beginnen wir mit dem seriellen Port:
CD SA INI $02CF
initialisiert die Schnittstelle, stellt die Interface-Parameter ein und ermöglicht die direkte Beeinflussung der Handshake-Signale DTR und RTS.
Die Übergabeformate sind in Tabelle 1 näher beschrieben.
CD SA PARAMS $0360
gibt die momentane Parameter-Einstellung der SIO zurück.
CD SA INPUT CHAR $0371
liest ein Zeichen von der SIO (wartet eventuell, bis ein Zeichen gesendet wird). Bei Interrupt-Kontrolle wird das Zeichen aus dem SIO-Puffer gelesen.
CD SA INPUT STATUS $03CD
prüft, ob ein Zeichen von der SIO vorliegt.
CD SA OUTPUT CHAR $03E4
gibt ein Zeichen an die SIO aus.
CD SA OUTPUT STATUS $03EE
überprüft die Ausgabebereitschaft der SIO.
Tabelle 1: Übergabe-Formate für die Parameter der seriellen Schnittstelle
Modus: $00
$FF
$FE
$FD
=
=
=
=
Polling (Abfrage) ohne Handshake
Polling mit Handshake
Interrupt-Kontrolle ohne Handshake
Interrupt-Kontrolle mit Handshake
Stopbits: $00
$01
$02
=
=
=
1 Stopbit
1.5 Stopbits
2 Stopbits
Parität: $00
$01
$02
=
=
=
keine Parität
gerade Parität
ungerade Parität
Signal-Status: $80
$7F
$7E
$7D
=
=
=
=
DTR löschen
DTR setzen
RTS löschen
RTS setzen

Falls die SIO im Interrupt-Modus betrieben werden soll, hält auch hier das BIOS die entsprechenden Routinen bereit. In diesem Modus erzeugen Zeichen, die von der SIO empfangen werden, einen Interrupt, der dafür sorgt, daß die empfangenen Zeichen in einen Puffer geladen werden.
Dieser Puffer nimmt bis zu 98 Zeichen auf und kann vom Anwender über "normale" Eingaberoutinen oder auch direkt über die Systemroutine CD SA IPT INPUT ausgelesen werden.
Für die Initialisierung der Interrupt-Steuerung wird man für gewöhnlich den Einsprung CD SA INIT (Modus $FE oder $FD, siehe Tabelle 1) benutzen, dann können die normalen I/O-Routinen für die Kommunikation benutzt werden. Für spezielle Anwendungen kann die Interrupt-Kontrolle aber auch separat programmiert werden. Dabei sollten Sie aber beachten, daß dann auch die Routinen für die Statusabfrage und Zeicheneingabe (im folgenden mit dem Kürzel "IPT" bezeichnet) direkt aufgerufen werden müssen:
Interrupt-Polling aktivieren $0427
initialisiert den SIO-Zeichenpuffer, setzt die SIO zurück und aktiviert den Interrupt-Header.
Interrupt-Polling deaktivieren $043C
entfernt den Interrupt aus der External Event Chain.
Die External Event Chain ist eine "verkettete Liste", in der alle externen Interrupts "eingehängt" werden.
CD SA RESET $0442
schickt ein Reset-Kommando an die SIO.
CD SA IPT STATUS $0450
prüft, ob Zeichen im SIO-Puffer sind.
CD SA IPT INPUT $0456
liest ein Zeichen aus dem Zeichenpuffer beziehungsweise wartet, bis ein solches vom Interrupt-Service in den Puffer geladen wird.
CD SA INIT BAUD (?CINIT) $04B3
legt die Baud-Rate für die SIO fest. Sender- und Empfänger-Baud-Rate werden im B-Register spezifiziert.
Dieser Aufruf wird wieder direkt von CP/M benutzt.
CD SA BAUD $04B9
ermöglicht die Festlegung getrennter Baud-Rates für Empfänger und Sender. Wer seine eigenen Übertragungsfrequenzen benutzen will, muß die Timer-Werte direkt in der Baud-Rate-Tabelle ändern.
Tabelle 2: Die Standard-Baud-Rates der seriellen Schnittstelle
ID (Nummer) Baud-Rate Timer-Wert Adresse
$00
$01
$02
$03
$04
$05
$06
$07
$08
$09
$0A
$0B
$0C
$0D
$0E
$0F
 
50
75
110
134.5
150
300
600
1200
1800
2400
3600
4800
7200
9600
19200
- -
2500
1592
1136
929
833
417
208
104
69
52
35
26
17
13
7
$04D8
$04DA
$04DC
$04DE
$04E0
$04E2
$04E4
$04E6
$04E8
$04EA
$04EC
$04EE
$04F0
$04F2
$04F4
$04F6

Startadresse dieser Tabelle: $04D8, Format:
DEFW 0FFFFH
DEFW Baud_1
DEFW Baud_2
...
...
DEFW Baud_E
DEFW Baud_F

Paralleles

Für die Steuerung des parallelen Ausgangs der Schnittstelle sind natürlich auch entsprechende Routinen vorhanden, die dem Anwender einen direkten Zugriff auf diesen Ausgabe-Port gestatten:
CD SA CEN INIT $04F8
initialisiert den Centronics-Port.
CD SA CEN OUT $0508
gibt ein Zeichen an den Centronics-Port aus.
CD SA CEN STATUS $0520
prüft die Ausgabebereitschaft des Centronics-Ports.
Verfügen Sie über entsprechende Hardware-Kenntnisse, kann die Schnittstelle auch direkt programmiert werden. Für die serielle Kommunikation verwendet das Schnittstellenmodul CPS 8256 den Kanal A eines Z80-DART. Der Kanal B ist, zusammen mit einem 8-Bit-Centronics-Latch, für den parallelen Ausgang vorgesehen.
Die verwendeten I/O-Adressen sind:

$E0:
$E1:
$E2:
$E3:
$E4:
$E5:
$E6:
$E7:
$E&:
DART Kanal A Daten (SIO)
DART Kanal A Control (SIO)
DART Kanal B Daten (n.b.)
DART Kanal B Control (CEN)
8253 Timer 0 (TX-Clock A)
8253 Timer 1 (RX-Clock A)
8253 Timer 2 (TX/RX-Clock B)
8253 Mode-Register
Centronics-Latch

Die Beispiel-Listings geben einen kleinen Anhalt, wie die Routinen aufgerufen und für eigene Programme benutzt werden können.

Demnächst

Im Teil 3 unserer Serie werden Sie allerhand über das Programmsegment erfahren, welches die Kommunikation des CP/M Betriebssystems mit dem Bildschirm ermöglicht. Interessant, wenn man bedenkt, daß die Hauptaufgabe dieses Segments darin besteht, einen Anwenderprogramm vorzutäuschen, daß es mit einem Zenith Z19/Z29-Terminal kommuniziert. Unter anderem ist es dadurch möglich, daß CP/M-Programme auf so vielen verschiedenen Computern ohne (große) Änderungen laufen können.

Tabelle 3: Die Funktionen des Communication Drivers im Überblick
Die Listings zu diesem Teil:

(Norbert Finke/rs)
[1. Teil] [Inhalt] [3. Teil]

Eingescanned von Werner Cirsovius
März 2003
© DMV Verlag