SIO-INTERRUPTS
 
Die
SIO benutzt drei IRQ-Interrupts,um über den seriellen Bus mit den Geräten
zu kommunizieren. Die Interruts sind:
 
IRQ      
Speicherstelle,     
Funktion
         
Länge
 
VSERIR   
($020A,2)           
Serielle Ausgabe abgeschlossen
VSEROR   
($020C,2)           
Serielle Ausgabe benötigt
VSEROC   
($020E,2)           
‹bertragung beendet
 
 
Die
gesamte Programmausführung wird gestoppt, wenn die SIO den
seriellen
BUS für die Datenübertragung benutzt. Für diese Ausgabe übergibt
die SIO ein Byte an das "serielle Ausgabe-Schieberegister" im POKEY-Chip
(SEROUT), welches dann auf den seriellen Bus gesendet wird. Danach wird in eine Warteschleife
gesprungen, bis ein IRQ (VSEROR) vom POKEY-Chip empfangen wird und der SIO mitteilt,
daß SEROUT für ein anderes Byte frei ist. Der IRQ bewirkt einen Sprung
zur SIO-Routine für das Laden von SEROUT mit einem Byte. Diese Schleife wird
solange ausgeführt, bis alle in der DCB-Länge festgelegten Bytes gesendet
wurden. VSEROR ist ein IRQ, der anzeigt, daß die ‹bertragung von Bytes über
den Bus abgeschlossen ist.
 
Die
SIO-Operation für die Eingabe läuft ähnlich ab. Der POKEY-Chip informiert
die SIO, daß ein Byte im seriellen Eingabe-Schieberegister empfangen wurde
(SERIN), indem ein IRQ (VSERIN) erzeugt wird. Die SIO speichert das Byte in einem
Puffer und geht daraufhin in eine Endlosschleife, die durch den nächsten IRQ
d.h. das nächste Byte unterbrochen wird.
 
Wie
man aus den oberen Absätzen ersehen kann, verliert die SIO einige Zeit, während
auf das Signal vom POKEY-Chip gewartet wird. Da die Vektoren für die 3 SIO-IRQ-Service-Routinen
RAM-Vektoren sind, können sie auch durch andere Handler benutzt werden, um die
I/O-Operationen des Systems zu verbessern.
 
Dieses
ist genau der Punkt, der dem 850-Modul ermöglicht, einen eigenständigen
I/O durchzuführen. Der Handler des 850-Moduls überschreibt die SIO-IRQ-Vektoren
mit den moduleigenen IRQ-Routinen. Dieses geschieht beim eigenständigen I/O,
wodurch der 850-Modul-Handler dann Kommandos über den Bus senden kann. Der Modul-Handler
gestattet dann, daß ein Programm weiterläuft, während das 850-Modul
ein I/O-Kommando ausführt.
 
 
INTERRUPTS
Einführung
 
Im
vorangegangenen Abschnitt wurde gezeigt, wie die SIO Interrupts zum Koordinieren
von Datenübertragungen über den seriellen Bus benutzt. Der Computer besitzt
außerdem noch andere Interrupt-Arten, die ein Programm um leistungsstarke Möglichkeiten
erweitern können. Es gibt 2 verschiedene Interrupt-Typen: den maskierbaren Interrupt
(IRQ) und den nicht-maskierbaren Interrupt (NMI). Die Interrupts das ATARI ¥TM¥
Personal Computers sind:
 
Name (Vektor)            
Typ  Funktion            
     Benutzt
                                                        
von**
DISPLAY LIEST
    
(VDLIST)            
NMI  Graphik-Timing           
B
SYSTEM RESET
    
(keinen)            
NMI  System-Initials.         
C
VERTIKAL BLANK
    
(VVBLKI,VVBLKD)     
NMI  Graphik-Display          
C,B
SERIELLE AUSGABE
BEENDET
    
(VSERIN)            
IRQ  Ser. Eingabe             
C
SERIELLE EINGABE
ABGESCHLOSSEN
    
