← ST-Computer 12 / 1988

Die Systemvariablen des TOS Teil 2

Grundlagen

Heute kommen wir zum zweiten und letzten Teil der Besprechung der Systemvariablen.

Resetresidente Programme

Die Systemvariablen unterstĂŒtzen eine Möglichkeit, wie Programme einen Reset ĂŒberleben können (Tab. 1). Unmittelbar nach dem Reset werden zuerst alle Interrupts gesperrt und die Peripheriebausteine mit dem ‘reset’-Befehl des 68000 zurĂŒckgesetzt. Ein eventuell vorhandenes “Diagnose-ROM-Modul” wird aufgerufen. Falls es sich um einen Warmstart handelt, wird ‘memcntrl’ in das MMU-RegisterĂŒbertragen, um die alte Speicherkonfiguration wieder herzustellen.

Adr. Name Gr. Std.-Wert Bedeutung
$426 resvalid L $31415926 Magic fĂŒr ‘resvector’
$42A resvector L Vektor fĂŒr resetresidente Programme

Tab. 1: Resetresidente Programme

Wenn ‘resvalid’ den Magiewert $31415926 enthĂ€lt (hier war wohl ein Mathematiker am Werk, denn das sind die ersten Stellen der Zahl Pi), wird noch geprĂŒft, ob der Vektor ‘resvector’ eine sinnvolle Adresse enthĂ€lt (Bits 0 und 24-31 gelöscht). Dann erfolgt der Aufruf der durch ihn bezeichnten Routine.

Dabei muß man beachten, daß ansonsten noch keinerlei Systeminitialisierungen gemacht wurden.

Wenn man nicht gerade das ganze System selbst ĂŒbernehmen will, möchte man wahrscheinlich nach einigen kleinen Aktionen wieder in die normale Reset-Routine zurĂŒckkehren.

Hierzu gibt es zwei Möglichkeiten. Mit ‘jmp (A6)’ springt man vor die Abfrage von ‘resvalid’. Das ist nur möglich, wenn man ‘resvalid’ vorher ungĂŒltig macht, weil man sonst immer wieder von Neuem aufgerufen wird (eine nette Form der Endlosschleife).

Nach einem ‘jmp $24(A6)’ dagegen fĂ€hrt man in der normalen Reset-Routine fort.

Das weicht zwar von der Original-BIOS-Dokumentation ab, doch ist es von ATARI nun selbst so vorgeschlagen worden.

Auch hier ist es natĂŒrlich sinnvoll, eine Kette zu bilden: Bei der Installation merkt man sich, ob ‘resvalid’ gĂŒltig ist, und springt dann am Ende der eigenen Reset-Routine ĂŒber den gemerkten ‘resvector’.

A6 ist ĂŒbrigens das einzige Register, das einen definierten Wert hat. Benutzt werden dĂŒrfen alle Register. Da noch nicht einmal die Stackzeiger sinnvolle Werte haben, dĂŒrfen natĂŒrlich keine Unterprogrammaufrufe gemacht werden!

Vertical Blank Interrupt

Der Vertical Blank Interrupt (VBI) wird jedesmal ausgelöst, wenn der Elektronenstrahl des Monitors ein Bild fertig gezeichnet hat, d.h. 50, 60 oder ca. 72 mal pro Sekunde.

Der VBI-Handler des BIOS erledigt hauptsÀchlich Aufgaben, die die Bilddarstellung beeinflussen. Dazu gehören Cursor-Blinken, der Wechsel der Bildschirmadresse, der Farbpalette oder der Bildschirmauflösung. Ein wenig aus der Rolle fÀllt nur die Floppy-VBL-Routine.

WĂŒrde dies erledigt werden, wĂ€hrend das Bild aufgebaut wird, kĂ€me es zu unschönen Flackererscheinungen.

Der Interrupt-Handler des BIOS benutzt die Systemvariablen aus (Tab. 2).

Adr. Name Gr. Std.-Wert Bedeutung
5466 _frclock L * Zahl der aufgetretenen VBI-Interrupts
$462 _vbclock L * Zahl der ausgefĂŒhrten VBI-Routinen
$452 vblsem W 1 0 sperrt VBI-Routinen
$454 nvbls W 8 Zahl der EintrĂ€ge in ‘vblqueue’
$456 _vblqueue L $4CE Zeiger auf Vektortabelle fĂŒr VBI-Routinen
$4CE _vbl_list 8L * Standard-'vblqueue’

Tab. 2: Vertical Blank-Interrupt

In ‘ Jrclock’ wird die Anzahl der seit dem letzten Kaltstart registrierten VBIs mitgezĂ€hlt.

‘ vbclock’ dagegen registriert die Zahl der tatsĂ€chlich ausgefĂŒhrten VBI-Routi-nen. Denn wenn ‘vblsem’ auf 0 gesetzt wird, wird der VBI ignoriert (bis auf das Erhöhen von ‘Jrclock’). Normalerweise hat ‘vblsem’ den Wert 1.

WĂ€hrend der Abarbeitung der VBI-Rou-tine ist ‘vblsem’ automatisch auf 0 gesetzt, so daß ein VBI, der vor der Beendigung des alten auftritt, ignoriert wird. Dieser Fall kann aber ohnehin nur dann eintreten, wenn der Interrupt-Level der CPU wĂ€hrend einer VBI-Routine heruntergesetzt wird, was normalerweise nicht der Fall ist.

Nachdem alle oben erwĂ€hnten Aufgaben des Systems erledigt wurden, werden noch von anderen Programmen gewĂŒnschte VBI-Routinen aufgerufen.

Dazu zeigt Jblqueue’ auf eine Tabelle mit Adressen von VBI-Routinen. Die Anzahl der Adressen ist durch ‘nvbls’ bestimmt. Ein Nullzeiger (0L) in der VBI-Tabelle zeigt an, daß der “VBI-Slot” unbenutzt ist.

Die korrekte Vorgehensweise, um eine eigene VBI-Routine zu installieren, ist wie folgt:

  1. die durch Jblqueue' adressierte Tabelle nach einem leeren Slot (Nullzeiger) durchsuchen (‘nvbls’-EintrĂ€ge untersuchen).
  2. Wenn ein Slot frei ist, einfach gewĂŒnschte Adresse eintragen.
  3. Wenn alle Slots besetzt sind, gibt es zwei Möglichkeiten. Entweder bricht das Programm mit einer Fehlermeldung ab, oder es verschiebt die gesamte Tabelle in einen eigenen um einen Eintrag grĂ¶ĂŸeren Speicherbereich, trĂ€gt sich dort ein und erhöht ‘nvbls’ um Eins. Dies ist jedoch nur sinnvoll, wenn das Programm resident im Speicher verbleibt, da ein “RĂŒckverschieben” i.allg. nicht ohne weiteres möglich ist.
  4. Um seine eigene Routine wieder zu entfernen, durchsucht man die durch das aktuelle ‘_vblqueue’ und ‘nvbls’ bestimmte Tabelle nach der Adresse der eigenen Routine und ersetzt sie durch OL (inzwischen könnte ein anderes Programm ja die Tabelle verschoben haben).

Die VBI-Routinen werden im Supervisor-Modus aufgerufen und dĂŒrfen alle Register (außer SSP und USP) verĂ€ndern.

GEM installiert ebenfalls eine eigene VBI-Routine, die fĂŒr das Neuzeichnen des Mauszeigers sorgt.

Dabei hĂ€lt sich GEM jedoch nicht an die Spielregeln. Es benutzt nĂ€mlich immer den ersten Slot, auch wenn dieser schon besetzt sein sollte! Daher muß bei AUTO-Ordner-Programmen Punkt 1) dahingehend abgeĂ€ndert werden, daß erst ab dem zweiten Slot gesucht wird.

GEM sollte einem hier also nicht als Vorbild dienen. Ebenfalls sollte man davon absehen, sich vor eine andere VBI-Routine in den gleichen Slot zu hĂ€ngen (durch Verkettung), da man so dieser Routine die Möglichkeit nimmt, sich wieder auszuhĂ€ngen (oder man wird selbst mit abgehĂ€ngt, das ist dann KĂŒnstlerpech).

Die Standard-VBI-Tabelle liegt ĂŒbrigens auch in den Systemvariablen i‘_vbl_lisf), allerdings sollte man sie nie direkt, sondern nur ĂŒber ‘_vblqueue’ ansprechen.

Nach Aufruf dieser Anwender-VBI-Routinen wird noch die Hardcopy-Routine auf gerufen, falls ALT-HELP gedrĂŒckt wurde (s.u.).

Buntes oder Schwarzweißes

Auch zur Verwaltung des Monitors und des Bildes auf ihm gibt es Systemvariablen (Tab. 3).

TOS unterscheidet zwischen einem “logi-'Chen” und einem “physikalischen” Bildschirm.

Adr. Name Gr. Std.-Wert Bedeutung
$44E _v_bs_ad L * Zeiger auf logischen Bildschirm
$45A colorptr L 0 Zeiger auf neu zu setzende Farbtabelle
$45E screenpt L 0 Zeiger auf neu zu setzende Bildschirmadr.
$44C sshiftmd B * Kopie der akt. Bildschirmauflösung
$44A defshiftmd B 0 Defaultauflösung bei Wechsel S/W -> Farbe
$46E swv_vec L Vektor fĂŒr Wechsel S/W <-> Farbe
$448 palmode W 0 * legt Femsehnorm fest (unbenutzt!)

Tab. 3: Bildschirm

Der physikalische Bildschirm ist derjenige, der gerade auf dem Monitor dargestellt wird. Seine Adresse ist demnach direkt in Registern des Video-Chips (Shifters) zu finden.

Auf den logischen Bildschirm beziehen sich dagegen alle gerade stattfindenden Ausgabeoperationen. Dies sind die Textausgaben des VT52-Emulators und die Grafikausgaben der Line A-Routinen. Seine Adresse ist in ‘vbsad’ abgelegt.

