[Back to INTERRUP SWAG index]  [Back to Main SWAG index]  [Original]

{
CARLOS BEGUIGNE
}
Program ClockOnScreen;

{$R-,V-,S-,M 1024, 0, 0

  ClockOnScreen - Installs resident clock on upper right corner of screen.

{$IFOPT S+ }

{
  You must disable stack checking here, since a Runtime error 202 will
  be generated whenever the stack Pointer (as returned by SPtr) is likely
  to drop below 1024.
}
Uses
  Dos, Crt;
Const
  Offset       = $8E;    { Line 1, Column $8E/2 = 71 }
  TimerTick    = $1C;                  { Timer interrupt }
  black        = 0;
  gray         = 7;
  EnvSeg       = $002C;                { Segment of Dos environment }
  ColourSeg    = $B800;                { Segment of colour video RAM }
  MonoSeg      = $B000;                { Segment of monochrome ideo RAM }
  CrtSegment   : Word = ColourSeg;

Type
  ScreenArray  = Array[0..7] of Record
    number, attribute : Char;
  end;

  ScreenPtr    = ScreenArray;

Var
  VideoMode    : Byte Absolute $0000:$0449;
  Screen       : ^ScreenPtr;            { Physical screen address }
  ClockColour  : Char;
  Int1CSave    : Procedure;

Procedure ShowTime; Interrupt;
Const
  separator    = ':';
Var
  ThisMode     : Byte;
  Time         : LongInt;
  i            : Integer;
  BIOSTicker   : LongInt Absolute $0000:$046C;

  Procedure DisplayDigit(offset : Integer; digit : Integer);
  begin
    Screen^ [offset].number := Chr(digit div 10+Ord('0'));
    Screen^ [offset+1].number := Chr(digit mod 10+Ord('0'));
  end;  { DisplayDigit }

begin
  ThisMode := VideoMode;
  if not ((ThisMode = 2) or (ThisMode = 3) or (ThisMode = 7)) Then
    Exit;                              { Do not popup in a Graphic mode }
  For i := 0 to 7 Do
    Screen^[i].attribute := ClockColour;
  Time := (1365*BIOSTicker) div 24852;
  DisplayDigit(0, Time div 3600);      { hours }
  Screen^[2].number := separator;
  Time := Time mod 3600;
  DisplayDigit(3, Time div 60);        { minutes }
  Screen^[5].number := separator;
  DisplayDigit(6, Time mod 60);        { seconds }
  Inline($9C); { PUSHF }
  Int1CSave;
end;  { ShowTime }

Procedure Release(segment : Word);
InLine(
  $07/                 { POP   ES       ; get segment of block to release }
  $B4/$49/             { MOV   AH, 49h  ; Free Allocated Memory }
  $CD/$21);            { INT   21h      ; call Dos }

begin  { ClockOnScreen }
  if VideoMode = 7 Then
    CrtSegment := MonoSeg;
  ClockColour := Chr(gray*16+black);      {display video attribute }
  Screen := Ptr(CrtSegment, Offset);
  GetIntVec(TimerTick, @Int1CSave);
  SetIntVec(TimerTick, @ShowTime);
  Release(MemW[PrefixSeg:EnvSeg]);        {Release the environment }
  Keep(0);
  readln;
end.  { ClockOnScreen }


[Back to INTERRUP SWAG index]  [Back to Main SWAG index]  [Original]