(VSEROR)            
IRQ  Ser. Eingabe             
C
SERIELLE AUSGABE
ABGESCHLOSSEN
    
(VSEROC)            
IRQ  Ser. Ausgabe             
C
POKEY-TIMER 1
    
(VTIMR1)            
IRQ  Hardware-Timer           
B
POKEY-TIMER 2
    
(VTIMR2)            
IRQ  Hardware-Timer           
B
*POKEY-TIMER 4
    
(VTIMR4)            
IRQ  Hardware-Timer           
B
TASTATUR
    
(VKEYBD)            
IRQ  Tastendruck              
C
BREAK-TASTE
    
(keinen)            
IRQ  (BREAK)-Tastendruck      
C
SERIELLER BUS ABLAUF
    
(VPRCED)            
IRQ  Geräte-Ablauf            
N
SERIELLER BUS INTERRUPT
    
(VINTER)            
IRQ  Geräte-Interrupt         
N
* Dieser IRQ wird
im augenblicklichen im Computer vorhandenen OS nicht vektorisiert.
 
** B=Benutzer; C=Computer;
N=Nicht benutzt
 
 
Ist
der Leser nicht mit Interrupts vertraut, dann sei er auf Abschnitt 6 des OS-Manuals
verwiesen, der Information zu diesem Thema enthält. Das Arbeiten mit Interrupts
kann kompliziert sein. Wird z.B. der Tastatur-IRQ-Interrupt ausgeschaltet, dann ignoriert
der Computer sämtliche Tastendrücke mit Ausnahme der (BREAK)-Taste. Obwohl
dieses manchmal von Nutzen sein kann, macht es die Fehlersuche in einem Programm
ein wenig schwierig.
 
 
DER
IRQ-INTERRUPT-HANDLER
 
Das
OS besitzt einen IRQ-Interrupt-Handler, der die verschiedenen IRQs bearbeitet. Dieser
Handler hat RAM-Vektoren für alle IRQs, ausgenommen den (BREAK)-Tasten-IRQ.
Die IRQ-Vektoren werden während des Einschaltens bzw. beim SYSTEM-RESET auf
ihre Werte gesetzt. Die Speicherstellen der IRQ-RAM-Vektoren werden in Abbildung
8.9b gezeigt.
 
Die IRQ-Vektoren sind:
 
 
VIMIRQ Direkter IRQ-Vaktor. Alle IRQs laufen über diese Speicherstelle. VIMIRQ zeigt normalerweise auf den IRQ-Handler. Dem Benutzer ist es aber möglich, diesen Vektor zu ändern, um eigene Routinen für die Interrupts abarbeiten zu lassen.
 
VSEROR IRQ-Vektor POKEYs zur Beendigung der seriellen Ausgabe (siehe Abschnitt 8.2).
 
VSERIN IRQ-Vaktor POKEYs zur Beendigung der seriellen Ausgabe (siehe Abschnitt 8.2).
 
VSEROC IRG-Vaktor POCKEYs zum Abschluss der seriellen Ausgabe (siehe Abschnitt 8.2).
 
VTIMR1 Timer 1-Vektor POKEYs (siehe Abschnitt 8.7 für Information über die POKEY-Timer).
 
VTIMR2
Timer 2-Vektor POKEYs.
 
VTIMR4
Timer 4-Vektor POKEYs.
 
VKEYBD Tastatur-IRQ-Vektor. Das Drücken einer Taste, ausgenommen der (BREAK)-Taste, verursacht diesen IRQ. Der VKEYBD-Vektor kann zum Vorarbeiten des Tastencodes benutzt werden, bevor er durch das OS in ATASCII-Code umgewandelt wird. Dieser Vektor zeigt normalerweise auf die Tastatur-Routine des OS.
 
VPRECD IRQ-Vektor für den Peripherie-Ablauf. Diese Signalleitung ist über den seriellen Bus für Peripherie-Geräte zugänglich. Dieser IRQ wird zur Zeit noch nicht benutzt und zeigt daher normalerweise auf einen RTI-Befehl.
 
