Searching \ for '[OT] Small delays' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/timers.htm?key=delay
Search entire site for: 'Small delays'.

Exact match. Not showing close matches.
PICList Thread
'[OT] Small delays'
2000\02\16@152004 by PerErik Klarenfjord

flavicon
face
I work on a program that transfer some data via the LPT port. I need to use
very short delays, but can't figure out how to do them less than 1 us. I
will run the program on different machines and the best results should be to
use interrupts. But how ?
I appreciate any help from you. :)

/Per-Erik


____________________________________________

Per Erik Klarenfjord
Third Base Electronics
Triogatan 7
656 36  KARLSTAD

Tel: 054-837852   070-3975147
E-mail: spam_OUTpererikTakeThisOuTspam3base.net

http://www.3base.net

2000\02\17@162752 by John De Villiers

flavicon
face
you cant. something to do with bus clock speed or something. I did the same
with a linux box recently and also ran into the problem. Its explained in
one of the io.c or io.h files.

> {Original Message removed}

2000\02\18@101919 by Jose Souto

flavicon
face
The 16 bit register used for the 18ms DOS/Windows ticks at 0.8xx us
You can get small delays pooling this register. Let's say 400us.
So, 400/0.8xx ~= 500. Get the reg value + 500 and keep comparing
until you have a >=. Watch out this register wrap from 0xFFFF to
0x0000
JSouto

PerErik Klarenfjord wrote:
{Quote hidden}

2000\02\21@083632 by PerErik Klarenfjord

flavicon
face
Thanks a lot.
Do you know the address to that (0.8xxx us) register ?

I noticed some very interesting pages in a book i have.
The code can be used with 286, 386, 486 and Pentium....
To create a processor independent delay, IBM made PB4 pf port 61h toggle
every 15.085 us. That means that by monitoring PB4 of port 61h, a fixed time
delay can be obtained, as shown next from IBM PC AT BIOS. Upon entering this
subroutine called WAITF, register CX must hold the number of 15.085 us time
delays needed.

;CX = Count of 15,085 us
WAITF           PROC    NEAR
               PUSH    AX
WAITF1:
               IN      AL,61h
               AND     AL,10h  ;Check PB4
               CMP     AL,AH           ;Did it just change ?
               JE      WAITF1  ;Wait for Change
               MOV     AH,AL           ;Save the new PB4 Status
               LOOP    WAITF1  ;Continue until CX becomes 0
               POP     AX
               RET
WAITF           ENDP

Example, to create a half-second delay, set CX=33144 (33144 * 15,085 us) =
1/2 second, and then call the above routine as done by IBM PC AT BIOS.


The 16 bit register used for the 18ms DOS/Windows ticks at 0.8xx us
You can get small delays pooling this register. Let's say 400us.
So, 400/0.8xx ~= 500. Get the reg value + 500 and keep comparing
until you have a >=. Watch out this register wrap from 0xFFFF to
0x0000
JSouto

PerErik Klarenfjord wrote:
>
> I work on a program that transfer some data via the LPT port. I need to
use
> very short delays, but can't figure out how to do them less than 1 us. I
> will run the program on different machines and the best results should be
to
{Quote hidden}

2000\02\21@161210 by paulb

flavicon
face
part 0 5100 bytes
> Thanks a lot.
> Do you know the address to that (0.8xxx us) register ?

 The system timer is port $43.  There are a number of "gotcha"s.

* It is an 8-bit device!  You have to use a latch command to read it.

* Later machines are not "IBM compatible" - when they "virutalised" the
timer chip from the earlier machines, they decided to alter it a bit,
make it "simpler" etc.  There are some tricks about it I haven't full
documentation on.

* All timing routines will be distorted by interrupts.  Only code based
on reading the system timer (or keyboard chip as you mention) will be
less severely affected.  The system timer is used by Windoze to task
switch.  If you let it roll over, not only do you have to adjust the
count, but you likely lose control for 1/18 of a second at least.

* The timer counts *down*.

 Possible approach, as per attached test code: Wait until the timer has
recently rolled over (value about 65000 or so), then initiate the
action to be timed, wait for a correspondingly lesser timer count, and
finish the timed action.  The test code (which does not print out the
result until after the time delay finishes) suggests this will be about
99% reliable.  If gross overrun 1% of the time doesn't matter, this will
work.  If you can't accept the overrun, use external hardware.

