The following article was printed in issue 7 1986 of the magazine „CT".
This article provides information about the overlay interface of TURBO-PASCAL.

Turbo-Overlay privat

Programme von anderen Programmen aus starten unter CP/M 80

Ulrich Fuchs
Thomas Groß-Albenhausen

Aufwendige kommerzielle Programme unter dem Betriebssystem CP/M, wie WordStar oder Turbo-Pascal, bieten dem Anwender die Möglichkeit, andere Programme auszuführen, ohne den CCP einzuschalten, und sich nach deren Abarbeitung automatisch neu zu starten. Das ist besonders angenehm, wenn man öfter zwischendurch kleine Utilities ausführen möchte, ohne sich die Finger wund zu tippen. Der Turbo-Compiler bewerkstelligt dies mit dem File TURBO.OVR. Dieses Overlay läßt sich leicht dazu bewegen, seine Dienste auch außerhalb des Compilers zur Verfügung zu stellen, und das nicht nur in Turbo-Pascal-Programmen.

Turbo-Pascal-Programmierer kennen die eingebaute Prozedur Execute, mit der von einem Turbo-Programm aus andere Programme aktiviert werden können. Laut Handbuch kann Execute zur Ausführung jeder COM-Datei verwendet werden. Es vergißt aber andererseits auch nicht daraufhinzuweisen, daß Vorsicht geboten ist, wenn Programme ausgeführt werden sollen, die nicht mit Turbo-Pascal erstellt sind. Viele Programme ließen sich mit der Execute-Anweisung des Compilers 2.0 entweder gar nicht oder nur fehlerhaft auf dem Apple II der Autoren starten.

WordStar zum Beispiel lief an, versuchte dann aber immer, Laufwerk I zu selektieren. Das existierte aber leider nicht, und der Absturz war unvermeidlich. Trace80 wurde geladen, verabschiedete sich dann aber alsbald mit der Meldung 'Relocating Error'. DDT wurde zwar geladen und gestartet, und man konnte auch damit arbeiten, trotzdem meldete es sich nach dem Start nicht wie gewohnt, sondern mit der Angabe des Programmzählers.

Insgesamt hinterließen die Tests des Execute-Befehls eine gewisse Unzufriedenheit, weil eben doch nicht alles so war, wie man sich das im allgemeinen wünscht.

Wahrscheinlich hängen diese Probleme damit zusammen, daß Turbo-Pascal den Bereich ab 80H manipuliert, wie auch im Handbuch zu lesen war.

Dadurch ist es leider auch nicht möglich, mit Execute Argumente an das aufgerufene Programm zu übergeben. Genau das möchte man aber oft machen. Als Beispiel sei hier nur der transiente Befehl STAT erwähnt. Am gravierendsten ist aber doch der Nachteil, daß man nicht ins aufrufende Programm zurückkehrt.

Unbefriedigend

Mit alledem unzufrieden, wurde untersucht, wie der Turbo-Compiler dieses Problem gelöst hat. Die Aufgabe, das neue Programm zu laden und zu starten, Argumente in 80H zu übergeben und nach Ausführung des gestarteten Programms so nach Turbo zurückzukehren als sei nichts geschehen, obliegt dort dem 1 K Byte langen Programm TURBO.OVR. Dieses Overlay wird nach 8000H geladen und über den Stack mit den notwendigen Informationen versorgt, die es sich selbst in seinen Rückladeteil kopiert. Dieser Rücklader wird dann anschließend kurz unterhalb BDOS verschoben, so daß er das auszuführende Programm möglichst wenig behindert.

Und das klappt alles so reibungslos, daß dieses Overlay auch für beliebige Anwenderprogramme nutzbar gemacht wurde. Die Prozedur EXEC zeigt beispielhaft, wie man TURBO.OVR dazu bewegt, seine Dienste auch in anderen Programmen zur Verfügung zu stellen.

