Free timing unit! - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Free timing unit!

BlackWolfBlackWolf Posts: 7Member
Unit ZChrono;

{*************************************************
* BlackWolf's CHRONO *
* I wrote this unit for timing uses. *
* This is freeware, and you can use *
* without any restriction. *
*************************************************}

Interface

Var
UsesDOSChrono : Boolean;
{uses borland Delay instead the system timer}
Frequenza : Word;
{timer frequency (Hz). Set BEFORE call Init}
ticks : Array[0..5] Of LongInt;
{timer counter. You must use this.}
{Don't use ticks[0]!}

Procedure Init;
{Handler initialization}
Procedure Done;
{Close timer handler and set old timer frequency. (If you don't call this procedure, at the end of program, probably the system will crash!)}
Procedure Start(NumTimer : Byte);
{Set to zero ticks[numtimer]}
Procedure Wait(del : Word);
{Same of borland Delay, but this use the setted timer}

Implementation

Uses Dos, Crt;

Const TIMERINTR = $8;
PIT_FREQ = $1234DD;

Var BIOSTimerHandler : procedure;
clock_ticks, counter : longint;

{$F+}
Procedure Tick; Interrupt;
Var
k : Byte;
Begin
For k := 0 To 5 Do
Inc(ticks[k]);
clock_ticks := clock_ticks + counter;
if clock_ticks >= $10000 then
begin
clock_ticks := clock_ticks - $10000;
asm pushf end;
BIOSTimerHandler;
asm popf end
end
else
Port[$20] := $20
End;
{$F-}

Procedure Init;
Var
k : Byte;
Begin
If Not counter = -1 Then Exit;
If UsesDOSChrono Then Exit;
For k := 0 To 5 Do
ticks[k] := 0;
clock_ticks := 0;
counter := $1234DD div Frequenza;
GetIntVec(TIMERINTR, @BIOSTimerHandler);
SetIntVec(TIMERINTR, @Tick);
Port[$43] := $34;
Port[$40] := counter mod 256;
Port[$40] := counter div 256
End;

Procedure Done;
Begin
If counter = -1 Then Exit;
If UsesDOSChrono Then Exit;
Port[$43] := $34;
Port[$40] := 0;
Port[$40] := 0;
counter := -1;
SetIntVec(TIMERINTR, @BIOSTimerHandler)
End;

Procedure Start(NumTimer : Byte);
Begin
ticks[NumTimer] := 0
End;

Procedure Wait(del : Word);
Begin
If UsesDOSChrono Then
Begin
Delay(del);
Exit
End;
Start(0);
Repeat Until ticks[0] >= del
End;

Begin
counter := -1;
Frequenza := 1000;
UsesDOSChrono := False
End.


----------------------------------------
Examples of use:


program Ex1;

uses zchrono;

begin
zchrono.init;
write('Waiting 5 seconds...');
Wait(5000);
writeln('done!');
zchrono.done
end.


program Ex2;

uses zchrono;

begin
zchrono.init;
write('Looping 5 seconds...');
start(1); {Set to zero the first counter}
while ticks[1] < 5000 do
begin
WriteLn('Waiting...');
end;
writeln('done!');
zchrono.done
end;


program Ex3;

uses zchrono;

begin
zchrono.frequenza := 100;
zchrono.init;
write('Waiting 10 seconds...');
Wait(1000);
writeln('done!');
zchrono.done
end;

--------------------------------



Enjoy!
BlackWolf

Comments

  • NordquistNordquist Posts: 49Member
    Have I understood this correctly; there is no call in any standard unit for pascal that just pauses the program execivation (NO WAY I spelled that right) for like 2 seconds. I assume this because I've already tried with stuff like
    sleep(2000);
    or
    wait(2000);
    or
    hold(2000);

    In this case: Your unit is a great solution.
    Is this true?

    If it is, please tell me what I have to do to make the text you wrote into a unit (I'm using the Free Pascal-compiler).

  • ManningManning Posts: 1,621Member
    : Have I understood this correctly; there is no call in any standard unit for pascal that just pauses the program execivation (NO WAY I spelled that right) for like 2 seconds. I assume this because I've already tried with stuff like
    : sleep(2000);
    : or
    : wait(2000);
    : or
    : hold(2000);
    :
    : In this case: Your unit is a great solution.
    : Is this true?
    :
    : If it is, please tell me what I have to do to make the text you wrote into a unit (I'm using the Free Pascal-compiler).
    :

    Try Delay(2000); - its declared in the CRT unit.

  • BlackWolfBlackWolf Posts: 7Member
    Delay function on CRT system-unit is a sufficient way to have a pause in your program. The parameters of this function is express in milliseconds but, on current our speedy pc, it's not accurate about right timing!
    To avoid this trouble, you can use just my unit. It modify the frequency of system timer (system clock is'nt affected!) and give you a good way for accurate timing.
    Easily, initialize the unit (init procedure) and use "Wait(milliseconds)" function.

    (sorry for my bad english)

  • BlackWolfBlackWolf Posts: 7Member
    : If it is, please tell me what I have to do to make the text you wrote into a unit (I'm using the Free Pascal-compiler).
    :

    Cut and paste the text (from "Unit..." to "end.") in a new text file and save it (ex: "zchrono.pas") in a directory where you store unit file. Then, in a new program (see examples in my text) declare this:

    Uses ...., ZChrono;

    ...
    ...
    ...
    begin
    ...
    ...
    Wait(2000);
    ...
    ...
    end.

Sign In or Register to comment.