Der folgende Text ist ein Auszug (Kapitel 8) aus dem Buch The Amstrad Plus von Andrew R.M. Clarke und David Powys-Lybbe (1986). Ein weiterer Artikel zum Thema RSX findet sich in der Zeitschrift CT.

RSX Erweiterung für das Betriebssystem

Durch den Einsatz von RSXen können die Möglichkeiten des Betriebssystems erweitert werden. RSXen sind mächtige Werkzeuge und können bei sorgfältiger Nutzung für interessante Anwendungen eingesetzt werden. Obwohl die RSX grundsätzlich für die Erweiterung des Betriebssystems entwickelt wurde, kann einfaches Multitasking umgesetzt werden, z.B. als Print-Spooler oder bei der DFÜ. Sie kann eingesetzt werden als Terminal-Emulator, zur Bildschirmdarstellung einer Uhr, CP/M 2.2 Emulation, Mausnutzung oder zum Austesten von Geräten.

Da mehrere RSXen geladen sein können, entsteht für den Nutzer der Eindruck, der einer Anzahl von zugleich ablaufenden Programmen ähnlich ist.

Zwar sind RSXen neu für CP/M Plus, jedoch entstand die Idee in den Anfängen von CP/M. DDT war das erste Programm, das sich selbst an die Spitze der TPA relozierte und dementsprechend die Größe der TPA verringerte. Da DDT den Restart-Vektor nutzte, um Kontrolle über die CPU zu bekommen, und vor Einführung der RSXen eingesetzt wurde, kann es nicht als RSX betrachtet werden. Auch nicht DESPOOL, das alte CP/M 1.4 Spooler-Programm, obwohl es ähnlich ist. Die GSX sollte eine RSX sein, ist es aber nicht. Sie wurde zu den Zeiten von CP/M 2.2 entwickelt und eine Version für CP/M Plus wurde nie herausgebracht. GSX wurde ursprünglich von einer Firma (GSS) entwickelt und war kein Bestandteil von Digital Research.

Wird das BDOS von einem transienten Programm aus aufgerufen, so durchläuft dieser Aufruf alle RSXen, die zur Zeit geladen sind, weil diese vom Lader entsprechend umgelenkt wurden. Die RSX kann jeden BDOS Aufruf abfangen oder den reservierten RSX BDOS Aufruf (Funktion 60) bearbeiten. Es gibt drei Typen von RSXen:
  1. Sie können auf BDOS Aufrufe einwirken, so dass auf den ursprüngliche Aufruf eingewirkt wird.
  2. Sie können zusätzliche BDOS Aufrufe zur Verfügung stellen.
  3. Sie können CPU-Zeit 'stehlen' bei einigen oder allen BDOS Aufrufen.
Ein Beispiel für (1) kann ein Patch sein, um ein temporäres Hilfsgerät (AUX) einzubringen. Dazu wird es notwendig, die Funtionen 3, 4, 7 und 8 umzuleiten. (Eine Geräteumkonfiguration oder Umleitung funktioniert nicht!) Ein Beispiel für (2) ist ein Grafikpaket oder ein Paket für den Zugriff auf ein Ton- oder Musikschaltkreis. Das gilt auch für den Zugriff auf einen Joystick. Ein Drucker-Spooler ist ein Beispiel für (3).

Aufbau einer RSX

Ein RSX-Programm unterscheidet sich von einem '.COM'-Programm durch das Einfügen eines RSX-Vorspanns am Anfang des Programmes. Der Vorspann hat eine Länge von 27 Bytes und die meisten Elemente werden vom CCP Lader initialisiert, wenn die RSX installiert wird. Eine RSX muss die üblichen Regeln für einen normalen BDOS Aufruf befolgen. Diese besagen, dass Parameter in den Registern C, D und E übergeben und in A, B, H und L zurückgegeben werden. Auch sollte eine RSX ihren eigenen Stack verwenden. Anders als die Regeln eines '.COM'-Programmes für den BDOS Aufruf besagen muss die RSX ihre eigenen BDOS Aufrufe über den Vorspann durchführen und nicht über Adresse 0005h.

