ELEMANIA
Z80 - Un esempio di gestione dell'interrupt
Un esempio completo di gestione dell'interrupt

Al termine della nostra spiegazione sul funzionamento delle interruzioni nello Z80, consideriamo qui un esempio di gestione di una periferica di input. Per semplicità consideriamo solo il caso di interrupt mascherabile in modo 1:

Supponiamo che all’inizio il flip flop sia inizialmente azzerato: la linea Busy sarà bassa (segnalando in tale modo la disponibilità del sistema a ricevere dati). Quando la periferica avrà pronto un carattere da inviare, poiché il segnale Busy lo consente, predisporrà il dato sulla linea del dato e invierà un impulso (di breve durata) sulla linea Strobe.

Come si può dedurre dall’analisi dello schema in figura, l'impulso Strobe ottiene due effetti: carica il dato nel Registro di latch e porta a “1” il FF, tramite l’ingresso di Preset. La linea di Busy viene così portata alta automaticamente, indicando alla periferica che non possiamo ricevere altri dati, per il momento (infatti il dato ricevuto è attualmente nel registro dei latch, ma non e` stato ancora acquisito dal processore).

Il segnale EN, generato dalla decodifica dell’indirizzo del buffer 3-state, è collegato anche al clock del FF: la lettura del dato da parte del processore causerà, "via-hardware", l'azzeramento delle linee di Busy e di Ready, permettendo ora alla periferica di inviare un ulteriore dato e cancellando la segnalazione di dato pronto rivolta al processore stesso.

La linea Busy attraverso la porta NOT produce invece una richiesta di interrupt allo Z80, il quale potrà così intervenire a leggere il dato solo quando necessario, senza essere impegnato periodicamente ad interrogare la periferica in polling. Questo rappresenta un grosso vantaggio: il processore potrà tranquillamente continuare a lavorare su altri compiti senza doversi preoccupare di controllare periodicamente i dispositivi presenti, gestendo le richieste di questi soltanto all'atto del loro effettivo bisogno.

Qui sotto è mostrato il codice relativo al programma principale e alla routine di interrupt:

  ORG 000h  
  JP 0100h ; salta al programma (il RESET fa iniziare il programma da 0000h)
 
; ******************* Interrupt Routine *******************
  ORG 0038h ; indirizzo a cui dev'essere caricata la routine
  PUSH AF ; salva sullo stack il contenuto di tutti i registri interni
  PUSH BC  
  PUSH DE  
  PUSH HL  
  PUSH IX  
  PUSH IY  
  IN A,(040h) ; legge in A un dato dalla periferica
  LD HL,0200h ; legge l'indirizzo a cui salvare il dato
  LD (HL), A ; scrive il dato in memoria
  INC HL ; incrementa HL due volte
  INC HL  
  LD 0200h, HL ; scrive in memoria l'indirizzo di salvataggio successivo
  POP IY ; ripristina il contenuto dei registri interni
  POP IX ; in ordine contrario rispetto al salvataggio
  POP HL  
  POP DE  
  POP BC  
  POP AF  
  EI ; abilita gli interrupt
  RETI ; termina la routine di gestione dell'interrupt
 
; ******************* Programma principale *******************
  ORG 0100h  
  LD HL,0200h ; carica in 0200h l'indirizzo iniziale a cui bisogna salvare i dati (0202h)
  LD (HL),0202h  
  IM1 ; setta l'interrupt di modo 1
  EI ; abilita gli interrupt mascherabili
inizio:    
  ... ; qui ci sono le istruzioni del programma principale
  ...  
  JP inizio ; il programma viene eseguito ciclicamente
           

 

 

precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it