Dieses Konzept ermöglicht es, einen Bildschirm unabhĂ€ngig von dem gerade tatsĂ€chlich angezeigten aufzubauen. In vielen FĂ€llen werden beide Adressen natĂŒrlich gleich sein, trotzdem sollte man bei eigenen Routinen, die direkt auf den Bildschirmspeicher zugreifen, stets ‘ v bs ad’ benutzen.

Ganz böse Praxis ist es, direkt auf das vermeintliche Video-RAM zuzugreifen (auch nicht ĂŒber ‘phystop’ minus 32 kB), da es keineswegs immer dort liegen muß.

Die Bildschirmadressen mĂŒssen ĂŒbrigens immer Vielfache von 256 sein, d.h. die untersten 8 Bits sind immer Null.

Um eine neue Farbpalette (16 Words) zu installieren, schreibt man einfach einen Zeiger auf diese nach 'colorptr' . Bei der nĂ€chsten ausgefĂŒhrten VBI-Routine wird die Farbpalette in die entsprechenden Register des Shifters ĂŒbertragen. Dann wird 'colorptr' automatisch gelöscht.

Ähnlich verhĂ€lt es sich mit screenpf, nur daß hier die Adressen des logischen und des physikalischen Bildschirms neu gesetzt werden. .Allerdings wird ‘screenpf anschließend nicht gelöscht, so daß dies bei jedem A BI erneut passiert. Abgesehen von einer gewissen Zeitverschwendung fĂŒhrt das zu Kollisionen mit der XBIOS-Funktion ‘Setscreen’. Daher sollte man entweder nur ‘screenpf oder nur ‘Setscreen’ benutzen und im ersten Fall spĂ€testens beim Terminieren des Programms v auf 0 setzen.

Die aktuelle Bildschirmauflösung wird in ‘sshiftmd’ aufbewahrt. Dabei stehen 0,1 und 2 fĂŒr die niedrige, mittlere und hohe Auflösung. Daher sollte ‘sshiftmd’ nicht verĂ€ndert werden, ohne auch das entsprechende Register im Shifter neu zu setzen. HierfĂŒr gibt es außerdem die XBIOS-Funktion ‘Setscreen’.

Der VBI-Handler erkennt an einem besonderen Signal des Video-Ports, ob der ATARI Monochrom-Monitor angeschlossen ist.

Beim Wechsel Schwarzweiß- zu Farbmonitor bestimmt ‘defshiftmd', ob die niedrige oder mittlere Auflösung eingestellt werden soll. Daher sollte hier 0 oder 1 stehen. Nach dem Kaltstart steht hier 0.

Die neue Auflösung (beim Wechsel zum Monochrom-Monitor natĂŒrlich die hohe) wird nun nach ‘sshiftmd’ und direkt in den Shifter ĂŒbertragen.

Um ein Programm von den verĂ€nderten VerhĂ€ltnissen zu unterrichten, wird ĂŒber den Vektor ‘swv_yec’ gesprungen.

Normalerweise ist hier die Reset-Routine eingetragen, d.h. es wird ein Warmstart durchgefĂŒhrt. Dabei bleiben sowohl ‘sshiftmd’ als auch ‘defshiftmd’ erhalten, so daß nach dem Reset tatsĂ€chlich die gewĂŒnschte neue Auflösung vorliegt.

Der Reset ist jedoch nur deshalb notwendig, weil das GEM sich beim Systemstart einmal auf eine bestimmte Auflösung “eingestellt” hat und daher neu initialisiert werden muß. Beim Wechsel zwischen den beiden Farbmodi ĂŒber den Desktop ist dies noch möglich, aber aus der VBI-Routine heraus, wo der Monitorwechsel bemerkt wird, nicht.

Programme, die ganz ohne GEM aus-kommen (vornehmlich Spiele), können jedoch mit einem Monitorwechsel besser umgehen. Daher sollten Sie in ‘swvvec’ eine eigene Routine eintragen. Hier ist es natĂŒrlich nicht sinnvoll, eine Kette zu bilden, daher reicht es, die alte Adresse zu retten und ‘swv_vec’ beim Verlassen des Programms wieder zu restaurieren. Jetzt wird es kritisch, weil GEM nicht mit der verĂ€nderten Auflösung zurechtkommt.

Nach Abarbeitung der ‘swv vec’ -Routine wird ganz normal im VBI-Handler fortgefahren.

Die Routine wird im Supervisor-Mode aufgerufen und darf alle Register (außer SSP und USP) verĂ€ndern.

In ‘palmode’ schließlich soll die Fernsehnorm festgelegt sein, mit der ein eventuell angeschlossener HF-Modulator arbeitet. 0 steht fĂŒr die NTSC-Norm, alles andere bedeutet PAL-Norm. Soweit mir bekannt, steht hier immer 0. Ein Ă€hnliches Flag findet sich stattdessen im “system header block” (Abb. 2 des 1. Teils).

