program Test_Tick;

{Test nejprve automaticky otestuje nasledujici vlastnosti knihovny Tick:
  ActIRQTime
  FastIRQTime
  DefIRQTime
  FastIRQpSec
  DefIRQpSec
 a jejich nastaveni po funkcich
  SetTickDivider(1);
  SetTimeUser1(55e-3);
  SetTimeUser1(1e-3);
  SetTickDivider(55);
  SetTimeUser1(5e-3);
  SetTickDivider(11);
  SetTimeUser1(10e-3);
  DoneTick;

 Pote nastavi zrychleny a i zpomaleny casovac a na obrazovku vypisuje
 citace v jednotlivych casovacich
}

uses
  Crt,
  Dos,
  HWsyst,
  Tick,
 {$ifdef KitV40}
  ChnVirt,
  ChnV40_,
 {$endif}
  Timer;

const
  cVerApp = '01.10,16.11.2004'; {verze tohoto testu}

const
  MyOldInt8 : pointer = nil;
  CounterMyNew   : word = 0; {citac, ktery se zvetsuje +1 v MyNewInt8}
  CounterMyTick1 : word = 0; {citac, ktery se zvetsuje +1 v MyTick1}
  CounterMyTick2 : word = 0; {citac, ktery se zvetsuje +1 v MyTick2}
  MyTimer : tTimer = (); {casovac pro overeni citani}

{$F+}
procedure MyNewInt8; interrupt;
{$F-}
begin
  Inc(CounterMyNew);
  asm
     pushf {musime ulozit priznaky, aby je MyOldInt8 mohla obnovit}
     call [MyOldInt8]
  end;
end;

procedure MyTick1; far;
begin
  Inc(CounterMyTick1);
  if CounterMyTick1=10000 then
  begin {pri preteceni citace, vynulujeme take ty ostatni}
    MyTimer.SaveTime;
    CounterMyNew   := 0;
    CounterMyTick1 := 0;
    CounterMyTick2 := 0;
  end;
end;

procedure MyTick2; far;
begin
  Inc(CounterMyTick2);
end;

procedure BaseTest;
var P1,P2:pointer;
  procedure Err(I:byte);
  begin
    writeln('Chyba ',I);
    writeln('ActIRQtime: ',ActIRQtime,'   DefIRQtime: ',DefIRQtime,'   FastIRQtime: ',FastIRQtime);
    writeln('ActIRQpSec: ',ActIRQpSec,'   DefIRQpSec: ',DefIRQpSec,'   FastIRQpSec: ',FastIRQpSec);
    delay(1000);
    RunError(I);
  end;
begin
  GetIntVec($08,P1);
  InitTickI;

  if ActIRQTime<>DefIRQTime then Err(1);
  if FastIRQTime<>DefIRQTime then Err(2);
  if Round(FastIRQpSec*10000)<>Round(DefIRQpSec*10000) then Err(3);

  SetTickDivider(1);{55ms}
  if ActIRQTime<>DefIRQTime then Err(4);
  if FastIRQTime<>DefIRQTime then Err(5);
  if Round(FastIRQpSec*10000)<>Round(DefIRQpSec*10000) then Err(6);

  SetTimeUser1(55e-3);{55ms}
  if ActIRQTime<>DefIRQTime then Err(7);
  if FastIRQTime<>DefIRQTime then Err(8);
  if Round(FastIRQpSec*10000)<>Round(DefIRQpSec*10000) then Err(9);

  SetTimeUser1(1e-3);{1ms}
  if ActIRQTime<>DefIRQTime then Err(10);
  if FastIRQTime*55<>DefIRQTime then Err(11);
  if Round(FastIRQpSec)<>1000 then Err(12);

  SetTickDivider(55);{1ms}
  if ActIRQTime<>DefIRQTime then Err(13);
  if FastIRQTime*55<>DefIRQTime then Err(14);
  if (Round(FastIRQpSec)>1002)or {zde povolime jistou toleranci, jelikoz SetTickDivider nenastavuje UserTick1 tak presne}
     (Round(FastIRQpSec)< 998) then Err(15);

  SetTimeUser1(5e-3);{5ms}
  if ActIRQTime<>DefIRQTime then Err(16);
  if FastIRQTime*11<>DefIRQTime then Err(17);
  if Round(FastIRQpSec)<>(1000 div 5) then Err(18);

  SetTickDivider(11);{5ms}
  if ActIRQTime<>DefIRQTime then Err(19);
  if FastIRQTime*11<>DefIRQTime then Err(20);
  if Round(FastIRQpSec)<>(1000 div 5) then Err(21);

  SetTimeUser1(10e-3);{10ms}
  if ActIRQTime<>10*GetTickDivider then Err(22);
  if FastIRQTime*55<>DefIRQTime*10 then Err(23);
  if Round(FastIRQpSec)<>(1000 div 10) then Err(24);

  DoneTick;
  if ActIRQTime<>DefIRQTime then Err(25);
  if FastIRQTime<>DefIRQTime then Err(26);
  if Round(FastIRQpSec*10000)<>Round(DefIRQpSec*10000) then Err(27);
  GetIntVec($08,P2);
  if P1<>P2 then Err(28);