Der RSX Vorspann

      .z80
0000  Serial:                    ; 6 Byte Seriennummer
           db   0,0,0,0,0,0      ; Durch den Lader initialisiert
0006  Start:                     ; Sprung zum RSX Programm
           jp   rsx_prog
0009  Next:                      ; Sprung zur naechsten RSX (BDOS Start)
           jp   $-$              ; Durch den Lader initialisiert
000C  Prev:                      ; Adresse der vorigen RSX oder Seite Null
           dw   7                ; Durch den Lader initialisiert
000E  Remove:                    ; Remove Marker
           db   0FFh             ; Auf 0 setzen bei permanenter RSX
000F  Nonbank:                   ; Marker bei System ohne Speicherbaenke
           db   0                ; Auf 0FFh setzen nur fuer System ohne Speicherbaenke
0010  Name:                      ; Name der RSX
           db   '12345678'       ; Beliebiger Name aus 8 Zeichen
0018  Loader:                    ; Lader Marker
           db   0                ; Durch den Lader initialisiert auf 0

0019       ds   2                ; Frei - reserviert

Die folgenden Felder der RSX müssen initialisiert sein:
Start:Eingestellt auf den Sprung zum RSX Programm
Next:Das erste Byte muss den Sprung-Opcode 0C3h enthalten
Remove:Marker wie erforderlich auf 00h oder 0FFH setzen
Nonbank:Auf Null voreinstellen
Name:Beliebigen Namen eintragen

START: Dieses Feld beinhaltet eine Sprunganweisung zur Startadresse der RSX. Dieser Teil der RSX testet, ob die BDOS Funktion, die im Register C angegeben ist, abgefangen werden soll. Falls nicht, muss ein Sprung zur Marke NEXT: erfolgen, ohne die Register C, D oder E zu verändern.

NEXT: Dieses Feld entspricht dem BDOS Einsprung in Adresse 0005h und wird stattdessen vom RSX Programm aufgerufen. Es enthält die Adresse der Marke START: der folgenden RSX oder die Adresse des CCP Laders im Falle der letzten RSX.

PREV: Dieses Feld beinhaltet die Adresse der vorigen RSX. Bei der ersten RSX ist das die Adresse des BDOS Vektors. Bei der ersten Installation wird das Feld auf Adresse 0007h eingestellt. Dies wird geändert, wenn eine andere RSX unterhalb dieser RSX geladen wird.

REMOVE: Diese Marke ist normalerweise auf 0FFh gesetzt, so dass die RSX beim nächsten Warmstart durch den CCP Lader entfernt wird. Soll die RSX ständig geladen sein, muss die Marke auf 00h gesetzt werden. Die Marke wird dann auf 0FFh gesetzt, wenn die RSX nicht mehr benötigt wird.

NONBANK: Diese Marke ist immer auf Null gesetzt. Sie war für anfängliche Implementierungen von CP/M Plus auf Basis von CP/M 2.2 Maschinen mit nur 64k Speicher bestimmt. Sie wurde genutzt, um einige der CP/M Plus Möglichkeiten zu bieten, die bei der Version ohne Speicherbänke ausgeschlossen waren. Ein Beispiel ist der CP/M Plus Dienst DIRLBL.RSX, der die BDOS Funktion zur Nutzung ohne Speicherbänke 100 enthält.

NAME: Dieses Feld mit acht Zeichen kennzeichnet die RSX für ein beliebiges Dienstprogramm, das die Liste der RSXen untersucht. Der CCP Lader hat den Namen 'LOADER '.

LOADER: Diese Marke ist vom CCP Lader immer auf Null gesetzt. Der CCP Lader selbst setzt das Feld auf 0FFh. Dies markiert dann das Ende der RSX Kette. Vorsicht ist geboten, wenn nach RSXen gesucht wird, da dieses Feld nicht im BDOS existiert. Programme müssen zunächst prüfen, ob RSXen oder der CCP-Loader vorhanden sind. Dazu wird das Byte, das drei Bytes vor dem Start des SCB liegt (Adressabstand von -3) und die BDOS Startseite ist, verglichen mit dem Byte in Adresse 0007h, welches die aktuelle BDOS Startseite darstellt.