Konsole - Zeichen fĂŒr Zeichen

Die “Konsole” des ST, bestehend aus Tastatur und dem ĂŒber den VT52-Emula-tor verwalteten Bildschirm, hat auch ihr PlĂ€tzchen im Variablendschungel gefunden (Tab. 4).

Adr. Name Gr. Std.-Wert Bedeutung
$484 conterm B 7 Bitvektor fĂŒr Funktionen der Konsole
$4A8 constate L Vektor fĂŒr Ausgabe auf Konsole
$4AC sav_row W * Zwischenspeicher fĂŒr Cursorzeile bei ESC Y

Tab. 4: Konsole

‘conterm ist ein Bitvektor, der einige Optionen steuert. Der Standardwert ist 7.

Bei gesetztem Bit 0 ertönt bei der Ausgabe von CTRL-G die “Glocke”. Der GEM-Anwender hört diesen Sound, wenn er außerhalb einer Dialog-Box herumklickt. Sonst bleibt CTRL-G stumm.

Die automatische Tastenwiederholung lĂ€ĂŸt sich durch ein gesetztes Bit 1 aktivieren.

Der Tastenklick ertönt nur bei gesetztem Bit 2.

Normalerweise geben BIOS und GEM-DOS bei der Eingabe von der Tastatur nur ASCII- und Scan-Kode zurĂŒck. Bei gesetztem Bit 3 wird zusĂ€tzlich in den Bits 31-24 der RĂŒckgabe werte der aktuelle Tastenstatus wie ihn auch ‘Kbshift’ liefert, abgelegt.

Über den Vektor ‘con_state’ springt das BIOS zu Beginn der ‘Bconout’ - Routine fĂŒr die Konsole. In den Bits 7-0 von Dl findet man das auszugebende Zeichen, die Bits 31-8 sind immer Null (die Bits 15-8 des an ‘Bconout’ ĂŒbergebenen Zeichens gehen verloren).

Die normale Routine gibt die druckbaren Zeichen aus und wertet alle CTRL-Codes und ESC-Sequenzen aus. Nach Registrierung eines ESC setzt sie einfach den ‘conjstate’-Vektor auf eine spezielle ESC-Behandlungsroutine um. Dadurch wird das nachfolgende Zeichen als zum ESC gehörig erkannt und ausgewertet, so daß das ‘A’ aus ‘ESC A’ nicht als ‘A’ auf dem Bildschirm erscheint.

Alle ESC-Sequenzen außer ESC Y bestehen nur aus einem weiteren Zeichen. Daher wird ‘constate’ wieder auf die normale Routine zurĂŒckgesetzt und die Funktion ausgefĂŒhrt.

Bei ESC Y (Setzen der Cursor-Position) wird ‘con state’ auf eine weitere Routine gesetzt, die nichts weiter macht, als das nĂ€chste Zeichen, die neue Cursor-Zeile, in ‘save row’ zwischenzuspeichem und ‘con state’ erneut umzusetzen. Erst beim nĂ€chsten Zeichen, der neuen Cursor-Spalte, ist die Sequenz beendet, ‘con state’ wird wieder auf den Ausgangswert gesetzt und die Funktion ausgefĂŒhrt.

Man kann hier eine eigene Routine ein-hĂ€ngen, die aber dann zumindest kein ESC mehr an die Original-Routine “durchlassen” darf, da diese dann sofort den ‘con_state -Vektor umsetzt, und die eigene Routine damit nicht mehr zum Zuge kommt.

Die ‘con_state’-Routine wird im Supervisor-Modus aufgerufen und darf alle Register (außer SSP und USP) verĂ€ndern.

Hardcopy oder 30 Sekunden Pause?

Adr. Name Gr. Std.-Wert Bedeutung
$4EE _dumpflg W -1 Status der Hardcopy-Routine
$502 scr_dump L Vektor fĂŒr Hardcopy CScrdmp’)
$506 prvjsto L Vektor fĂŒr Ausgabestatus paralleler Port
$50A prvjst L Vektor fĂŒr Ausgabe auf parallelem Port
$50E prv_auxo L Vektor fĂŒr Ausgabestatus serieller Port
$512 prv_aux L Vektor fĂŒr Ausgabe auf seriellem Port

Tab. 5: Hardcopy

Tab. 5 gibt Aufschluß ĂŒber die mit der Bildschirm-Hardcopy verbundenen Systemvariablen.

Der ZĂ€hler ‘ dumpfig’ hĂ€lt den Zustand der ALT-HELP-TastendrĂŒcke bzw. der Hardcopy-Routine fest.

Er steht auf -1 im “Normalzustand” und wird von der Interrupt-Routine, die TastendrĂŒcke verarbeitet, um Eins höher gezĂ€hlt, jedesmal wenn ALT-HELP gedrĂŒckt wird.

Demnach bedeutet eine 0, daß mit dem Ausdruck der Hardcopy begonnen werden soll.

