🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #10738

CIA Timer Example

#10738
From: John Schultz
Date: Thu, 29 Dec 1988 03:57
136 lines
4692 bytes

  Ok, here's what I've got so far:


IMPLEMENTATION MODULE CIATimer;

FROM SYSTEM IMPORT ADDRESS,ADR,BYTE,INLINE;
FROM InOut IMPORT WriteString;
FROM CIAHardware IMPORT ciaa,CIABITS,CIAicrTB;
FROM CIAResource IMPORT AbleICR,AddICRVector,RemICRVector,SetICR,
                        CIAAName;
FROM Resources IMPORT OpenResource,ResourcePtr;
FROM Interrupts IMPORT Interrupt,InterruptPtr;
FROM Nodes IMPORT NTInterrupt;

CONST
  TIMERON    = CIABITS(1);
  TIMEROFF   = CIABITS(0);

  LATCHLOW   = CIABITS(0CCH); (* 2CCH = 716, for 1000hz *)
  LATCHHIGH  = CIABITS(002H);

VAR
  CIAResource : ResourcePtr;
  timer       : Interrupt;
  oldint      : InterruptPtr;

  oldciacrb,  (* So we can restore them later *) 
  oldciatblo,
  oldciatbhi  : CIABITS;

PROCEDURE ResetTimer;
BEGIN
  CIATime := 0D;
END ResetTimer;

PROCEDURE Wait(msec : LONGCARD);
BEGIN
  CIATime := 0D;
  REPEAT UNTIL CIATime >= msec;
END Wait;

PROCEDURE IncTimer(): LONGCARD; (* Private: Not exported *)
BEGIN
  INC(CIATime);
  RETURN 0D;
END IncTimer;

PROCEDURE CreateTimer(): BOOLEAN;
BEGIN
  WITH timer DO
    isNode.lnType := NTInterrupt;
    isNode.lnPri := BYTE(0);
    isNode.lnName := ADR("PrivateCIATimerCIAicrTB");
    isData := ADR(CIATime);
    isCode := ADR(IncTimer);
  END; (* WITH *)

  CIAResource := OpenResource(ADR(CIAAName));

  IF CIAResource = NIL THEN
    WriteString("OpenCIAResource Failed.\n");
    RETURN FALSE;
  END;

  oldint :=  AddICRVector(CIAicrTB,timer,CIAResource^);
  IF oldint # NIL THEN (* Not available? Take it by force! *)
    RemICRVector(CIAicrTB,oldint^,CIAResource^);
    IF AddICRVector(CIAicrTB,timer,CIAResource^) # NIL THEN (* Install ours *)
      WriteString("AddICRVector Failed.\n");(*What?! This should never happen*)
      oldint := AddICRVector(CIAicrTB,oldint^,CIAResource^);
      CIAResource := NIL; (* So DeleteTimer will do nothing. *)
      RETURN FALSE;
    END; (* IF *)
  END; (* IF *)

  WITH ciaa^ DO             (* Using Timer B *)
    oldciacrb  := ciacrb;   (* Save the old so we can restore later *)
    oldciatblo := ciatblo;
    oldciatbhi := ciatbhi;
    ciacrb  := TIMEROFF;    (* Turn off Timer B *)
    ciatblo := LATCHLOW;    (* Set timer latch to 0x2CC (716) *)
    ciatbhi := LATCHHIGH;   (* to give us 1000hz resolution *)
    ciacrb  := TIMERON;     (* Turn on Timer B *)
  END; (* WITH ciaa^ *)

  RETURN TRUE;

END CreateTimer;

PROCEDURE DeleteTimer;
BEGIN
  IF CIAResource # NIL THEN
    ciaa^.ciacrb := TIMEROFF; (* Turn off Timer B *)
    RemICRVector(CIAicrTB,timer,CIAResource^); (* Remove our timer interrupt *)
    WITH ciaa^ DO            (* Restore old cia values so the disk drives *)
      ciatblo := oldciatblo; (* will work [nice feature]. *)
      ciatbhi := oldciatbhi;
      ciacrb  := oldciacrb;
    END; (* WITH *)
    (* Put back the old interrupt, this also sets the ICR bit and enAbles
       the corresponding bit interrupt, in this case Timer B [bit 1]. *)
    IF AddICRVector(CIAicrTB,oldint^,CIAResource^) # NIL THEN 
      WriteString("DANGER: Couldn't restore old CIAicrTB Vector!\n");
      WriteString("  Disk drives will now no longer function until\n");
      WriteString("  REBOOT!\n");   
    END;
  END;
END DeleteTimer;

BEGIN
  CIAResource := NIL;
END CIATimer.


  Here's what I'm trying to do:
    Wait with millisecond accuracy (has to be _accurate_), measure
response times with millisecond accuracy.
  This is being used for a research project, so I'm not worried
about multitasking, etc., but I'd like it to be "legal" if
possible [possibly just read system timers for stamps? Can I get high-res
accuracy (1ms), reliably?].
  The above works fine, >> as long as there are disks in all of the
drives and no disk access takes place <<.  
  What's the scoop?  What is the bottom line on these timers? Am I
reading the docs wrong, or is the documentation inaccurate?  
  Timer B on ciaa *should* be available.  I can't use timer A
because we need the serial port at the same time.
  I'd love to be enlightened on all of this...Any help appreciated.


  Thanks,


    John Schultz
Technical Details
Message-ID: <38@sdcc10.ucsd.EDU>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!lll-winken!lll-lcc!ames!mailrus!tut.cis.ohio-state.edu!rutgers!ucsd!sdcc6!sdcc10!cs161agc
References: <1439@percival.UUCP> <5587@cbmvax.UUCP>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!lll-winken!lll-lcc!ames!mailrus!tut.cis.ohio-state.edu!rutgers!ucsd!sdcc6!sdcc10!cs161agc
From: cs161agc@sdcc10.ucsd.EDU (John Schultz)
Newsgroups: comp.sys.amiga.tech
Subject: CIA Timer Example
Message-ID: <38@sdcc10.ucsd.EDU>
Date: 29 Dec 88 03:57:07 GMT
References: <1439@percival.UUCP> <5587@cbmvax.UUCP>
Reply-To: cs161agc@sdcc10.ucsd.edu.UUCP (John Schultz)
Distribution: na
Organization: University of California, San Diego
Lines: 136