[comp.lang.pascal] "TICKING CLOCK" THANKS FOR THE HELP/SUMMARY

asolima@hubcap.clemson.edu (abdel w soliman) (04/24/91)

Keywords:SUMMARY OF YOUR REPLIES, THANX a MILLION
Sender:Adnan Zejnilovic

April 22, 1991

Dear netters,

Some time ago I have posted a help request for "ticking" clock implementation.
I have received a lot of good advice, a program and I really do appreciate it
a lot. To be honest with you, I was pleasantly surprised with the solidarity
that you all have demonstarted for a fellow programmer.

I regret not having enough time to express my thanks to each one of you
individually. I want you to know that you have saved me hours and hours of
work. I hope to be able to share my knowledge one day as you all did with me.

Once again, thank you all very much.

Sincerely,

Adnan Zejnilovic.

P. S.

As promised, I have summarized your replies. I am sure that someone will
benefit from it.

From emory!wrdis01!mips!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!ira.uka.de!fauern!NewsServ!tritsche Thu Apr 18 10:31:56 EDT 1991
Article 6430 of comp.lang.pascal:
Path: hubcap!emory!wrdis01!mips!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!ira.uka.de!fauern!NewsServ!tritsche
>From: tritsche@Informatik.TU-Muenchen.DE (Stefan Tritscher)
Newsgroups: comp.lang.pascal
Subject: Re: Help needed - ticking clock impl.
Message-ID: <1991Apr17.082006.9933@Informatik.TU-Muenchen.DE>
Date: 17 Apr 91 08:20:06 GMT
References: <1991Apr16.124739.18124@hubcap.clemson.edu>
Sender: news@Informatik.TU-Muenchen.DE
Organization: Technische Universitaet Muenchen, Germany
Lines: 193

This is one which I wrote some time ago (works only in text mode):

Have fun,

	Stefan

--------snip, snip----------------------------------------
(******************************************************)
(*       UNIT CLOCK (C) 1990 Stefan Tritscher         *)
(*                                                    *)
(* Declaration:                                       *)
(*    PROCEDURE Start_Clock( X, Y : byte);            *)
(*    PROCEDURE Stop_Clock;                           *)
(*                                                    *)
(* Description:                                       *)
(*    Start_Clock concurrently displays the actual    *)
(*    time at position X and Y of the screen.         *)
(*    Stop_Clock stops the running Clock.             *)
(*                                                    *)
(******************************************************)

UNIT CLOCK;

INTERFACE

USES DOS,CRT;

PROCEDURE Start_Clock( X, Y : byte);

PROCEDURE Stop_Clock;


IMPLEMENTATION

VAR
   Hour      : word;
   Minute    : word;
   Second    : word;
   Int_Count : byte;
   Correct   : byte;
   XPos      : byte;
   YPos      : byte;
   SaveX     : byte;
   SaveY     : byte;
   Old_Int   : pointer;
   Old_Exit  : pointer;


{$F+}
PROCEDURE Clock_Handler; INTERRUPT; {$F-}
(* This procedure is the interrupt handler for interrupt 1CH. *)
(* It is called on every clock tick (18.2 per sec.).          *)
(* Every second the actual Time is recalculated an displayed  *)
(* at the screen.                                             *)
(* Be carefull not to use any DOS or BIOS call within an      *)
(* interrupt hander (reentrancy problem). For this reason     *)
(* the unit CRT is used for output, because it writes         *)
(* the output directly to video memory.                       *)
BEGIN
   dec(Int_Count);
   IF Int_Count = 0
   THEN BEGIN
      (* one second has passed *)

      dec(Correct);
      IF Correct = 0
      THEN BEGIN
	 (* every five seconds we must wait one tick longer *)
	 (* because we get 18.2 ticks per second            *)
         Correct := 5;
         Int_Count := 19;
      END
      ELSE Int_Count := 18;

      (* calculate new time *)

      inc(Second);
      IF Second = 60
      THEN BEGIN
         Second := 0;
         inc(Minute);
         IF Minute = 60
         THEN BEGIN
            Minute := 0;
            inc(Hour);
            IF Hour = 24
            THEN Hour := 0;
         END;
      END;

      (* display new time *)

      SaveX := wherex;
      SaveY := wherey;
      gotoxy(XPos,YPos);
      IF Hour < 10
      THEN write('0');
      write(Hour,':');
      IF Minute < 10
      THEN write('0');
      write(Minute,':');
      IF Second < 10
      THEN write('0');
      write(second);
      gotoxy(SaveX,SaveY);

      (* done *)

   END;
END;


PROCEDURE Start_Clock( X, Y : byte );
(* Start the Clock. *)
VAR
   Dummy : word;
BEGIN
   Int_Count := 18;
   Correct := 5;
   XPos := X;
   YPos := Y;

   (* get time from DOS *)
   gettime(Hour, Minute, Second, Dummy);

   (* set up Clock_Handler as interrupt handeler for int 1CH *)
   setintvec($1C, @Clock_Handler);
END;


PROCEDURE Stop_Clock;
(* Stop the Clock *)
BEGIN
   (* simply restore old handler for int 1CH *)
   setintvec($1C, Old_Int);
END;


{$F+}
PROCEDURE Error_Exit; {$F-}
(* Called on errors in TURBO PASCAL *)
BEGIN
   (* stop the clock before exit or the PC will crash. *)
   Stop_Clock;
   exitproc := Old_Exit;
END;


BEGIN
   checkbreak := FALSE;
   getintvec($1C, Old_Int);
   Old_Exit := exitproc;
   exitproc := @Error_Exit;
END.

------snip, snip-------------------------------------------------
{$R-,S+,I+,D+,F-,V+,B-,N-,L+ }
{$M 1024,0,400 }
PROGRAM Test;
USES DOS, CLOCK;

BEGIN
   (* start clock at upper right corner of screen *)
   Start_Clock(70,1);

   (* terminate but stay resident (TSR) *)
   Keep(0);
END.
------snip, snip-------------------------------------------------
                                            / relay.cs.net (CS-NET, ARPA)
tritsche%lan.informatik.tu-muenchen.dbp.de@ - unido.uucp   (UUCP)
                                             unido.bitnet (BITNET)
Munich University of Technology,  Department of Computer Science, FRG

===============================================================================

From 209507097@ucis.vill.edu Wed Apr 17 09:55:50 1991
Received: from UCIS.VILL.EDU by hubcap.clemson.edu; Wed, 17 Apr 91 09:55:48 -0400
Message-Id: <9104171355.AA16972@hubcap.clemson.edu>
Date: 17 Apr 91 08:44:00 EDT
From: "MCREE, JAMES F" <209507097@ucis.vill.edu>
Subject: RE: Help needed - ticking clock impl.
To: "asolima" <asolima@hubcap.clemson.edu>
Status: RO

Adnan,

	As one of the functions of a program that I wrote, a real-time clock is
updated.  I can send you the code if you want it.

	Basically, it's quite easy to implement.  Put the GetTime call in your
main loop which will always be executed and be sure to redisplay the time
through each iteration.  Instead of using the READ and READLN procedures for
input, use the KeyPressed and ReadKey functions.  These functions will not
pause the loop so you can keep displaying the time.  It takes a litle more
work, but you get a time which is constantly updated.

						Have a good day,

						Jim.

From TOMJ%csdserver3.csd.scarolina.edu@UNIVSCVM.CSD.SCAROLINA.EDU Tue Apr 16 14:05:54 1991
Received: from univscvm.csd.scarolina.edu by hubcap.clemson.edu; Tue, 16 Apr 91 14:05:50 -0400
Received: from mailgate.csd.scarolina.edu by UNIVSCVM.CSD.SCAROLINA.EDU (IBM VM SMTP R1.2.2MX) with TCP; Tue, 16 Apr 91 14:06:12 EDT
Received: From CSDSERVER3/WORKQUEUE by mailgate.csd.scarolina.edu
          via Charon 3.1 with IPX id 100.910416140449.384;
          16 Apr 91 14:07:00 +0500
