Um bei JEDEM BRK wieder in einen defi- nierten Zustand zu gelangen, müssten wir das unterbrochene Programm gänzlich stoppen und anschließend wieder zur BA- SIC-Eingabe zurückkehren. Dies ist eine sehr einfache Öbung. Wir müssen ledig- lich den "Müll" den Prozessor und Be- triebssystem-BRK-Routine auf dem Stapel abgelegt haben, mit Hilfe von sechs auf- einanderfolgenden "PLA"-Befehlen von dort wieder wegholen, und anschließend einen BASIC-Warmstart durchführen. Noch einfacher und sauberer geht es jedoch, wenn wir den Stapelzeiger gleich nochmal neu initialisieren. Hierbei werden näm- lich auch nicht mehr benötigte Daten, die evtl. vor Auslösen des Interrupts auf dem Stack abgelegt wurden, entfernt. Demnach kann jedes Programm mit folgen- dem Interrupt abgebrochen werden: LDX #$FF ;Stapelzeiger per X-Register TXS ; zurücksetzen JMP $E386 ;BASIC-Warmstart anspringen. Es ist ein beliebiges Programm daß immer am Ende eines Interrupts stehen kann. Es bricht zusätzlich auch den Interrupt ab und kehrt zur BASIC-Eingabe zurück. Folgendes Programmbeispiel nutzt diese Methode. Zuvor holt es sich jedoch die vom Interrupt auf dem Stapel abgelegten Informationen, und gibt Sie in hexadezi- maler Schreibweise auf dem Bildschirm aus. Dadurch haben Sie eine ganz simple Debugging-Kontrolle, mit der Sie Fehler in eigenen Programmen abfangen können. Wird z.B. ein bestimmter Programmteil angesprungen, der einen BRK-Befehl enthält, so wird diese Routine ange- sprungen, die Ihnen die Registerinhalte, sowie Zustand des Programmzählers, des Statusregisters und des Stapelzeigers zum Zeitpunkt der Unterbrechung auf dem Bildschirm ausgibt. Hier das Listing: ;*** Hauptprogramm
1000: LDX #$0B ;BRK-Vektor auf 1002: LDY #$10 ; eigene Routine 1004: STX $0316 ; bei $100B 1007: STY $0317 ; verbiegen 100A: BRK ;Interrupt auslösen ;*** Interruptroutine 100B: LDA #$69 ;Adresse Infotext 100D: LDY #$10 ; ($1069) laden 100F: JSR $AB1E ;Text ausgeben 1012: PLA ;Inhalt Y-Register 1013: JSR $103E ; ausgeben 1016: PLA ;Inhalt X-Register 1017: JSR $103E ; ausgeben 101A: PLA ;Akkuinhalt 101B: JSR $103E ; ausgeben 101E: PLA ;Statusregister 101F: JSR $103E ; ausgeben 1022: PLA ;PC Low-Byte holen 1023: STA $02 ; u. zwischenspeich. 1025: PLA ;PC High-Byte holen 1026: JSR $103E ; u. ausgeben 1029: LDA #$9D ;'CRSR' left 102B: JSR $FFD2 ; ausgeben 102E: LDA $02 ;PC Low-Byte holen 1030: JSR $103E ; u. ausgeben 1033: TSX ;Stapelzähler nach 1034: TXA ; Akku übertragen 1035: JSR $103E ; u. ausgeben 1038: LDX #$FF ;Stapelzähler 103A: TXS ; initialiseren 103B: JMP $E386 ;BASIC-Warmstart
Im Bereich von $1000-$1009 setzen wir, wie gewohnt, den BRK-Interruptvektor auf den Beginn unserer Routine, der in die- sem Beispiel bei $100B liegt. In $100A wird ein BRK ausgelöst, der die Inter- ruptroutine sofort anspringt. Diese gibt nun, mit Hilfe der Betriebssystemroutine "STROUT" bei $AB1E, einen kleinen Info- text auf dem Bildschirm aus. Hiernach holen wir uns Y- und X-Register, sowie Akku und Statusregister vom Stapel (in dieser Reihenfolge), und zwar in dem Zustand, den sie zum Zeitpunkt, als die Unterbrechung eintrat, innehatten. Die Werte werden dabei einzeln mit der Rou- tine bei $103E auf dem Bildschirm ausge- geben. Diese Routine wandelt den Akkuin- halt in eine hexadezimale Zahl um, die auf dem Bildschirm angezeigt wird. Hin- ter dieser Zahl gibt sie zusätzlich ein Leezeichen aus, das als optische Tren- nung zwischen diesem, und dem nächsten Wert dienen soll. Die genaue Beschrei- bung erspare ich mir hier, da sie ja eigentlich nichts mit unseren Interrupts zu tun hat. Im Bereich von $1022-$1032 wird nun zunächst das Low-Byte des alten Pro- grammzählers vom Stapel geholt und in der Speicherzelle $02 zwischengespei- chert. Hieraufhin wird das High-Byte geladen und auf dem Bildschirm ausgege- ben. Abschließend wird das Low-Byte wie- der aus $02 herausgeholt und ebenfalls ausgegeben. Zwischen den beiden Zahlen schicken wir noch ein 'CRSR links'- Zeichen auf den Bildschirm, da das Lee- zeichen, das durch unsere Ausgaberoutine zwischen High- und Lowbyte steht, nicht erscheinen soll. Die beiden Werte sollen ja zusammenhängend ausgeben werden. Abschließend wird der Stapelzeiger in den Akku transferiert und ebenfalls aus- gegeben. Da wir zu diesem Zeitpunkt ja schon alle Daten, die durch den Inter- rupt auf den Stapel gelegt wurden, wie- der von dort entfernt haben, entspricht der Stapelzeiger genau dem Wert, der zum Zeitpunkt der Unterbrechung vorhanden war. Abschließend wird der Stapelzeiger wie oben beschrieben zurückgesetzt, und das Programm verzweigt auf den BASIC-Warm- start, womit wir den Interrupt ohne Ver- wendung von "RTI", unter Korrektur aller ggf. erfolgten Änderungen am Stapel, verlassen hätten. Versuchen Sie doch jetzt einmal BRKs von anderen Adressen aus (durch "POKE Adres- se,0:SYS Adresse", oder in eigenen Pro- grammen auszulösen. Sie werden hierbei immer wieder zu unserer kleinen Regi- steranzeige gelangen, die das System automatisch wieder ins BASIC zurück- führt. Benutzen Sie jedoch nach dem erstmaligen Initialiseren des Programms nach Möglichkeit keinen Speichermonitor mehr, da diese Hilfsprogramme nämlich ähnlich arbeiten wie unser Programm, und somit den von uns eingestellten BRK- Vektor auf ihre eigenen Routinen verbie- gen. Experimentieren Sie einmal ein wenig mit den BRK-Unterbrechungen, um sich die Eigenarten von Interrupts im Algmeinen anzueignen. Im nächsten Kursteil werden wir uns dann um die Ansteuerung der NMI- und IRQ-Unterbrechungen kümmern, bevor wir uns dann im dritten Teil endlich den interessantesten Interrupts, den Raster- IRQs nämlich, zuwenden werden.
(ub/ih)