Skip to content

Latest commit

 

History

History
153 lines (115 loc) · 7.22 KB

turbo-r_systeemcounter.md

File metadata and controls

153 lines (115 loc) · 7.22 KB
   T U R B O   R   S Y S T E E M C O U N T E R 
                                                           
      
      Beloofd is  beloofd, ik  zou nog een tekst schrijven over de 
      systeemcounter van de turbo R.
      
      
                 W A A R O M   E E N   C O U N T E R ? 
      
      Waarom hebben de ontwerpers van de turbo R er een counter in 
      gezet?  Het  is  bij  software vaak  nodig om  zo nauwkeurig 
      mogelijk tijdsduren te kunnen meten. Bijvoorbeeld om iets te 
      timen.  Bij  de  Z80  werd hiervoor  gewoon de  verwerkings- 
      snelheid van  de Z80  zelf gebruikt.  Bij de  Z80 staat  het 
      namelijk  van elke  instructie vast  hoe lang  de Z80 erover 
      doet,  zodat   je  precies  kunt  uitrekenen  hoe  lang  het 
      uitvoeren van een bepaald stukje code duurt.
      
      Bij  de  R800  is  dat  anders, zie  het artikel  op Sunrise 
      Special  #1. De  R800 wordt  bijvoorbeeld sneller  als alles 
      zich binnen  dezelfde 256 bytes afspeelt, en bovendien is de 
      refresh  anders  geregeld.  Bij  de  Z80  wordt  er na  elke 
      instructie  een refresh  gedaan, bij  de R800 is dat 32 keer 
      per seconde.
      
      Door dit  alles is tijdmeting op basis van klokpulsen bij de 
      R800  niet nauwkeurig.  Vandaar dat er een systeemcounter in 
      is gezet.
      
      
                             1 6   B I T S 
      
      De  systeemcounter is  eigenlijk heel  simpel, gewoon een 16 
      bits tellertje  dat op twee I/O poorten zit en hardwarematig 
      wordt verhoogd (dus onafhankelijk van of bijv. de interrupts 
      aan of uit staan, of er wordt geladen van disk, etc.).
      
      De  frequentie van  de counter,  en dus  van de low byte, is 
      precies  ÇÇn  veertiende deel  van de  snelheid van  de Z80A 
      (3.58 MHz),  ofwel 255682 Hz. De counter wordt dus elke 3.91 
      microseconde (miljoenste seconde) verhoogd.
      
      De high byte loopt uiteraard op 1/256 van deze snelheid, dat 
      is  999  Hz.  De  high  byte  heeft  dus een  frequentie van 
      ongeveer 1 kHz.
      
      
                         I / O   P O O R T E N 
      
      De counter  zit op de I/O poorten &HE6 en &HE7, waarbij &HE6 
      de  low byte  is en &HE7 de high byte. Voor gebruik in BASIC 
      zijn deze  counters gewoonweg  te snel, maar voor gebruik in 
      ML zijn ze uitermate geschikt.
      
      De  counter  kan  worden  gereset  (op  0  gezet)  door  een 
      willekeurige  waarde te schrijven naar poort &HE6. Schrijven 
      naar poort &HE7 heeft geen enkele invloed.
      
      Beide poorten kunnen worden gelezen. Het gebruiken van beide 
      poorten  tegelijk  heeft  een  klein  probleempje,  ze  gaan 
      namelijk  zo  snel  dat  het  kan  gebeuren dat  de counters 
      verspringen net  nadat je  de eerste  hebt gelezen.  Stel je 
      lees  poort &HE6 het eerst en daar staat een 255. De kans is 
      dan groot  dat de  counter vlak daarna wordt verhoogd, en je 
      leest dan bijvoorbeeld de waarde 18 bij poort &HE7. Dit moet 
      dan echter 17 zijn!
      
      
                        T O E P A S S I N G E N 
      
      Er  zijn natuurlijk vele toepassingen, maar de belangrijkste 
      is wel  bij samplen.  De samplechip heeft trouwens z'n eigen 
      counter, die echter maar 2 bits is en wordt gebruikt voor de 
      timing  bij de  _PCMPLAY/_PCMREC commando's  in BASIC.  Deze 
      counter loopt  op de  bekende 15.75 kHz, de snelheid bij een 
      _PCMxxx comando met snelheidsparameter 0.
      
      Als we een sample play of record routine in ML willen maken, 
      kunnen  we beter  van de  low byte  van de  16 bits  counter 
      gebruik maken, omdat die veel nauwkeuriger is.
      
      De counter  wordt ook  veel gebruikt bij afspeelroutines van 
      muziek  voor MSX-MUSIC  en MSX-AUDIO. Bij deze chips moet er 
      namelijk bij  het beschrijven  van de  registers steeds even 
      gewacht  worden. Routines  die voor  de Z80  zijn geschreven 
      gebruiken dan  bijvoorbeeld twee  keer EX  SP,(HL), maar dat 
      duurt bij de R800 te kort waardoor het mis gaat.
      
      
                         M O O N B L A S T E R 
      
      Als  voorbeeld hier even een klein stukje van de MoonBlaster 
      replay. De  replay kijkt  zelf of  hij onder R800 draait, en 
      indien   dat  het  geval  is  zal  hij  aangepaste  routines 
      gebruiken om  de registers  van de MSX-MUSIC en MSX-AUDIO te 
      beschrijven. Als voorbeeld hier MSX-MUSIC.
      
      PAROUT: EX    AF,AF
              CALL  TRBWT     ; wacht indien nodig
              LD    A,C
              OUT   (&H7C),A  ; selecteer register
              IN    A,(&HE6)  ; lees counter
              LD    (RTEL),A  ; sla waarde op
              EX    AF,AF
              OUT   (&H7D),A  ; schrijf waarde
              RET
      
      TRBWT:  PUSH  BC
              LD    A,(RTEL)  ; stand counter bij vorige keer
              LD    B,A
      TRBWL:  IN    A,(&HE6)  ; lees counter
              SUB   B
              CP    7         ; al minimaal 7 verhoogd?
              JR    C,TRBWL
              POP   BC
              RET
      
      Door de  routine TRBWT  (TuRBo WaiT) wordt er gewacht totdat 
      de  counter sinds  de vorige  keer dat  er een register werd 
      beschreven  7  maal is  verhoogd. De  huidige waarde  van de 
      counter wordt in (RTEL) opgeslagen voor de volgende keer dat 
      deze routine wordt aangeroepen.
      
      
                               B A S I C 
      
      In  BASIC kan de counter ook worden gebruikt, er is namelijk 
      een  speciaal  BASIC commando  voor. Dit  is echter  wel een 
      simpel commando, het kan alleen maar wachten! Wat een humor. 
      Je koopt  een snelle  computer en  ÇÇn van  de nieuwe  BASIC 
      commando's  dient om  te wachten!  Enfin, de  syntax van het 
      nieuwe commando is:
      
      _PAUSE(x)
      
      waarbij  voor  x  een  getal tussen  1 en  32767 kan  worden 
      ingevuld. De  computer zal  dan wachten  totdat de high byte 
      van  de counter  (frequentie ca. 1 kHz) het opgegeven aantal 
      stapjes is  verhoogd. Hiermee kunnen we de dus tot op 1/1000 
      seconde nauwkeurig wachten. Bijvoorbeeld:
      
      _PAUSE(1000)
      
      wacht precies een seconde (N.B. Eigenlijk moet dit 999 zijn, 
      want zoals we weten loopt de high byte van de counter op 999 
      Hz.)
      
      Meer valt  er eigenlijk niet over de counter te zeggen. Voor 
      langere  tijdmeting is  hij niet  geschikt, want hij doet er 
      maar ruim een kwart seconde over om "klokkie rond" te gaan.
      
                                                      Stefan Boer