> To create a processor independent delay, IBM made PB4 pf port 61h
> toggle every 15.085 us. That means that by monitoring PB4 of port 61h,
> a fixed time delay can be obtained, as shown next from IBM PC AT BIOS.

 That'll be the keyboard controller.  Presumably works still in current
machines, but same problems as system timer.

> The 16 bit register used for the 18ms DOS/Windows ticks at 0.8xx us
> You can get small delays pooling this register. Let's say 400us.
> So, 400/0.8xx ~= 500. Get the reg value + 500 and keep comparing
> until you have a >=.

 Wrong way.  It counts DOWN.

> Watch out this register wrap from 0xFFFF to 0x0000

 Yes - as above!
--
 Cheers,
       Paul B.
\\ INTTEST1.SEQ  Light Chaser Test               ver:1.00  14/10/98 P.B. Webster

{ ' noop alias   immediate

DEFINED TARGET-INIT NIP         \ Are we target compiling?
0<> #IF
       ' \    alias \F immediate       ' noop alias \T immediate
#ELSE
       ' noop alias \F immediate       ' \    alias \T immediate
#ENDIF
\ ***************************************************************************

decimal
$278        VALUE       PORT
           VARIABLE    TIMER   $40 TIMER !
$6C.0040    2CONSTANT   times
VARIABLE    PRVTIME
VARIABLE    TTIME

code RTIME      ( -- time )     \ read system timer
\T              CLEAR_LABELS
\T              SAVE_BX
               mov dx, timer           \ point to timer
               add dx, # 3             \ control register
               sub al, al              \ timer zero
               out dx, al              \  latched
               sub dx, # 3             \ timer zero
               in  al, dx              \ get the byte
               mov ah, al              \ hide it
               in  al, dx              \ get secnd byte
               xchg al, ah             \ swap them
\F              1push
\T              MOV BX, AX
\T              RET
               end-code


: TICK?         ( --- f )       \ has a tick passed?
               times @L dup prvtime @ -
               if dup prvtime ! $FF00 or else drop false then ;

: PARTICK?      ( delay --- f )       \ has a partial tick passed?
               rtime ttime @ over -
               rot > if dup ttime ! else drop false then ;

: WAITICK       BEGIN TICK? UNTIL ;

: WAITQTC       BEGIN $4000 PARTICK? UNTIL ;

: PPUT  ( c --- )       \ write to parallel port
       port pc! ;

: PGET  ( --- c )       \ read parallel port
       port pc@ ;

: CPUT  ( c --- )       \ write to control register
       $0B xor port 2+ pc! ;

: CGET  ( --- c )       \ read control register
       port 2+ pc@ $0B xor ;


\ Control register bit: 0: Pin 1
\                       1: Pin 14
\                       2: Pin 16
\                       3: Pin 17

400 value tard

: dally tard 0 do loop ;


: poff  ( shut off drivers )    0 pput 0 cput ; poff

variable tmax   variable tmin
variable tstart 1000 tstart !   \ tstart is test delay time

: 1stime        ( -- time )     \ Waits for 500 < ticks < 1000 and reports
       begin
           rtime dup -1000 u<
           over -500 u> or
       while drop repeat ;

: loint         ( -- delay )    \ Waits prescribed delay, reports actual delay
       1stime dup tstart @ -
       begin rtime 2dup u< while drop repeat
       nip dup u. - dup u. cr ;

: int1000                       \ Do this a thousand times!
       cr 0 tmax ! 32000 tmin !
       1000 0 do
           loint
           dup tmax @ max tmax !
           tmin @ min tmin !
       loop
       tmin @ ." Minimum of" tstart @ . ."  = " . cr
       tmax @ ." Maximum of" tstart @ . ."  = " .
       cr ;




2000\02\21@162242 by Jose Souto

flavicon
face
part 0 177 bytes
PerErik Klarenfjord wrote:
>
> Thanks a lot.
> Do you know the address to that (0.8xxx us) register ?
Attachment converted: wonderland:Delay.zip (pZIP/pZIP) (00018049)

2000\02\21@163042 by Jose Souto

flavicon
face
You are right (as always, I see). Digging my files I
found the Delay stuff I used and the hole thing counts
down. I used to set the 16 bit register (Counter #2)
with the desired delay value and wait until it gets <= zero.
Sorry for the wrong info.
JSouto

"Paul B. Webster VK2BZC" wrote:
{Quote hidden}

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...