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:
- die durch Jblqueue' adressierte Tabelle nach einem leeren Slot (Nullzeiger) durchsuchen (ânvblsâ-EintrĂ€ge untersuchen).
- Wenn ein Slot frei ist, einfach gewĂŒnschte Adresse eintragen.
- 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.
- 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