Die I/0-Karte für den ecb-bus Datenverkehr

c't-Projekt
Die I/0-Karte für den ECB-Bus
Datenverkehr
Georg Umbach
Spätestens, wenn man mit seinem Rechner Steuerungsaufgaben bewältigen möchte, muß man sich Gedanken über die zur Verfügung stehende Anzahl von Input-/Output-Ports machen.
Dem Gesetz der konstanten Bosheit folgend, wird der Computer mindestens einen Port zuwenig haben.
Aber auch wenn man 'nur' Super-Tape auf seinem Rechner implementieren möchte, benötigt man einen freien I/O-Port.
Besitzer eines ECB-Bus-orientierten Rechners finden die Lösung ihres Problems auf den Folgenden Seiten: Die c't-I/O-Karte bietet vier parallele 8-Bit-Ports und zwei serielle
Schnittstellen (Duplex).
Ein Zähler-/Zeitgeber-Baustein vervollständigt die Karte.
Und für spezielle Anwendungen hält die Karte alle Interrupt-Möglichkeiten der Z80-Bausteine offen.
Die c't-I/O-Karte ist zum Betrieb in Z80-Systemen mit ECB-Bus vorgesehen.
Als Schnittstellen-Bausteine stehen ein Z80-CTC (Counter/Timer
Circuit Zähler-XZeitgeber-Schaltkreis), eine Z80-SIO(O)
(Serial Input/Output serielle Ein-/Ausgabe) und zwei Z80-PIOs (Programmable Input/Output programmierbare Ein-/Ausgabe) zur Verfügung.
Man kann statt der Z80-SIO auch einen Z80-DART (Dual Asynchron Receiver/Transmitter Zweifacher,asynchroner Empfänger/Sender) verwenden, der preisgünstiger
als die SIO ist und für den Betrieb einer seriellen Schnittstelle völlig ausreicht, wenn keine blockweise synchrone Datenübertragung stattfinden soll.
Alle I/O-Bausteine können im Interrupt-Betrieb arbeiten,auch wenn man die Karte nur teilweise mit den Z80-Chips bestückt.
Außerdem ist auf der Karte ein Quarz-Oszillator mit dem notwendigen Frequenzteiler zur Baudratenerzeugung untergebracht.
Somit kann zum Beispiel der Timer mit den unterschiedlichsten Taktfrequenzen betrieben werden.
Alle Leitungen zum ECB-Bus sind gepuffert, so daß nur eine geringe Belastung des Systembusses stattfindet. Sind - Pokistonning jan.sharqiy qismidagi viloyat. Maydoni 140,9 ming km². Aholisi 29,9 mln. kishi (1998). Maʼmuriy markazi - Karochi sh. Yer yuzasining aksari qismi tekislik. Iklimi tropik iqlim, yanvarning urtacha temperaturasi 16-17°, iyulniki 29-35°.
Wer auf der Karte zusätzliche Schaltungen aufbauen will, wie zum Beispiel Treiber oder Wandler, hat auf einem Lochrasterfeld von 3,5x9 Zentimetern genügend Platz.
Der CTC-Baustein kann als Timer, gesteuert durch den Systemtakt, oder als extern getriggerter Zähler verwendet werden.
Alle seine Ein-/Ausgänge sind auf den 26poligen Pfostenstecker J4 geführt.
Soll die serielle Schnittstelle (SIO(0)/DART) mit 'exotischen' Baudraten betrieben werden, zum Beispiel mit 45,5 Baud für Funkfernschreibbetrieb,so kann man den CTC0
und CTC1 für die Erzeugung dieser Baudraten verwenden.
Der Teil B der SIO(0)/DART ist als serielle Schnittstelle ausgelegt.
Die Ausgangspegel der SIO werden von einem Baustein 75188 (IC10) in V24-Pegel umgesetzt.
Dazu müssen allerdings am Systembus die Spannungen 12V und 12V anliegen, was meistens auch der Fall ist.
Stellt das verwendete System diese Spannungen nicht bereit, kann man auf dem Verdrahtungsfeld einen Wandler für 12/ 12V aufbauen.
Die Umsetzung der V24-Empfangssignale geschieht in dem Baustein 75189 (ICH).
Soll die Schnittstelle anstelle von V24- Pegeln TTL-Signale erzeugen und verarbeiten, so ist dies mit einer kleinen Platinenänderung und der Verwendung anderer ICs möglich.
Aber dazu später mehr.
Der Sende- und Empfangstakt für die SIO(0)/DART wird mit einem Quarz-Oszillator (4,9152 MHz) erzeugt.
Die Frequenz wird binär in einem Zähler 74LS393 (IC9) heruntergeteilt,so daß sie als Takt zur Verfügung steht.
Sofern man die Eigenschaft der SIO(0)/DART ausnutzt, für einen seriellen 'Schritt' den l-, 16- oder 64 fachen Takt zu verarbeiten,kann man alle gängigen Baudraten bis hinunter zu 300 Baud
erzeugen.
Sollte ein von der Frequenz her geeigneter Systemtakt zur Verfügung stehen,so kann der Oszillator entfallen, da alle weiteren Signaledann aus dem Systemtakt abgeleitet werden können.
Alle Ein-/Ausgänge des Teils A der SIO(0)/DART sind auf den Pfostenstecker J4 geführt.
Hier kann man sie ungepuffert für besondere Anwendungen (z. B. synchrone Datenübertragung) abnehmen.
Damit bei der Verwendung dieses Teils der SIO(0)/DART hier die höhere Interrupt-Priorität liegt, wurde der Teil A des ICs benutzt.
Ist er inaktiv, so wird Teil B der SIO(0)/DART interruptmäßig nicht benachteiligt.
Die Ausgänge der zwei ZSO-PIOs sind auf 26polige Pfostenstecker geführt (PIO1-J1, PIO2-J2).
Um die Karte universell zu halten, sind die PIO-Leitungen ungepuffert.
Von IC zu IC
Die vier Z80-I/O-Bausteine belegen zusammen 16 Port-Adressen.
Die Auswahl der einzelnen Ports in den I/O-Bausteinen erfolgt durch die gepufferten Adressen A0/A1.
Die Selektierung der einzelnen Bausteine mit je 4 Ports geschieht über die Adressen A3/A2 und den Dekoder 74LS138 (IC3).
Mit den DIL-Schaltern (S l S4) kann man die obere Adressenhälfte (BASE) einstellen.
Es ergibt sich eine Adressenverteilung, wie sie Tabelle 1 zeigt.
Basis-Adresse I/O-Karte x0h
(DIL-Schalter)
CTC 0 x0h
CTC 1 x1h
CTC 2 x2h
CTC 3 c3h
SIO A Daten x4h
SIO A Control x5h
SIO B Daten x6h
SIO B Control x7h
PIO 1 A Daten x8h
PIO 1 B Daten x9h
PIO 1 A Control xAh
PIO 1 B Control xBh
PIO 2 A Daten xCh
PIO 2 B Daten xDh
PIO 2 A Control xEh
PIO 2 B Control xFh
Tabelle 1. Verteilung der Port-adressen
Wird nun ein Port auf der Karte durch einen I/O-Zugriff der CPU selektiert (M1 = 1, A7- A4 = BASE, IORQ = 0), so steht am Komparator 74LS85 (IC4), Pin 6 ein Signal mit dem
logischen Pegel 1.
Ist gleichzeitig das RD-Signal aktiv, so entsteht durch die Inverter 74LS04 (IC15), das NAND-Gatter 74LS20 (IC12) und das AND-Gatter 74LS08 (IC14) ein Signal mit Pegel logisch 0 für die
Richtungsumschaltung des Datenbustreibers 74LS245 (IC1).
Das IC ist immer aktiviert und sendet im Normalfall alle Daten, die auf dem Systembus liegen, in den Kartenbus.
Somit können alle Z80-I/O-Bausteine den Systembus 'abhören' und den Befehl RETI (Return from Interrupt) dekodieren.
Die Richtung des Treibers wird nur bei einem I/O-Read oder dem Einlesen eines Interrupt-Vektors umgeschaltet.
Dieser Fall tritt ein, wenn ein I/O-Baustein einen Interrupt anfordert (INT = 0).
Dabei legt dieser Baustein seinen Ausgang IEO auf logisch 0.
Durch die 'wired AND'-Verknüpfung der 'Daisy-Chain'-Leitungen liegt auch das Signal IEO der Karte auf logisch 0.
Wenn die CPU den geforderten Interrupt annimmt, sendet sie M1 und IORQ mit dem Pegel logisch 0.
Liegt das Signal IEI der Karte auf logisch 1 (kein Interrupt einer höher priorisierten Karte),so wird jetzt aus den Signalen M1, IORQ, IEI und IEO über die Inverter 74LS04 (IC15), das
NAND 74LS20 (IC12) und das AND 74LS08 (IC14) ein Richtungssignal für den Datenbustreiber mit dem logischen Pegel 0 erzeugt.
Gleichzeitig legt der betreffende I/O-Baustein seinen Interrupt-(INT-)Vektor auf den Datenbus, der jetzt zur CPU gesendet wird.
Die I/O-Bausteine haben beim Interrupt folgende Priorität:
CTC --- SIO(0)/DART ---
PIO1 --- PIO2.
Beim Einschalten des Computers oder beim Reset erzeugt ein AND-Gatter des 74LS08 (IC14) aus den Bussignalen CLR und M1 einen Hardware-Reset für die PIOs, die diesen Befehl aus
den Signalen M1 aktiv ohne RD oder IORQ aktiv ableitet.
Im Aufbau
Vor dem Bestücken sollte man die Karte einer optischen Prüfung unterziehen.
Eventuell vorhandene Fehler sind jetzt noch relativ einfach zu beheben.
Das Beseitigen von Fehlern (zum Beispiel Kurzschlüssen) unter einer IC-Fassung ist nach der Bestückung schwierig oder sogar unmöglich.
Da die Bauteile auf der Karte teilweise sehr dicht beieinanderliegen, sollte man prüfen,ob die Stützkondensatoren und die vorhandenen Fassungen für CTC, SIO, PIOs zusammen passen.
Verwendet man als Stützkondensatoren Ausführungen mit einer Stärke von 2,5 mm (z.B. WIMA MKS2 0,1µF/50V) und 'anreihbare' IC-Fassungen, ist der Platz für die Kondensatoren zwischen
den I/O-ICs ausreichend.
Verwendet man Fassungen mit größeren Maßen, so ist vor der Bestückung zu prüfen, ob die Kondensatoren nicht durch eine andere Bauform mit günstigeren Maßen ersetzt werden müssen.
Für die Widerstände sollte man Bauformen wählen, die einen Durchmesser unter 2,5 mm haben.
Praxis
Zuerst werden die Widerstände eingesetzt.
Dabei sollte man einen Pappstreifen von etwa 8 mm Stärke unter die Widerstände legen.
Nach dem Verlöten des Bauteils kann man den Streifen entfernen.
Dadurch wird verhindert, daß es zwischen den Kappen der Widerstände und den Leiterbahnen zu Kurzschlüssen kommt.
Anschließend bestückt man die Karte mit den IC-Fassungen,dem Quarz, dem DIL-Schalter und den Kondensatoren.
Danach folgen die Pfostenstecker und die zwei Lötnägel im Verdrahtungsfeld.
Beim Stecker J5 können leicht Verwechselungen auftreten: Der Stecker J5 kommt in die 'eckigen' Lötaugen.
Zuletzt wird die VG-Steckerleiste montiert.
Sie sollte unbedingt vor dem Löten mit der Platine verschraubt werden.
Die Lötverbindung steht so nicht unter mechanischer Spannung.
Hat man die Karte soweit bestückt, sollte nochmals eine optische Überprüfung erfolgen (vergessene Lötstellen, Lötbrücken).
Ist diese Kontrolle positiv verlaufen, kann man den Widerstand zwischen den Lötnägeln messen.
Sind alle DIL-Schalter 'OPEN', muß sich ein unendlich hoher Widerstand ergeben.
Andernfalls liegt ein Kurzschluß vor.
Anschließend setzt man alle TTL-ICs in ihre Fassungen.
Nach dem Anlegen der Versorgungsspannung von 5V darf die Karte etwa 100mA Strom 'ziehen'.
Ergibt sich hierbei kein überhöhter Wert, kann man die I/O-Chips und die V24-ICs bestücken.
Nach dem erneuten Anlegen der Betriebsspannung sollte sich eine Gesamtstromaufnahme von rund 300mA ergeben.
Eine von diesem Wert wesentlich abweichende Stromaufnahme weist auf einen Fehler hin.
Dann wird mit dem DIL-Schalter die Basis-Adresse der Karte eingestellt und das Testprogramm gestartet.
Das Programm muß laufend das Zeichen '0' auf dem Schirm darstellen.
Setzt man die Brücke J3/3 5, akzeptiert das Programm Zeichen von der Tastatur, die zwischen den Nullen abgebildet werden.
Die Leitung B7 der PIO 2 ist offen, wodurch ein Interrupt generiert wird, den das Programm als '4' auf dem Schirm darstellt.
Berührt man mit dem Finger den Stecker J2/21, so werden (gemischt) das Zeichen '0' und überwiegend die '4' ausgegeben.
Um diesen Interrupt 'abzuschalten', berührt man mit der Hand gleichzeitig den 'GND-Lötnagel' und den Stecker J2/21.
Dadurch gelangt Masse-Potential auf den PIO-Eingang.
Überprüft man die Karte mit einem Oszilloskop, ist folgendes zu beachten: Beim Betrieb der Karte an langen (z. B. 20 Plätze), nicht terminierten Bussen oder auf langen Extendern
können, je nach 1C 4 (74LS85),in den CS-Impulsen der I/O-Bausteine 'Spikes' auftreten.
Dies hat sich bisher in keinem Betriebszustand negativ bemerkbar gemacht.
Im übrigen verschwindet dieser Effekt, sobald man die Karte direkt an dem Bus betreibt und dieser gegebenenfalls terminiert ist.
Modifiziert
Bestückt man die Karte nur teilweise mit den I/O-Bausteinen,muß man die Pins IEI und IEO des fehlenden Bausteins mit einer Brücke verbinden, wenn dieser Chip vor anderen I/O-Bausteinen in der 'Daisy Chain' liegt.
Soll die serielle Schnittstelle mit TTL-Pegel arbeiten und gleich zeitig galvanisch von der Karte getrennt sein (zum Beispiel durch Optokoppler), sind folgende Änderungen durchzuführen :
Senden: Das IC10 (75188) entfällt.
Die Leitung zu Pin 14 ( 12 V) ist aufzutrennen, der freie Pin ist mit 5 V zu verbinden.
Außerdem muß man die Leitung zu Pin 1 trennen
c't-Projekt
Interrupt, warum und wie?
Es gibt grundsätzlich zwei Verfahren, um einen Computer auf Ereignisse von außen reagieren zu lassen.
Bei dem einen,dem Polling-Verfahren, werden die Rechner-Ports oder die Statusregister der Portbausteine zyklisch abgefragt und ausgewertet.
Die Reihenfolge ist per Programm vorgegeben, außerdem läuft die Abfrage (normalerweise) nicht weiter, während der Computer auf ein Ereignis reagiert.
So entstehen zwangsläufig 'Überwachungslücken', in denen kurze Ereignisse verlorengehen können.
Ebenso nimmt die Reaktionszeit des Rechners erheblich zu,wenn mehrere 'bedienungsbedürftige' Ereignisse gleichzeitig auftreten.
In diesem Zusammenhang kann auch eine niedrige Taktfrequenz der CPU zu Problemen führen, da dieselbe Bedienroutine dann länger dauert als bei einer hohen Taktfrequenz.
Wenn die Reaktionszeitkritisch ist, muß man beim Polling zusätzliche Abfragen in die Bedienroutinen einbauen.
Die andere Methode ist, daß der entsprechende Port einen Interrupt (Unterbrechung des laufenden Programms) anfordert.
Damit ist eine schnelle Reaktion auch auf kürzeste Ereignisse möglich, weil die CPU bei jedem Befehl prüft, ob eine Interrupt-Anforderung vorliegt.
Dazu besitzt die Z80-CPU zwei Eingänge:
- Der NMI (Non Maskable Interrupt) hat außer bei einer DMA-Anforderung (die CPU gibt die Kontrolle über den Bus an einen anderen Baustein ab)
absoluten Vorrang und kann nicht durch Software gesperrt (maskiert) werden.
Der INT (maskierbarer Interrupt) ist per Programm steuerbar.
Dabei kann der Anwender zwischen drei verschiedenen Betriebsarten wählen:
Mode 0: 8080-Modus
Mode 1: Call nach Adresse 0038h
Mode 2: vektorisierter Interrupt
Im 8080-Modus erwartet die CPU, daß der anfordernde Portbaustein oder Interrupt-Controller während des Interrupt-Acknowledge-Zyklus
('Stattgegeben!', signalisiert durch IORQ = M1 = logisch 0) einen Maschinenbefehl auf den Datenbus schaltet, den die CPU dann ganz normal ausführt.
Üblicherweise ist dies ein RST-Befehl (Ein-Byte-Call mit 'eingebauter' Adresse) oder ein CALL, um die aktuelle Adresse des unterbrochenen Programms zu retten, es kann aber
prinzipiell jeder Befehl sein.
Im 'Mode l' führt die CPU als Antwort auf einen Interrupt immer einen RST 38h aus.
Im 'Mode 2' liest die CPU ebenfalls während des Interrupt-Acknowledge vom Datenbus, diesmal allerdings exakt ein Byte.
Dieser sogenannte Interrupt-Vektor, den wiederum der Port/Controller liefern muß, bildet die niederwertige
Hälfte einer Speicheradresse (die oberen acht Bit stehen im I-Register der CPU), unter der die Startadresse für die gewünschte Interrupt-Bedienroutine zu finden ist.
Die Bedienroutine wird dann als Unterprogramm aufgerufen.
Durch die Adressierung über das I-Register erhält man im Speicher eine Tabelle, die bis zu 128 verschiedene Interrupts verwalten kann.
Mit einem anderen Wert im I-Register greift die CPU auf eine andere Adreßtabelle zu, so erreicht man andere Reaktionen auf dieselben Interrupts.
Die Portbausteine der Z80-Familie sind für diesen Interrupt-Modus ausgelegt.
Gibt es nicht nur eine Interrupt-Quelle im System, muß man dafür sorgen, daß auch bei mehreren Interrupt-Anforderungen gleichzeitig immer nur einer der betreffenden Bausteine seinen Befehl/Vektor auf den Datenbus legen kann.
Sonst gibt es einen 'Crash' auf dem Datenbus, und die CPU liest 'wirres Zeug'.
Man verteilt daher Prioritäten: Auf jeden Acknowledge-Zyklus reagiert von den Bausteinen, die einen Interrupt angemeldet haben,jeweils der höchstpriorisierte.
Dazu bedient man sich einer Prioritäts-Leitungskette, der 'Interrupt Daisy Chain', für die alle interruptfähigen Ports in Reihe geschaltet werden.
Die entsprechende Steuerlogik ist in den Z80-Portbausteinen bereits integriert und wird durch die Anschlüsse IEI (Interrupt Enable Input) und IEO (Interrupt Enable Output) repräsentiert.
Im Ruhezustand, das heißt,wenn kein Interrupt angemeldet ist, liegt an den IE-Ausgängen derselbe Pegel wie an den IE-Eingängen.
( 12V) und die Pins 1 und 2 verbinden.
Je nach gewünschter Polarität des Ausgangssignals ist für IC10 ein 74.. 00 oder 74. .08 einzusetzen.
Als Treiber für einen Optokoppler kann man auch ein IC des Typs 74. .38 verwenden.
Empfangen: Das IC11 (75189) entfällt.
Es sind jeweils die Pins 1 und 3, 4 und 5, 9 und 10 sowie 12 und 13 miteinander zuverbinden.
Ja nach gewünschter Polarität des Ausgangssignals kann man für IC11 ein IC des Typs 74.. 00 oder 74.. 08 einsetzen.
Bei Verwendung von Optokopplern im Empfangsweg sind Standard-TTL-ICs anstelle des 74 . . 00 oder 74 . . 08 einzusetzen.
Soft-Test
Das Testprogramm ist für das Betriebssystem CP/M 2.2 geschrieben, kann jedoch nach entsprechenden Modifikationen auch auf Rechnern mit anderen Betriebssystemen laufen.
Nach dem Start des Programms werden die Sprünge zuden Unterprogrammen CONsole,STatus, CONsole INput,CONsole OUTput aus der BlOS-Sprungleiste in das Testprogramm einkopiert.
Die Routine CONST prüft, ob ein Zeichen von der Tastatur ansteht.
Wenn ja, enthält der Akku den Wert FFh, sonst 00h.
Das Programm CONIN wartet auf ein Zeichen von der Tastatur und lädt dann das empfangene Zeichen in den Akku.
Die Routine CONOUT sendet das Zeichen aus dem C-Register zum Bildschirm.
Der Akku enthält später ebenfalls den Character.
Nach diesen Routinen folgt die Initialisierung der Z80-Portbausteine.
Die Unterprogramme INIT und INITX senden eine Bytegruppe mit einem Block-I/O-Befehl zu den Portbausteinen.
Für jedes I/O-IC gibt es eine Tabelle.
Das erste Byte eines Tabellenabschnitts gibt die Anzahl der Bytes an,die gesendet werden sollen.
Das zweite Byte ist die Portadresse.
Die weiteren Bytes dienen zur Initialisierung des Bausteins.
Danach folgt der nächste Tabellenabschnitt.
Ist das erste Byte eines neuen Tabellenabschnitts 00, so ist das Ende der für diesen Portbaustein gültigen Tabelle erreicht.
Die Bedeutung der einzelnen Bytes inder Tabelle ist dem Kommentar im Listing zu entnehmen.
Nach der Initialisierung der Portbausteine arbeitet das Pro
gramm eine Schleife ab.
Dadurch wird an den Ausgängen B0 bis B6 der PIO 2 ein Rechtecksignal erzeugt.
Anschließend wird im Polling (also direkte Abfrage des Ports ohne Interrupt) geprüft, ob ein Zeichen von der SIO(0)/DART empfangen wurde.
Falls ein Zeichen ansteht, so wird es aus der SIO(0)/DART geholt und zum Bildschirm gesendet.
Im Anschluß daran wird die Tastatur abgefragt und ein eventuell eingegebenes Zeichen abgeholt.
Ist dieses Zeichen ein '.', so erfolgt ein Warmboot des Systems.
Alle anderen Zeichen werden zur SIO(0)/DART gesendet.
Zum Test kann man den seriellen Ausgang des ICs mit dem seriellen Eingang verbinden (Brückenstecker J33-5).
Das Programm fragt dann die Tastatur ab, sendet und empfängt die Zeichen über die SIO(0)/DART und schickt sie dann zum Bildschirm.
Bei einem Interrupt durch den CTC 0 (erfolgt etwa alle 15ms bei 4 MHz Systemtakt) wird eine '0' ausgegeben; einen Interrupt durch die PIO 2 B meldet das Programm durch eine '4'.
Die Interrupt-Vektoren müssen auf einer geraden Adresse liegen, da sie bei der Programmierung der I/O-Bausteine als Kennung am Ende den Wert 0
haben.
SIO(0)/DART generiert folgende Vektoren: yyyyXXX0.
Ein Teil des programmierten Vektors ist yyyy Je nach Art des Interrupts generiert die SIO(0)/DART die Bitfolge XXX0 dazu.
Daraus folgt,daß Vektoren von yyyy0000 (x0h) bis yyyyy110 (xEh) auftreten können.
Sinngemäß gilt das gleiche auch für den CTC.
Dieser Baustein erzeugt Vektoren in der Form yyyyyXX0, das heißt, es entstehen Vektoren von yyyyy000 (x0h/x8h) bis yyyyy110 (x6h/xEh).
Bei den Interrupt-Vektoren der PIO ist nur auf die gerade Adresse zu achten, da hier nicht aus einem programmierten Vektor andere Vektoren abgeleitet werden.
Besondere Aufmerksamkeit ist allerdings der Lage der Vektortabelle zu widmen, wenn man das Programm mit einem Assembler und anschließendem Link-Lauf
erstellt: Linker wie der
L80.COM setzen CSEG-Module gegebenenfalls auf die Adresse 103h.
Wird eine Vektortabelle auf ungerade Adressen verschoben, so wird das Programm im Interrupt-Betrieb mit Sicherheit 'abstürzen'.
Eine weitere Besonderheit muß man bei Computern beachten,die zeitweilig das RAM mit EPROMs oder anderen Speicherbänken überblenden, wie zum Beispiel der PROF-80.
Ruft das Testprogramm das BIOS des Rechners auf, um zum Beispiel die Tastatur abzufragen, schaltet das BIOS dann ein EPROM mit Boot-, Input-,Output- und Monitor-Routinen ein.
Das RAM an dieser Stelle wird ausgeblendet.
Erfolgt jetzt ein Interrupt, so bildet die CPU aus dem I-Register und dem Interrupt-Vektor eine Adresse,unter der in Form von zwei Bytes die Startadresse der Interrupt-Routine liegen soll.
Hier aber ist nun das EPROM eingeblendet, und es wird eine falsche Adresse aus der 'Interrupt-Tabelle' geholt; die Folge ist 'Programmabsturz'.
Es ist also sehr wichtig, daß die Interrupt-Vektor-Tabelle und die Interrupt-Routinen so im RAM liegen, daß sie zu keiner Zeit von EPROMs oder anderen Speicherbänken 'verdeckt' werden.
Eventuell muß man das Testprogramm in einen anderen Speicherbereich verschieben.
Das Testprogramm geht von Routinen aus, wie sie ein einfaches BIOS enthält.
Bei komplexeren BIOS-Versionen sind eventuell bei den Interrupt-Routinen die Registerinhalte auf dem Stack zu sichern.
Zum Schluß noch ein Hinweis für die Benutzung des Testprogrammes auf Computern, die Floppy-Zugriffe mit Interrupts steuern.
Da bei diesem Testprogramm das I-Register der CPU verändert wird, ist nach dem Start des Testprogrammes eventuell kein Warmboot mehr möglich, wenn das BIOS hier das I-Register
nicht neu lädt.
Floppy-Zugriffe werden nun nicht mehr ausgeführt, da die Routine falsche Interrupt-Adressen bildet.
In diesem Fall hilft nur ein Hardware-Reset.
Literatur:
Einzelheiten zum Interrupt-Betrieb und zu den verwendeten Bausteinen kann man dem Artikel 'Computus Interruptus' aus c't 9/84, S. 56 sowie den Datenblättern
zur Z80-CPU,Z80-CTC, Z80-SIO(0), Z80-DART und Z80-PIO entnehmen.
Eine 'c't-Applikation'über die Z80-PIO ist in Heft 12/83, S. 86 erschienen.
Die Datenblätter sind erhältlich bei:
Zilog GmbH, Eschenstraße 8,
8028 Taufkirchen,
089/6126046.
J5 14-16: Systemtakt teilen für SIO(0)/DART oder
15-16: 4,9152 MHz teilen für SIO(0)/DART
J5 4— 3: 256:1 oder
5— 3: 128 : 1 oder
6— 8: 64:1 oder
7— 8: 32:1 oder
10— 8: 16: 1 oder
9-11: 8:1 oder
12-11: 4 : 1 oder
13-11: 2: 1
J6 5— 7 Takt vom Teiler auf SIO(0)/DART A oder
5— 6 Takt vom CTC0 auf SIO(0)DART A
8-10 Takt vom Teiler auf SIO(0)DART B oder
9-10 Takt vom CTC1; auf SIO(0)DART 13
J6 2— 4 Takt von). Teiler auf CTC0
1— 3 Takt vom Teiler auf CTC1
Tabelle 2. Funktion der Brückenstecker
Ein Baustein kann nur dann einen Interrupt anfordern, wenn sein IEI auf '1' liegt.
Tut er dies, geht sein IEO auf '0' und bleibt so, bis das zugehörige Interrupt-Unterprogramm beendet ist (mit dem Befehl RETI).
Damit verhindert er, daß ein inder Kette hinter ihm liegender Port einen Interrupt absetzen kann, bevor er an der Reihe ist.
Dieselbe Logik erlaubt es auch,daß ein höher priorisierter Interrupt die laufende Bedienroutine eines 'unwichtigeren' Ports unterbricht.
Der umgekehrte Fall ist dagegen nicht möglich.
Im 'Fachchinesisch' nennt man das 'Nested Interrupt' (verschachtelte Programmunterbrechung).
Die einzelnen Interrupt-Ebenen innerhalb eines Portbausteins sind genauso organisiert (siehe Abbildung).
Ein Problem bei der 'Blümchenkette' wörtliche Übersetzung von Daisy Chain sind jedoch die Signallaufzeiten zwischen IEI und IEO:
Im ungünstigsten Fall muß der Null-Pegel am IEO des höchstpriorisierten Bausteins die gesamte Kette durchlaufen, um den niedrigstpriorisierten Interrupt zu sperren.
Die CPU stellt dafür aber nur eine begrenzte Zeit zur Verfügung, die ohne weitere Maßnahmen für vier Port-ICs ausreicht (bei maximaler Taktfrequenz).
Für längere Ketten greift man zu 'vorausschauenden' Schaltungen (Look-ahead-Logik) mit TTL-Gattern, die jede '0' an irgendeinem IEO sofort und schnell weitergeben
(bei der c't-I/O-Karte mit einem LS 09).
Mit den Z80-I/O-Bausteinen ist auch Mischbetrieb von Polling und Interrupt möglich, bei der Z80-PIO allerdings eingeschränkt, da ihre Strobe-Eingänge
(ASTB und BSTB) nicht per Polling abgefragt werden können (kein Statusregister).
Welcher Betriebsart der Vorzug gegeben wird, hängt von der Aufgabenstellung ab - - und vom Können des Programmierers, da Fehler in Interrupt-Routinen nicht leicht zu finden sind.
Die Daisy Chain der c't-I/O-Karte
Stückliste
Widerstände
R1..5 4k7
R11,12 4k7
R6..9 10k
R10,13,14 2k2
Kondensatoren
C1 100 nF, RM 5 mm
CB 11 Stützkondensatoren je 100 nF RM 5 mm
Halbleiter
IC1 74LS245
IC2 74LS244
IC3 74LS138
IC4 74LS85
IC5 Z80A — CTC
IC6 Z80A — DART oder SI0(0)
IC7,8 Z80A — PIO
IC9 74LS393
IC10 75188 oder MC1488
IC11 75189 oder MC1489
IC12 74LS20
IC13 74LS09
IC14 74LS08
IC15 74LS04
Sonstiges
Q Quarz. 4,9152 MHz., HC18
S1...4 DIL-Schalter, 4polig
X1...4 Pfostenleiste 26polig
X5 Pfostenleiste 16polig
X6 Pfostenleiste 10polig
X7 VG-Steckerleiste, Reihen a und c bestückt, 64polig
IC-Fassungen:
7 x 14polig
2 x 16polig
2 x 20polig
2 x Schrauben M 2,5 x 10 mit Mutter, Platine 'c't-I/0-Karte..
|