VINTER IRQ-Vektor für Peripherie-Interrupt. Diese Signalleitung ist über den seriellen Bus für den Computer zugänglich. VINTER zeigt normalerweise auf ein RTI-Kommando.
 
VBREAK IRQ-Vektor für 6502-BRK-Anweisungen. Immer, wenn ein $00 Opcode (softwaremäßige BREAK-Anweisung) ausgeführt wird, taucht dieser Interrupt auf. Dieser Vektor kann zum Setzen von Unterbrechungs-Punkten innerhalb eines Maschinensprache-Debuggers benutzt werden. VBREAK zeigt normalerweise auf einen RTI-Befehl.
 
 
Die
IRQs werden gemeinsam durch die 6502-Instruktion CLI bzw. SEI ein- oder ausgeschaltet.
Weiterhin haben die IRQS eigene Ein/Ausschalt-Bits. Ein Abschnitt des Hardware-Manuals
führt die IRQs sowie die Ein/Ausschalt-Bits auf.
 
Das
Register IRQEN enthält die meisten der E/A-Bits für die IRGs und ist ein
Nur-Schreib-Register. Das OS besitzt eine für den Benutzer zugängliche
Schattenadresse. Diese Adresse ist POKMSK und wird während des Vertical-Blanks
geschrieben.
 
 
BENUTZEN
DER IRQS
 
Viele
Programme erfordern eine "gesicherte" Tastatur. Der Benutzer kann also
jede Tasten-Kombination drücken, wobei nur die zulässigen akzeptiert und
die anderen ignoriert werden. Der Benutzer kann eine Reihe von IRQs verwenden, um
diese Sicherung zu erreichen. Das Beispiel in Abbildung 8.8 benutzt den VKEYBD-IRQ-Vektor,
um die Kontroll-Taste (CTRL) abzuschalten, d.h. unwirksam zu machen. Die Routine
maskiert außerdem die (BREAK)-Taste, indem der VIMIRQ-Vektor geändert
und der (BREAK)-Tasten-Interrupt ignoriert wird.
 
 
DER
NMI-HANDLER
 
Das
OS besitzt einen NMI-Handler zum Bearbeiten der nicht-maskierbaren Interrupts. Im
Gegensatz zu den IRQs können die NMIs nicht "maskiert" werden, d.h.
sie können nicht über den 6502 ausgeschaltet werden. Alle NMIs ausgenommen
des SYSTEM-RESET-Interrupts, können über den ANTIC-Prozessor ausgeschaltet
werden.
 
Zwei
NMIs, der Display-List-Interrupt und der Vertical-Blank-Interrupt VBLANK) , besitzen
RAM-Vektoren, die vom Programmierer benutzt werden können. Die Vektoren sind:
 
 
    
Name                     
Vektor
    
SYSTEM-RESET             
keinen
    
DISPLAY-LIST-INTERRUPT    VDSLST($0200)
    
VERTICAL-BLANK:
         
IMMEDIATE           
VVBLKI($0222)
         
DEFERRED            
VVBLKD($0224)
 
 
Der
SYSTEM-RESET-NMI besitzt keinen RAM-Vektor. Ein SYSTEM-RESET resultiert immer in
einem Sprung zur Warmstart-Routine des Monitors (siehe Abschnitt 8.5). Der DLI- und
der VBLANK-Interrupt werden in Kapitel 5 bzw. in Anhang I besprochen.
 
