###   Projekte und Informationen rund um den KC85   ### 

Programmieren mit der SYSLIB

von Jörg Linder

Einleitung

Welcher Assemblerprogrammierer kenn das nicht: Man erarbeitet sich jede Zeile Quelltext mühsam, erfindet das Fahrrad zum zigsten Mal neu und heraus kommen ein paar klägliche Bytes Programm. Wäre es nicht toll, wenn man auf vorgefertigte Routinen zurückgreifen könnte? Eine Sammlung von Programmroutinen für das CP/M-System gibt es in Form der SYSLIB.

Bereits in den 80er Jahren hat sich Richard Conn bemüht, Routinen für wiederkehrende Aufgaben zu sammeln und zu dokumentieren. Im Laufe der Jahre ist die SYSLIB gewachsen, die Routinen wurden debuggt, überarbeitet und optimiert, so daß sie nun eine solide Basis darstellen. Natürlich gibt es auch hier einen Haken! Die SYSLIB kommt aus Amerika, demzufolge sind alle Dokumentationen nur in englischer Sprache verfügbar.

Neben der eigentlichen SYSLIB findet ihr auf der Beilagen-Diskette auch die Help-Dateien dazu. Diese können mit dem Programm HILFE.COM angesehen werden, welches eine ältere Version des Z-System Programmes HELP.COM darstellt, die auch unter CP/M läuft. Wenn man wissen will, wie's funktioniert, braucht man nur "HILFE" einzugeben. Die Datei HILFE.HQP (gesqueezt) enthält alle notwendigen Informationen.

Für das Betrachten der Help-Dateien zur SYSLIB muß man "HILFE SYSLIB.HLP" eingeben. Die hierarchisch aufgebauten Hilfeseiten erreicht man über den jeweils vorangestellten Buchstaben. Noch sind alle Texte in englischer Sprache, aber vielleicht hat ja jemand Zeit und Muße, die Dateien ins Deutsche zu übertragen...

Um aus diesem Artikel eine Art "Programmierkurs" zu machen, habe ich mir ein Projekt herausgesucht, anhand dessen man (m)eine Vorgehensweise erkennen kann. Als Redakteur der KC-News muß ich mich mit den verschiedensten Dateiformaten herumplagen. Zwar gibt es schon diverse Konvertierungsprogramme, aber jedes hat seine Schwächen. Was lag näher, als selbst mal eine Variante zusammenzustellen.

Das hier vorgestellte Programm ist universell einsetzbar und kann individuell erweitert werden. Es ist nicht nur auf Text­ sondern auch auf andere Dateien anwendbar. Selbstverständlich erhebe ich nicht den Anspruch auf Vollkommenheit. In erster Linie möchte ich damit eine Anregung geben, was mit der SYSLIB möglich ist und den einen oder anderen ermutigen, es selbst mal mit dem Programmieren zu versuchen.

Das Programm UNIKON

In diesem Kurs wird mit Hilfe der SYSLIB ein UNIverselles KONvertierungsprogramm "zusammengeschustert". Das Prinzip eines Konvertierungsprogrammes ist doch immer gleich: Quelldatei einlesen, Daten konvertieren, Zieldatei ausgeben. Für den ersten und letzten Schritt habe ich mich in der SYSLIB nach passenden Routinen umgesehen und bin fündig geworden. Hier die Übersetzung der Help-Texte:

Die folgende Dokumentation beschreibt die Reihe von byteorientierten Dateiein- und -ausgaberoutinen der SYSLIB. Mit diesen Routinen ist es möglich auf eine außerordentlich einfache Weise, sequentiell Byte für Byte von Dateien zu lesen (GET) und in Datei zu schreiben (PUT).

Ein Programm, das diese Routinen verwendet, muß zuerst die entsprechende Datei öffnen, bevor es irgendwelche Operationen ausführt. Anschließend wird der Verarbeitungsprozeß mit der geöffneten Datei durchgeführt. Ist der Prozeß beendet, muß die Datei geschlossen werden. (Das Schließen ist nicht zwingend erforderlich, wenn die Datei nur gelesen wurde, bei Schreiboperationen in eine Datei ist es jedoch unumgänglich.)

