Skip to content

Latest commit

 

History

History
139 lines (112 loc) · 6.71 KB

interrupt_mode_2.md

File metadata and controls

139 lines (112 loc) · 6.71 KB
                    I N T E R R U P T   M O D E   2 
                                                     
      
      De Z80 kent 3 interrupt modes. Het hele operating system van
      MSX werkt maar met  ��n  van  deze  modes,  te  weten  IM  1
      (Interrupt Mode). Feitelijk is dit een  beperking  omdat  de
      andere  interrupt  modes  zeer  interessante  mogelijkheden
      bieden.
      
      De precieze  werking van de verschillende interrupt modes is 
      nader  beschreven in  een eerder artikel op Sunrise Special. 
      Interrupt  mode  0  is  op MSX  niet bruikbaar,  IM 1  wordt 
      normaliter gebruikt en IM 2 is een twijfelgeval.
      
      In het eerdere artikel heb ik beweerd dat ook IM  2  op  MSX
      niet bruikbaar is, maar dat is niet helemaal  waar.  Om  het
      geheugen eerst wat op te frissen volgt eerst even een  korte
      uitleg van IM 2.
      
      
                                I M   2 
      
      IM 2 is op Z80 de zgn. 'Vector Interrupt' mode. Dat houdt in
      dat er naar verschillende ISR's (Interrupt Service  Routine)
      gesprongen kan worden na het optreden van een interrupt.  Op
      Z80 werkt dit als volgt.
      
      In het geheugen staat een tabel  van  max.  256  bytes  waar
      praktisch per twee bytes een 16 bits adres kan staan. Totaal
      zijn volgens deze rekening 128 adressen mogelijk. In  het  I
      register van de processor  moet  nu  het  HI  byte  van  het
      startadres van deze tabel komen.
      
      &HC000 = vector entry 0
      &HC002 = vector entry 1
        ...
      &HC0FE = vector entry 127
      
      Het I register moet hier de waarde &HC0 hebben  waardoor  de
      processor het startadres van de tabel weet.
      
      IM 2 gaat er van uit dat het interrupt genererende  apparaat
      niet alleen het INT lijntje aktief maakt, maar dat ditzelfde
      apparaat (bv. de VDP) ook een getal op de bus  zet.  In  ons
      voorbeeld mogen dat dan alleen positieve getallen zijn. Stel
      een chip genereert een interrupt en zet de waarde  2  op  de
      bus. De processor gaat nu  de  waarde  van  het  I  register
      combineren met de waarde die op  de  bus  komt  tijdens  een
      interrupt. Daaruit volgt dan een 16 bits waarde  (&HC002  in
      dit voorbeeld). De processor leest  nu  het  16  bits  getal
      vanaf dit gecombineerde adres en springt vervolgens naar het
      zojuist gelezen adres.
      
      Vb:
      
      &HC000 = (&H8000 = ISR 1)
      &HC002 = (&H9000 = ISR 2)
      I = &HC0
      Indien chip A een interrupt genereert en de waarde 0  op  de
      bus  zet  zal  uiteindelijk  naar  adres  &H8000  gesprongen
      worden. Indien chip  B  de  waarde  2  op  de  bus  zet  zal
      uiteindelijk naar adres &H9000 toegesprongen worden.  Indien
      chip C de waarde 1 op de bus zou zetten zal naar adres  &H80
      gesprongen worden (voer voor de pro's).
      
      Het voordeel van deze methode is  dat  er  geen  vertragende
      routines meer nodig zijn om er achter  te  komen  van  welke
      chip  de  interrupt  af  komt.  Dat  wordt   allemaal   door
      hardware geregeld. Het enige waarvoor gezorgd moet worden is
      dat  indien  er  verschillende  chips  zijn  die  interrupts
      genereren deze allen een  verschillende  waarde  op  de  bus
      zetten.
      
      
                         I M   2   E N   M S X 
      
      IM 2 is op MSX niet expliciet nodig omdat er maar 1 chip  is
      die een interrupt aan de processor door kan  geven,  nl.  de
      VDP. Daar komt nog bij dat de VDP helemaal geen waarde op de
      bus zet als deze een interrupt genereert, dus IM 2 lijkt  op
      MSX nutteloos.
      
      Vanuit die gedachtengang heb ik destijds beweerd dat IM 2 op
      MSX niet mogelijk is, wat niet helemaal waar blijkt te zijn.
      Het is op MSX mogelijk om  1  vectorinterrupt  te  gebruiken
      i.p.v. de praktische 128 in het vorige voorbeeld. Op MSX  is
      de Z80 zelf de enige chip in de computer  die  een  lees  of
      schrijfaktie op de bus kan beginnen. De CPU is dus de  enige
      'Bus Master'. Indien zelfs de Z80 niet op  de  bus  schrijft
      zal de waarde op de bus altijd &HFF zijn. De buslijnen  zijn
      van het 'Pull up'  type  (open  collector  uitgang  voor  de
      electrotechneuten) wat dus praktisch neerkomt op  de  waarde
      &HFF.
      
      Treedt er nu een interrupt op (altijd afkomstig van de  VDP)
      dan zal de Z80 indien IM 2 aktief is op de bus kijken en  de
      waarde &HFF zien. Indien het I register de waarde &HC0 heeft
      zal dus de 16 bits waarde vanaf adres &HC0FF gelezen  worden
      waarna naar deze waarde gesprongen wordt.
      
      Het praktisch nut van dit 'geintje' is dat zo voorkomen  kan
      worden dat naar adres &H38 gesprongen wordt.  We  kenden  al
      een geintje om via &HFD9A te voorkomen dat  de  hele  rimram
      die normaal gesproken bij  een  interrupt  uitgevoerd  wordt
      over te slaan. Een andere methode was het  uitschakelen  van
      de ROM-BIOS waardoor een  eigen  routine  vanaf  adres  &H38
      gezet kan worden.
      
      Het uitschakelen van  de  ROM-BIOS  is  echter  vrij  lastig
      (vooral in combinatie met de BDOS).  Via  IM  2  is  het  nu
      echter mogelijk om te  voorkomen  dat  er  naar  adres  &H38
      gesprongen wordt. Daarmee is het dus  mogelijk  om  wel  een
      kompleet eigen ISR te schrijven, terwijl de ROM-BIOS  gewoon
      'aan' kan blijven staan.
      
      Het   is   overigens   zeer   eenvoudig   om    een    klein
      testprogrammatje te maken dat met IM 2 werkt. Dat kan er bv.
      zo uit zien:
      
             ORG  &HC000
      
      RUN:   DI
             LD   HL,&H38
             LD   (&HC0FF),HL
             LD   A,&HC0
             LD   I,A
             IM   2
             EI
             RET
      
      De werking van dit programma laat zich raden.
      
      Het is best leuk om eens te stoeien met IM 2. Overigens zijn
      de termen IM 0, IM 1 en IM 2 ook assembler  instrukties  die
      als zodanig letterlijk gebruikt kunnen worden. Let wel  even
      op dat je na afhandeling van een ISR de interrupts weer  aan
      zet.
      
                                                 Alex van der Wal