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