end;

{$ifdef KitV40}
procedure InitComV40;
var P:pChnVirt;
begin
  P:=New(pChnV40_,Init);
  P^.ChSetParam('NAM=V40_ LRB=1000 BD=38400');
  P^.ChOpen;
  P^.ChConnect;
end;
{$endif}

const
  cTstTickFast =  1; {perioda [ms] pro zrychleny casovac}
  cTstTickNorm = 10; {perioda [ms] pro normalni casovac}

var LCntMyNew,
    LCntMyTick1,
    LCntMyTick2,
    LCntTimer:longint;
    P:pointer;
Begin
  BaseTest;

  GetIntVec($08,MyOldInt8); {ulozime obsluhu preruseni}
  SetIntVec($08,@MyNewInt8);{nastavime vlastni obsluhu preruseni}

  InitTickI;{inicializujeme driver pro zrychleny casovac}
  SetTimeUser1(cTstTickFast*1e-3);
  SetTimeUser2(cTstTickNorm*1e-3);
  MyTimer.SaveTime;
  asm cli end;
  UserTick1:=MyTick1;{vola se ve zrychlene obsluze preruseni casovace}
  UserTick2:=MyTick2;{vola se ve standardni obsluze preruseni casovace}
  asm sti end;
  {tj. MyTick1 je volan s periodou 1ms,
       MyTick2 s periodou 55ms a
       MyNewInt8 rovnez s periodou 55ms}
  ClrScr;
  writeln('Test1 jednotky Tick');
  writeln('Verze testu  : ',cVerApp);
  writeln('Verze Tick   : ',Tick.cVer);
  repeat
    gotoxy(10,4);
    if FlTick1Over then write('Tick1Over!!! ');
    gotoxy(25,4);
    if FlTick2Over then write('Tick2Over!!! ');
    asm pushf; cli end;
    LCntMyNew  :=CounterMyNew;
    LCntMyTick1:=CounterMyTick1;
    LCntMyTick2:=CounterMyTick2;
    LCntTimer:=MyTimer.ReadTime;
    asm popf end;
    gotoxy(1,5);
    writeln('CounterMyInt8  :',LCntMyNew  :6,' [',cTstTickNorm:2,'ms]');
    writeln('CounterNormTick:',LCntMyTick2:6,' [',cTstTickNorm:2,'ms]');
    writeln('CounterFastTick:',LCntMyTick1:6,' [',cTstTickFast:2,'ms]');
    writeln('Timer    :      ',LCntTimer  :6,' [',cTstTickFast:2,'ms]');
    if Abs(LCntMyNew-(LCntMyTick1 div ActIRQtime))   > 1{povolena tolerance} then
      RunError(10);
    if Abs((LCntMyTick1 div ActIRQtime)-LCntMyTick2) > 1{povolena tolerance} then
      RunError(10);
    if Abs(LCntMyTick2-(LCntTimer div ActIRQtime))   > 1{povolena tolerance} then
      RunError(10);
  until keypressed;
  DoneTick;
  GetIntVec($08,P);
  if P<>@MyNewInt8 then RunError(10);
End.
