Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!comp.vuw.ac.nz!virtue!canterbury.ac.nz!phys169 From: phys169@canterbury.ac.nz Newsgroups: comp.os.msdos.programmer Subject: Re: How can I get a timed delay of 1 millisecond ? Message-ID: <1990Sep19.130854.9187@canterbury.ac.nz> Date: 19 Sep 90 02:54:06 GMT References: <6250@castle.ed.ac.uk> <4064@rtifs1.UUCP> Organization: University of Canterbury Lines: 55 In article <4064@rtifs1.UUCP>, bcw@rti.rti.org (Bruce Wright) writes: > In article <6250@castle.ed.ac.uk>, elee24@castle.ed.ac.uk (H Bruce) writes: >> What is the best way to get a program to wait for one milliosecond ? >> (I am using Microsoft C V5.1). > >... you can reprogram the 8253 timer if your machine > is a "true" compatible (which most are these days, but it depends > on how paranoid you need to be for this application). The problem > with reprogramming the 8253 (besides hardware compatibility issues) > is that you will then need to steal the timer interrupt from DOS, > and if you want the DOS time to remain accurate you will need to > provide DOS with a simulated interrupt every once in a while... There is a *MUCH* better way than re-programming that chip, and it is easier than using the P.I.T. chip that simple PC's don't have. It is this: Read the current count off the 8253 timer channel 0, the one normally used to provide the 18.2Hz (approx) timer tick for the system. Don't reprogram it or intercept the interrupt, simply keep looking at the current value (read port 040hex twice in a loop, LSB first, and wait for it to change 1mS/0.001193180 times - it doesn't upset anything else, is easy to program, and unlikely to be affected by anything else people may do to the chip (e.g. BASIC's reprogrammming of it). The only thing to worry about is the interval being too large because of interrupt service routines (including the system clock handler itself) taking time from your program... you could do a bit of arithmetic to calculate the counter value to wait for (but do a <= test, not =), and allow for the count wrapping when it decrements to zero, and read both successive bytes with interrupts turned off. The accuracy of the method is theoretically about 1 microsecond, but the CPU overheads starting and stopping may make this about 40uS on a 10Mh AT in a HLL. example code: {Turbo Pascal, from memory (so E&OE)} procedure WaitAMillisecond; var LastCount, PresentCount : word; CountsToGo : integer; begin DisableInterrupts; PresentCount:=Port[$40]+256*Port[$40]; EnableInterrupts; CountsToGo:=round(1.0/1.193180e3); {1.0 millisec; can be up to 27 mS} repeat LastCount:=PresentCount; DisableInterrupts; PresentCount:=Port[$40]+256*Port[$40]; EnableInterrupts; if LastCount>=PresentCount then CountsToGo:=CountsToGo-(LastCount-PresentCount) else CountsToGo:=CountsToGo-(65536-PresentCount+LastCount) until CountsToGo<=0; end; Hope this helps, Mark Aitchison, Physics, University of Canterbury, New Zealand.