Z80 Interrupthandling

#3794075
Lesenswert?

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
void vSetClock(bool active)
2
{
3
  digitalWrite(clk, active);
4
}
5

6
...
7

8
  bool clock = 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
#3794333
Lesenswert?

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
#3794337
Lesenswert?

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.
#3794345
Lesenswert?

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.
Gast #3794484
Lesenswert?

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 :-)
Gast #3794858
Lesenswert?

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
#3795313
Lesenswert?

> 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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren