Board index » delphi » RTC interruption

RTC interruption

I'd like to use the periodic interruption from the RTC. Does it alreday
exist a unit that manage RTC interruption ?
Thanks.

Dominique

 

Re:RTC interruption


JRS:  In article <3990EAB5.A9846...@loaser.univ-lille1.fr> of Wed, 9 Aug
2000 07:23:01 seen in news:comp.lang.pascal.borland, Dominique

Quote
<m...@loaser.univ-lille1.fr> wrote:
>I'd like to use the periodic interruption from the RTC. Does it alreday
>exist a unit that manage RTC interruption ?

Web <URL: http://www.merlyn.demon.co.uk/programs/int70at2.pas> is a
program that does that; you might be able to adapt it.

--
? John Stockton, Surrey, UK.  j...@merlyn.demon.co.uk   Turnpike v4.00   MIME. ?
 <URL: http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
 <URL: ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ;
 <URL: http://www.merlyn.demon.co.uk/clpb-faq.txt> Pedt Scragg: c.l.p.b. mFAQ.

Re:RTC interruption


In article <Dk$8lpFEpck5E...@merlyn.demon.co.uk>, Dr says...

Quote

>JRS:  In article <3990EAB5.A9846...@loaser.univ-lille1.fr> of Wed, 9 Aug
>2000 07:23:01 seen in news:comp.lang.pascal.borland, Dominique
><m...@loaser.univ-lille1.fr> wrote:
>>I'd like to use the periodic interruption from the RTC. Does it alreday
>>exist a unit that manage RTC interruption ?

>Web <URL: http://www.merlyn.demon.co.uk/programs/int70at2.pas> is a
>program that does that; you might be able to adapt it.

Or try this:

-------------------begin unit----------------
UNIT RTCtimer;

{
This unit programs the RTC to generate interrupts,
and supplies an ISR to service the interrupts.
The ISR simply increments a counter which is used by
the app for timing.

Quote
}

INTERFACE

USES DOS;

TYPE
IpsType=(ips8192,ips4096,ips2048,ips1024,ips512,ips256,ips128,ips64,
         ips32,ips16,ips8,ips4,ips2);

CONST
_systimer : longint = 0;

Procedure Enable(rate:IpsType; var rt:integer);

Procedure Disable(var rt: integer);

Function systimer: Longint;
Inline(
  $8B/$16/>_systimer+2/ {MOV     DX,[>_systimer+2]  ; read hi word}
  $A1/>_systimer/       {MOV     AX,[>_systimer]    ; read lo word}
  $8B/$1E/>_systimer+2/ {MOV     BX,[>_systimer+2]  ; read hi word again}
  $39/$D3/              {CMP     BX,DX              ; did hi change?}
  $74/$05/              {JE      done               ; if not, AX:DX is OK}
  $A1/>_systimer/       {MOV     AX,[>_systimer]    ; re-read lo word}
$89/$DA);             {MOV     DX,BX              ; use second read of hi word}
                        {done:}

IMPLEMENTATION

CONST
OldInt70    : pointer = nil;
Int70Active : Boolean = FALSE; {to protect ENable/DISable}

Procedure Int70ISR; assembler;
{warning: do not do wild and crazy things in this ISR. It uses whatever stack
was in place at the time of the interrupt}
asm

push ax
push ds

mov     al,0Ch     { Reset interrupt at timer by reading Register C }
out     070h,al
jmp     @@y1       {these jumps are for old 386 PC's}
@@y1:
jmp     @@y2
@@y2:
jmp     @@y3
@@y3:
in      al,071H

mov     ax, seg @DATA  {Get Turbo data segment}
mov     ds,ax

{here's the RTC counter/timer:}
add word ptr _systimer, 1
adc word ptr _systimer[2], 0

mov     al,20H   {EOI}
out     0A0H,al  {send EOI to PIC2}
out     020H,al  {send EOI to PIC1}

pop ds
pop ax

iret

end;

Procedure Enable;

Begin

rt:=-1; {set error as default; clear if successful}

If Int70Active then Exit;

{ Initialize RT clock vectors }
GetIntVec($70,OldInt70);
SetIntVec($70,@Int70ISR);    { Set INT70 vector to handler routine }

asm cli end;
{ Set the Rate Selection Bits in RegisterA }
port[$70] := $A;
port[$71] := $23+ord(rate);         { Bit-encoded rate word }

{ Enable periodic interrupts from real-time clock }
port[$70] := $B;
port[$71] := $42;
asm sti end;

{ Enable Int70 }
Port[$A1] := Port[$A1] AND not 1;

rt:=0; {success}
Int70Active:=TRUE;

End;

Procedure Disable;

Begin

rt:=-1; {set error as default; clear if successful}
if OldInt70 = NIL THEN Exit;
rt:=-2;
if not Int70Active then Exit;

asm cli end;
{ Disable periodic interrupts from the AT real-time clock }
{ Note: Code here assumes that interrupt occurring between cli and
        register $B reset will be removed by the reset operation }
  port[$70] := $B;
  port[$71] := 2;  { 2=24hr clock }
{ Reset Reg A to default }
  port[$70] := $A;
  port[$71] := $26; { 0010 0110 }
asm sti end;

{ Disable Int70 }
Port[$A1] := Port[$A1] or $01;

SetIntVec($70,OldInt70);

OldInt70 := NIL;

Int70Active:=FALSE;
rt:=0;

End;

VAR
SaveExit        : pointer;
Procedure MyExit; Far;
var discard: integer;
Begin
ExitProc := SaveExit;
Disable(discard);
End;

BEGIN

SaveExit := ExitProc;                 { Set up exit procedure }
ExitProc := @MyExit;

END.
---------------------end unit-------------------

--------------begin test program--------------------
uses rtctimer,crt;

var
rt:integer;

begin

enable(ips1024,rt);
if rt<>0 then begin
  write('rt=',rt);
  halt;
  end;

repeat
write(#13,systimer:12);
until keypressed;

end.
---------------end test program---------------

No charge.

Other Threads