home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!wupost!waikato.ac.nz!canterbury.ac.nz!cantva!phys169
- Newsgroups: comp.lang.pascal
- Subject: Re: High speed clock
- Message-ID: <1992Dec17.145105.1@csc.canterbury.ac.nz>
- From: phys169@csc.canterbury.ac.nz
- Date: Thu, 17 Dec 1992 01:51:05 GMT
- References: <1992Nov20.091212.24871@lth.se>
- <peter.422.723796479@psychnet.psychol.utas.edu.au> <Bz47zL.5sH@news.cso.uiuc.edu> <peter.430.724488284@psychnet.psychol.utas.edu.au>
- Organization: University of Canterbury, Christchurch, New Zealand
- Nntp-Posting-Host: cantva.canterbury.ac.nz
- Lines: 77
-
- In article <peter.430.724488284@psychnet.psychol.utas.edu.au>, peter@psychnet.psychol.utas.edu.au (Peter R. Tattam) writes:
- > In article <Bz47zL.5sH@news.cso.uiuc.edu> amead@s.psych.uiuc.edu (Alan Mead) writes:
- >>From: amead@s.psych.uiuc.edu (Alan Mead)
- >>>Does anyone out there know how to do high-speed timing?
- >>>The internal clock ticks with 18.2 ticks per second, and
- >>>sometimes this is too slow. I want a resolution of about
- >>>one millisecond.
- >
- > Basically the idea is to reprogram the timer chip to tick at a different rate.
- > ...What you have to do is change the divisor to some other number. To
- > get 1000 Hz (1 millisecond) you will need a divisor of 1193.
-
- There is another way, avoiding reprogramming the timer.
-
- You can read the value of the counter out while it is counting, and use it
- in conjunction with the longint count of 18.2..Hz ticks at $40:$6C (probably
- ignore the least significant byte - you should still read it from the port
- though). Remember to disable interrupts for the few instructions, and read the
- two halves of the counter twice if you want toi take notice of the least
- significant byte.
-
- The following program has two functions - one that returns the time as a real
- number of seconds (accurate to about 0.0005 sec on a 10Mhz AT), and one giving
- the time in microticks (4770000/4 of them per second), accurate to about 90
- microticks (sometimes more due to the PC's timer interrupt service routine) on
- a 10MHz AT. Notice the lack of floating point arithmetic helps the speed.
-
- If you have a slow PC/XT with a CMOS clock card, you may prefer to use the
- internal timer in that, which can give a resolution down to 1/1000th of a
- second if you find the correct I/O port to read, by the way.
-
- ----snip----
- program HighResClock; {example program by M.Aitchison@csc.canterbury.ac.nz}
-
- uses DOS;
-
- function RealTime : real;
- const f1 = -$40000/4.77e6; f2 = f1/256;
- var TickCount : longint absolute $40:$6C; {approx. 18.1961 ticks per second}
- TicksTimes256 : longint absolute $40:$6B;
- result : longint;
- CounterHi : byte;
- CounterLo : byte;
- begin
- inline($FC); {DisableInterrupts}
- result:=TickCount; {number of times counter has ticked over since boot}
- CounterLo:=port[$40]; {have to read it, even though we don't use it}
- CounterHi:=port[$40];
- inline($FB); {EnableInterrupts}
- RealTime:=Result*f1 + CounterHi*f2;
- end;
-
- function ExactTime : longint;
- var TickCount : word absolute $40:$6C; {approx. 18.1961 ticks per second}
- Part : record LoByte,HiByte : byte;
- HighestWord : word;
- end;
- result : longint absolute Part;
- CounterHi,
- CounterLo : byte;
- begin
- DisableInterrupts;
- Part.HighestWord:=TickCount;
- CounterLo:=port[$40];
- CounterHi:=port[$40]; {over-write the first byte from 46Bh}
- Part.LoByte:=Port[$40];
- Part.HiByte:=Port[$40]; {read twice, in case Hi byte changed}
- EnableInterrupts;
- if CounterHi<>Part.HiByte
- then Part.LoByte:=200;
- ExactTime:=result; {result is units of 0.838574423 microseconds}
- end;
-
- begin
- writeln('Takes ',RealTime-RealTime:9:6,' sec to call the RealTime function');
- writeln('Takes ',-(ExactTime-ExactTime):16,' microticks in ExactTime');
- end.
-