home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PASCAL / MICROT.ZIP / TIMING.PAS
Pascal/Delphi Source File  |  1990-10-11  |  5KB  |  143 lines

  1. (* Several programs have been evaluated for accurate time delay procedures
  2. with accuracy greater than the Turbo Pascal 1 millisecond resolution. A few
  3. have used the computer clock timing chip, resetting the chip then following
  4. procedures:
  5.  
  6.   procedure Initialize;
  7.     {-Reprogram the timer chip to allow 1 microsecond resolution}
  8.   begin                      {InitializeTimer}
  9.     {select timer mode 2, read/write channel 0}
  10.     Port[$43] := $34;        {00110100b}
  11.     inline($EB/$00);         {jmp short $+2 ;delay}
  12.     Port[$40] := $00;        {LSB = 0}
  13.     inline($EB/$00);         {jmp short $+2 ;delay}
  14.     Port[$40] := $00;        {MSB = 0}
  15.   end;                       {InitializeTimer}
  16.  
  17.   procedure Restore;
  18.     {-Restore the timer chip to its normal state}
  19.   begin                      {RestoreTimer}
  20.     {select timer mode 3, read/write channel 0}
  21.     Port[$43] := $36;        {00110110b}
  22.     inline($EB/$00);         {jmp short $+2 ;delay}
  23.     Port[$40] := $00;        {LSB = 0}
  24.     inline($EB/$00);         {jmp short $+2 ;delay}
  25.     Port[$40] := $00;        {MSB = 0}
  26.   end;                       {RestoreTimer}
  27.  
  28. The use of the above has been found to stop the time function if TSR or
  29. application programs require reporting the then current time. As a result
  30. the computer time has to be reset using the DOS "time" commnad.
  31.  
  32. An alternative has been found which uses the timer chip that drives the
  33. speaker within the computer. The same timing accuracy is the basis for
  34. measurement, i.e., the counts per second are 1193181.667. The actual
  35. resolution therefore is 0.838 microsecond per count. No resetting of the
  36. computer time clock is required however. The Port that is read if either
  37. Port[$61] or Port[$62], depending on your computer type (AT or XT).
  38. The following is an example of how to use the new timing procedure *)
  39.  
  40. Program TimeTest;
  41. {$M 1024,10240,10240}
  42.  
  43. Uses Crt;
  44.  
  45. Var
  46.  machineID : Byte absolute $FFFF : $000E;
  47. (* Information return from Byte $FFFF : $000E for various Machines:
  48.           $FF   PC
  49.           $FE   XT
  50.           $FB   Later Model XT
  51.           $FD   PC Junior
  52.           $FC   XT-286, AT, PS/2 Model 50 & 60
  53.           $FA   PS/2 Model 30
  54.           $F9 : PC Convertible
  55.           $F8 : PS/2 Model 70 & 80 *)
  56.  read_port : byte;         (* port to read, depending on Machine code *)
  57.  clock_count : longint;    (* Longint used to allow over a second timing
  58.                               with multiples of 1193182 counts per second
  59.                               and up to 2147483647/1193182 = 1799.8 seconds
  60.                               (30 minutes) *)
  61.  
  62. Procedure Test_Delay_Timing;
  63. var
  64.   Count : longint;
  65.   Accum_Count : word;
  66.   Ch : Char;
  67.   I, J : Shortint;
  68.   CStr : string[5];
  69.   err : Integer;
  70.  
  71. Begin
  72. if MachineID = $FB then read_port := $62 else read_port := $61;
  73. ClrScr;
  74. writeLn('Enter delay time to test in decimal Microseconds');
  75. WriteLn('100000 Microseconds will equal a Second, entry over');
  76. Writeln('up to 65536 Microseconds allowed, default to 55536 Microseconds maximum');
  77.  
  78. repeat
  79. Readln(CStr);
  80. val(CStr,count,err);
  81. writeln('Count       ',count);
  82. writeln('lo(count)   ',lo(count));
  83. writeln('hi(count)   ',hi(count));
  84. if MachineID = $FB then read_port := $62 else read_port := $61;
  85. writeln('MachineId   ',machineID);
  86. writeln('Read_Port   ',read_port);
  87. Port[$43] := $B2;              {Set timer chip to one shot mode*}
  88. (* Program timer chip, lower byte first then higher byte *)
  89. Port[$42] := lo(count);        {lower byte}
  90. Port[$42] := hi(count);        {higher byte}
  91.  
  92. Accum_Count := 0;
  93. Port[$61] := Port[$61] AND $FC;{trigger timer}
  94. port[$61] := Port[$61] OR  $01;{start count at 1}
  95. (* Bit 5 of I/O port remains low until clock cycles = count *)
  96.  
  97. for I := 1 to 10 do
  98. begin
  99. repeat
  100.  
  101. until Port[$61] AND $20 <> 0; {read bit 5 until low,
  102.                                AND $20 allows read bit 5 only }
  103.  
  104. Port[$61] := Port[$61] AND $FC;{trigger timer}
  105. port[$61] := Port[$61] OR  $01;{start count at 1}
  106. Accum_Count := Accum_Count + Port[Read_Port];
  107. end;
  108.  
  109. writeln(Accum_Count,' Number of counts');
  110. writeLn(Accum_Count/1193182*1000000:0:1,' Microseconds delay');
  111. until count = 0;
  112. end;
  113.  
  114. Procedure Test_Write_to_Screen_time;
  115. var
  116.   X, Y, I : Shortint;
  117.   Count : Longint;
  118.   Ch : Char;
  119.  
  120. Begin
  121. if MachineID = $FB then read_port := $62 else read_port := $61;
  122. Port[$43] := $B2;              {Set timer chip to one shot mode*}
  123. Port[$61] := Port[$61] AND $FC;{trigger timer}
  124. port[$61] := Port[$61] OR  $01;{start count at 1}
  125.  
  126. For X := 1 to 80 do {Columns}
  127.     For Y := 1 to 25 do {Rows}
  128.         Begin
  129.         Gotoxy(X,Y);
  130.         Write('A');
  131.         End;
  132. Count := Port[read_port]; {read counts}
  133. WriteLn(Count,' Clock counts occurred');
  134. writeLn(Count/1193182*1000000:0:1,' Microseconds to write 80 characters');
  135.  
  136. Ch := ReadKey;
  137. end;
  138.  
  139. BEGIN
  140. clrscr;
  141. Test_Write_to_Screen_time;
  142. Test_Delay_Timing;
  143. End.