Zunächst wird der Filename des auszuführenden Programms eingelesen und falls erforderlich um die Dateiklassenangabe '.COM' ergänzt. Danach muß untersucht werden, ob diese Datei auf der Diskette überhaupt vorhanden ist. Da das Overlay grundsätzlich nach 8000H geladen wird, gehen unter Umständen wichtige Programmteile verloren, so daß es bei nicht vorhandener Datei zum Absturz kommen kann. Erst nach erfolgreicher Überprüfung wird das Overlay nach 8000H geladen. Damit auch dabei nichts schiefgeht, wird dies durch eine eigene kleine Laderoutine ausgeführt, die als Inline-Code in der Prozedur EXEC enthalten ist. Es wäre zwar auch möglich, Blockread zu benutzen, man muß sich dann aber im klaren darüber sein, daß der Bereich ab 8000H nicht gerade vom Code der Blockread-Anweisung belegt wird. Aus diesem Grund verschiebt sich die Laderoutine in den mit Sicherheit nicht gefährdeten Bereich nach 100H, bevor es das Overlay lädt.

Auch der Filename des auszuführenden Programms darf nicht im Bereich 8000H liegen. Mit der absolute-Deklaration dürfte es in Turbo-Pascal immer möglich sein, das zu gewährleisten.

Das Inline kann natürlich leicht an andere Programmumgebungen angepaßt werden, weil es unabhängig von der Turbo-Runtime-Library ist. Es muß ja schließlich nicht immer ein Turbo-Programm sein, das das Overlay nutzt!

Ist das Overlay geladen, gibt das Inline insgesamt sieben Parameter auf den Stack. Trotz größter Bemühungen ist es den Autoren bei einem dieser Parameter nicht gelungen, seine Funktion zu entschlüsseln. Aber es funktioniert trotzdem. Vielleicht findet es noch jemand heraus.

Über sieben Parameter...

Die Parameter eins bis vier werden von EXEC automatisch verwaltet.

Zeiger auf ein Argument oder Ctrl Z
Zeiger auf FCB
Nummer des Laufwerks
$03F3 ???
Anzahl der zu rettenden Bytes
Zeiger auf den Anfang des zu rettenden Datenbereichs
Rücksprungadresse
 
Das Turbo-Overlay erwartet insgesamt sieben Parameter, die über den Stack übergeben werden Die Funktion des vierten Parameters ist bislang nicht entschlüsselt.
Die restlichen drei müssen von Fall zu Fall angepaßt werden. Der erste Parameter ist ein Zeiger auf ein mögliches Argument im Filenamen. Gibt es keine Argumente, muß dieser Zeiger auf Ctrl Z zeigen. Als nächstes wird ein Zeiger auf den Standard-File-Control-Block für das zu startende Programm übergeben. Der dritte Parameter ist die Nummer des Laufwerks mit dem gewünschten Programm (A : 1, B : 2, ...). An vierter Stelle folgt der große Unbekannte. Turbo übergibt $3F3, wir auch.

Der fünfte und sechste Parameter ermöglichen, Datenbereiche des aufrufenden Programms zu sichern, die nach dem Rückladen wieder verfügbar sind. Der Turbo-Compiler sichert so die Workfile- und Mainfile-Namen. Die zu rettenden Daten müssen dazu in einem zusammenhängenden Bereich des aufrufenden Programms stehen. Das Inline der Prozedur Exec übergibt die Größe und die Startadresse dieses Bereiches.

Die Prozedur EXEC demonstriert dies mit der Konstanten Message. Es kann ein Text eingegeben werden, der nach dem Rückladen in der Konstanten Message verfügbar ist und nach dem automatischen Neustart angezeigt wird. Der Beginn des Datenbereichs ist in diesem Fall $1FE7, die Adresse der Konstanten. Wenn kein Datenbereich gerettet werden soll, muß die Größenangabe '1' betragen. Die Adresse des Datenbereichs ist dann beliebig, darf aber nicht fehlen. Die zu sichernden Daten werden vom Overlay unterhalb BDOS verschoben und vor der Rückkehr ins aufrufende Programm wieder an ihre alte Stelle gebracht. Unterhalb der geretteten Daten liegt der eigentliche Rücklader des Turbo-Overlay.

Natürlich muß dem Overlay bekannt sein, welches Programm es zurückladen soll. Dazu manipuliert man eine Kopie des Overlay, die im Beispiel EXECUTE.OVR heißt, wie folgt. Mit Hilfe von DDT lädt man das Overlay ab $100 und findet ab Adresse $281 den Filenamen 'TURBO COM'. Ihn tauscht man gegen den Namen des aufrufenden Programms aus (hier: EXECUTE COM). In der Fehlermeldung 'TURBO.COM not found' (ab $2A3) ersetzt man ebenfalls den Filenamen. Der Name des Overlays muß natürlich auch im vorbereiteten File-Control-Block des Inlines eingetragen werden!