0000          
10 POKMSK = $0010
D209          
20 KBCODE = $D209
0208          
30 VKEYBD = $0208
D20E          
40 IRQEN  = $D20E
D20E          
50 IRQST  = $D20E
0216          
60 VMIRQ  = $0216
0000          
70       *=
$0600
0600
78       
80 START  SEI           
IRQs abschalten
0601 AD 16 02 
90        LDA
VMIRG      IRQ-Vektor
durch
0604 8D 4D 06 
0100      STA
NBRK+1     einen vom Benutzer
0607 AD 17 02 
0110      LDA
VMIRQ+1    ersetzen. Alle IRQs
060A 8D 4E 06 
0120      STA
NBRK+2     gehen dann zu
NBRK.
060D A9 45    
0130      LDA
#IRQ&255
060F 8D 16 02 
0140      STA
VIMRQ
0612 A9 06    
0150      LDA
#IRQ/256
0614 8D 17 02 
0160      STA
VIMRQ+l
0617 58       
0170      CLI           
IRQs einschalten
0618 AD 08 02 
0180      LDA
VKEYBD     Tastatur-IRQ
zeigt
061C 8D 43 06 
0210      STA
JUMP+1     nach REP.
061F AD 09 02 
0220      LDA
VKEYBD+1
0622 8D 44 06 
0230      STA
JUMP+2
0625 A9 39    
0240      LDA
#REP&255   Tastatur-IRQ-Vektor
0627 8D 08 02 
0250      STA
VKEYBD     niederwertiges
Byte
062A A9 06    
0260      LDA
#REP/256   des Vektors
062C 8D 09 02 
0270      STA
VKEYBD+1
062F 60       
0280      RTS
              
0290    
*= $0639
0639 AD 09 02 
0300 REP  LDA KBCODE    
Hierher laufen alle
063C 29 80    
0310      AND
#$80       Tastatur-IRQs.
CTRL-
063E F0 02    
0320      BEQ
JUMP       Taste
sedrueckt? Nein,
0640 68       
0330      PLA           
dann springe.. andern-
0641 40       
0340      RTI           
falls CTRL ignorieren.
0642 4C 42 06 
0350 JUMP JMP JUMP      
Dieses ruft den alten
0645 48       
0360  IRQ 
PHA           
Tasten-IRQ.
0646 AD 0E D2 
0380      LDA
IRQST      <BREAK>?
0649 10 04    
0390      BPL BREAK     
Ja-, BREAK-IRQ
064B 68       
0400      PLA           
Andernfalls alter IRG
064C 4C 4C 06 
0410 NBRK JMP NBRK      
Alten IRQ-Vektor auf-
064F A9 7F    
0430 BREAK LDA #$7F      
rufen.
0651 8D 0E D2 
0440      STA
IRQST      <BREAK>
nicht zeigen
0654 A5 10    
0450      LDA
POKMSK
0656 8D 0E D2 
0460      STA
IRQEN
0659 68       
0462      PLA
065A 40       
0464      RTI           
Ruecksprung, Wie ohne
065B          
0470   
 *= $02E2        
BREAK.
02E2 00 06    
0480      .WORD START
 
 
Abbildung
8.8:
"Sicherung"
der Tastatur
 
 
DIE
SYSTEM-VEKTOREN
 
Das
OS besitzt zwei Arten von Vektoren: ROM- und RAM-Vektoren. ROM-Vektoren sind Speicherstellen,
die JMP-Befehle enthalten, welche auf System-Routinen zeigen. Die RAM-Vektoren enthalten
2-Byte-Adressen zu System-Routinen, zu Handler-Einsprung- zeigern (siehe CIO-Abschnitt
8.2) oder zu Initialisierungs-Routinen.
 
Sowohl
die RAM- und ROM-Vektoren werden sich in neuen Versionen des Operating-Systems nicht
ändern. Dieses gilt aber nicht für ihre Inhalte, d.h. ein Programm, das
auf dem jetzigen und allen zukünftigen Systemen laufen soll, muß auf die
Vektoren, anstatt auf die in ihnen befindlichen Adressen zeigen. Die Vektoren, ihre
Inhalte und eine kurze Beschreibung ihrer Funktion findet sich in den Abbildungen
8.9a und 8.9b.
 
 
ROM-Vektoren
 
Name     
Speicher- Funktion
         
