Atari brachte mit dem TOS 1.6 (STE) einige Neuheiten ins Betriebssystem, die die speziellen Fähigkeiten dieser Geräte ausnutzen sollen. Bei näherer Untersuchung dieser TOS-Version sowie der verfügbaren Dokumentation [1] kommt ein sehr interessantes und nützliches Verfahren ans Licht, das auch in allen alten Betriebssystemversionen angewendet werden kann (und sollte !): die Informationsbereitstellung mit Hilfedes sogenannten Cookie Jars.
Doch nicht nur im STE wird dieses Verfahren eingesetzt, auch das TOS 3.0 des nun endlich verfügbaren Atari TT macht hiervon ausgiebig Gebrauch.
Viele von Ihnen kennen sicherlich das XBRA-Protokoll zur Verwaltung vektorverbiegender Programme. Nun, ein Cookie besitzt einen sehr ähnlichen Aufbau: eine 4 Bytes große (aus ASCII Zeichen bestehende) individuelle Programm-Identifikation und einen 32 Bits langen Cookie-Wert.
In C könnte man einen solchen Cookie wie folgt deklarieren:
typedef struct {
char cookie_id[4];
/* Identifikations-Code */
long cookie_value; /* Wert des Cookies */
}COOKIE;
cookie_id bezeichnet dabei den Namen (genauer: die Cookie Identifikation) des Programms, welches den Cookie installiert hat.
Um überhaupt etwas mit Cookies anfangen zu können, sollte man zuerst einmal nachfragen ob - und wenn ja, wo - diese im System vorhanden sind. Dazu schaut man sich nur den Inhalt der Systemvariablen _p cookies an, welche an Adresse 0x5a()L (dezimal: 1440) zu finden ist.
Handelt es sich hier um einen NULL-Zeiger, so bedeutet dies, daß noch kein Cookie Jar im Speicher installiert ist (der Jar ist nichts anderes als eine Tabelle, in der alle Cookies festgehalten werden), anderenfalls zeigt _p_cookies auf eben diesen. Mit diesem Zeiger kann nun die Cookie-Tabelle (Jar) angesprungen und gezielt auf bestimmte Cookies durchsucht werden.
Sie fragen, was das für einen Sinn haben soll? Nun, nehmen wir einmal an, Programm A möchte einem anderen Programm seine Existenz anzeigen. Alles, was A dazu tun muß. ist, seine Cookie-ID in den Jar einzutragen, schwupps das war's. Die anderen Programme müssen nur noch den Cookie-Jar nach dieser ID absuchen und wissen sofort, ob A installiert ist oder nicht!!!
An diesem Beispiel wird (wie oben schon angedeutet) ersichtlich, daß jedes Programm. welches am Cookie-Verfahren teilnehmen möchte, eine eigene d.h. individuelle Cookie-Kennung benötigt.
Damit sind wir schon wieder bei einem wichtigen Punkt angelangt, denn die folgenden zwei Punkte sollten bei der Namensgebung (Cookie-ID) unbedingt eingehalten werden:
(1) Kennungen, die mit dem Unterstrich beginnen, dürfen von Otto-Normalverbraucher NICHT (!) benutzt werden, da diese bereits von Atari reserviert sind.
(2) Damit zwei Programme nicht versehentlich dieselbe Kennung erhalten, sollten sich alle Programmierer, die dieses Verfahren anwenden, bei Julian Reschke (erreichbar z.B. in der Mailbox MAUS, Münster) melden, und die von ihnen benutzten Kennungen dort registrieren lassen; hier kann übrigens auch eine Liste aller z.Zt. bekannten Kennungen sowie der Programme, die sie bereitstellen, bezogen werden (dies gilt natürlich nach wie vor auch für XBRA!)
Die Cookie-ID sollte dabei, wie gesagt, aus ASCII Zeichen bestehen. So weit, so gut. Kommen wir nun zur zweiten Komponente unserer COOKIE-Struktur, cookic value.
In diesem Langwort kann eine beliebige (!) Information abgelegt werden, z.B. ein Zeiger auf eine interne Programmstruktur [über die andere Programme beispielsweise bestimmte Betriebsparameter verstellen könnten (beim Mausbeschleuniger MACCEL2 der Fall)] auf einen Text oder sonst etwas; der Phantasie sind hier keine Grenzen gesetzt!
Es versteht sich natürlich von selbst.daß die Bedeutung von cookie_value irgendwo dokumentiert sein sollte! (Was nützt schon ein Eintrag, wenn man nicht weiß, wozu er zu gebrauchen ist?)
Die Aufmerksamen unter Ihnen werden jetzt wahrscheinlich fragen, wieviele Cookies denn eigentlich in den Jar hinein passen? Diese Frage kann natürlich nicht pauschal beantwortet werden, da der Speicherbereich, auf den _p_cookies verweist, in der Regel durch Malloc oder ähnliche Funktionen angefordert wurde - die Größe des Jars ist also variabel!
Um aber trotzdem das Ende dieser Tabelle erkennen zu können, existiert der sogenannte NULL-Cookie (ID „0000“), der als Wert die maximale Anzahl der in den Jar hinein passenden Cookies enthält.
So weit die Theorie. Schauen wir uns nun einige Beispiele an, die die Nützlichkeit dieses Verfahrens noch einmal unterstreichen sollen.
Besonders wichtig (im Hinblick auf portable Programmierung) ist es z.B., festzustellen, ob ein bestimmtes Programm auf einem normalen ST, einem getunten Rechner (etwa mit 68020-Prozessor) oder gar auf dem neuen TT läuft. Denn wie schon in [3] angedeutet, ist es nicht unbedingt sinnvoll, Software zu schreiben, die zwar problemlos auf ST und TT läuft, aber die Fähigkeiten der neuen Maschine nicht auszunutzen versteht.
Dank der vom BIOS installieren System-Cookies (siehe Tabelle 1) ist es aber kein Problem mehr, einen ST vom STE oder TT zu unterscheiden. Es sei noch einmal ausdrücklich darauf hingewiesen, daß diese Cookies erst in TOS-Versionen ab 1.6 (STE) zu finden sind; bei allen älteren Versionen (inkl. 1.4) ist _p_cookies nach einem Kaltstart des Rechners zunächst einmal NULL.
Aufgrund der außerordentlichen Nützlichkeit dieses Verfahrens bot es sich an, einige Hilfsroutinen zu schreiben, die den Umgang mit Cookies erleichtern sollen (Listing 2). Bevor ich auf Aufbau und Wirkungsweise dieser Funktionen eingehe, soll jedoch anhand von Listing 1 ein typischer Anwendungsfall von Cookies demonstriert werden: Wie kann ein Programm feststellen, ob es sich bereits installiert hat? Einige der im Listing verwendeten Funktionen stammen aus dem Cookie-Modul (Listing 2); in der Praxis dürf te es sich als nützlich erweisen, dieses Modul getrennt zu übersetzen und in einer ,,.LIB“-Datei festzuhalten. Bei einer Programmentwicklung wird dann diese Datei automatisch vom Projektmanager an den Linker weitergereicht...
COOKIE_ID | COOKIE_VALUE |
---|---|
_CPU | Art des Prozessors: 0. 10 20 oder 30 für Rechner des Typs 680x0. |
MCH | Maschine (benutztes Gerät): |
0,0 : normaler ST (260er, 520er 1040er) | |
1.0 : Mega ST | |
2,0 : STE | |
3,0 : TT | |
_VDO | Art der Video-Hardware: |
0.0 : normaler ST (einschließlich Mega) | |
1.0 : STE | |
2,0 : TT | |
_SND | beschreibt die Soundmöglichkeiten des Rechners |
Bit 0 : normaler Soundchip | |
Bit 1 : Stereo-Sound (STE und TT) | |
_FRB | Fast-RAM-Bufler: |
Adresse eines 64kB Puffers, der für DMA Transfer genutzt wird (das "Fast-RAM“ des TT ist hierfür nicht geeignet). | |
_SWI | allgemeine Konfigurationswerte (z.Zt. keine näheren Angaben bekannt) |
Tabelle 1: Die System-Cookies des STE und TT
Kommen wir aber nun zu den eigentlichen Hilfsroutinen des Moduls. Sämtliche Funktionen wurden mit dem Turbo C-Compiler (Version 2.0) der Fa. Borland erstellt (By the way, wann kommt Turbo-C++ für den ST?). Sie übernehmen die wichtigsten Operationen, die beim Umgang mit Cookies auftreten können (erzeugen, eintragen, abfragen, löschen etc.) Besitzer eines Nicht-ANSI-Compilers müssen bei der Parameterübergabe die altbekannte Schreibweise übernehmen (Funktionsprototypen gabes bei K&R noch nicht). Ansonsten dürfte aber einer erfolgreichen Übersetzung nichts im Wege stehen...
Doch zur Sache: Ein neuer Cookie kann ganz einfach mit Hilfe der Funktion create_cookie erstellt werden: man über gibt dieser dazu lediglich einen Zeiger auf eine COOKIE-Struktur, die Programmkennung (Cookie ID) sowie den Wert des Cookies (long!). Der so erzeugte Cookie kann nun mittels new_cookie in den hoffentlich vorhandenen Cookie Jar eingetragen werden.
Apropos Cookie Jar: ein Programm, das diesen korrekt installiert, findet sich in verschiedenen Mailboxen (z.B. der PADERBOX) und auch in [2]. Der Einfachheit halber sollte es im Autoordner der Boot-Partition abgelegt werden...
Doch zurück zu new_cookie: Diese Funktion ist nämlich noch nicht 100%ig sauber ausprogrammiert. Falls der installierte Jar schon vollständig belegt sein sollte (habe ich aber noch nicht erlebt), wird der übergebene Cookie einfach nicht eingetragen. Besser wäre es, neuen Speicher anzufordern und den kompletten Cookie Jar umzukopieren (dabei aber nicht vergessen, _p_cookies entsprechend zu ändern!).
Mit Hilfe von get_cookie kann überprüft werden, ob ein bestimmter Cookie bereits im System vorhanden ist (Return-Wert = TRUE); in diesem Fall wird auch gleich der zugehörige Wert in der Variablen value mitgeliefert.
Das Löschen von Cookies (das kann beispielsweise dann notwendig sein, wenn das Programm, das diesen installiert hat, sich wieder aus dem Speicher entfernen will) übernimmt die Funktion remove_cookie. Gelöscht wird übrigens einfach dadurch, daß - nachdem die Cookie-ID gefunden wurde - alle folgenden Cookies (einschließlich des NULL-Cookies) eine Position nach oben gezogen werden.
move_cookiejar ermöglicht es, den kompletten Jar an eine neue Speicherstelle zu kopieren (der zweite Parameter gibt dabei die evtl, neue Größe des Jars an), und cookie_size liefert die Größe des Jars, d.h. die Anzahl der maximal in ihn hineinpassenden Cookies. Zu guter Letzt kann der Inhalt des gesamten Cookie Jars noch mittels print_cookiejar auf die Standardausgabe ausgegeben werden.
Wie gesagt könnten einzelne Routinen noch verbessert werden (new_cookie): außerdem ist zu beachten, daß die Funktionen nicht aus dem Supervisor-Mode aufgerufen werden sollten:
Da alle Routinen nämlich, um auf _p_cookies zuzugreifen, kurz in den Systemmodus schalten, würden sie bei einem Aufruf aus dem Super Mode evtl. wieder in den User-Modus versetzt. (Der Rechner bedankt sich mit einem Busfehler...) Das Problem kann aber dadurch gelöst werden, daß mittels der GEMDOS-Funktion 0x20 (Super) abgefragt wird, in welchem Modus sich der Prozessor zur Zeit befindet. Dazu übergibt man der Funktion als Parameter lediglich eine l(long). Ein Return-Wert von '0' symbolisiert dann den User-, eine '-1' den System-Modus.
So, damit ist eigentlich alles Wichtige gesagt. Ich hoffe jedenfalls, daß dieses praktische Verjähren von möglichst vielen Programmierern angewendet werden wird...
Literatur
[1] STE TOS Release-Notes, Atari Corporation, Oktober '89
[2] "Vorhang auf für die Keksdose", Julian F. Reschke, ST-Magazin 03/90, Seite 62-63
[3] »Wie ST-kompatibel ist der TT?“, Uwe Seimet, ST-Computer 10/90, Seite 57-61