 |
Ein Interrupt ist ein Programmwechsel aufgrund
eines externen Ereigniserkennungscodes. Das Unterbrechungsprogramm nennen wir
Interruptserviceroutine. Interrupt
steht für Unterbrechung - gemeint ist die Unterbrechung des
aktuellen Hauptprogrammes (das kann auch ein Unterprogramm, oder aber im
Extremfall eine bereits laufende ISR sein), um ein Notfallprogramm einzuschieben. |
 |
Versuchen wir das an einem (natürlich hinkenden) Beispiel dazustellen: Du
gehst einkaufen. Programm ist, Deinen Einkaufszettel abzuarbeiten. Du stehst in
der Kaufhalle und entdeckst, dass ein Hosenknopf fehlt! Aha, ein
unvorhergesehenes Ereignis (auf welches wir allerdings vorbereitet sein
müssen (oder besser: vorbereitet sein sollten!)) - Interrupt
(Unterbrechung) - Notprogramm "einschleifen" und Knopf sowie Sternchenzwirn kaufen.
Danach Einkauf an der Folgestelle fortsetzen, wo unterbrochen wurde. Das genau
macht eine Interruptserviceroutine - nur nicht mit Hosenknöpfen und
Sternchenzwirn ;-)
|
 |
1. Interrupt-Prinzip der Z80 CPU
2. Interrupt-Freigabe und -sperrung der Z80 CPU
3. Interrupt-Verhalten der Z80-CPU
4. NMI - Non Mascable Interrupt
5. Interrupt-Mode 0
6. Interrupt-Mode 1
7. Interrupt-Mode 2
8. Beispielprogramme für den LC-80
9. Verwandte Themen
|
 |
|
 |
|
 |
mehr
Interrupt gibt's hier und hier
geht's zum MS-DOS-Interrupt |
 |
