program test_timer;

uses crt,dos;

Var OTimerInt  : pointer;
    Timerfreq    : word;
    Orig_freq    : word;
    Sync_counter : word;
    Tizaehler    : 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 StelleTimerEin(Proc : pointer; Freq : word);
var izaehler : word;
    oldv : pointer;
begin;
 asm cli end;
 izaehler := 1193180 DIV Freq;
 Port[$43] := $36;
 Port[$40] := Lo(IZaehler);
 Port[$40] := Hi(IZaehler);

 Getintvec(8,OTimerInt);
 SetIntVec(8,Proc);
 asm sti end;
end;

procedure Neue_Timerfreq(Freq : word);
var izaehler : word;
begin;
 asm cli end;
 izaehler := 1193180 DIV Freq;
 Port[$43] := $36;
 Port[$40] := Lo(IZaehler);
 Port[$40] := Hi(IZaehler);
 asm sti end;
end;

procedure StelleTimerAus;
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;
  StelleTimerEin(@Syncro_interrupt,Timerfreq);
  Repeat
    dec(Timerfreq,2);
    waitretrace;
    Neue_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  Modus }
  Port[$40] := Lo(TiZaehler);
  Port[$40] := Hi(TiZaehler);

  setcolor(0,63,0,0);

  port[$20] := $20;
end;

Procedure Starte_Syncrotimer(Proc : pointer);
var calcl : longint;
begin;
 asm cli end;
  port[$43] := $36;
  Port[$40] := 0;
  Port[$40] := 0;

  Tizaehler := 1193180 DIV (Timerfreq+5);
  setintvec(8,Proc);
  waitretrace;
  Port[$43] := $34;                     { Mono - Flop  Modus }
  Port[$40] := Lo(TiZaehler);
  Port[$40] := Hi(TiZaehler);
 asm sti end;
end;

begin;
  clrscr;
  Syncronize_Timer;
  writeln('Die Timerfrequenz ist : ',Timerfreq);
  Starte_Syncrotimer(@Timer_Proc);
  repeat until keypressed;
  while keypressed do readkey;
  StelleTimerAus;
  setcolor(0,0,0,0);
end.