Wer nicht ständig das Overlay von Diskette laden möchte, beziehungsweise Directory-Einträge opfern möchte, kann das Overlay auch resident an anderer Stelle im Speicher halten, um es bei Bedarf zum Beispiel mit der Prozedur MOVE nach 8000H zu verschieben. Am einfachsten läßt sich das bewerkstelligen, indem man TURBO.OVR in eine Array-Konstante kopiert. Diese Array-Konstante kann dann mit der Include-Anweisung oder dem Editor in den Quelltext eingebunden werden. Selbstverständlich entfällt dann der Lader des Inlines, und es wird nur noch der Teil von READY bis ERROR benötigt.

Bei Turbo-Pascal V 3.0 muß das Overlay übrigens ab $9000 geladen werden. Nach den entsprechenden Adreßänderungen müßte es aber eigentlich genauso funktionieren.

Die Prozedur EXEC macht das Turbo-Overlay für eigene Anwendungen verfügbar und ist zu Demonstrationszwecken in ein kleines Hauptprogramm eingebunden. Die Inline-Anweisungen übergeben die notwendigen Parameter an das Overlay.
[TURBO-Pascal listing] and Z80 source for the [inline part]

In issue 8 86 of the magazine „CT" two corrections were published:

Sonst nur Chaos

Dieser Artikel ist für Turbo-Pascal 2.0 geschrieben und auch nur dort lauffähig, denn nur die Änderung der Adressen von $8000 auf $9000 reicht leider nicht aus. Aber auch für Turbo-Pascal 2.0 muß, um ein in allen Fällen sicheres Laufen zu garantieren, der FCB um zwei Bytes verlängert werden.

Grund: Sie verschieben die Laderoutine an den Anfang der Laufzeitbibliothek. Dort liegen zwei Bereiche, die zum Initialisieren des Terminals benutzt werden. Sind diese nicht benutzt, also 0, tritt kein Fehler auf. Stehen dort aber Werte ungleich null, so wird EXECUTE.OVR nicht geladen.

Entgegen der Behauptung im Artikel können sehr wohl Parameter an das aufgerufene Programm übergeben werden, sie werden von der Routine ausgewertet, deren Adresse in dem 'großen unbekannten' vierten Parameter übergeben wird. Für Pascal 3.0 ist dieser Wert auf $3EE zu ändern.

Ferner finde ich es unverständlich, daß der Autor bei der Parameterübergabe des zu rettenden Bereiches den absoluten Wert $1F7E angibt und nicht den Konstantennamen Message, wie sonst auch gehandhabt. Beim Ausprobieren unter Pascal 3.0, wo Message unweigerlich an anderer Stelle steht, gibt es sonst nur Chaos.
Olaf Krumnow, Hamburg

Geheimnis gelüftet

Das Geheimnis des vierten Parameters ist gelüftet. Es handelt sich um die Startadresse eines Unterprogramms aus dem Runtime Modul des Compilers! Dieses Unterprogramm - bei Turbo 3.0 liegt es bei $3EEh - baut aus einem String einen CP/M-gemäßen FCB auf. Die Startadresse des Strings wird in DE übergeben, das letzte Byte ist 1Ah. Der FCB steht ab 5Ch im Speicher.

Die Konsequenz ist leider, daß das Overlay nicht unabhängig von Turbo arbeiten kann, es sei denn, man schreibt selbst eine solche Routine und übergibt ihre Startadresse als vierten Parameter. Benutzer von CP/M+ haben es einfacher. Sie verfügen über eine ähnliche Routine (BDOS-Funktion 152), die nur darauf wartet, angesprochen zu werden.
Michael Riepe, Hannover

Hier noch eine Zusammenstellung der Adressen, die in den TURBO Versionen unterschiedlich sind:
 TURBO 2.0TURBO 3.0
Lade-Adresse des Overlays8000H9000H
Wildcard Marke03F3H03EEH
Adresse von Message1FE7H20FFH
Die Adressen in der Datei *.OVR (0281H und 02A3H) sind in beiden Versionen gleich.

Scanned by Werner Cirsovius
January 2005
© Heise Verlag