Magic Disk 64

home to index to html: MD9311-KURSE-IRQ-KURS_1.2.html
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)



Valid HTML 4.0 Transitional Valid CSS!