stelle
DISKIV   
$E450     Initialisierung
des Disk-Handlers
DSKINV   
$E453     Vektor
für Disketten-Handler
CIOV     
$E456     Vektor
für zentrale I/0-Routine
SIOV     
$E459     Vektor
für die serielle I/O-Routine
SETVBV   
$E45C     Routinen-Vektor
z.Setzen d. System-Timer
SYSVBV   
$E45F     Berechnungen
d.Systems f.d. Vert.Blank
XITVBV   
$E462     Berechnungen
z.Ausgang a.d. Vert.Blank
SIOINV   
$E465     Initialisierung
des seriellen I/Os.
SENDEV   
$E468     Einschaltroutine
z.Senden ü.d.ser.Bus.
INTINV   
$E46B     Interrupt-Handler-Routine.
CIOINV   
$E46E     Initialisierung
des zentralen I/0s.
BLKBDV   
$E471     Blackboard-Modus
(MEMOPAD)-Vektor.
WARMSV   
$E474     Warmstart-Einsprungpunkt
(SYSTEM-RESET).
COLDSV   
$E477     Kaltstart-Einsprungpunkt
(Einschalten).
RBLOKV   
$E47A     Routine
zum Block-Einlegen von Cassette.
CSOPOV   
$E47D     Bereitmachen
für Eingabe (Cassette).
 
 
Ein Beispiel für
die Verwendung eines ROM-Vektors wäre:
 
JSR
CIOV
 
 
Abbildung
8.9a:
ROM-Vektoren
 
Name
  Stelle 
Inhalt Funktionen
VDSLST $0200  
$E7B3  Display-List-Vektor (NMI)
VPRCED $0202  
$E7B3  IRG-Vektor Proceed-Leitung-z.Z.unbenutzt
VINTER $0204  
$E7B3  IRG-Vektor Interrupt-Leitung-z.Z.unben.
VBREAK $0206  
$E7B3  IRG-Vektor So+tware-BREAK
VKEYBD $0208  
$FFBE  IRG-Vektor Tastatur.
VSERIN $020A  
$EB11  IRG-Vektor serielle Eingabe
beendet.
VSEROR $020C  
$EA90  IRG-Vektor serielle Ausgabe
beendet.
VSEROC $020E  
$EAD1  IRQ-Vektor ser. Ausgabe
abgeschlossen
VTIMR1 $0210  
$E7B3  IRQ-Vektor POKEY-Timer
1
VTIMR2 $0212  
$E7B3  IRG-Vektor POKEY-Timer
2
VTIMR4 $0214  
$E7B3  IRG-Vektor POKEY-Timer
4.
VIMIRQ $0216  
$E6F6  Direkter IRD-Vektor zum
IRG-Handler.
VVBLKI $0222  
$E7D1  Immediate NMI-Vektor Vertical-Blank.
VVBLKD $0224  
$E93E  De+erred NMI-Vektor Vertical-Blank.
CDTMA1 $0226  
$xxxx  JSR-Adresse für System-Timer
1.
CDTMA2 $0228  
$xxxx  JSR-Adresse für System-Timer
2.
CASINI $0002  
$xxxx  Initialisierung des Cassetten-BOOTs.
DOSINI $000C  
$xxxx  Initialisierung des Disketten-BOOTs.
RUNVEC $02E0  
$xxxx  DUP-File Run-Vektor
INIVEC $02E2  
$xxxx  DUP-File Initialis.-Vektor.
HATABS $031A  
"P"    Drucker-Geräte
I.D.
    
  $031B  
$E430  Adr. d. Drucker Einsprungpunkt-Tafel.
    
  $031D  
"C"   
Cassetten-Geräte I/D.
    
  $031E  
$E440  
Adr. d. Cassetten Einsprungpunkt-Tafel.
    
  $0320  
"E"    Display-Editor
I.D.
    
  $0321  
$E400  Adr. d. Dis.Edit.Einsprungpunkt-Ta+el.
    
  $0323  
"S"    Bildschirm-Handler
I.D.
    
  $0324  
$E410  Adr. d.B-Handler Einsprungpunkt-Tafel.
    
  $0326  
"K"    Tastatur-Handler
I.D.
    
  $0327  
$E420  Adr. d. Tast.-Handleinsprungpunkt-Ta+el.
    
  $0329  
"x"    Unbenutzter
HATABS-Eintrag   1
    
  $032B  
