UNIT Y767RTC (* Y767 Real Time Clock routines  D. J. Wilke N3HGQ 09/26/89 *);

INTERFACE

USES CRT, DOS, Y767GLO, Y767UTIL;

PROCEDURE SaveOldTimer;
PROCEDURE InstallOurTimer;
PROCEDURE RestoreOldTimer;
PROCEDURE TimerError;
PROCEDURE InitClock;

IMPLEMENTATION

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE Clock(Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP : WORD);
INTERRUPT;

VAR
    HiClock           : INTEGER ABSOLUTE $0040:$006E;
    LoClock           : INTEGER ABSOLUTE $0040:$006C;
    TimerTics         : REAL;
    HiWord, LoWord    : REAL;
    HrTemp, HrTempL   : INTEGER;
    Mins, Secs, AmPm  : STRING[2];
    HoursUTC,HoursLoc : STRING[2];
    TimeUTC,TimeLoc   : STRING[20];

BEGIN (* Clock *)
    IF ClockFlag THEN BEGIN                  (* Clock runs only if TRUE *)
        INLINE($FB);                         (* Enable interrupts *)
        TicCount := SUCC(TicCount);
        IF TicCount >17 THEN BEGIN           (* Rollover value for 1 sec *)
            HiWord := HiClock;
            LoWord := LoClock;
            IF HiWord < 0.0 THEN HiWord := 65536.0 + HiWord;
            IF LoWord < 0.0 THEN LoWord := 65536.0 + LoWord;
            TimerTics := HiWord * 65536.0 + LoWord;
            TimerTics := TimerTics / 18.206481934;
            STR((TRUNC(TimerTics / 3600.0) + TimeZone) MOD 24, HoursUTC);
            HrTemp       := TRUNC(TimerTics / 3600.0) MOD 24;
            IF HrTemp     = 0  THEN HrTempL := 12;
            IF HrTemp     > 12 THEN HrTempL := HrTemp - 12
            ELSE HrTempL := HrTemp;
            IF HrTemp     > 11 THEN AmPm    := 'PM'
            ELSE AmPm    := 'AM';
            STR(HrTempL,HoursLoc);
            IF HoursUTC[0] = #1 THEN HoursUTC := '0' + HoursUTC;
            IF HoursLoc[0] = #1 THEN HoursLoc := ' ' + HoursLoc;
            STR(TRUNC(TimerTics / 60.0) MOD 60, Mins);
            IF Mins[0]     = #1 THEN Mins  := '0' + Mins;
            STR(TRUNC(TimerTics - INT(TimerTics / 60) * 60),Secs);
            IF Secs[0]     = #1 THEN Secs         := '0' + Secs;
            TimeUTC       := '  ' + HoursUTC + Mins + ':' + Secs + ' UTC ';
            TimeLoc       := ' ' + HoursLoc + ':' + Mins + ' ' + AmPm + TZ;
            ScreenWrite(TimeLoc,65,2,CLA);
            ScreenWrite(TimeUTC,65,3,CLA);
            TicCount      := 0;
        END; (* IF TicCount *)
    END; (* IF ClockFlag *)
END; (* Clock *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE SaveOldTimer;

BEGIN (* SaveOldTimer *)
    GETINTVEC(TimerInt,OldVector);           (* Get copy of orig to save *)
END; (* SaveOldTimer *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE InstallOurTimer;

BEGIN (* InstallOurTimer *)
    SaveOldTimer;                            (* Save orig for orderly exit *)
    SETINTVEC(TimerInt,@Clock);              (* Give vector ISR(Clock) addr *)
END; (* InstallOurTimer *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
{$F+}
PROCEDURE RestoreOldTimer;

BEGIN (* RestoreOldTimer *)
    SETINTVEC(TimerInt,OldVector);           (* Put Int 1C back to what it was *)
END; (* RestoreOldTimer *)
{$F-}

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE TimerError;

BEGIN (* TimerError *)
    ErrorAlarm(TimerErr,0,12);               (* Issue Timer error warning *)
    RestoreOldTimer;
END; (* TimerError *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE InitClock; (* Set up for on-screen clock *)

BEGIN (* InitClock *)
    SaveCseg       := Cseg;
    TicCount       := 18;                    (* Number of tics per second *)
    InstallOurTimer;
END; (* InitClock *)

END. (* of UNIT Y767RTC *)
