🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #2286

Re: How can I get a timed delay of 1 millisecond ?

#2286
From: phys169
Date: Wed, 19 Sep 1990 02:54
55 lines
3107 bytes
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.
Technical Details
Message-ID: <1990Sep19.130854.9187@canterbury.ac.nz>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!comp.vuw.ac.nz!virtue!canterbury.ac.nz!phys169
References: <6250@castle.ed.ac.uk> <4064@rtifs1.UUCP>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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