Am Ende des VBI-Handlers wird, wenn ‘ dumpfig’ 0 ist, die Hardcopy-Routine ‘Scrdmp’ (XBIOS #20) aufgerufen. ‘Scrdmp’ ruft die eigentliche Hardcopy-Routine ‘Prtblk’ (XBIOS #36) auf.

Vorher stellt sie noch den von ‘Prtblk’ erwarteten Parameterblock zusammen und setzt ‘ dumpfig’ auf 1. Dies signalisiert somit eine laufende Hardcopy.

'Prtblk' bricht die Hardcopy ab, wenn '_dumpflg’ ungleich 1 wird, also bei einem erneuten ALT-HELP (wobei ‘_dumpflg’ ja 2 wird).

Am Ende von ‘Prtblk’ wird ‘_dumpflg’ auf jeden Fall wieder auf -1 gesetzt.

Daraus folgt, daß man vor dem Aufruf von ‘Prtblk’ ĂŒber das XBIOS ‘ dumpfig’ selbst auf 1 setzen muß.

‘Scrdmp’ springt gleich zu Anfang ĂŒber den Vektor ‘scr_dump’. Hier kann also eine eigene Hardcopy-Routine installiert werden.

Sie kann entweder ebenfalls ‘Prtblk’ aufrufen (mit einem anderen Parameterblock) oder ganz neugeschrieben sein. Sie muß noch nicht einmal ‘ dumpfig’ zurĂŒcksetzen, da dies von ‘Scrdmp’ nachher schon erledigt wird.

Die ‘scr_dump’-Routine wird im Supervisor-Modus aufgerufen und darf die Register D0-D2 und A0-A2 verĂ€ndern.

‘Prtblk’ benutzt zur Ausgabe der einzelnen Zeichen an den Drucker nicht direkt die BIOS-Funktion ‘Bconout’, sondern hat eigene Ausgabe-Routinen, die ĂŒber die Vektoren ‘prv_lst’ oder ‘prv_aux’ springen, je nachdem ob der Drucker parallel oder seriell angeschlossen ist (dies kann im Parameterblock von ‘Prtblk’ festgelegt werden).

Normalerweise sind hier die Adressen der normalen Ausgabe-Routinen eingetragen, die auch ‘Bconout’ aufruft. Bei ‘prv aux’ ist dies allerdings ein Fehler, da hier noch die Abfrage der BIOS-Konfiguration (einstellbar etwa mit dem Kontrollfeld-Accessory bzw. der XBIOS-Funktion ‘Setprt’) erfolgt. Somit ist eine Ausgabe ĂŒber den seriellen Port nur möglich, wenn der serielle Drucker sowohl mit ‘Setprt’ als auch im Parameterblock angewĂ€hlt wurde.

Sinnvoll wĂ€re es, wenn alle Programme ihre Grafikausgaben an Drucker ĂŒber diese Routinen leiten wĂŒrden. Dann wĂ€ren Druckertreiber, die sich in ‘Bconout’ einhĂ€ngen und bestimmte Code-Umwandlungen vornehmen, des Problems entledigt, daß solche Umwandlungen bei Grafikdaten nicht erwĂŒnscht sind.

Ferner hat die Hardcopy-Funktion auch ihre eigenen Routinen fĂŒr den Ausgabestatus (‘prvjsto’ bzw. ‘prv_auxo’). Hier stehen natĂŒrlich normalerweise die entsprechenden Routinen, die auch ‘Bcostat1 aufruft. Diese Routinen werden jedoch von ‘Prtblk’ nie aufgerufen! Das lĂ€stige Warten nach einem ALT-HELP, wenn der Drucker nicht eingeschaltet ist, könnte z.B. vermieden werden, wenn ‘Prtblk’ gleich zu Beginn mit diesen Funktionen feststellen wĂŒrde, ob der Drucker ĂŒberhaupt annahmebereit ist, und gegebenenfalls abbrechen wĂŒrde.

Dies wĂ€re schon eine Anwendung fĂŒr eine eigene ‘scr_dump’ - Routine, die genau diese Abfrage durchfĂŒhrt, bevor sie in die normale ‘scr_dump’ -Routine zurĂŒckkehrt.

Eigene Hardcopy-Ausgabe-Routinen mĂŒssen sich einfach wie die entsprechenden BIOS-Funktionen verhalten, d.h. das auszugebende Zeichen steht ab 6(SP). Die normalerweise bei 4(SP) stehende GerĂ€tenummer ist hier Undefiniert.

FĂŒr eigene Hardcopy-Ausgabestatus-Routinen gilt Entsprechendes.

Ereignisvektoren

Adr. Name Gr. Std.-Wert Bedeutung
$400 etv_timer L Anwendervektor fĂŒr 50-Hz-System-Timer
$404 etv_critic L Vektor fĂŒr Behandlung kritischer I/O-Fehler
$408 etv_term L Vektor fĂŒr Prozeßterminierung
$40C etv_xtra 5L 0 * reserviert fĂŒr zukĂŒnftige ‘etv’-Vektoren

Tab. 6: Ereignisvektoren

Es gibt einige Routinen, die beim Eintreten spezieller Ereignisse (“events”) aufgerufen werden (Tab. 6).

Der ‘etv timer’ wird gleich im Zusammenhang mit dem 200-Hz-Interrupt erklĂ€rt.

Bei Fehlern wĂ€hrend Diskettenoperationen ruft das BIOS den “Critical Error Handler” (CEH) auf, der in ‘etv_critic‘ festgelegt ist. Er soll “kritische” Fehler handhaben und entscheiden, wie darauf reagiert werden soll.

Das TOS hat einen CEH fĂŒr TOS und einen fĂŒr GEM-Programme. Der letztere, vom AES installiert, gibt die bekannten Alert-Boxen wie “Floppy A: antwortet nicht..." aus.

Eigene Laufwerkstreiber oder Programme können den CEH auch ohne weiteres aufrufen.

Auf dem Stack werden dem CEH die BIOS-Fehlemummer (-1...-31) und die Laufwerkskennung (0 fĂŒr A: usw.) ĂŒbergeben (beides ‘words’).

Außerdem kann im Register D0 eine Default-Fehlernummer ĂŒbergeben werden. Dies wird vom CEH des AES aber ignoriert.

Der CEH muß im Supervisor-Modus aufgerufen werden und darf die Register A0-A2 und D0-D2 verĂ€ndern.

Er liefert ein ‘longword’ zurĂŒck. Dies kann eine BIOS-Fehlemummer sein, die der Aufrufer seinerseits zurĂŒckgeben soll. Auch 0 ist erlaubt, um zu signalisieren, daß der Fehler ignoriert werden soll. Der AES-CEH gibt hier den ihm ĂŒbergebenen Fehlercode zurĂŒck, wenn der Anwender die Alert-Box mit ‘ABBRUCH’ beendet.

Ein Wert von $10000 zeigt an, daß die fehlerhafte Operation noch einmal wiederholt werden soll. Der CEH des AES liefert dies, wenn ‘WEITER’ ausgewĂ€hlt wurde.

Ein eigener CEH kann auch installiert werdendst praktikabel aber nur fĂŒr TOS-Programme. Dazu setzt ein residentes AUTO-Ordner-Programm ‘etv_critic’ einfach um. Der eigene CEH wird aber nur bei TOS-Programmen aktiviert.

Der CEH darf BIOS/XBIOS-, aber keine GEMDOS- oder gar AES-Aufrufe machen.

Bei der Terminierung eines Programms mit der GEMDOS-Funktion 'Pterm’l

'PtermOTPtermres’ wird eine in ‘etv_term installierte Routine aufgerufen.

Sie kann vom Programm zur VerfĂŒgung gestellt werden, um eine korrekte Terminierung auch in unerwarteten Situationen (CTRL-C oder Bomben) zu gewĂ€hrleisten. Dazu gehört z.B. das Restaurieren verĂ€nderter Sprung Vektoren.

'etv_term wird im Supervisor-Modus aufgerufen, darf die Register D0-D2 und A0-A2 verĂ€ndern und endet normalerweise mit ‘RTS’. Vorher sollte sie sich selbstverstĂ€ndlich deinstalliert haben.

Es ist allerdings auch möglich, direkt ins Programm zurĂŒckzuspringen, um das ‘Pterm’ zu ignorieren. Dazu mĂŒssen natĂŒrlich alle Register usw. restauriert werden (in C macht man das mit einem longjmp’).

Die ‘etv_term’ -Routine darf GEMDOS-Aufrufe nur machen, wenn sie nicht mehr zurĂŒckkehrt. BIOS/XBIOS-Aufrufe sind dagegen ohne weiteres möglich.

Bei ‘Pterm’/’Pterm()’wird 'etv_term' vor allem anderen aufgerufen, bei ‘Ptermres’ sind allerdings schon die dem Prozeß gehörenden Speicherbereiche vor der Freigabe geschĂŒtzt worden (die Memory -Descriptoren wurden aus der Belegt-Liste entfernt).

Normalerweise zeigt ‘etv_term einfach nur auf ‘RTS’.

Ab ‘etv_xtra’ ist Platz fĂŒr 5 weitere, zukĂŒnftige Event-Vektoren reserviert.

200-Hz-Interrupt

TOS erledigt noch einige weitere periodische Aufgaben, die unabhÀngig von der Bildwiederholfrequenz laufen oder eine höhere PrioritÀt als der VBI haben sollen.

Daher ist der Timer C im MFP so programmiert, daß er alle 5 Millisekunden (also 200 mal pro Sekunde) einen Interrupt auslöst.

Die Variablen hierzu sind in Tab. 7 aufgefĂŒhrt.

Adr. Name Gr. Std.-Wert Bedeutung
$4BA _hz_200 L * Zahl der 200-Hz-Interrupts
$442 __timer_ms W 20 * ms zwischen zwei Systemtimer-Interrupts

Tab. 7: 200-Hz-Systeminterrupt

Die Anzahl dieser Interrupts seit dem letzten Kaltstart wird in ‘_hz_200’ mitgezĂ€hlt. Dies ist also das Analogon zu '_frclock’, aber wesentlich besser geeignet, um Zeitmessungen vorzunehmen, da die Frequenz hier immer die gleiche ist. Die Zeitdauer (eines Benchmarks z.B. erhĂ€lt man also durch einfache Differenzbildung der '_hz_200’-Werte zu Beginn und zum Ende.

Um Überlaufprobleme braucht man sich nicht zu kĂŒmmern, da ‘_hz_200’ erst nach 248,6 Tagen einmal durchgezĂ€hlt ist!

'_hz_200' wird vom BIOS selbst fĂŒr verschiedene Zeitmessungen benutzt.

Direkt mit 200 Hz werden sonst keine periodischen Aufgaben durchgefĂŒhrt. Bei jedem vierten 200 Hz-Interrupt, also mit 50 Hz, wird aber noch einiges erledigt. Dazu gehören die Soundverarbeitung (im Hintergrund ablaufende “Musik" einschließlich des Tastaturklicks) und die automatische Tasten Wiederholung (hier wird das Bit 1 von ‘conterm’ abgefragt).

Zum Schluß werden noch vom Anwender definierbare Routinen aufgerufen. Dazu wird ĂŒber den ‘etv_timer’-Vektor gesprungen. Hier kann man sich also - in einer Kette - einhĂ€ngen. Als erstes Argument auf dem Stack (Word bei 4(SP)) bekommt man die Zahl der Millisekunden seit dem letzten Interrupt ĂŒbergeben. TatsĂ€chlich handelt es sich dabei um ‘_timer_ms’, das dementsprechend immer 20 ist.

Die Anwender-Routinen werden im Supervisor-Modus aufgerufen und dĂŒrfen alle Register (außer den Stackzeigern) verĂ€ndern.

Beim Systemstart hĂ€ngen sich sowohl GEMDOS als auch das AES in den ‘etv_timer’-Vektor ein. GEMDOS benutzt dies, um seine Uhr weiterzusetzen (in 2-Sekunden-Schritten).

Dies ist die Uhr, die fĂŒr die Erstellungszeit bei Dateien verantwortlich ist.

Sonstiges

Die bisher noch nicht besprochenen Systemvariablen sehen Sie in Tab. 8.

Adr. Name Gr. Std.-Wert Bedeutung
S4A2 savptr L Zeiger auf BlOS-Stack fĂŒr Register
$4B2 Jrufl 2L 2 Zeiger auf GEMDOS-BCB-Listen
$516 pun_ptr L Zeiger auf Harddisk-Information
$51E bis_vec 8L Vektoren fĂŒr 'Bconstat'
$53E bi_vec 8L Vektoren fĂŒr ‘Bconin’
$55E bos_vec 8L Vektoren fĂŒr "Bcostat’
$57E bo_vec 8L Vektoren fĂŒr "Bconout'

Tab. 8: Sonstiges

Das BIOS ist “reentrant”, d.h. wĂ€hrend der Abarbeitung eines TRAPs (13 oder 14) darf ein erneuter TRAP ausgelöst werden (von einer Interrupt-Routine oder einem Unterprogramm des BIOS), ohne daß es zu Konflikten beim Retten oder Restaurieren der Arbeitsumgebung der CPU kommt.

Das heißt natĂŒrlich nicht, daß z.B. mitten in einem Flopp>-Zugriff plötzlich eine weitere Floppy-Operation gestartet werden darf. Auf solche Kollisionen muß man selbst achten, so daß man sich meistens auf "harmlose" BlOS-Operationen beschrĂ€nkt (z.B. 'Kbshift', ‘Physbase usw.).

Es sei noch angemerkt, daß GEMDOS und AES in keiner Weise reentrant sind, so daß ein GEMDOS-Aufruf aus einer Interrupt-Routine mehr einem Lottospiel gleicht, wobei die Gewinnchancen allerdings bedeutend höher sind.

Bei einem TRAP befinden sich auf dem Stack bekanntlich die Parameter fĂŒr den jeweiligen Funktionsaufruf, daher können die zu rettenden Register nicht so ohne weiteres ebenfalls dort abgelegt werden, da sich dann die Offsets fĂŒr die Parameter verschieben wĂŒrden.

BIOS hat extra hierfĂŒr einen eigenen kleinen Stack, ‘savptr’ zeigt auf dessen Spitze. Bei einem TRAP 13 oder 14 werden nun einige Register (SR,PC,D3-D7,A3-A7) ab ‘savptr abwĂ€rts dort abgelegt.

Danach ist ‘savptr’ also um 46 erniedrigt worden. Am Ende des TRAPs werden dementsprechend alle Register restauriert und ‘savptr’ wird wieder erhöht.

Die maximal erlaubte Schachtelungstiefe von TRAPs liegt bei 6 (die Original-ATARI-Dokumentation spricht von 3), dies dĂŒrfte wohl mehr als genug sein.

Allerdings ist der TRAP-Aufruf von Interrupt-Routinen aus doch nicht so ohne weiteres möglich, da ein Interrupt auch wĂ€hrend des Rettens der Register auftre-ten kann. Da ‘savptr’ noch nicht erniedrigt wurde, werden schon gerettete Register bei einem nachfolgenden TRAP ĂŒberschrieben. Hier brauchten bloß wĂ€hrend des Arbeitens mit dem ‘savptr’ alle Interrupts gesperrt zu werden.

Dieser Fehler kann umgangen werden, indem man sich in Interrupt-Routinen den ‘savptr’ merkt, auf einen eigenen kleinen Speicherbereich (46 oder sicherheitshalber 92 Byte groß) umsetzt, seine BIOS-Aufrufe macht und anschließend ‘savptr’ wieder restauriert.

Seit einiger Zeit macht der ATARI-Harddisktreiber eine Struktur ĂŒber ’pun_ptr verfĂŒgbar.

Zuerst kommt ein ‘word’, das die Anzahl der gefundenen physikalischen Harddisks angibt. Danach folgen 16 Bytes (fĂŒr die Laufwerke A: bis P:), die angeben, ob das Laufwerk vom Harddisktreiber verwaltet wird (gleich 0) oder nicht (ungleich 0).

Ohne ATARI-Harddisktreiber ist ‘pun_ptr’ wie zu erwarten ein Nullzeiger.

‘_bnfl’ sind zwei Zeiger auf sogenannte BCB-Listen. Dies sind Strukturen, mit denen GEMDOS gepufferte Sektoren verwaltet. Dieses Thema ist zu umfangreich, um hier behandelt zu werden. Ich verweise daher auf [1],

Seit Blitter-TOS gibt es eine einfache Möglichkeit, die BIOS-Funktionen fĂŒr die zeichenrientierten GerĂ€te (‘Bconin’, ‘Bconout’, ’Bconstat’ und 'Bcostat’) zu modifizieren bzw. durch eigene zu ersetzen.

Es gibt hierzu 4 Vektortabellen mit den Adressen der jeweiligen Routinen der BIOS-GerÀte 0 bis 7.

So ist bo_vec[2] z.B. der Vektor fĂŒr die Ausgabe eines Zeichens auf dem Bildschirm.

BIOS unterstĂŒtzt eigentlich nur die GerĂ€tenummern 0 bis 5 und auch die nicht bei allen Funktionen. Nicht definierte Unterfunktionen und die Routinen fĂŒr die GerĂ€te 6 und 7 bestehen nur aus einem RTS’ und geben daher Undefinierte Werte zurĂŒck.

Die Routinen werden im Supervisor-Modus aufgerufen und die Register D0-D2 und A0-A2 dĂŒrfen verĂ€ndert werden. Die Parameter beginnen bei 4(SP) mit der GerĂ€tenummer, die hier nicht mehr beachtet werden muß.

Unbenutzte System variablen...

...gibt es nĂ€mlich auch. Einige haben wir schon kennengelernt, eine komplette Übersicht bietet (Tab. 9). Da sie von ATARI alle benannt wurden, kann man spekulieren, ob sie nur geplant oder nicht mehr notwendig sind.

Adr. Name Gr. Std.-Wert Bedeutung
$486 trpl4ret L 0 * Return-Adresse fĂŒr TRAP 14-Handler ?
$48A criticret L 0 * Return-Adresse fĂŒr CEH ?
$49E ___md L * Platz fĂŒr mehr MDs
$4AE sav_context L 0 * Beginn Post-Mortem-Bereich
$4BE the_env L 0 * Zeiger auf Default-environment
$4CA _auto_path L 0 * Zeiger auf Zugriffspfad fĂŒr AUTO-Ordner
S4F0 prt_abt W 0 * Abbruch-Flag fĂŒr Hardcopy ?
S4F6 _shell_p L 0 * Zeiger auf Arbeitsumgebung r Shellde

Tab. 9: Nie Benutztes

Ferner ist der Bereich von $3EC bis $3FF noch nicht genutzt.

Das Ende der benutzten Systemvariablen liegt zur Zeit bei $59E, was natĂŒrlich nicht so bleiben muß.

Abschließend möchte ich noch hinzufĂŒgen, daß mir die Auswahl und Zusammenstellung der Systemvariablen recht wahllos und unĂŒberlegt zu sein scheint.

Bei einigen scheint die NĂŒtzlichkeit Ă€ußerst fragwĂŒrdig zu sein (wie z.B. ‘themd'), bei anderen ist die Beeinflußbarkeit des TOS geringer als erwartet (z.B. ‘seekrate’).

An andere wichtige Variablen, die man oft vermißt, kommt man meist legal ĂŒberhaupt nicht heran. Hier seien als Beispiel nur der Schreibschutz-Status sowie der auf Grund dessen ermittelte Mediachange-Status der Floppies erwĂ€hnt.

Literatur:

[1] Auf der Schwelle zum Licht, Teil 3, ST-Computer 3/88

Alex Esser