"x"           
..       
..       
2
    
  $032E  
"x"           
..       
..       
3
    
  $0331  
"x"           
..       
..       
4
    
  $0234  
"x"           
..       
..       
5
    
  $0237  
"x"           
..       
..       
6
    
  $032A  
"x"           
..       
..       
7
    
  $034D  
"x"           
..       
..       
8
    
  $0340  
"x"           
..       
..       
9
 
 
 
 
Ein "X"
zeigt einen sich ändernden Inhalt an.
Ein Beispiel für
die Benutzung eines RAM-Vektors wäre:
 
JSR
CALL
CALL
JMP (DOSINI)
 
Abbildung
8.9b:
 RAM-Vektoren
 
 
              
0010 ; seschrieben von MiChaei Ekbers
 
0600          
0030 START     =
$600
000C          
0040 DOSINI    = $0C
02E7          
0050 MEMLO     =
$2E7
3000          
0060 NEWMEM    = $3000
Dieser Wert legt die
              
0065 ; Groesse fest.
              
0070 ; Diese Routine sichert Speicherplatz
              
0080 ; fuer Assembler-Routinen, indem der
              
0090 ; MEMLO-Zeiger gesetzt wird. Sie laeuft
              
0100 ; als AUTORUN.SYS-File. Sie setzt
              
0110 ; ausserdem MEMLO bei <SYSTEM-RESET>
              
0120 ; zurueck. MEMLO wird auf den Wert von
              
0130 ; NEWMEM sesetzt.
              
0135 ;
              
0140 ; Dieser Teil ist Permanent, d.h. muss
              
0150 ; resident sein. Der DOS-InitVektor
              
0160 ; wurde geaendert und in die Speicher-
              
0170 ; stelle INITDOS+1 & 2 gebracht. Das
              
0180 ; DOS wird initialisiert, worauf
              
0190 ; gleiches mit MEMLO geschieht. INITDOS
              
0191 ; wird bei <SYSTEM-RESET> ausgefuehrt.
0000          
0200          
*= START
              
0210 INITDOS
0600 20 0D 06 
0220          
JSR CYNTHIA     ;DOS INITLIST
0603 A9 00    
0230          
LDA #NEWMEM&255  ;ausfuehren
0605 8D E7 02 
0240          
STA MEMLO
0608 A9 30    
0250          
LDA #NEWMEM/256
060A 8D E8 02 
0260          
STA MEMLO+1
              
0270 CYNTHIA
060D 60       
0280          
RTS
              
0290 ; Dieser Teil wird nur beim Einschalten
              
0300 ; ausgefuehrt und kann danach geloescht
              
0310 ; werden. Diese Routine speichert die
              
0320 ; Inhalte von DOSINI in einem JSR bei
              
0330 ; der Speicherstelle INITDOS+1. Danach
              
0340 ; wird der Wert von DOSINI ersetzt;
              
0350 ; der neue ist die Speicherstelle
              
0360 ; INITDOS.
              
0390 JACKIE
060E A5 0C    
0400          
LDA DOSINI      ;DOSINI
sichern
0610 8D 01 06 
0410          
STA INITDOS+l
0613 A5 0D    
0420          
LDA DOSINI+1
0615 8D 03 06 
0430          
STA INITDOS+2
0618 A9 00    
0440          
LDA #INITDOS&255 ;DOSINI setzen
061A 85 0C    
0450          
STA DOSINI
061C A9 06    
0460          
LDA #INITDOS/256
06lE 85 0D    
0470          
STA DOSINI+1
0620 A5 00    
0480          
LDA NEWMEM&255  ;MEMLO setzen
0622 8D E7 02 
0490          
STA MEMLO
0625 A9 30    
0500          
LDA #NEWMEM/256
0627 8D E8 02 
0510          
STA MEMLO+1
062A 60       
0520          
RTS
062B          
0530          
*= $2E2
02E2 0E 06    
0540          
.WORD JACKIE ;RUN-Adresse setzen
 
 
Abbildung
8.10: MEMLO-ƒnderer