[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]
{$S-,R-,I-,V-,B-}
{*********************************************************}
{* TPTIMER.PAS 2.00 *}
{* by TurboPower Software *}
{*********************************************************}
Unit TpTimer;
{-Allows events to be timed With 1 microsecond resolution}
Interface
Const
TimerResolution = 1193181.667;
Procedure InitializeTimer;
{-ReProgram the timer chip to allow 1 microsecond resolution}
Procedure RestoreTimer;
{-Restore the timer chip to its normal state}
Function ReadTimer : LongInt;
{-Read the timer With 1 microsecond resolution}
Function ElapsedTime(Start, Stop : LongInt) : Real;
{-Calculate time elapsed (in milliseconds) between Start and Stop}
Function ElapsedTimeString(Start, Stop : LongInt) : String;
{-Return time elapsed (in milliseconds) between Start and Stop as a String}
{==========================================================================}
Implementation
Var
SaveExitProc : Pointer;
Delta : LongInt;
Function Cardinal(L : LongInt) : Real;
{-Return the unsigned equivalent of L as a Real}
begin {Cardinal}
if L < 0 then
Cardinal := 4294967296.0+L
else
Cardinal := L;
end; {Cardinal}
Function ElapsedTime(Start, Stop : LongInt) : Real;
{-Calculate time elapsed (in milliseconds) between Start and Stop}
begin {ElapsedTime}
ElapsedTime := 1000.0*Cardinal(Stop-(Start+Delta))/TimerResolution;
end; {ElapsedTime}
Function ElapsedTimeString(Start, Stop : LongInt) : String;
{-Return time elapsed (in milliseconds) between Start and Stop as a String}
Var
R : Real;
S : String;
begin {ElapsedTimeString}
R := ElapsedTime(Start, Stop);
Str(R:0:3, S);
ElapsedTimeString := S;
end; {ElapsedTimeString}
Procedure InitializeTimer;
{-ReProgram the timer chip to allow 1 microsecond resolution}
begin {InitializeTimer}
{select timer mode 2, read/Write channel 0}
Port[$43] := $34; {00110100b}
Inline($EB/$00); {jmp short $+2 ;Delay}
Port[$40] := $00; {LSB = 0}
Inline($EB/$00); {jmp short $+2 ;Delay}
Port[$40] := $00; {MSB = 0}
end; {InitializeTimer}
Procedure RestoreTimer;
{-Restore the timer chip to its normal state}
begin {RestoreTimer}
{select timer mode 3, read/Write channel 0}
Port[$43] := $36; {00110110b}
Inline($EB/$00); {jmp short $+2 ;Delay}
Port[$40] := $00; {LSB = 0}
Inline($EB/$00); {jmp short $+2 ;Delay}
Port[$40] := $00; {MSB = 0}
end; {RestoreTimer}
Function ReadTimer : LongInt;
{-Read the timer With 1 microsecond resolution}
begin {ReadTimer}
Inline(
$FA/ {cli ;Disable interrupts}
$BA/$20/$00/ {mov dx,$20 ;Address PIC ocw3}
$B0/$0A/ {mov al,$0A ;Ask to read irr}
$EE/ {out dx,al}
$B0/$00/ {mov al,$00 ;Latch timer 0}
$E6/$43/ {out $43,al}
$EC/ {in al,dx ;Read irr}
$89/$C7/ {mov di,ax ;Save it in DI}
$E4/$40/ {in al,$40 ;Counter --> bx}
$88/$C3/ {mov bl,al ;LSB in BL}
$E4/$40/ {in al,$40}
$88/$C7/ {mov bh,al ;MSB in BH}
$F7/$D3/ {not bx ;Need ascending counter}
$E4/$21/ {in al,$21 ;Read PIC imr}
$89/$C6/ {mov si,ax ;Save it in SI}
$B0/$FF/ {mov al,$0FF ;Mask all interrupts}
$E6/$21/ {out $21,al}
$B8/$40/$00/ {mov ax,$40 ;read low Word of time}
$8E/$C0/ {mov es,ax ;from BIOS data area}
$26/$8B/$16/$6C/$00/ {mov dx,es:[$6C]}
$89/$F0/ {mov ax,si ;Restore imr from SI}
$E6/$21/ {out $21,al}
$FB/ {sti ;Enable interrupts}
$89/$F8/ {mov ax,di ;Retrieve old irr}
$A8/$01/ {test al,$01 ;Counter hit 0?}
$74/$07/ {jz done ;Jump if not}
$81/$FB/$FF/$00/ {cmp bx,$FF ;Counter > $FF?}
$77/$01/ {ja done ;Done if so}
$42/ {inc dx ;else count int req.}
{done:}
$89/$5E/$FC/ {mov [bp-4],bx ;set Function result}
$89/$56/$FE); {mov [bp-2],dx}
end; {ReadTimer}
Procedure Calibrate;
{-Calibrate the timer}
Const
Reps = 1000;
Var
I : Word;
L1, L2, Diff : LongInt;
begin {Calibrate}
Delta := MaxInt;
For I := 1 to Reps do begin
L1 := ReadTimer;
L2 := ReadTimer;
{use the minimum difference}
Diff := L2-L1;
if Diff < Delta then
Delta := Diff;
end;
end; {Calibrate}
{$F+}
Procedure OurExitProc;
{-Restore timer chip to its original state}
begin {OurExitProc}
ExitProc := SaveExitProc;
RestoreTimer;
end; {OurExitProc}
{$F-}
begin
{set up our Exit handler}
SaveExitProc := ExitProc;
ExitProc := @OurExitProc;
{reProgram the timer chip}
InitializeTimer;
{adjust For speed of machine}
Calibrate;
end.
[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]