<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Z80_Interrupt-Logik</id>
	<title>Z80 Interrupt-Logik - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki-de.moshellshocker.dns64.de/index.php?action=history&amp;feed=atom&amp;title=Z80_Interrupt-Logik"/>
	<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Z80_Interrupt-Logik&amp;action=history"/>
	<updated>2026-05-31T07:02:01Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Wikipedia (Deutsch) – Lokale Kopie</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki-de.moshellshocker.dns64.de/index.php?title=Z80_Interrupt-Logik&amp;diff=662833&amp;oldid=prev</id>
		<title>imported&gt;Lómelinde: :Kategorie:Wikipedia:Seite mit Syntaxhervorhebungsfehlern nicht mehr unterstützte Pflichtangabe lang=&quot;z80&quot;→asm?</title>
		<link rel="alternate" type="text/html" href="https://wiki-de.moshellshocker.dns64.de/index.php?title=Z80_Interrupt-Logik&amp;diff=662833&amp;oldid=prev"/>
		<updated>2024-01-17T10:29:31Z</updated>

		<summary type="html">&lt;p&gt;&lt;a href=&quot;/index.php?title=Kategorie:Wikipedia:Seite_mit_Syntaxhervorhebungsfehlern&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Kategorie:Wikipedia:Seite mit Syntaxhervorhebungsfehlern (Seite nicht vorhanden)&quot;&gt;Kategorie:Wikipedia:Seite mit Syntaxhervorhebungsfehlern&lt;/a&gt; nicht mehr unterstützte Pflichtangabe lang=&amp;quot;z80&amp;quot;→asm?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Die &amp;#039;&amp;#039;&amp;#039;Z80 Interrupt-Logik&amp;#039;&amp;#039;&amp;#039; dient der [[Interrupt]]-Steuerung des [[Zilog Z80|Zilog-Z80]]-Prozessors.&lt;br /&gt;