Message-Id: <MAILQUEUE-99.910416140442.368@csdserver3.csd.scarolina.edu>
To: asolima@hubcap.clemson.edu
From: "Thomas E. Jenkins, Jr."  <TOMJ@csdserver3.csd.scarolina.edu>
Date:     16 Apr 91 14:04:41 EDT
Subject:  Re: Help needed - ticking clock impl.
Reply-To: tomj@csdserver3.csd.scarolina.EDU
X-Mailer: Pegasus Mail v2.1a.
X-Pmrqc:  1
Status: RO

Hi,

  I don't have code to help you, but what you need to do is write an
interupt procedrue.  Look up the Interupt keyword in the manual ( or with
ctrl-F1 ) to see how to decalre it.  NOTE!  Bios and DOS calls are pretty
much non-reenterant.  This means that you must output to ram, DON'T USE
WRITE and WRITELN as these call DOS to do the job.  You should get a book
that explains interupts before playing with them too much.  It is EASY to
hang your system if you aren't careful.

  What you'll need to do is attach you procedure to the clock interupt ( 1Ch
? ).  Since this interupt is called 18.2 times every second, your procedure
needs to be FAST.  Try incrementing a counter until it hits 18 and then
update the screen.  Basicly this will make your "clock" tick about every
second.  Once your program exits ( CHECK FOR ABNORMAL TERMINATION - see
ExitProc ), restore the timer/clock interupt so that your clock goes away
without hanging the system.

tom
+--------------------------------------------------------------------------+
|  Thomas E. Jenkins, Jr.   Programmer, University of South Carolina CSD   |
+--------------------------------------------------------------------------+
| BITNET         :  C0361@UNIVSCVM.BITNET  |  CSDNET  :  tomj/csdserver3   |
| INTERNET       :  TOMJ@csdserver3.csd.scarolina.EDU          {PREFERRED} |
|                :  C0361@univscvm.csd.scarolina.EDU  |  129.252.43.30     |
| FROM Compuserv :  INTERNET:TOMJ@csdserver3.csd.scarolina.EDU {PREFERRED} |
|                :  INTERNET:C0361@univscvm.csd.scarolina.EDU              |
+--------------------------------------------------------------------------+

From thoger@lise.unit.no Tue Apr 16 19:40:19 1991
Received: from lise1.lise.unit.no by hubcap.clemson.edu; Tue, 16 Apr 91 19:39:59 -0400
Received: from lise7.lise.unit.no by lise1.lise.unit.no with SMTP
	id <AA13403>; Wed, 17 Apr 91 01:39:51 +0200
From: Terje Th|gersen <thoger@lise.unit.no>
Received: by lise7.lise.unit.no ; Wed, 17 Apr 91 01:39:49 +0200
Date: Wed, 17 Apr 91 01:39:49 +0200
Message-Id: <9104162339.AA15644@lise7.lise.unit.no>
To: asolima@hubcap.clemson.edu
Status: RO


Subject: Help needed - ticking clock impl.

Hi!

You have to implement an interrupt-routine. I'm not sure right now
what the correct int is, but this should be trivial to look up. "Timer
Interrupt", the one that ticks every 18.2 seconds.  Now, hook this
with the GetIntVec(IntNo,@MyClock); procedure, and make sure
Myclock looks like this :

Procedure MyClock;

Interrupt;

VAR ...

BEGIN
.  { Insert code to see is one full second has elapsed }
.  { If so, paint the clock, *without* using interrupts! }
.  { Using Int's from within an Int is bad news.  Use the Mem[]- }
.  { command to put the char's directly to video memory }
.  { Then just Exit; your Int-procedure. }
.  { Try yo keep the code short, the "has a second elapsed" code }
.  { gets executed 18 times a second! }
END;

Most assembly books have a clock as one of the examples.  One that
comes to mind is "The IBM PC from the inside out", Sargent &
Shoemaker, Addison Wellesley 1988.

Regards,
  -Terje