In der SYSLIB sind vier Sets von Routinen für byteorientierte Dateiein- und -ausgabe enthalten. Dies sind:

Input Open Output Open GET PUT Input Close Output Close

FI0$OPEN FO0$OPEN F0$GET F0$PUT FI0$CLOSE FO0$CLOSE
FI1$OPEN FO1$OPEN F1$GET F1$PUT FI1$CLOSE FO1$CLOSE
FI2$OPEN FO2$OPEN F2$GET F2$PUT FI2$CLOSE FO2$CLOSE
FI3$OPEN FO3$OPEN F3$GET F3$PUT FI3$CLOSE FO3$CLOSE


Dieses System erlaubt es, bis zu 8 Dateien gleichzeitig geöffnet zu halten - 4 geöffnete Dateien für die Eingabe (Input mittels GET) und 4 geöffnete Dateien für die Ausgabe (Output mittels PUT). Das folgende Beispiel zeigt, wie der Quellcode aussehen könnte, wenn diese Routinen für zwei Dateien benutzt werden.

EXT FI0$OPEN    ; Deklaration der externen Label
EXT FO0$OPEN    ; (Bezug auf Bibliothek)
EXT FI0$CLOSE
EXT FO0$CLOSE
EXT F0$GET
EXT F0$PUT
...
LD DE,FCBI      ; Zeiger auf FCB der Eingabedatei
CALL FI0$OPEN
LD DE,FCBO      ; Zeiger auf FCB der Ausgabedatei
CALL FO0$OPEN
...
[Verarbeitungsroutine - enthält CALL F0$GET und CALL F0$PUT]
...
CALL FI0$CLOSE  ; Dateien schließen
CALL FO0$CLOSE
...
END

Es ist dabei zu beachten, daß nur die wirklich verwendeten Routinen in den EXT-Anweisungen aufgeführt werden. Alle nicht benötigten Routinen sollten nicht aufgeführt werden, da sie zusätzlichen Speicher belegen.

Jedes Set von INPUT OPEN, INPUT CLOSE, OUTPUT OPEN, OUTPUT CLOSE, GET und PUT Routinen ist in einem Modul der Bibliothek enthalten. Demzufolge wird bei Bezug einer dieser Routinen das gesamte Modul geladen und alle enthaltenen Routinen sind für den Nutzer bzw. Programmierer verfügbar (vorausgesetzt, sie wurden als EXTerne Bezüge deklariert) ohne darüber hinaus zusätzlichen Speicher zu belegen. Alle Routinen mit einer Null, also FI0$OPEN, FI0$CLOSE, FO0$OPEN, FO0$CLOSE, F0$GET und F0$PUT, sind in einem Modul enthalten. Dies gilt ebenso für die anderen Sets.

Die CLOSE-Routine für die Ausgabe (FOn$CLOSE) wird immer benötigt. Sie füllt den Rest des Blocks mit Control-Z, gefolgt von <NULL>-Bytes und schließt die Datei ordnungsgemäß. Die CLOSE-Routine für die Eingabe (FIn$CLOSE) wird nur dann benötigt, wenn später mit der entsprechenden OPEN-Routine eine andere Datei geöffnet werden soll. FIn$CLOSE setzt nur das OPEN-Flag der Datei zurück. (Es wird benutzt, um der GET-Routine anzuzeigen, daß die Datei ordnungsgemäß geöffnet wurde.)

<<< Mit Rücksichtnahme auf die Downloadzeiten wurde auf die vollständige Beschreibung der einzelnen Routinen an dieser Stelle verzichtet. >>>

Der Quelltext

