program test_timer;

uses crt,dos;

Var OTimerInt    : pointer;
    Timerfreq    : word;
    Orig_freq    : word;
    Sync_counter : word;
    Ticounter    : word;

procedure SetColor (Nr, R, G, B : BYTE);
begin;
  asm
    mov   al,Nr
    mov   dx,03C8h
    out   dx,al
    mov   dx,03C9h
    mov   al,r
    out   dx,al
    mov   al,g
    out   dx,al
    mov   al,b
    out   dx,al
  end;
end;

procedure waitretrace;
begin;
  asm
    MOV   DX,03dAh
@WD_R:
    IN    AL,DX
    TEST  AL,8d
    JZ    @WD_R
@WD_D:
    IN    AL,DX
    TEST  AL,8d
    JNZ   @WD_D
  end;
end;

procedure SetTimerOn(Proc : pointer; Freq : word);
var icounter : word;
    oldv : pointer;
begin;
 asm cli end;
 icounter  := 1193180 DIV Freq;
 Port[$43] := $36;
 Port[$40] := Lo(ICounter);
 Port[$40] := Hi(ICounter);

 Getintvec(8,OTimerInt);
 SetIntVec(8,Proc);
 asm sti end;
end;

procedure New_Timerfreq(Freq : word);
var icounter : word;
begin;
 asm cli end;
 icounter  := 1193180 DIV Freq;
 Port[$43] := $36;
 Port[$40] := Lo(ICounter);
 Port[$40] := Hi(ICounter);
 asm sti end;
end;

procedure SetTimerOff;
var oldv : pointer;
begin;
  asm cli end;
  port[$43] := $36;
  Port[$40] := 0;
  Port[$40] := 0;
  SetIntVec(8,OTimerInt);
  asm sti end;
end;

procedure Syncro_interrupt; interrupt;
begin;
  inc(Sync_counter);
  port[$20] := $20;
end;

procedure Syncronize_timer;
begin;
  Timerfreq := 120;
  SetTimerOn(@Syncro_interrupt,Timerfreq);
  Repeat
    dec(Timerfreq,2);
    waitretrace;
    New_timerfreq(Timerfreq);
    Sync_counter := 0;
    waitretrace;
  until (Sync_counter = 0);
end;

procedure Timer_Handling;
begin;
  setcolor(0,0,63,0);
end;

procedure Timer_Proc; interrupt;
begin;
  Timer_Handling;
  waitretrace;
  Port[$43] := $34;                     { Mono - Flop  mode }
  Port[$40] := Lo(TiCounter);
  Port[$40] := Hi(TiCounter);

  setcolor(0,63,0,0);

  port[$20] := $20;
end;

procedure Start_Syncrotimer(Proc : pointer);
var calcl : longint;
begin;
 asm cli end;
  port[$43] := $36;
  Port[$40] := 0;
  Port[$40] := 0;

  Ticounter := 1193180 DIV (Timerfreq+5);
  setintvec(8,Proc);
  waitretrace;
  Port[$43] := $34;                     { Mono - Flop  mode }
  Port[$40] := Lo(TiCounter);
  Port[$40] := Hi(TiCounter);
 asm sti end;
end;

begin;
  clrscr;
  Syncronize_Timer;
  writeln('The timer frequency is : ',Timerfreq);
  Start_Syncrotimer(@Timer_Proc);
  repeat until keypressed;
  while keypressed do readkey;
  SetTimerOff;
  setcolor(0,0,0,0);
end.
