Hallo Leute,
ich habe hier eine Z80 CPU mit der ich ein wenig rum spiele. Ich hab sie
soweit auch zum laufen bekommen, das ist alles kein Problem, jedoch
verhalten sich die Interrupts merkwürdig.
Die kommen zwar, verhalten sich aber vollkommen merkwürdig wenn das
Interruptsignal etwas länger an dem INT Pin anliegt. Ein etwas längerer
Zeitpunkt ist dabei 1ms.
Liegt er etwas kürzer an (den Zeitraum kann ich leider nicht bestimmten)
funktioniert er zuverlässig.
Wie Prüfe ich die Interrupts? Ich habe dazu für den Arduino Uno ein
kleines Programm geschrieben, was alle 5 Sekunden ein Interrupt
triggert.
Der Code auf dem Arduino:
1
voidvSetClock(boolactive)
2
{
3
digitalWrite(clk,active);
4
}
5
6
...
7
8
boolclock=false;
9
while(1)
10
{
11
vSetClock(clock);
12
clock=!clock;
13
//delay(1);
14
vSetClock(clock);
15
clock=!clock;
16
delay(5000);
17
}
Der Code auf dem Z80
1
#target bin ; declare target file format
2
3
#code 0,$38 ; declare code segment start, size
4
5
; Stack Konfigurieren
6
LD IX, $ffff
7
LD SP, IX
8
; PIO Konfigurieren
9
LD A, $80
10
OUT ($03), A
11
; Enable Interrupts
12
IM 1
13
EI
14
; App Init
15
LD D, $00
16
17
mainLoop:
18
CP D
19
JP Z, mainLoop
20
CALL wait
21
LD A, $01
22
OUT ($00), A
23
CALL wait
24
LD A, $00
25
OUT ($00), A
26
JP mainLoop
27
28
wait:
29
LD BC, $ffff
30
LD HL, $100
31
waitLoop:
32
LD ($ff), BC
33
CP (HL)
34
RET Z
35
DEC BC
36
JP waitLoop
37
38
#code $38, $2E
39
INT:
40
DI
41
CP D
42
LD D, $01
43
JR Z, $ + 4
44
LD D, $00
45
EI
46
RETI
47
48
#code $0066, 20
49
NMI:
50
HALT
51
#end ; terminate #target
Der Code auf dem Z80 macht nichts anderes als eine LED blinken zu
lassen. Durch den Interrupt schalte ich das Blinken alternierend aus
oder an.
Das Funktioniert aber nur zuverlässig wenn in dem Arduino Programm kein
Delay vorhanden ist. Warum ist das so?
MfG
Tobias
Das INT Signal ist pegelgetriggert. Wenn INT bei RETI noch low ist, dann
gibts sofort wieder einen Interrupt.
Wenn INT also länger low ist, als der Interrupt-Handler dauert, dann
gibts den Handler doppelt oder noch häufiger.
Üblicher Weise steuert man den Interrupt ja nicht direkt an, sondern
über die PIO. Und die PIO setzt man dann einfach auf flankengetriggert.
Einen nackten Z80 ohne PIO, SIO, CTC zu verwenden, halte ich für wenig
sinnvoll. Man verschenkt damit die meisten Möglichkeiten.
Irgendeinen PIO scheint es zu geben, aber zum Z80 PIO passen die
Adressen 00=data und 03=control nicht. Sehr wohl aber zum 8255, und der
hat mit Interrupts nichts im Sinn.
Danke für die Antwort!
Dann weiß ich nun wie die gestrichelten Linien im Timingdiagram zu
interpretieren sind.
Das heißt die Interruptleitung wird im letzten Taktstate von der gerade
aktiven Instruktion gesampled, (angenommen INT ist Low was bedeutet, das
ein Interrupt ausgelöst wird) dann macht die CPU ein IORQ um einen 8 Bit
Vektor vom Datenbus zu lesen, welcher das Gerät das den Interrupt
ausgelöst hat auf den Datenbus schreibt, und dann wird zu der Adresse im
RAM/ROM gesprungen.
Was nun mit dem Vektor geschieht hängt von dem Interruptmode ab. Bei dem
IM 1 wie oben in dem Programm benutzt sollte das, was auf dem Datenbus
geschrieben wurde, gänzlich egal sein, da er bei einem INT und NMI immer
zu festen Adressen springt.
Das bedeutet also, wenn ich ein Interrupt auslöse, kann ich dann als
Gerät durch das IORQ und dem zusätzlich aktivem M1 erkennen, das der
Interrupt verarbeitet wird, und kann dann die Leitung wieder auf High
schalten und somit dem Interrupt deaktivieren.
MfG
Tobias
Tobias Bla schrieb:> Das heißt die Interruptleitung wird im letzten Taktstate von der gerade> aktiven Instruktion gesampled,
Genauer gesagt im M1 Zyklus.
> IM 1 wie oben in dem Programm benutzt sollte das, was auf dem Datenbus> geschrieben wurde, gänzlich egal sein, da er bei einem INT und NMI immer> zu festen Adressen springt.
Richtig.
> Das bedeutet also, wenn ich ein Interrupt auslöse, kann ich dann als> Gerät durch das IORQ und dem zusätzlich aktivem M1 erkennen, das der> Interrupt verarbeitet wird, und kann dann die Leitung wieder auf High> schalten und somit dem Interrupt deaktivieren.
Ja. Üblicherweise überlässt man dieses Spiel aber der Peripherie, wie
Peter schon darlegte.
Tobias Bla schrieb:> Da steht zwar im Datenblatt auch etwas über Interrupts drinnen, aber> soweit bin ich noch nicht ;)
Wenn du dort angekommen bist, wirst du feststellen, dass der Z80 PIO
wundersamerweise besser zur Z80 CPU passt als der 8255, was Interrupts
angeht. Die Z80 hatte ein recht ausgefeiltes Interrupt-Verfahren,
insbesondere im IM2.
Die Interrupts des 8255 wurden ursprünglich für sowas wie die parallele
Druckerschnittstelle gebaut, nicht als Interrupt-Controller für diverse
externe Ereignisse.
A. K. schrieb:> angeht. Die Z80 hatte ein recht ausgefeiltes Interrupt-Verfahren,> insbesondere im IM2.
Und auch andere feine Sachen wie z.B. die Alternate Registers -
- ideal für schnelle Interrupts...
Interrupt-Tabelle im RAM...
Tobias Bla schrieb:> In der Tat benutze ich einen WS82C55A ;)> Da steht zwar im Datenblatt auch etwas über Interrupts drinnen, aber> soweit bin ich noch nicht ;)
Vergiss den für den Z80! Der ist für das INTEL 8085 System gemacht. Mit
IM2 ist die PIO einfach genial.
Peter Dannegger schrieb:> Einen nackten Z80 ohne PIO, SIO, CTC zu verwenden, halte ich für wenig> sinnvoll. Man verschenkt damit die meisten Möglichkeiten.
Doch, die FuA-melo-Klingel funktioniert nur mit NMI 1000-fach :-)
Tobias Bla schrieb:> kann ich dann als> Gerät durch das IORQ und dem zusätzlich aktivem M1 erkennen, das der> Interrupt verarbeitet wird, und kann dann die Leitung wieder auf High> schalten und somit dem Interrupt deaktivieren.
Wenn du mit dem einen IRQ auskommst. Die Schaltung ist etwas aufwendig,
vielleicht kommst du auch mit einem Monoflop aus, das aus dem INT einen
flankengesteuerten Eingang macht.
Georg
> Wenn du dort angekommen bist, wirst du feststellen, dass der Z80 PIO> wundersamerweise besser zur Z80 CPU passt als der 8255, was Interrupts> angeht. Die Z80 hatte ein recht ausgefeiltes Interrupt-Verfahren,> insbesondere im IM2.
Das glaube ich, jedoch ist nicht ganz so einfach an solch ein PIO dran
zu kommen. Die Z80 und alles drum rum ist doch leider recht betagt,
jedoch scheint sie zum Einstieg in die Rechnerachitektur noch recht gut
geeignet zu sein.
Man kann solch ein System wunderbar auf dem Steckbrett aufbauen und kann
sich über LEDs die Aktivität auf dem Bus anzeigen lassen (eine Niedrige
Tacktung im Hz Bereich voraus gesetzt ;) ), man bekommt Details mit, wie
z. B. das Handling der IO Geräte, die doch auf moderneren Architekturen
wunderbar weg abstrahiert wurden und das alles ohne das es übermäßig
kompliziert wird.
Tobias Bla schrieb:> nicht ganz so einfach an solch ein PIO dran> zu kommen
Farnell oder Mouser haben so viele auf Lager, die müssen die schon
verkaufen.
Für Mouser gibt es den Sammelbestellungs Thread hier im Forum.
Hallo Tobias,
ich habe noch einige Bausteine im Lager.
Auf die Schnelle:
Zilog z80 dma
Zilog z80 ctc
Toshiba z84c30 (z80 ctc)
Sharp LH5082AL (Z80 CMOS CTC)
diverse statische Rambausteine
Intersil IM6402-LI Keramik Uart
ay-38910 sound
der Rest ist noch auf Europaplatinen.
Melde dich halt, wenn Du etwas davon brauchst.