Interrupts
spielen vor allem in der Echtzeitverarbeitung eine entscheidende Rolle,
tun aber auch in jedem PC fast unbemerkt vom Nutzer ihren Dienst - z.B.:
- wenn eine beliebige Taste gedrückt wird
- das
Drücken einer Taste ist kein zeitrelevantes Ereignis - d.h., es tritt
nicht durch den Programmablauf zwangsläufig ein (es kann wenige Sekunden, oder aber Tage dauern, bis eine
Taste gedrückt wird)
- der
Prozessor könnte auch die ganze Zeit über alle Tasten (natürlich
schnell, aber eben: nacheinander!) fragen: Bist du
gerade gedrückt (das sind immerhin 102 Tasten auf 'ner
Standardtastatur)?
- wenn
die Maus bewegt wird
- das
Bewegen der Maus Taste ist wiederum kein zeitrelevantes Ereignis - d.h., es tritt
nicht durch den Programmablauf zwangsläufig ein (es kann wenige Sekunden, oder aber Tage dauern, bis eine
Mausbewegung ausgeführt wird)
- der
Prozessor könnte auch die ganze Zeit über alle Tasten
und die Maus (natürlich schnell, aber eben: nacheinander!) fragen: Bist du
gerade gedrückt oder gerade bewegt worden?
-
wenn sich der Bildaufbau
verändert
- das
Aufbauen eines neuen Bildes ist auch kein zeitrelevantes Ereignis -
d.h., es tritt nicht durch den Programmablauf zwangsläufig ein (es kann
wenige Sekunden, oder aber Tage dauern, bis ein tatsächliches Ergebnis
zur Anzeige ausgerechnet wurde (stell' mal 'nen Sortieralgorithmus
grafisch dar, dann merkst Du das)
- der
Prozessor könnte auch die ganze Zeit über alle Tasten (natürlich
schnell, aber eben: nacheinander!) fragen: Bist du
gerade gedrückt (das sind immerhin 102 Tasten auf 'ner
Standardtastatur), hat sich evtl. die Maus bewegt - und/oder: liegt
ein neuer Bildaufbau an?
|
 |
Was irgendwie gemacht
werden muss, bevor ein Interrupt an einer Z80-CPU wirksam werden kann:
- Interruptvektor (IV) laden
- Bausteine initialisieren
und deren Interruptmöglichkeit freigeben
- Interruptmode (IMO)
per Befehl setzen
- Int-Freigabe
- hoffentlich hab'
ich jetzt nix vergessen - auch lang' nicht mehr aktiv programmiert ;-)
|
 |
|
 |
Alle Interrupt-Operationen
beginnen mit einer Interruptbestätigung. Das ist dadurch gekennzeichnet,
dass gleichzeitig IORQ und M1 aktiv sind. Dieser Zustand wird von den
peripheren Schaltkreisen dekodiert, und der relevante, den Interrupt
anmeldende Schaltkreis liefert einen vorgegebenen, d. h. diesem vorher
einprogrammierten Interruptvektor auf den Datenbus. Nach der obligatorischen
Rettung des PC bei Interrupt wird durch den Pointer, dessen niederwertiger
Teil der gelieferte Vektor und dessen höherwertiger Teil das I-Register
bilden, der Speicher adressiert und 2 Byte gelesen, die als Adresse der
Interruptserviceroutine in den PC geladen werden. |
 |
Ein Interrupt ist eine Unterbrechung eines gerade
ausgeführten Programms, damit der Prozessor auf bestimmte Forderungen
reagieren kann. Damit wird ermöglicht, dass mehrere Programme durch eine CPU
abgearbeitet werden können, wenn es die äußeren Umstände erfordern. Man
lenkt die CPU durch geschaltete Interrupts und geeignete Priorisierung auf
die zum Zeitpunkt jeweils wichtigste Aufgabe. Gegenüber einer zyklischen
Abfrage, ob eine Aufgabe zu erfüllen ist, werden Zeit und Speicherraum
eingespart, da sofort reagiert werden kann und die Latenzzeit nicht durch
die Abfrageperiode bestimmt ist. Die zyklische Abfrage wird auch als Polling
bezeichnet. Die durch die verschiedenen Interruptvarianten gegebenen
Möglichkeiten haben einen effektiven Einfluss auf die Leistungsfähigkeit
eines Mikroprozessorsystems. |
 |
Übersicht über Interruptmodi der Z80 CPU
|
 |
CPU-Aktion |
IFF1 |
IFF2 |
Bemerkungen |
Rücksetzen der CPU |
0 |
0 |
Interrupts (außer NMI) sind gesperrt |
Befehl DI |
0 |
0 |
|
Befehl EI |
X |
X |
P/V := IFF2 |
Befehl LD A, I |
X |
X |
P/V := IFF2 |
Befehl LD I, R |
X |
X |
|
NMI-Quittierung |
0 |
X |
|
Rückkehrbefehl RETN |
IFF2 |
X |
IFF1 := IFF2 |
INT-Quittierung |
0 |
0 |
|
Rückkehrbefehl RETI |
X |
X |
|
Beeinflussung der Interruptfreigabe-Flip Flops |
 |
Die Aufgabe eines Interruptsystems besteht darin, auf vorliegende
Interruptanmeldungen aus der Peripherie durch Einschieben einer zugehörigen
Programmfolge (ISR) in das laufende Programm zu reagieren. Die
Interruptbearbeitung von peripheren Geräten stellt die Alternative zur
programmgestützten Peripheriebearbeitung durch zyklische Abfrage (Polling)
dar. Sie ermöglicht eine Bearbeitung auf Anforderung und belastet den
Prozessor zeitlich geringer. Die Einsatzmöglichkeiten werden durch die Länge
des einzuschiebenden Unterprogramms und durch Art und Anzahl der
interruptfähigen Peripherieelemente bestimmt. Damit der Prozessor möglichst
schnell auf eine Interruptanforderung aus der Peripherie reagieren kann,
besitzt die CPU unterschiedlich priorisierte Interrupteingänge. Es ist die
Anmeldung von nichtmaskierbaren Interrupts (NMI) und von maskierbaren
Interrupts (INT) möglich. Ein NMI unterbricht grundsätzlich jede
Programmabarbeitung, während ein INT softwaremäßig gesperrt werden kann und
somit für die Dauer der Sperrung unwirksam bleibt. Die CPU hat die
Möglichkeit der Auswertung eines Interruptvektors, der vom peripheren
Systemelement im Interruptquittierungszyklus erzeugt wird und mit dessen
Hilfe die Startadresse der ISR gebildet werden kann. Hierdurch kann im
Programmablauf auf die Abfrage aller Peripherieelemente nach der Quelle der
Interruptauslösung verzichtet werden. Die Auswahl des zur Anmeldung
kommenden Interrupts bei mehreren Anforderungen durch verschiedene Geräte
erfolgt in der Peripherie durch Bildung einer Interruptprioritätenkette.
Diese Prioritätenkette wird hardwaremäßig durch Kaskadierung der
interruptfähigen Elemente gebildet. Der Prozessor wird also auch bei der
Festlegung der Interruptwertigkeit nicht zusätzlich belastet. Die
Leistungsfähigkeit des Interruptbetriebs wird außerdem durch komfortable
CPUBefehle verbessert, die den Tausch der Registersätze bzw.
Registerrettungsoperationen in den Stackbereich des Hauptspeichers bewirken.
Somit kann nach Ablauf der eingeschobenen ISR der alte
Programmbearbeitungszustand wiederhergestellt werden.
Die in den nachfolgenden Abschnitten angeführten Zeitangaben sowie
Diskussionen zu Einschwingverhältnissen beziehen sich vordergründig, wegen
dessen größerer Verbreitung, auf das 2,5-MHz-System UB880. Es werden aber
alle notwendigen Zusammenhänge (Formeln, Parameter) angegeben, so dass
unkompliziert auf die Verhältnisse im 4-MHz-System UA880 geschlossen werden
kann. |
 |
Für die Bearbeitung von
Unterbrechungsanforderungen sind bei der CPU U880 zwei Interrupteingänge
vorhanden. Diese unterscheiden sich durch Priorität und Maskierbarkeit. Der
NMI (nicht maskierbarer Interrupt) besitzt die höchste Interruptpriorität
und kann per Programm nicht gesperrt werden, so daß die CPU unbedingt ihr
laufendes Programm unterbricht, wenn irgendeine periphere Einheit diesen
Interrupt anfordert. Im allgemeinen ist dieser Interrupt für sehr wichtige
Ereignisse, z. B. Ausfälle, Havarien und andere nichtvorhersehbare
Geschehnisse, reserviert.
Der INT (maskierbarer Interrupt) kann per Programm gezielt gesperrt und
freigegeben werden. Das kann z. B. notwendig sein, wenn zwar eine
Interruptserviceroutine niedriger Priorität abläuft, aber eine Unterbrechung
bestimmter Programmteile aufgrund des geforderten Echtzeitverhaltens nicht
tragbar ist. Dann wird gerade dieser Programmteil durch Sperrung des
maskierbaren Interrupts geschützt. Freigabe bzw. Sperrung werden in einem
Flipflop zwischengespeichert. Durch die Befehle EI (ermögliche Interrupt)
und DI (sperre Interrupt) wird dieses Flipflop entsprechend gesetzt bzw.
rückgesetzt. |
 |
Der Prozessor U880 reagiert auf externe Anforderungen zur Unterbrechung
der laufenden Programmfolge mit der nachfolgend dargestellten Priorität:
- Busanforderung durch BUSRQ
- Interruptanmeldung durch NMI
- Interruptanmeldung durch INT
Die Anforderung des Prozessorbusses durch das Steuersignal BUSRQ dient
zur Ausführung einer DMA-Operation (s. Abschn. 4.3). Dieser direkte
Speicherzugriff kann nach jedem abgearbeiteten Maschinenzyklus in die
Programmbearbeitung eingeschoben werden, wenn das interne BUSRQ-Flipflop
zuvor gesetzt wurde. Der Zustand dieses Flipflops wird in Abhängigkeit vom
Signal am BUSRQ-Eingang der CPU während der steigenden Flanke des letzten
Taktes eines jeden Maschinenzyklus ermittelt. Im Gegensatz hierzu erfolgt
die Auswertung der Zustände der Interruptflipflops (NMI-Flipflop,
INT-Flipflop) nur am Ende des letzten Maschinenzyklus eines vollständig
abgearbeiteten Befehls. Falls zu diesem Zeitpunkt ebenfalls eine
Busanforderung vorliegt, wird diese vorrangig abgearbeitet.
Das Setzen des NMI-Flipflops erfolgt zustandsgesteuert durch das Aktivwerden
des entsprechenden Signals am NMI-Eingang des Prozessors. Zum Anmelden eines
nichtmaskierbaren Interrupts ist somit nur ein Impuls mit einer bestimmten
Impulsbreite als NMI-Signal notwendig. Der Zustand des INT-Flipflops wird
dagegen durch Auswertung des INT-Eingangs mit der letzten steigenden
Systemtaktflanke des letzten Maschinenzyklus jedes Befehls bestimmt, da die
Interruptanmeldung nochmals durch die peripheren Systemelemente
zwischengespeichert wird. Die CPU-interne Auswertung der Interruptflipflops
erfolgt ebenfalls nur zu diesem Zeitpunkt und bewirkt bei einer erkannten
Anmeldung das Einschieben der entsprechenden Interruptquittierungszyklen.
Die Maskierung des INT-Eingangs erfolgt durch die beiden CPU-internen
Interruptfreigabeflipflops IFF1 und IFF2. Das Freigabeflipflop IFF1 wirkt
hierbei als Maskierungsflipflop, und Flipflop IFF2 dient zur Protokollierung
des Zustands von IFF1 in NMI-Serviceroutinen. Beide Flipflops können
softwaremäßig durch die CPU-Befehle EI und DI gesetzt bzw. rückgesetzt
werden. |
 |
Aus bestimmten noch zu erläuternden Gründen sind in der CPU U880 zwei
Freigabeflipflop enthalten, die IFF1 und IFF2 genannt
werden. Dabei bildet IFF1 das Flipflop, das den Befehlsablauf
direkt beeinflusst.
In bestimmten Situationen ist das Zwischenspeichern des aktuellen Inhalts
von IFF1 erforderlich. Dafür ist IFF2 vorgesehen.
Ein Rücksetzen der CPU bewirkt, dass sowohl IFF1 als auch IFF2
zurückgesetzt werden, so dass die Annahme von Interruptanforderungen
gesperrt ist. Durch den Befehl EI kann die Freigabe von maskierbaren
Interrupts bewirkt werden. Nach Ausführung des Befehls EI wird die Annahme
eines angemeldeten Interrupts so lange gesperrt, bis der dem Befehl EI
folgende Befehl ausgeführt ist. Wenn ein Interrupt angenommen wird, werden
sowohl IFF1 als auch IFF2 zurückgesetzt, um weitere
Unterbrechungen zu verhindern, bis in der Interruptserviceroutine eine
Freigabe durch Ausführung des Befehls EI erfolgt. Der Zweck der Verzögerung
der Freigabe für die Ausführung eines Befehls ist, zu sichern, dass nach der
Freigabe noch ein Rücksprung aus der Interruptserviceroutine (RETI oder RETN)
möglich ist. Damit wird ein Einschachteln mehrerer Interruptserviceroutinen
vermieden. |
 |
In allen bisherigen Fällen war der Inhalt von IFF1 und IFF2
identisch. Bei der Quittierung eines nichtmaskierbaren Interrupts wird
einerseits wiederum IFF1 rückgesetzt, um maskierbare
Interruptforderungen zu unterbinden; andererseits wird aber der Inhalt von
IFF2 nicht verändert. Damit bleibt in der CPU der
Interruptfreigabezustand, der vor Einschachtelung der
NMI-Bearbeitungsroutine aktuell war, erhalten. Er kann nach Beendigung der
NMI-Routine wiederhergestellt werden. Hierzu dient der Rückkehrbefehl RETN,
bei dessen Ausführung u. a. IFF2 in IFF1 kopiert wird.
Eine weitere Möglichkeit der Testung des IFF2 bieten die
CPU-Befehle LD A,I und LD A,R. Bei diesen Befehlen wird der Zustand von IFF2
in das Paritätsflag P/V geladen. Er ist somit testbar und kann für
Programmverzweigungen verwendet werden. In Tafel unten sind zusammenfassend
alle Aktionen dargestellt, die einen Einfluss auf den Zustand der
Interruptfreigabeflipflops haben. |
 |
CPU-Aktion |
IFF1 |
IFF2 |
Bemerkungen |
Rücksetzen der CPU |
0 |
0 |
|
Befehl DI |
0 |
0 |
|
Befehl EI |
1 |
1 |
|
Befehl LD A, I |
- |
- |
P/V := IFF2 |
Befehl LD A, R |
- |
- |
P/V := IFF2 |
NMI-Quittierung |
0 |
- |
|
Rückkehrbefehl RETN |
IFF2 |
- |
IFF1 := IFF2 |
INT-Quittierung |
0 |
0 |
|
Rückkehrbefehl RETI |
- |
- |
|
Beeinflussung der
Interruptfreigabeflipflops |
 |
Neben den beiden
Interrupteingängen besitzt die CPU U880 den
BUSRQ-Steuereingang für die
Busfreigabesteuerung, der insbesondere bei DMA-Betrieb zur Anwendung kommt.
Die CPU reagiert auf Unterbrechungsforderungen über diese drei
Steuereingänge (NMI,
INT,
BUSRQ) mit folgender
Rangfolge:
- Busanforderung mittels
BUSRQ
- nichtmaskierbarer Interrupt
NMI
- maskierbarer Interrupt
INT
|
 |
Eine Busanforderung kann hierbei von der CPU am Ende eines jeden
Maschinenzyklus bestätigt werden. Demgegenüber erfolgt die Abfrage der
Interruptlinien NMI und
INT nur jeweils am Ende jedes
letzten Maschinenzyklus eines Befehls. Bei der Bestätigung einer
Interruptforderung (NMI bzw.
INT) fügt der Prozessor einen
Quittierungszyklus in die Befehlsbearbeitung ein. Die hierbei durchgeführten
Aktivitäten sind am Ende der Tafel 3.1.13 aufgeführt. Bild unten zeigt
zusammenfassend das CPU-Verhalten bei Unterbrechungsforderungen im Flussbild.
Das Zeitverhalten des Prozessors bei einer Busanforderung ist im Bild 3.1.8
dargestellt. Die Einbeziehung des DMA-Betriebs in das Gesamtsystem ist im
Abschnitt enthalten. Die CPU-Aktivitäten bei den Interruptbetriebsarten sind
nachfolgend zusammengefasst. |
 |
|
 |
Nichtmaskierbarer Interrupt Nichtmaskierbarer Interrupt. Ein nichtmaskierbarer Interrupt wird
jederzeit durch die CPU anerkannt. Der
NMI kann asynchron angemeldet
werden. Damit wird intern ein Auffangflipflop gesetzt. Die zeitlichen
Darstellungen entsprechen in den Relationen zum Takt ansonsten dem
INT und sind auf das
Auffangflipflop bezogen. Wenn ein
NMI anerkannt wird, führt die CPU statt der geholten Instruktion
einen Rückstart zur Adresse
0066H aus. Dieser Rückstart
entspricht einem implizit adressierten Unterprogrammaufruf auf spezifische
Adressen der Seite 0 des Speichers. Man beachte, dass aber keine der sonst
vorhandenen acht Rückstartadressen eingesetzt wird. |
 |
Maskierbarer Interrupt
Die Ausführung einer durch einen maskierbaren Interrupt (INT) angeforderten
Programmunterbrechung kann programmäßig gesperrt werden. Diese Maskierung
geschieht durch Beeinflussung der CPU-internen Interruptfreigabeflipflops
IFF1 und IFF2. Beide Freigabeflipflops werden durch den Befehl EI gesetzt
und erlauben somit die Ausführung der am INT-Eingang des Prozessors
anstehenden Interruptanmeldung. Das Rücksetzen der Flipflops kann
softwaremäßig durch den Befehl DI erfolgen. Während der Abarbeitung dieser
beiden Befehle wird prozessorintern die Interruptfreigabe gesperrt. Das
bedeutet, dass nach Ausführung dieser Befehle kein
Interruptquittierungszyklus in die Programmfolge eingeschoben werden kann.
Der Sinn dieser Maßnahme besteht darin, dass nach Interruptfreigabe (Befehl
EI) am Ende eines Unterprogramms (z. B. ISR) noch der nachfolgende
Rücksprungbefehl (RET, RETI oder RETN) zum höheren Programmniveau ausgeführt
wird. Eine etwaige Interruptanmeldung wird dann erst in diesem Programmteil
wirksam. Dadurch werden Verschachtelungen der Interruptbedienroutinen
vermieden und der Stackbereich des Speichers weniger belastet.
Die Programmunterbrechung erfolgt ansonsten bei Interruptfreigabe sofort
nach dem Befehl, an dessen Ende die Interruptanmeldung vom Prozessor erkannt
wurde. Die CPU reagiert daraufhin durch Einschieben eines
Interruptquittierungszyklus. Voraussetzung hierfür ist, dass keine Bus- oder
NMI-Anforderung vorliegt, die sonst zuvor bearbeitet werden. Der Prozessor
U880 kann in drei Interruptbetriebsarten (IM0, IM1, IM2) arbeiten, die sich
im wesentlichen durch unterschiedliche Wirkung und Leistungsfähigkeit
unterscheiden.
Die Anwendung des INT-Interruptsystems ist vor allem für die schnelle und
leistungsfähige Bedienung der peripheren Systemelemente vorgesehen. Die
Systemelemente (PIO, SIO, CTC, DMAC) sind hardwaremäßig für die
Interruptbearbeitung zugeschnitten. Sie beinhalten eine automatische
Interruptprioritätenauswahl und erzeugen für die Bearbeitung in der
leistungsfähigsten Interruptmode (IM2) einen Interruptvektor. Für die
Interruptverarbeitung von Mikrorechnern, die ohne die peripheren
Systemelemente realisiert werden, besitzt der Prozessor U880 zwei weitere
Interruptbetriebsarten (IMO, IM1). Diese Interruptmoden sind insbesondere
für die Verwendung spezieller Interruptschaltkreise (interrupt controller)
bzw. für die Anwendung in kleinen, sehr speziellen Mikrorechnern vorgesehen.
Die Annahme einer Interruptanforderung über die INT-Linie erfolgt durch den
Prozessor, wenn das interne Interruptfreigabeflipflop IFF1 gesetzt ist und
wenn an der CPU keine NMI- oder Busanforderung ansteht. Die Bearbeitung
eines DMA-Betriebs oder einer nichtmaskierbaren Interruptanmeldung wird
ansonsten zuvor durchgeführt. Der Prozessor U880 unterbricht nach dem
Erkennen der Interruptanmeldung unter den genannten Bedingungen sofort die
Programmbearbeitung und schiebt einen Interruptquittierungszyklus in die
Befehlsfolge ein. Hierbei erfolgt automatisch das Rücksetzen der
CPU-Freigabeflipflops (IFF1 und IFF2) und somit die Sperrung weiterer
Interruptforderungen der Peripherie. Der erste Maschinenzyklus der
Interruptquittierung ist durch das gleichzeitige Auftreten aktiver Ml- und
IORQ-Signale gekennzeichnet und wird so von dem üblichen CPU-Maschinenzyklus
der Befehlsbearbeitung unterschieden. Die pheripheren Elemente können somit
die Interruptquittierung erkennen und entsprechend reagieren (die
Systemelemente setzen das interne Interruptbearbeitungsflipflop und senden
einen Interruptvektor aus). Die CPU fügt in diesen Maschinenzyklus der
Quittierung automatisch zwei WAIT-Zustände ein, die ein verzögertes
Aussenden des IORQ-Signals bewirken. Hierdurch wird erreicht, dass in der
Peripherie eine hardwaremäßig realisierte Interruptprioritätenkette bei
Auftreten des Signals IORQ einen eingeschwungenen Zustand erreicht. In
Abhängigkeit vom Auftreten dieses Signals im Interruptquittierungszyklus
erfolgt vom ausgewählten, priorisierten Systemelement das Belegen des
Datenbusses mit dem Interruptvektor. Bei anders realisierten
Peripherieelementen kann in Abhängigkeit vom lORQ-Signal ebenfalls die
Übernahme des Datenbusses vorgenommen werden. Die Voraussetzung für die
Belegung des Datenbusses ist aber, dass durch alle peripheren Elemente bei
aktivem M1-Signal der Interruptanmeldungszustand nicht verändert werden
darf. Die weitere Reaktion des Prozessors U880 in diesem Zyklus ist nun von
der vorgewählten Interruptbetriebsart abhängig. Diese Interruptmoden können
softwaremäßig durch die Befehle IMO, IM1 und IM2 gewählt werden. Nach
Anlegen eines RESET-Signals an die CPU nimmt die IS U880 automatisch die
Betriebsart IMO ein. Das Einstellen der Interruptbetriebsart erfolgt
üblicherweise im Initialisierungsteil des Programms. Aufgrund der
unterschiedlichen CPU-Reaktion und der spezifischen Peripherie bei den
verschiedenen Interruptmoden kann i. allg. die Interruptbetriebsart im
Programmablauf nicht geändert werden. |
 |
Der "Non Mascable
Interrupt" - also der "nicht maskierbare Interrupt" von im Sinne:
"nicht sperrbar", ist die Operation mit absolutem Vorrang vor allen anderen
Signalen sowie auch Befehlen. Er wird nach Beendigung des letzten laufenden
Befehls in jedem Falle ausgeführt - es sei denn, vorab hat ein anforderndes
BUS-Request-Signal BUSRQ |
 |
keinerlei softwaretechnische Vorbereitung notwendig, außer dass auf
Adresse
0066H ein sinnvolles Programmstück
oder ein Sprung zu selbigem existiert, welches mit
ED 45H (RETN) abgeschlossen wird |
 |
hardwaremäßige Unterbrechung höchster Priorität mit Sprung auf Adresse
0066H |
 |
wie der Name schon sagt, kann dieser Interrupt nicht verhindert werden -
höchstens das Eingangssignal NMI auf konstantes H-Potential verhindert
dessen Nutzung |
 |
die Nutzung des NMI sollte eine Konstante im Programm sein - also
sinnvolle Anweisungen direkt ab 0066H einsetzen |
 |
|
 |
Die Ausführung einer NMI-Anmeldung kann programmäßig nicht verhindert
werden. Die laufende Programmabarbeitung wird nach Setzen des internen
NMI-Flipflops sofort im nächsten Befehl durch die Quittierung des Interrupts
unterbrochen, vorausgesetzt, es lag keine BUSRQ-Anmeldung vor. Die Anwendung
dieser höchstwertigen Interruptaumeldung ist deshalb für Rechnerfunktionen
vorbehalten, die eine sehr schnelle Reaktion des Prozessors erfordern.
Beispiele hierfür sind das Reagieren auf bevorstehende Ausfälle der
Rechnerversorgungsspannung und die Bearbeitung von vorrangigen Informationen
aus der Peripherie (z. B. Alarmsignale).
Nach Annahme einer NMI-Anmeldung schiebt der Prozessor einen
NMI-Quittierungszyklus in die Befehlsabarbeitung ein. Der Prozessor rettet
in diesem Quittierungszyklus den aktuellen maskierbaren Interrupts und setzt
den Programmzähler auf die Restartadresse 0066H.
Im M1-Zyklus der NMI-Quittierung erfolgt auf dem Adressbus die Ausgabe des
letzten, aktuellen Programmzählerstands. Der dadurch im Hauptspeicher
adressierte Befehlskode wird aber nicht mehr durch den Datenbus des
Prozessors übernommen. Der Befehlsholezyklus (op-rode fetch) wird somit von
der CPU ignoriert. Anstelle dieses nicht bearbeiteten Befehls wird
prozessorintern ein Restartbefehl zur Programmspeicherzelle 0066H
ausgeführt. In den beiden nachfolgenden Maschinenzyklen
(Speicherschreibzyklen M2, M3) erfolgt deshalb die Auslagerung des zuvor
ausgesendeten aktuellen Programmzählerstands (PC) in den Stackbereich des
Hauptspeichers. Als neuer PC-Stand wird die Restartadresse 0066H gebildet,
die im Befehlsholezyklus des nachfolgenden Befehls auf dem Adressbus
ausgegeben wird. Gleichzeitig erfolgt im NMI-Quittierungszyklus die
Rücksetzung des CPU-internen Interruptfreigabeflipflops IFF1, um die
Anmeldung und Ausführung von maskierbaren Interrupts zu verhindern. Der
Zustand des Freigabeflipflops IFF2 wird hierbei nicht verändert. Dieses
Flipflop dient zur Speicherung des Zustands, den IFF1 vor der NMI-Anmeldung
einnahm. Der Zustand des Freigabeflipflops IFF2 kann softwaremäßig durch
Ausführung entweder des Befehls LD A, I oder des Befehls LD A, R ermittelt
werden. Nach Abarbeitung eines dieser Befehle beinhaltet der Wert des
Paritätsflags (Bit FZ) den Zustand von IFF2.
Die Rückkehr aus der NMI-Bearbeitungsroutine (ISR) in die unterbrochene
Programmbearbeitung erfolgt durch den Befehl RETN. Das CPU-Zeitverhalten bei
der Ausführung dieses Befehls ist im Bild oben dargestellt. Der Prozessor
stellt bei der RETN-Befehlsabarbeitung in Hinsicht auf die Inhalte
des Programmzählers und des Stackpointers sowie auf den
Interruptbearbeitungszustand der CPU den Programmbearbeitungszustand wieder
her, der vor Anmeldung und Ausführung des nichtmaskierbaren Interrupts
vorlag. Hierzu speichert er den vor der NMI-Anmeldung aktuellen
Programmzählerstand aus dem Stackbereich des Hauptspeichers in die CPU
zurück. Durch zweimaliges Inkrementieren des Stackpointers wird ebenfalls
der ursprüngliche Wert des SP erreicht. Der PC-Stand in der
NMI-Serviceroutine geht verloren. Der Inhalt des Interruptfreigabeflipflops
IFF2 wird in das Flipflop IFF1 kopiert. Da das Freigabeflipflop IFF2 durch
die Ausführung der NMI-Quittierung und -Bearbeitung nicht automatisch
verändert wird, ergibt sich der Interruptbearbeitungszustand, der in der
unterbrochenen Programmfolge aktuell war. Voraussetzung hierfür ist jedoch,
dass in der NMI-Serviceroutine kein EI- bzw. DI-Befehl erfolgte, da diese
Befehle beide Freigabeflipflops beeinflussen. Zur erneuten Freigabe der
NMI-Anmeldeleitung erfolgt außerdem die Rücksetzung des CPU-internen
NMI-Flipflops. |
 |
Existert eine Freigabe und
wurden die entsprechenden Bausteine im Interrupt-Status bei ihrer
Programmierung freigeggeben, können sie bei Eintreffen eines externen
Ereignisses einen Interrupt im schnellen Mode 0 anmelden. Aus
Interruptvektorregister sowie dem Inhalt des betreffenden Interrupt-Adressinhalts des anmeldenden Bausteines ergibt sich eine direkte
Adresse, welche nach Beenden des letzten Befehls nach eintreffen des
Interrptereignisses aufgerufen wird, nachdem der aktuelle PC auf den
Stackpointer abgelegt wurde. |
 |
Diese Mode ist in der Ausführung
ähnlich wie beim Prozessor U808. Die CPU U 880 betrachtet das von der
unterbrechenden Einheit auf dem Datenbus plazierte Wort als Befehl und führt
diesen entsprechend aus. Das bedeutet, dass nach
INT-Annahme nicht der
Speicher angesprochen wird, sondern ein spezieller Interruptcontroller. Es
kann dabei jeder Befehl auf den Datenbus gebracht werden, jedoch sind
natürlich die Einbytebefehle RST p besonders vorteilhaft.
Die CPU fügt in den Bestätigungszyklus automatisch zwei zusätzliche
WAIT-Zustände ein, so dass die Befehlsausführung um zwei Taktzustände
verlängert ist. Damit ermöglicht die CPU den Aufbau und das Einschwingen
einer externen Prioritätskette, unabhängig von den speziellen peripheren
Schaltkreisen des Systems U880. Die Ausführung eines
RESET durch die CPU
veranlasst diese, automatisch die Interruptmode 0 einzunehmen, da das die
allgemeine Mode ist. |
 |
Hier wird günstigerweise eine der möglichen Einsprungadressen via Befehl "angesprungen"
- sie lauten im einzelnen:
- C7H - Einsprungadresse ist dann die 0000H
- CFH - Einsprungadresse ist dann die 0008H
- D7H - Einsprungadresse ist dann die 0010H
- DFH - Einsprungadresse ist dann die 0018H
- E7H - Einsprungadresse ist dann die 0020H
- EFH - Einsprungadresse ist dann die 0028H
- F7H - Einsprungadresse ist dann die 0030H
- FFH - Einsprungadresse ist dann die 0038H
... dabei spielt der Einsprung auf technisch/theoretisch keine
Rolle, da dies einen System-Neustart bedeutet. |
 |
die Kurzrufadressen sollten nicht von anderen Elementen des Betriebssystems
genutzt werden |
 |
da die einzelnen Adressen nur im Abstand von 3 Byte liegen, macht es
Sinn, hier nur die Bytes einer Sprungadresse (möglichst in den
RAM-Bereich - das macht ihre Nutzung flexibel) |
 |
hier sendet der entsprechend anfordernde Baustein selbst den
niederwertigen Teil einer Ansprungadresse - der höherwertige Anteil wird
aus dem Inhalt des Interrupt-Vektorregisters der CPU entnommen |
 |
das adressierte Byte muss direkt den Befehl enthalten |
 |
mehrere Bausteine sind via Adress-Logik kaskadierbar (max. jedoch 128
Bausteine im Gesamtsystem) |
 |
jeder Kanal verfügt über ein separate Interrupt-Logik, wobei der erste Kanal
jedoch grundsätzlich die höhere Priorität besitzt |
 |
Die Interruptbetriebsart IM0 der CPU U880 dient zur Ausführung eines
Befehlskodes, den das interruptanmeldende periphere Element im
Interruptquittierungszyklus auf den Datenbus legt. Das erste Byte (op-code
fetch) der Instruktion wird hierbei in dem durch aktive M1- und IORQ-Signale
gekennzeichneten Maschinenzyklus der Interruptquittierung vom Datenbus
übernommen. Erfordert die Befehlsausführung weitere Befehls- bzw.
Datenzyklen, werden diese als gewöhnliche Maschinenzyklen (memory read,
memory write, input, output) ausgeführt. Sie haben jedoch die Besonderheit,
dass der Befehlszählerstand (PC) jeweils nicht erhöht wird. Der PC-Stand vor
der Interruptanmeldung bleibt somit erhalten. Da dieser ungültige
Programmzählerstand auf dem Adressbus ausgegeben wird, muss hardwaremäßig
abgesichert werden, dass keine Fehlreaktionen im Hauptspeicher bzw. in der
Peripherie ausgelöst werden. Bei Anwendung dieser Interruptbetriebsart
bietet sich der RST-Befehl (restart) zur Ausführung besonders an, da er ein
sehr leistungsfähiger Einbytebefehl ist. Bei hardwaremäßiger Realisierung
der Datenbusübernahme im Interruptquittierungszyklus bleibt bei Verwendung
dieses Befehls der Aufwand in Grenzen. Zudem können durch Spezifizierung der
Bits D3, D4 und D5 des Befehlskodes acht unterschiedliche
Unterprogrammstartadressen (00H, 08H, 10H, 18H, 20H, 28H, 30H, 38H)
aufgerufen werden. Die Interruptbearbeitung in dieser Mode (IMO) ist
zusammenfassend im Bild 4.2.4 dargestellt. Sie wirkt ähnlich wie die
Interruptbearbeitung des Prozessors U808 (s. Abschn. 2.1.). Diese
Interruptbetriebsart ermöglicht deshalb die Nutzung evtl. vorhandener
peripherer Einheiten des Systems U808.
Die Interruptbetriebsart IM1 des Prozessors U880 realisiert eine einfache,
ohne periphere Unterstützung wirkende Interruptbearbeitung durch Ausführen
eines Programmrücksprungs zur Speicherplatzadresse 003811. Hierbei wird
automatisch der aktuelle Programmzählerstand durch Laden in den Stackbereich
des Speichers gerettet. Im Bild 4.2.5 ist das Zeitverhalten des
Interruptquittierungszyklus in dieser Interruptbetriebsart dargestellt. Der
Prozessor reagiert in der Mode IM1 ähnlich wie bei der Bearbeitung einer
NMI-Anforderung. Der Programmzähler wird jedoch auf den Wert PC = 3811
gesetzt. Die Anwendung dieser Interruptbetriebsart ist deshalb in
Mikrorechnern denkbar, die ohne periphere Systemelemente realisiert werden
und die nur zwei Interruptebenen benötigen. Als erste Ebene könnte dann der
nichtmaskierbare Interrupt verwendet werden, während der in der Mode IM1
betriebene maskierbare Interrupt die zweite Interruptebene darstellt. Die
Interruptbearbeitung in der Betriebsart IM1 ist zusammenfassend im Bild
4.2.6 dargestellt.
Die Interruptbetriebsart IM2 der CPU U880 ist die leistungsfähigste der drei
genannten Moden. Sie führt einen indirekt adressierten CALL-Befehl zu einer
beliebigen Programmspeicherzelle im Adressierungsraum aus. Der zur
indirekten Adressierung benötigte 16-bit-Pointer wird hierbei aus dem
I-Register der CPU (H-Byte) und einem Interruptvektor (L-Byte) gebildet.
Dieser Interruptvektor wird im M1-Maschinenzyklus der Interruptquittierung
vom Prozessor gelesen. Er muss deshalb zu diesem Zeitpunkt von dem
priorisierten, interruptanmeldenden peripheren Gerät auf den Systemdatenbus
gelegt werden. Das entsprechende Zeitverhalten ist im Bild 4.2.7
dargestellt. Die Leistungsfähigkeit dieser Interruptmode ist vor allem
dadurch gegeben, dass die peripheren Systemelemente U855 (PIO), U856 (SIO),
U857 (CTC), U858 (DMAC) den angeforderten Interruptvektor automatisch bei
der Quittierung ihrer Interruptanmeldungen aussenden. Somit ist hierfür kein
zusätzlicher Hardwareaufwand notwendig. Des weiteren gestattet die
Interruptmode IM2 die Zuordnung von Interruptbearbeitungsroutinen (ISR) zu
den einzelnen interruptfähigen peripheren Systemelementen. Wegen der
Spezifizierung der Interruptvektoren durch die Peripherie können in einem
Rechnersystem bei unverändertem I-Register der CPU bis zu 128 verschiedene
ISR aufgerufen werden. Hierdurch wird Programmaufwand zur Feststellung des
interruptanmeldenden Geräts vermieden. Die Reaktion des Prozessors auf die
Interruptanmeldung erfolgt deshalb sehr schnell und leistungsfähig. Die
Bearbeitung dieser Interruptbetriebsart durch die CPU ist zusammenfassend im
Bild 4.2.8 als Flussbild dargestellt. Da die effektive Anwendung der
Interruptmode IM2 durch die Reaktionen der Systemperipherie unterstützt
wird, werden die Haupteigenschaften der peripheren Elemente bei der
Interruptbearbeitung in dieser Interruptbetriebsart im nachfolgenden
Abschnitt näher beschrieben. |
 |
|
 |
|
 |
Hier wird eine 16-Bit Adresse aus Vektoren (Zeiger)
zweier Geräte gebildet
und das erste eines Zweibyte-Blocks in einer "Interruptvektortabelle"
im Speicherbereich angesprungen
- dieser repräsentiert dann den Startpunkt der "Interruptserce-Routine" |
 |
Im System U880 ist eine
sehr leistungsfähige Mode in Verbindung mit den zugehörigen
Peripherieschaltkreisen implementiert. Diese Mode ist die leistungsfähigste,
da mit einem einzigen von der unterbrechenden Einheit zu liefernden Byte ein
indirekter Unterprogrammaufruf auf einem beliebigen Speicherplatz
spezifiziert werden kann.
Bei Anwendung dieser Mode baut der Programmierer im Speicher eine Tabelle
auf, in der die Anfangsadressen der Interruptserviceroutinen stehen. Die
Startadressen umfassen 16 bit, belegen also zwei Speicherplätze. Deshalb ist
das von der unterbrechenden Einheit gelieferte Byte immer geradzahlig (d0
= 0), und es lassen sich nur 128 Startadressen mit einem Byte definieren.
Dieses Byte bildet als Vektor den niederwertigen Teil der Startadresse. Die
CPU setzt aus dem I-Register (höherwertiger Teil der Startadresse) und dem
Vektor den 16-bit-Pointer zusammen., Bei der Anwendung der Mode 2 ist zu
beachten, dass eine geeignete Initialisierung vorausgehen muss, da beim
Auftreten eines RESET an der CPU die Mode 0 für Interrupts gesetzt und das
I-Register auf den Wert 00H gebracht wird. Das erste Byte, das durch den
Pointer adressiert wird, ist der niederwertige Teil der Adresse in der
Starttabelle für Interruptserviceroutinen.
Für die Ausführung eines Interrupts in dieser Mode werden 19 Taktzustände
benötigt. Das teilt sich auf in sieben Taktzustände zum Lesen der 8 bit der
unterbrechenden Einheit, sechs, um den Programmzähler zu retten (PUSH) und
weitere sechs, um die Sprungadresse zu erhalten. |
 |
durch dieses Verfahren können eine Vielzahl von anfordernden Geräten
schnell und komfortabel faktisch auf Unterprogrammtechnik beruhend,
bedient werden |
 |
|
 |

Übersicht über Interruptaufrufstruktur
der Z80 CPU im IMO2
|
 |
der höherwertige Teil des Interrptvektors wird über das
Interruptvektorregister der Z80-CPU gebildet |
 |
der niederwertige Teil wird über den Interruptvektor des anmeldenden
Gerätes zur Verfügung gestellt |
 |
neue Adresse wird auf das erste Byte des Interrptvektors in der
Interruptvektortabelle gestellt |
 |
der höherwertige Teil der Zieladresse der Interrptservice-Routine wird über das
erste Byte eingetragen |
 |
der niederwertige Teil der Zieladresse der Interrptservice-Routine wird über das
zweite Byte eingetragen |
 |
diese Bytes werden ausgelesen und daraus die Startadresse der
eigentlichen ISR gebildet |