'Anhang' zu Assembler für Einsteiger #5 Interrupt-Routinen des Betriebssystems -------------------------------------- von Tim-Philipp Müller Daß die Interrupt-Routinen die Register entsprechend retten, ist wohl klar... Die POKEY-TIMER werden vom OS nicht benutzt, ebenso wenig wie der DLI. Genauso geht es dem BRK-INTERRUPT, der höchstens auf eine 'Absturzroutine' zeigt. Der BREAK-TASTEN-INTERRUPT signalisiert durch löschen des Flags $11 BRKKEY, daß gedrückt wurde. Geschah dies während einer Input-/Output- Operation (also wenn $42 CRITIC=1), wird BRKKEY nicht auf 0, sondern auf $80 gesetzt. Der TASTATUR-INTERRUPT benutzt folgende Register: $22B SRTIMR Tastenwiederholungszähler $26D KEYDIS =0: Tastatur ein,sonst aus $2D9 KRPDEL Wiederholungsansprechzeit $2DC HELPFG Wenn gedrückt= CH $2F1 KEYDEL Zähler für Entprellung $2F2 CH1 enthält letzten Tastencode $2FC CH Schattenregister zu KBCODE $2FF SSFLAG =$FF:Screenausgabe stop $D209 KBCODE Tastencode-Hardwarereg. Zuerst wird KBCODE mit CH1 verglichen, um festzustellen, ob mittlerweile eine andere Taste gedrückt wurde. Ist dies nicht der Fall, wird geprüft, ob der Zähler KEYDEL schon auf 0 dekremiert wurde. Wenn nicht, wird der Tastendruck als Tastenprellen gewertet und ignoriert. Sollte auf einem 1200 XL Control und F1 gedrückt worden sein, wird das Flag KEYDIS umgeschaltet. Anschließend wird gerade dieses Flag überprüft, und eventuell zum Ende der Routine gesprungen. Sollte Control-1 gedrückt worden sein, wird das Flag SSFLAG umgeschaltet, das vor jeder Bildschirmausgabe auf den Wert $FF überprüft wird (dann wird die Ausgabe angehalten). Wenn gedrückt wurde, wird KBCODE einfach in HELPFG übertragen, ansonsten in CH und CH1. Danach wird KEYDEL auf 3 initalisiert und in SRTIMR der Wert aus KRPDEL übernommen. (siehe auch Tastenwiederholungsroutine im VBI des OS.) Der VBI des OS 'simuliert' quasi fünf Interrupts, nämlich die 5 Systemzähler, von denen jeder einen 16-Bit Abwärts- counter besitzt, der jeden Deferred VBI (Zähler 1 im Immediate VBI) dekremiert wird. Falls einer 0 erreicht hat, wird entweder durch einen Vektor gesprungen (Zähler 1+2) oder ein Flag gesetzt (Zähler 3-5). Nr. Zählregister Vektor/Flag 1 $218,$219 CDTMV1 $226,$227 CDTMA1 2 $21A,$21B CDTMV2 $228,$229 CDTMA2 3 $21C,$21D CDTMV3 $22A CDTMF3 4 $21E,$21F CDTMV4 $22C CDTMF4 5 $220,$221 CDTMV5 $22E CDTMF5 Da die SIO den Zähler 1 braucht, rate ich von einer Verwendung ab. Zähler 3 braucht die SIO nur beim Öffnen eines Kassettenkanals, ansonsten steht auch er für jeden Programmierer frei. Unterprogramme der beiden ersten Timer müssen mit einem RTS enden. Der OS-VERTIKAL-BLANK-INTERRUPT erhöht zuerst einmal die interne Uhr, den drei Byte Zähler RTCLOK $12-$14 ($14 ist das niedrigste Byte). Immer,wenn $13 erhöht wird (etwa alle 5 Sekunden), wird auch $4D ATRACT erhöht. Hat es nach circa sieben Minuten 127 überschritten, wird der automatische Farbwechsel, der das Einbrennen des Bildes in die Bildröhre verhindern soll, gestartet. Automatisch zurückgesetzt wird ATRACT bei jedem Tastendruck. Nun wird der erste System-Timer CDTMV1 erniedrigt und, null erreicht wurde, durch den Vektor CDTMA1 gesprungen. Wenn $42 CRITIC ungleich null ist (dann findet ein zeitintensiver IO-Vorgang statt), wird der VBI beendet. Ansonsten wird $D013 TRIG3 mit seinem Schattenreg $3FA GINTLK verglichen. Wenn ein Unterschied festgestellt wird, wird in eine Endlosschleife verzweigt, da seit dem letzten VBI ein Modul ein- gesteckt wurde. Andernfalls werden einige Werte aus den Schatten- in die Hardwareregister und umgekehrt übertragen: LPENV <- PENV LPENH <- PENH SDLSTH -> DLISTH SDLSTL -> DLISTL SDMCTL -> DMACTL GPRIOR -> PRIOR Nun wird gecheckt, ob der Finescroll- Modus des Editors eingeschaltet ist (FINE $26E bei Bildschirmopen auf $FF) und in diesem Fall der interne Scroll- Zähler VSFLAG $26C um eins erniedrigt, wenn er einen Wert ungleich 0 besitzt (der Editor setzt das Register ent- sprechend, wenn er eine Zeile verschieben will, und wartet, bis die Zeile fertig feingescrollt ist) und auch das Hardware Scrollregister entsprechend gesetzt. Jetzt wird 8 in CONSOL $D01F gesetzt, um den über den Tonausgang simulierten Tastaturlautsprecher abzuschalten. Danach werden die Schattenregister für Farben $2C0-$2C8 in die Hardwareregs übertragen. Ist ATRACT größer 127 (siehe oben), werden die Farben dabei entsprechend abgeändert (die Werte der Schattenregister bleiben aber gleich). Außerdem wird CHBAS in CHBASE, und CHACT in das Hardwareregister CHACTL transferiert. Nun wird der 2.Systemtimer erniedrigt und -falls er 0 ist- durch CDTMA2 gesprungen. Danach geht's weiter mit den Systemtimern drei bis fünf, nur das bei Erreichen von 0 das entsprechende Flag gesetzt wird (CDTMF3-5). Zuletzt folgt die VBI-Routine für die Tastenwiederholfunktion. Über SKSTAT $D20F (Bit 2 ($4) =1: die zuletzt gedrückte Taste ist weiterhin gedrückt) wird geprüft, ob überhaupt eine Taste gedrückt ist. Wenn nicht, wird der Zähler KEYDEL dekremiert (sofern er noch nicht 0 erreicht hat). Ist die Tastatur nicht abgeschaltet, noch immer die selbe Taste gedrückt, und die Frist zur Tastaturentprellung und -wiederholung abgelaufen, wird einfach noch einmal KBCODE in CH übertragen (allerdings nicht bei Control-1 oder Help). Danach wird durch den Vektor VVBKLD $224,$225 (der normalerweise auf XITVBV $E462 zeigt) gesprungen. Eine eigene Deferred-VBI Routine muß deshalb mit JMP XITVBV enden, weil diese Routine alle geretteten Register wieder entsprechend holt. Good Byte