Die RSX Funktionsaufrufe

Eine RSX kann verwendet werden, um BDOS Aufrufe abzufangen oder um neue BDOS Scheinfunktionen hinzuzufügen. Zu diesem Zweck hat CP/M Plus die BDOS Funktion 60 reserviert. Die RSX Funktionsnummer wird im ersten Byte des Parameterblocks übergeben, dessen Adresse im Registerpaar DE beim Aufruf vom BDOS steht. Diese Nummer muss im Bereich 0 bis 127 liegen und die eigentliche Nummer sollte mit einer bestimmten Vorstellung gewählt werden. Im BDOS-Abschnitt 7.11.2 sind Details zu finden und ein Beispiel wird gezeigt in Abschnitt 7.17.

Es ist ratsam, dass eine RSX, die die Funktion 60 benutzt, den Regeln eines BDOS-Aufrufes entspricht und das Resultat im Akkumulator und/oder Register HL zurückgibt.

Erstellen von RSX Dateien

RSX Dateien werden gewöhnlich mit dem Dienstprogramm GENCOM erzeugt, das RSXen mit einer (optionalen) COM-Datei kombiniert und eine spezielle COM-Datei erstellt. Diese beginnt mit einem GENCOM-Vorspann, gefolgt von der Original (oder einer leeren COM-Datei) und beendet mit einer oder mehreren RSXen. Siehe BDOS Funktion 59 im Abschnitt 7.11.2 für weitere Details.

Alternatively an RSX can be created directly and an examination of the CCP.COM file at offset 0959H (see Appendix E) demonstrates how this can be done.

RSX Beispiel - Spooler1

Es folgt nun als Beispiel eine RSX des dritten Typs. Dieser ist am schwierigsten auszuführen und die eigene Spooler-RSX von Digital Research wurde demzufolge nie herausgegeben. Wenn eine RSX auf ein Laufwerk zugreift, so kann sich das seltsam auf das Hauptprogramm in der TPA auswirken. Das BDOS wird fürchterlich durcheinandergebracht, wenn das TPA Programm eine Dateisuche vornimmt und die RSX zur selben Zeit auf ein Laufwerk zugreift. Wenn die Hintergrundtätigkeit der RSX die DMA Adresse ändert (der Speicherbereich, in dem die Ein/Ausgabe eines Laufwerks vorgenommen wird), während das TPA Programm einige Leseoperationen durchführt, so wird das Ergebnis anders als erwartet ausfallen. Laufwerkszugriffe durch die RSX sollten für ein glückliches und sorgenfreies Programmierleben vermieden werden. Im folgenden Spoolerbeispiel wurde der Stier bei den Hörnern gepackt mit der Einschränkung, die zeitliche Bereitstellung auf gepufferte Konsoleingabe zu reduzieren. (Das ist einfach zu bewerkstelligen durch das Patchen des Vektors BIOS CONST durch die RSX.)

Der Spooler schickt im Hintergrund einen oder mehrere Dateien auf den Anschluss AUX:.

Für den Spooler wird eine RSX an der höchsten Speicheradresse in der TPA benötigt, wo sie auch bleiben soll. Um das Beispiel klarer und kürzer zu halten, wurde der Hauptteil der RSX in C geschrieben. Das ist ein törichtes Unterfangen und eine echte RSX sollte immer im Assembler geschrieben werden. Daneben ist ein Programm erforderlich, das dies RSX aufruft und den Dateinamen der Datei übergibt, die der Nutzer zum Anschluss AUX: senden will. Der Spooler muss die Liste der zu sendenden Dateien verwalten und diese nacheinander übertragen.

