home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / pascal / 7538 < prev    next >
Encoding:
Internet Message Format  |  1992-12-16  |  3.7 KB

  1. Path: sparky!uunet!wupost!waikato.ac.nz!canterbury.ac.nz!cantva!phys169
  2. Newsgroups: comp.lang.pascal
  3. Subject: Re: High speed clock
  4. Message-ID: <1992Dec17.145105.1@csc.canterbury.ac.nz>
  5. From: phys169@csc.canterbury.ac.nz
  6. Date: Thu, 17 Dec 1992 01:51:05 GMT
  7. References: <1992Nov20.091212.24871@lth.se> 
  8.  <peter.422.723796479@psychnet.psychol.utas.edu.au> <Bz47zL.5sH@news.cso.uiuc.edu> <peter.430.724488284@psychnet.psychol.utas.edu.au>
  9. Organization: University of Canterbury, Christchurch, New Zealand
  10. Nntp-Posting-Host: cantva.canterbury.ac.nz
  11. Lines: 77
  12.  
  13. In article <peter.430.724488284@psychnet.psychol.utas.edu.au>, peter@psychnet.psychol.utas.edu.au (Peter R. Tattam) writes:
  14. > In article <Bz47zL.5sH@news.cso.uiuc.edu> amead@s.psych.uiuc.edu (Alan Mead) writes:
  15. >>From: amead@s.psych.uiuc.edu (Alan Mead)
  16. >>>Does anyone out there know how to do high-speed timing?
  17. >>>The internal clock ticks with 18.2 ticks per second, and
  18. >>>sometimes this is too slow. I want a resolution of about
  19. >>>one millisecond.
  20. > Basically the idea is to reprogram the timer chip to tick at a different rate. 
  21. > ...What you have to do is change the divisor to some other number.  To 
  22. > get 1000 Hz (1 millisecond) you will need a divisor of 1193.
  23.  
  24. There is another way, avoiding reprogramming the timer. 
  25.  
  26. You can read the value of the counter out while it is counting, and use it
  27. in conjunction with the longint count of 18.2..Hz ticks at $40:$6C (probably
  28. ignore the least significant byte - you should still read it from the port
  29. though). Remember to disable interrupts for the few instructions, and read the
  30. two halves of the counter twice if you want toi take notice of the least
  31. significant byte.
  32.  
  33. The following program has two functions - one that returns the time as a real
  34. number of seconds (accurate to about 0.0005 sec on a 10Mhz AT), and one giving 
  35. the time in microticks (4770000/4 of them per second), accurate to about 90
  36. microticks (sometimes more due to the PC's timer interrupt service routine) on
  37. a 10MHz AT. Notice the lack of floating point arithmetic helps the speed.
  38.  
  39. If you have a slow PC/XT with a CMOS clock card, you may prefer to use the
  40. internal timer in that, which can give a resolution down to 1/1000th of a
  41. second if you find the correct I/O port to read, by the way.
  42.  
  43. ----snip----
  44. program HighResClock; {example program by M.Aitchison@csc.canterbury.ac.nz}
  45.  
  46. uses DOS;
  47.  
  48. function RealTime : real;
  49. const f1 = -$40000/4.77e6; f2 = f1/256;
  50. var TickCount : longint absolute $40:$6C; {approx. 18.1961 ticks per second}
  51.     TicksTimes256 : longint absolute $40:$6B;
  52.     result        : longint;
  53.     CounterHi     : byte;
  54.     CounterLo     : byte;
  55. begin
  56. inline($FC);             {DisableInterrupts}
  57. result:=TickCount;       {number of times counter has ticked over since boot}
  58. CounterLo:=port[$40];    {have to read it, even though we don't use it}
  59. CounterHi:=port[$40];
  60. inline($FB);             {EnableInterrupts}
  61. RealTime:=Result*f1 + CounterHi*f2;
  62. end;
  63.  
  64. function ExactTime : longint;
  65. var TickCount  : word absolute $40:$6C; {approx. 18.1961 ticks per second}
  66.     Part       : record LoByte,HiByte : byte;
  67.                         HighestWord   : word;
  68.                         end;
  69.     result     : longint absolute Part;
  70.     CounterHi,
  71.     CounterLo  : byte;
  72. begin
  73. DisableInterrupts;
  74. Part.HighestWord:=TickCount;
  75. CounterLo:=port[$40];
  76. CounterHi:=port[$40];    {over-write the first byte from 46Bh}
  77. Part.LoByte:=Port[$40];
  78. Part.HiByte:=Port[$40];  {read twice, in case Hi byte changed}
  79. EnableInterrupts;
  80. if CounterHi<>Part.HiByte
  81.    then Part.LoByte:=200;
  82. ExactTime:=result;       {result is units of 0.838574423 microseconds}
  83. end;
  84.  
  85. begin
  86. writeln('Takes ',RealTime-RealTime:9:6,' sec to call the RealTime function');
  87. writeln('Takes ',-(ExactTime-ExactTime):16,' microticks in ExactTime');
  88. end.
  89.