&lt;br /&gt;
[[Hauptprozessor|Mikroprozessoren]] kommunizieren mit externen Geräten über Peripheriebausteine, um beispielsweise Daten von einem Modem zu empfangen. Damit der Prozessor schnell auf externe Ereignisse –&amp;amp;nbsp;zum Beispiel den Empfang eines Zeichens&amp;amp;nbsp;– reagieren kann, sendet das Peripheriegerät eine Unterbrechungsanforderung ([[Interrupt]]) an den Hauptprozessor (&amp;#039;&amp;#039;central processing unit&amp;#039;&amp;#039;, CPU), der sein normales Programm unterbricht, in eine Interrupt-Service-Routine (ISR) verzweigt und nach Verarbeitung des Zeichens im normalen Programmfluss fortfährt. Um einen Interrupt an den Prozessor zu übergeben, werden meist spezielle Bausteine benötigt, die [[Programmable Interrupt Controller|Interrupt-Controller]]. An diese Controller können mehrere Peripheriebausteine angeschlossen werden, im Ur-[[IBM Personal Computer]] von 1983 beispielsweise acht Stück. Sollten mehr als acht externe Geräte angeschlossen werden, wurde ein weiterer Controller benötigt, was zu aufwendigen Design-Änderungen führte.&lt;br /&gt;
&lt;br /&gt;
== Das Interrupt-Konzept des Z80 ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Zilog z80 interruptvektor.png|mini|Verweis der Interrupt-Register auf die [[Interruptvektor|Vektortabelle]]]]&lt;br /&gt;
[[Zilog]] baute bereits 1976 die Interrupt-Steuerung des Z80-Prozessors daher völlig anders auf. Der Z80 benötigt keinen Interrupt-Controller, kann im Interruptmodus IM2 aber trotzdem bis zu 128 externe Interrupt-Quellen bedienen – bei einer zugleich sehr einfachen Software-Struktur. Damit der Z80 die zugehörige ISR aufrufen kann, besitzt jeder Peripheriebaustein ein 8 bit breites Register, das zusammen mit einem internen [[Register (Prozessor)|Prozessor-Register]] auf eine [[Interruptvektor]]-Tabelle im Speicher zeigt, die wiederum die Einsprungadressen der Interrupt-Service-Routine enthält. Da das unterste Bit des Interrupt-Registers immer Null sein muss, ergeben sich somit maximal 128 Einträge in der Interruptvektor-Tabelle.&lt;br /&gt;
&lt;br /&gt;
== Ablauf einer Unterbrechungsanforderung ==&lt;br /&gt;
&lt;br /&gt;
* Das Peripheriegerät aktiviert an der CPU eine Unterbrechungsanforderung (&amp;#039;&amp;#039;interrupt request signal&amp;#039;&amp;#039;, IRQ)&lt;br /&gt;
* Die CPU bestätigt die Unterbrechungsanforderung.&lt;br /&gt;
* Das Peripheriegerät legt daraufhin den Inhalt des Interrupt-Registers auf den Datenbus.&lt;br /&gt;
* Die CPU unterbricht das laufende Programm, liest die Adresse, holt sich aus der Interruptvektor-Tabelle die Adresse des zugehörigen Programmcodes ISR und führt diesen aus. Nach Abarbeitung der Interrupt-Service-Routine führt die CPU das unterbrochene Programm fort.&lt;br /&gt;
&lt;br /&gt;
== Konfliktmanagement ==&lt;br /&gt;
&lt;br /&gt;
Da mehrere externe Ereignisse gleichzeitig eintreffen und außerdem auch wichtige Ereignisse die ISR von unwichtigeren Ereignissen unterbrechen können, braucht man eine Konflikt- oder Prioritätssteuerung. Wie bei den Vektoren sind auch hier die Peripheriebausteine dafür verantwortlich. Jeder Baustein besitzt je einen Eingang (&amp;#039;&amp;#039;interrupt enable input&amp;#039;&amp;#039;, IEI) und einen Ausgang (&amp;#039;&amp;#039;interrupt enable output&amp;#039;&amp;#039;, IEO). Alle beteiligten Bausteine sind in Kette geschaltet, der IEO ist mit dem IEI des jeweils nächsten verbunden. Der IEI des ersten Gliedes liegt fest auf logisch&amp;amp;nbsp;1. Es gilt:&lt;br /&gt;
* Ein Interrupt wird nur ausgelöst, wenn IEI logisch 1 ist.&lt;br /&gt;
* Ist ein Interrupt aktiv, so wird IEO logisch&amp;amp;nbsp;0, was zur Folge hat, dass alle folgenden Glieder der Kette gesperrt sind.&lt;br /&gt;
* Daraus ergibt sich, dass das erste Glied der Kette immer die höchste Priorität hat.&lt;br /&gt;
&lt;br /&gt;
Das Bild erläutert diese Kette näher:&lt;br /&gt;
[[Datei:Zilog z80 daisychain.png|zentriert|Interrupt-Kette der Peripheriebausteine]]&lt;br /&gt;
* A: Ruhezustand, alle Bausteine können einen Interrupt auslösen.&lt;br /&gt;
* B: Kanal 2 hat Interrupt ausgelöst, sperrt Kanal 3&lt;br /&gt;
* C: Kanal 1 löst Interrupt aus, unterbricht die ISR von Kanal 2&lt;br /&gt;
* D: Interrupt von Kanal 1 ist beendet, ISR von Kanal 2 geht weiter.&lt;br /&gt;
* E: Interrupt von Kanal 2 ist beendet, es geht im normalen Programmfluss weiter.&lt;br /&gt;
&lt;br /&gt;
Damit die Peripheriebausteine wissen, wann sie ihr IEO wieder freigeben dürfen, lauschen sie mit, welchen Programmcode die CPU gerade ausführt. Jede ISR endet mit dem Befehl &amp;lt;code&amp;gt;RETI&amp;lt;/code&amp;gt; (ED&amp;amp;nbsp;4D), was der externe Baustein erkennt und daraufhin sein IEO freigibt.&lt;br /&gt;
&lt;br /&gt;
== Die Trickkiste ==&lt;br /&gt;
&lt;br /&gt;
Oft ist es wünschenswert, die Interrupt-Prioritäten vom Programm aus zu ändern, was aber wegen der starren Hardware-Verdrahtung nicht möglich ist. Mit einigen Kniffen geht es trotzdem, dass beispielsweise Kanal&amp;amp;nbsp;3 die ISR von Kanal&amp;amp;nbsp;1 unterbricht.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Standard-ISR&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
 Kanal2:&lt;br /&gt;
       PUSH AF               ;Sichern der Register&lt;br /&gt;
       PUSH BC&lt;br /&gt;
       PUSH DE&lt;br /&gt;
       PUSH HL&lt;br /&gt;
       EI                    ;neue Interrupts gleich wieder erlauben&lt;br /&gt;
       …&lt;br /&gt;
       LD   HL,irgendwas     ;der Programmcode&lt;br /&gt;
       …&lt;br /&gt;
       POP  HL&lt;br /&gt;
       POP  DE&lt;br /&gt;
       POP  BC&lt;br /&gt;
       POP  AF               ;Zurückholen der Register&lt;br /&gt;
       RETI                  ;Ende der ISR&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kanal 1 könnte die ISR von Kanal&amp;amp;nbsp;2 unterbrechen, nicht aber Kanal&amp;amp;nbsp;3, da dieser per Hardware gesperrt ist. Um die Hardware zu überlisten, wird folgendes Programmfragment benutzt:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tricky ISR&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
 Main:&lt;br /&gt;
       LD   DE,wasauchimmer&lt;br /&gt;
       ADD  HL,DE&lt;br /&gt;
       …&lt;br /&gt;
       LD   A,1    ;&amp;lt;--- Hier wird der Interrupt wirksam,&lt;br /&gt;
                      ;die Adresse Main_R&lt;br /&gt;
                      ;wird als Rücksprungadresse auf den Stack gelegt.&lt;br /&gt;
 Main_R:&lt;br /&gt;
       LD    B,2&lt;br /&gt;
       …&lt;br /&gt;
&lt;br /&gt;
 ;Interrupt-Service-Routine fuer Kanal2&lt;br /&gt;
 Kanal2:&lt;br /&gt;
       CALL TRICKY_SAVE  ;Unterprogramm&lt;br /&gt;
 Kanal2_R:&lt;br /&gt;
       …&lt;br /&gt;
       LD   HL,irgendwas&lt;br /&gt;
       …&lt;br /&gt;
       RET&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 TRICKY_SAVE:&lt;br /&gt;
       EX   (SP),HL     ;Rücksprung-Adresse nach HL holen&lt;br /&gt;
       PUSH AF          ;Register sichern&lt;br /&gt;
       PUSH BC&lt;br /&gt;
       PUSH DE          ;Stack: MAIN, HL, AF, BC, DE&lt;br /&gt;
                           ;HL:    Kanal2_R&lt;br /&gt;
       LD   DE,CONTINUE ;Adresse von Programmcode CONTINUE&lt;br /&gt;
       PUSH DE          ;als Rücksprungadresse auf Stack legen&lt;br /&gt;
       EI&lt;br /&gt;
       RETI             ;Programm wird durch den RETI-Befehl&lt;br /&gt;
                           ;an der manipulierten Rücksprungadresse CONTINUE fortgesetzt.&lt;br /&gt;
                           ;Das Peripheriegerät erkennt die RETI-Instruktion,&lt;br /&gt;
                           ;betrachtet damit &amp;quot;seine&amp;quot; ISR als beendet&lt;br /&gt;
                           ;und gibt den Interrupt wieder frei.&lt;br /&gt;
&lt;br /&gt;
 CONTINUE:&lt;br /&gt;
       CALL  HL_JP      ;Programmcode wird an der im HL-Register gespeicherten Adresse&lt;br /&gt;
                           ;(=Kanal2_R) fortgesetzt&lt;br /&gt;
       POP   DE         ;Register zurückholen&lt;br /&gt;
       POP   BC&lt;br /&gt;
       POP   AF&lt;br /&gt;
       POP   HL&lt;br /&gt;
       RET              ;normales &amp;quot;return&amp;quot; reicht hier aus, da RETI bereits ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
 HL_JP:&lt;br /&gt;
       JP    (HL)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes Peripheriegerät kann damit jederzeit einen Interrupt auslösen, die Prioritätssteuerung kann per Software erfolgen.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.z80.info/1653.htm Z80 Family Interrupt Structure]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Mikroprozessortechnik]]&lt;br /&gt;
&lt;br /&gt;
[[pt:Z-80A]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Lómelinde</name></author>
	</entry>
</feed>