Der Anfang ist einfach. Das TPA Programm namens SEND erlaubt dem Nutzer der RSX anzugeben, welche Datei gesendet werden soll und kann jederzeit aufgerufen werden. Es verwendet den reservierten BDSO Aufruf 60 zum Informationsaustausch mit der Spooler RSX. Das Beispiel kann natürlich erweitert werden, z.B. zum Versenden von Listen von Dateinamen, aber es soll einfach gehalten werden.
[Hier als Quelle]
Eigentlich sollte das Programm Feinheiten wie z.B. eine Versionsüberprüfung enthalten, für die Demonstration genügt aber das Wesentliche.

Nach der Entscheidung, den Spooler in C zu schreiben, wird eine Assemblerschnittstelle benötigt, um die Konvention des RSX Header zu befolgen. In dieser Fassung wird das Hauptprogramm nur dann aktiv, wenn das erste Zeichen einer Zeileneingabe eingegeben wird (so wie bei der Anforderung A>). Es ist lehrreich, dies so zu ändern, dass es für verschiedene BDOS snd BIOS-Aufrufe funktioniert. Die Autoren haben dich für die sicherste Methode entschieden, allerdings kann es sehr lange dauern, bis die Datei ausgegeben wird!
[8080 oder Z80 Quelle]
Wie zu erkennen ist, erfordert der Einsatz von C für den Hauptteil der RSX (die Routine RSX_entry) Fummelarbeit, da der Linker davon ausgeht, dass ein C Programm, dass auf die Supportbibliothek zugreift, über den Eintrittspunkt MAIN verfügen muss. MALLOC usw. wird und kann nicht benutzt werden; daher kann auch die Prozedur MAIN nicht eingefügt werden, jedoch genügt das Label 'main_' dem Linker, auch wenn es niemals aufgerufen wird. Andere Versionen von C-Compilers können diese Problem umgehen.

An dieser Stelle ist nun die eigentliche Arbeit getan.
[Hier als Quelle]
Nun kommt die Aufgabe, alles zu verbinden, um die RSX zu erstellen. Der Linker soll eine '.PRL' Datei erzeugen und das Dienstprogramm GENCOM muss eine 'RET' Anweisung als erstes Byte in die '.COM' Datei einsetzen. Dies geht am einfachsten mit einer '.SUB' Datei. Der benutzte C Compiler liegt auf Laufwerk A: und wir bewegen ihn zur Erzeugung einer Assemblerdatei im RMAC Format.
[Hier für den M80 Assembler]
Natürlich bedarf es einer Anpassung an andere C Compiler und anderen Laufwerksbelegungen,

Wenn alles sicher zusammengestellt und compiliert ist, muss lediglich eingegebn werden:-
SPOOLER,
wodurch die RSX geladen wird. Das Kommando sollte nur einmal aufgerufen werden, weil diese Version nicht gegen eine Mehrfachinstalltion geschützt ist. Dazu müssten nachfolgende RSXen nach demselben Namen abgesucht werden, bevor die Remove-Marke auf 00h gesetzt wird.

Mit der Eingabe:-
SEND filename.typ
wird der Spooler aktiviert, die Datei zu senden, immer wenn das System leerläuft. Um das Programm besser nutzbar zu machen, sollte es beim Aufruf von CONST BIOS durch Umleiten des BIOS Vektors offensichtlich CPU Zeit stehlen. Auch die SETDMA Aufrufe müssen überwacht werden, damit nach einer Änderung der DMA vom Spooler diese wieder auf die Adresse für das TPA Programm zurückgesetzt wird. Das gilt auch für alle SEARCHFIRST und SEARCHNEXT Aufrufe, die das System sperren sollten bis zu einem anderen Dateiaufruf. (z.B. OPEN CLOSE READ WRITE usw.)
Wenn dies alles berücksichtigt wird, dann funktioniert das Programm besser, allerdings würde das Listing den Rahmen eines Beispielprogramms sprengen.


1. Die englische Firma M.M.L. Systems Ltd. brachte Ende der Achtziger einen Spooler auf den Markt, den ich disassembliert habe

Letzte Änderung: 27.Oktober 2014