mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-27 10:33:45 +02:00
212 lines
5.3 KiB
ObjectPascal
212 lines
5.3 KiB
ObjectPascal
program simpletimer;
|
|
|
|
|
|
uses exec, timer, amigados, amigalib;
|
|
|
|
|
|
|
|
{ manifest constants -- 'never will change' }
|
|
const
|
|
SECSPERMIN = (60);
|
|
SECSPERHOUR = (60*60);
|
|
SECSPERDAY = (60*60*24);
|
|
|
|
var
|
|
seconds : longint;
|
|
tr : ptimerequest; { IO block for timer commands }
|
|
oldtimeval : ttimeval; { timevals to store times }
|
|
mytimeval : ttimeval;
|
|
currentval : ttimeval;
|
|
|
|
Function Create_Timer(theUnit : longint) : pTimeRequest;
|
|
var
|
|
Error : longint;
|
|
TimerPort : pMsgPort;
|
|
TimeReq : pTimeRequest;
|
|
begin
|
|
TimerPort := CreatePort(Nil, 0);
|
|
if TimerPort = Nil then
|
|
Create_Timer := Nil;
|
|
TimeReq := pTimeRequest(CreateExtIO(TimerPort,sizeof(tTimeRequest)));
|
|
if TimeReq = Nil then begin
|
|
DeletePort(TimerPort);
|
|
Create_Timer := Nil;
|
|
end;
|
|
Error := OpenDevice(TIMERNAME, theUnit, pIORequest(TimeReq), 0);
|
|
if Error <> 0 then begin
|
|
DeleteExtIO(pIORequest(TimeReq));
|
|
DeletePort(TimerPort);
|
|
Create_Timer := Nil;
|
|
end;
|
|
TimerBase := pointer(TimeReq^.tr_Node.io_Device);
|
|
Create_Timer := pTimeRequest(TimeReq);
|
|
end;
|
|
|
|
Procedure Delete_Timer(WhichTimer : pTimeRequest);
|
|
var
|
|
WhichPort : pMsgPort;
|
|
begin
|
|
|
|
WhichPort := WhichTimer^.tr_Node.io_Message.mn_ReplyPort;
|
|
if assigned(WhichTimer) then begin
|
|
CloseDevice(pIORequest(WhichTimer));
|
|
DeleteExtIO(pIORequest(WhichTimer));
|
|
end;
|
|
if assigned(WhichPort) then
|
|
DeletePort(WhichPort);
|
|
end;
|
|
|
|
procedure wait_for_timer(tr : ptimerequest; tv : ptimeval);
|
|
begin
|
|
tr^.tr_node.io_Command := TR_ADDREQUEST; { add a new timer request }
|
|
|
|
{ structure assignment }
|
|
tr^.tr_time.tv_secs := tv^.tv_secs;
|
|
tr^.tr_time.tv_micro := tv^.tv_micro;
|
|
|
|
{ post request to the timer -- will go to sleep till done }
|
|
DoIO(pIORequest(tr));
|
|
end;
|
|
|
|
{ more precise timer than AmigaDOS Delay() }
|
|
function time_delay(tv : ptimeval; theunit : longint): longint;
|
|
var
|
|
tr : ptimerequest;
|
|
begin
|
|
{ get a pointer to an initialized timer request block }
|
|
tr := create_timer(theunit);
|
|
|
|
{ any nonzero return says timedelay routine didn't work. }
|
|
if tr = NIL then time_delay := -1;
|
|
|
|
wait_for_timer(tr, tv);
|
|
|
|
{ deallocate temporary structures }
|
|
delete_timer(tr);
|
|
time_delay := 0;
|
|
end;
|
|
|
|
function set_new_time(secs : longint): longint;
|
|
var
|
|
tr : ptimerequest;
|
|
begin
|
|
tr := create_timer(UNIT_MICROHZ);
|
|
|
|
{ non zero return says error }
|
|
if tr = nil then set_new_time := -1;
|
|
|
|
tr^.tr_time.tv_secs := secs;
|
|
tr^.tr_time.tv_micro := 0;
|
|
tr^.tr_node.io_Command := TR_SETSYSTIME;
|
|
DoIO(pIORequest(tr));
|
|
|
|
delete_timer(tr);
|
|
set_new_time := 0;
|
|
end;
|
|
|
|
function get_sys_time(tv : ptimeval): longint;
|
|
var
|
|
tr : ptimerequest;
|
|
begin
|
|
tr := create_timer( UNIT_MICROHZ );
|
|
|
|
{ non zero return says error }
|
|
if tr = nil then get_sys_time := -1;
|
|
|
|
tr^.tr_node.io_Command := TR_GETSYSTIME;
|
|
DoIO(pIORequest(tr));
|
|
|
|
{ structure assignment }
|
|
tv^ := tr^.tr_time;
|
|
|
|
delete_timer(tr);
|
|
get_sys_time := 0;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure show_time(secs : longint);
|
|
var
|
|
days,hrs,mins : longint;
|
|
begin
|
|
{ Compute days, hours, etc. }
|
|
mins := secs div 60;
|
|
hrs := mins div 60;
|
|
days := hrs div 24;
|
|
secs := secs mod 60;
|
|
mins := mins mod 60;
|
|
hrs := hrs mod 24;
|
|
|
|
{ Display the time }
|
|
writeln('* Hour Minute Second (Days since Jan.1,1978)');
|
|
writeln('* ', hrs, ': ',mins,': ', secs,' ( ',days, ' )');
|
|
writeln;
|
|
end;
|
|
|
|
|
|
begin
|
|
writeln('Timer test');
|
|
|
|
{ sleep for two seconds }
|
|
currentval.tv_secs := 2;
|
|
currentval.tv_micro := 0;
|
|
time_delay(@currentval, UNIT_VBLANK);
|
|
writeln('After 2 seconds delay');
|
|
|
|
{ sleep for four seconds }
|
|
currentval.tv_secs := 4;
|
|
currentval.tv_micro := 0;
|
|
time_delay(@currentval, UNIT_VBLANK);
|
|
writeln('After 4 seconds delay');
|
|
|
|
{ sleep for 500,000 micro-seconds = 1/2 second }
|
|
currentval.tv_secs := 0;
|
|
currentval.tv_micro := 500000;
|
|
time_delay(@currentval, UNIT_MICROHZ);
|
|
writeln('After 1/2 second delay');
|
|
|
|
writeln('DOS Date command shows: ');
|
|
Execute('date', 0, 0);
|
|
|
|
{ save what system thinks is the time....we'll advance it temporarily }
|
|
get_sys_time(@oldtimeval);
|
|
writeln('Original system time is:');
|
|
show_time(oldtimeval.tv_secs );
|
|
|
|
writeln('Setting a new system time');
|
|
|
|
seconds := 1000 * SECSPERDAY + oldtimeval.tv_secs;
|
|
|
|
set_new_time( seconds );
|
|
{ (if user executes the AmigaDOS DATE command now, he will}
|
|
{ see that the time has advanced something over 1000 days }
|
|
|
|
write('DOS Date command now shows: ');
|
|
Execute('date', 0, 0);
|
|
|
|
get_sys_time(@mytimeval);
|
|
writeln('Current system time is:');
|
|
show_time(mytimeval.tv_secs);
|
|
|
|
{ Added the microseconds part to show that time keeps }
|
|
{ increasing even though you ask many times in a row }
|
|
|
|
writeln('Now do three TR_GETSYSTIMEs in a row (notice how the microseconds increase)');
|
|
writeln;
|
|
get_sys_time(@mytimeval);
|
|
writeln('First TR_GETSYSTIME ',mytimeval.tv_secs,'.', mytimeval.tv_micro);
|
|
get_sys_time(@mytimeval);
|
|
writeln('Second TR_GETSYSTIME ',mytimeval.tv_secs,'.', mytimeval.tv_micro);
|
|
get_sys_time(@mytimeval);
|
|
writeln('Third TR_GETSYSTIME ',mytimeval.tv_secs,'.', mytimeval.tv_micro);
|
|
writeln;
|
|
writeln('Resetting to former time');
|
|
set_new_time(oldtimeval.tv_secs);
|
|
|
|
get_sys_time(@mytimeval);
|
|
writeln('Current system time is:');
|
|
show_time(mytimeval.tv_secs);
|
|
|
|
end.
|