[fpc-pascal]High resolution timers on linux ?

Gabor DEAK JAHN djg at tramontana.co.hu
Tue Aug 28 15:12:42 CEST 2001


At 8/27/01 09:13 PM, you wrote:

Kenneth,

 > I need some way to determine when 1/10000 sec has passed
 > I suppose it can be done with the timerchip in the PC - but how ?

I have a unit I've used quite a lot some years ago, it was written for
Borland Pascal, so you will need to modify it slightly. As far as I can
remember, its precision was below a microsecond and didn't even reprogram
the timer (it did modify one setting but not the actual rate so it didn't
disturb other software running). The trick is that although the usual timer
interrupt is very rare, the timer chip itself counts rather fast. All you
have to do is to read this counter value and use it to form a very high
resolution timer.

=================================================
unit Time;

interface

function GetTime : longint;
procedure ConvertTime (Stamp : longint; var HH, MM : word; var SS : real);

implementation
const
   TIMER0 = $40; TIMERC = $43; PICO0 = $20; OCW3IR = $0A; TMODE2 = $34;
   NEW_TICKS = trunc (256 * 12 * 3600 * 18.2); { Number of ticks until noon  }
   FRAC_SEC = 256 * 182;                       { Number of ticks in sec * 10 }
   NOON_SECS = 3600 * 12;                      { Number of secs in day at 
noon }

function GetTime;
var
   dummy : word;
   TempTime, Timer : longint;
   BiosTime : longint absolute $0040:$006B;    { $0040:$006C * 256           }
begin
   asm cli; end;
   TempTime := BiosTime and $FFFFFF00;
   Port [TIMERC] := 0; dummy := Port [TIMER0];
   Timer := 255 - ($FF and Port [TIMER0]);
   Port [PICO0] := OCW3IR;
   if (Port [PICO0] and 1) > 0 then Timer := Timer or $100;
   inc (TempTime, Timer);
   asm sti; end;
   GetTime := TempTime;
end; { GetTime }

procedure ConvertTime;
var
   Temp, SubFlag : longint;
begin
   SubFlag := 0;
   if Stamp > NEW_TICKS then
     begin dec (Stamp, NEW_TICKS); SubFlag := NOON_SECS; end;
   Temp := SubFlag + (Stamp * 10) div FRAC_SEC;
   SS := Temp mod 60 + word ((10000 * ((10 * Stamp) mod FRAC_SEC)) div 
FRAC_SEC) / 10000;
   Temp := Temp div 60; MM := Temp mod 60; HH := Temp div 60;
end; { ConvertTime }

begin
   asm cli; end;
   Port [TIMERC] := TMODE2;
   Port [TIMER0] := 0; Port [TIMER0] := 0;
   asm sti; end;
end.
=================================================


Regards,

   Gabor DEAK JAHN

-------------------------------------------------------------------
Gabor DEAK JAHN -- Budapest, Hungary.
WWW: www.tramontana.co.hu
E-mail: djg at tramontana.co.hu





More information about the fpc-pascal mailing list