Den weniger interessierten Lesern und auch dem Kopierer möchte ich das vollständige Listing in gedruckter Form ersparen. Ich habe den Quelltext in mehrere Dateien aufgeteilt, um eine einfache Umsetzung (z. B. in eine andere Sprache) zu ermöglichen. Natürlich kann man auch alles aus einem Stück machen. Die Datei "-UNIKON." enthält eine kurze Beschreibung der mitgelieferten Dateien. Darüberhinaus habe ich nicht mit Kommentaren in den Quelltexten gespart.

Für alle, die noch nicht mit externen Bezügen gearbeitet haben, möchte ich nachfolgend etwas genauer darauf eingehen.

Grundsätzlich kann jedes Unterprogramm in einer separaten Datei abgelegt werden. Dazu darf jedoch während des Assemblierens keine feste Adresse feststehen. Auf diese Weise gewinnt man eine sogenannte relozierbare Datei (Dateityp im Normalfall .REL). Erst beim Linken (zu deutsch: verbinden) werden die Bezüge aufgelöst und die entsprechenden Adressen eingetragen. Jedoch nicht alle Assembler können .REL-Dateien erzeugen und nicht alle Linker sie verarbeiten.

Wer sich selbst eine Art SYSLIB zusammenstellen möchte kann dies tun. Dazu müssen alle Marken (Label) in der Datei, die für andere Routinen verfügbar sein sollen, zugänglich gemacht werden. Dies geschieht mit dem PUBLIC-Befehl. Hat man mehrere .REL-Dateien, kann man sie mit Hilfe eines speziellen Programmes zu einer Bibliothek zusammenführen. (Diese Art Bibliotheken entsprechen nicht den oben erwähnten "Libraries".) Möchte der Programmierer vorgefertigte Routinen verwenden, muß er sie über den EXT-Befehl deklarieren. Erst danach können im weiteren Programm darauf CALLs ausgeführt werden.

Die Benutzung der EXT-Befehle ist im Quelltext gut zu erkennen. Sinnvollerweise sollte man alle Deklarationen, Vereinbarungen etc. zu Beginn aufführen. Desweiteren sollte man auch nicht vergessen, ab und an Kommentare einzufügen. (Als ordentlicher Programmierer macht man das - und ordentliche Programmierer wollen wir doch werden!)

Dem Linker muß natürlich noch mitgeteilt werden, daß und vor allem in welcher Bibliothek er nach den Routinen suchen soll. Leider kann ich hier keine allgemeingültige Anleitung geben, wie der Quelltext zu assemblieren und zu linken ist, da jeder Linker eine andere Syntax verwendet. Hier sollte man das Handbuch und eventuelle Hilfe-Dateien zu Rate ziehen.

Für M80/L80 müßten die Kommandozeilen lauten:

M80 =UNIKON10/R/Z
L80 UNIKON10,SYSLIB/S,UNIKON10/N/E

Wer glücklicher Besitzer von SLR180 und SLRNK ist, gibt folgendes ein:

SLR180 UNIKON10/R
SLRNK /A:0100,UNIKON10,SYSLIBS/S,UNIKON10/N/E

Und wie geht's weiter?

An dieser Stelle erstmal gar nicht. In der Hoffnung, daß dieser Kurs sein Ziel zumindest ansatzweise erreicht hat, beende ich ihn gleich. Doch hier noch ein paar Anregungen, in welcher Weise das Programm noch erweitert werden könnte:

  • Angabe von Laufwerk und Nutzerbereich für Quell-, Ziel- und Overlaydatei
  • Ausgabe von Informationen auf dem Bildschirm (z. B. Anzahl konvertierter Zeichen)
  • automatische Suche der Overlaydatei auf anderen (definierten) Laufwerken
  • Erweiterung des Modulformates, um Informationen unterzubringen wie z. B. Text für Meldung, welche Konvertierung erfolgt oder automatische Dateityperkennung und -umbenennung

Vielleicht (oder hoffentlich) ist nun so mancher ermutigt worden, es auch mal mit dem Programmieren zu versuchen. Wenn dies der Fall wäre, hätte ich mein Ziel erreicht! Über eine Reaktion würde ich mich jedenfalls freuen.