[comp.os.msdos.programmer] Generating delays

melling@cs.psu.edu (Michael D Mellinger) (03/04/91)

I need to be able to generate delays of around 1/2 second.  Anyone
have a good way of doing this?  I'm using MS C 6.0.  The best I can
come up with is a 1 second delay.

Also, how does MS C compare with Borland C++ and Zortech C++?  Borland
and Zortech seem to be more aggressive at updating their compilers.
Is ObjectVision good?  It sounds like it might give Borland a definite
edge over Zortech.  I know this is a FAQ, but things seemed to have
changed a lot recently in the PC C world.  At least as far as the
other guys are concerned.  MS did release a bug fix, so everyone can
safetly use 6.0 now :-).

-Mike

tlglenn@cs.arizona.edu (Ted L. Glenn) (03/04/91)

     One quick fix for generating delays is to fool around with loops. Doesn't
look good, but works. I can't remember, is there a sleep command in C?

-- 
        -Ted L. Glenn             "Don't worry, be happy!" <--Ack! Pffffhhht!
         tlglenn@cs.arizona.edu
         G19382105@ccit.arizona.edu    G19382105@ARIZRVAX.BITNET

melling@cs.psu.edu (Michael D Mellinger) (03/04/91)

In article <1010@caslon.cs.arizona.edu> tlglenn@cs.arizona.edu (Ted L. Glenn) writes:


	One quick fix for generating delays is to fool around with loops. Doesn't
   look good, but works. I can't remember, is there a sleep command in C?


That's machine dependant.  My program will run on an 8088 and a 80486.

-Mike

valley@uchicago (Doug Dougherty) (03/04/91)

melling@cs.psu.edu (Michael D Mellinger) writes:


>I need to be able to generate delays of around 1/2 second.  Anyone
>have a good way of doing this?  I'm using MS C 6.0.  The best I can
>come up with is a 1 second delay.

When I need a delay, I just do something like this:
(This is for the A86 assembler, and assumes a .RADIX 16, since all
values are in hex)

delay:	xor ax,ax
	mov ds,ax
	les bx,[1C*4]
	mov [1C*4],offset int1c
	mov [1C*4+2],cs
L1:	cmp word cs:[ticks],9		; 9 for 1/2 second delay
	jb L1
	mov [1C*4],bx
	mov [1C*4+2],es
	mov ds,cs
	ret
ticks:	dw 0

int1c:	inc word cs:[ticks]
	iret

You oughta be able to get this to work in C somehow.  Note that this isn't 
100% right, since I don't chain to the original INT1C vector, but it is,
as they say, good enough for government work...

joe@proto.com (Joe Huffman) (03/05/91)

melling@cs.psu.edu (Michael D Mellinger) writes:

>I need to be able to generate delays of around 1/2 second.  Anyone
>have a good way of doing this?  I'm using MS C 6.0.  The best I can
>come up with is a 1 second delay.

Depending on your machine that may be the best you can do.  For
example the Hitachi 2020 (sold in Japan only) only generates (at least 
4 years ago when I was looking at the problem) a clock tick once per second.
For more convential machines you can use msleep(500) (millisecond sleep) 
if you were using the Zortech compiler.

>Also, how does MS C compare with Borland C++ and Zortech C++?  Borland

If MSC doesn't have this function or handle C++ code then it's deficient
in at least two areas.  Other comments from me about MSC would be too biased 
to be worth your time reading.

---
Zortech mailing list: send email to 'ztc-list-request@uunet.uu.net' with:
Add: your-user-name@your-machine-name
In the body of the message.
---
Send Zortech bug reports to 'zortech-bugs@zortech.com'
Send requests for educational discounts to 'zortech-ed@zortech.com'
---
Zortech is my major source of income.  Statements about them or their 
competitors cannot be totally without bias.  
-- 
joe@proto.com

sdawalt@valhalla.wright.edu (Shane Dawalt) (03/05/91)

From article <1010@caslon.cs.arizona.edu>, by tlglenn@cs.arizona.edu (Ted L. Glenn):
> 
>      One quick fix for generating delays is to fool around with loops. Doesn't
> look good, but works. I can't remember, is there a sleep command in C?
> 
  The sleep command in Turbo C (C++) has 1 second resolution.  Loop are not
portable between machines due to different CPU speeds.  About the only real
fix is to take control of the timer tick interrupt.

  Shane();

--------------------------------------------------------------------------
From the keyboard of:			     email: sdawalt@cs.wright.edu
	Shane A. Dawalt
--------------------------------------------------------------------------

mikel@teda.UUCP (Mikel Lechner) (03/05/91)

melling@cs.psu.edu (Michael D Mellinger) writes:

> I need to be able to generate delays of around 1/2 second.  Anyone
> have a good way of doing this?  I'm using MS C 6.0.  The best I can
> come up with is a 1 second delay.

Here's some assembler for doing a 10-second delay using DOS's int 21h
function 2ch call to retrieve the time.  You may be able to modify this
to use the hundredths field instead of the seconds field to get delays
of fractions of a second.  I haven't tried this.

One caveat, Ray Duncan's book "Advanced MS DOS Programming" says:

	On most IBM PC-compatible systems, the real-time clock does not
	have the resolution of single hundredths of seconds.  On such
	machines, the values returned by this function in register DL
	are discontinuous.

I interpret this to mean the hundredths position does not increment
by 1, but by a larger value.  Therefore a simple test for equality
will not suffice.  I've included this  snipit of assembler which may
give you a starting point to solve this problem.

;
; This program scans the keyboard for 10 seconds looking for a typed
; key.  If no key is pressed, exit is normal, otherwise, exit with
; non-zero exit code.
;
; Author:	Mikel Lechner
; Date:		2/18/91
;

_text	segment	word public 'CODE'
	assume	cs:_text,ds:_data,es:_data,ss:stack

main	proc	far

	mov	ax,_data	; Set up data segment registers
	mov	ds,ax
	mov	es,ax

	mov	ah,2ch		; Get time of day
	int	21h
	add	dh,10		; Compute 10 secs into future
	cmp	dh,60		;   modulo 60
	jl	noadj
	sub	dh,60
noadj:
	mov	when,dh

again:
	mov	ah,6		; Check for pressed keyboard key
	mov	dl,0ffh
	int	21h
	jnz	gotit		; Yep, exit with code 1

	mov	ah,2ch		; Check for target time (seconds)
	int	21h
	cmp	dh,when
	jne	again		; Loop again
	mov	al,0
	jmp	done

gotit:
	mov	al,1

done:
	mov	ah,4ch
	int	21h

main	endp

_text	ends

_data	segment word public 'DATA'

when	db	0

_data	ends


stksiz	equ	64

stack	segment	para stack 'STACK'
	db	stksiz dup (?)
stack	ends

	end	main


-- 
Mikel Lechner			UUCP:  teda!mikel
Teradyne EDA, Inc.
5155 Old Ironsides Drive	| If you explain so clearly that nobody
Santa Clara, Ca 95054		| can misunderstand, somebody will.

ahodgson@athena.mit.edu (Antony Hodgson) (03/06/91)

>  The sleep command in Turbo C (C++) has 1 second resolution.  Loop are not
>portable between machines due to different CPU speeds.  About the only real
>fix is to take control of the timer tick interrupt.
>

I haven't been following this discussion, but could the delay() command
(TC++) work for what the original poster wanted?  It generates millisecond
precision delays.

Tony Hodgson
ahodgson@hstbme.mit.edu

py@meadow.uucp (Peter Yeung) (03/07/91)

In article <sg2Gwuw?@cs.psu.edu> melling@cs.psu.edu (Michael D Mellinger) writes:
>
>I need to be able to generate delays of around 1/2 second.  Anyone
>have a good way of doing this?  I'm using MS C 6.0.  The best I can
>come up with is a 1 second delay.
>

If it does not have to be really accurate, use a loop to check the clock
counter at location 0x46c (4 bytes counter) until it advances 9 times.
This method has the accuracy of within 1/18 of a second.

A more accurate method is to write a counting loop to count how many times
does it loop when the clock counter advance from x to x+1 and use the
loop count as a timing base for a timing loop which take the same number
of cycles to loop once as the initial counting loop. Yes, this implies
intimate knowledge of the code generated by the compiler or write both
loops in assembler (can be easily done in TC).

>-Mike


-- 
Peter Yeung     Amdahl Canada Ltd., Software Development Center
                2000 Argentia Road, Plaza 2, Suite 300
                Mississauga, Ont.   L5N 1V8
                Phone: (416) 542-6300    Fax: (416) 858-2233

29195@ruve.runit.sintef.no (Gulbrandsen,Arnt) (03/11/91)

In article <1991Mar7.053927.12273@meadow.uucp>, py@meadow.uucp (Peter Yeung) writes...
>A more accurate method is to write a counting loop to count how many times
>does it loop when the clock counter advance from x to x+1 and use the
>loop count as a timing base for a timing loop which take the same number
>of cycles to loop once as the initial counting loop. Yes, this implies
>intimate knowledge of the code generated by the compiler or write both
>loops in assembler (can be easily done in TC).
> 
NO! That won't work very well with multitaskers like DESQVIEW, which steal
cycles but leave the system clock intact.

Arnt Gulbrandsen
University of Trondheim, Norway
29195@ruve.runit.sintef.no

eversole@acae037.cadence.com (Richard Eversole; x6239) (03/12/91)

-- 

Look into the manual at the _bios_* calls. I do not remember exactly which calls
you need but I think they are similar to bios_gettime. Also you could use the
interrupt routines to intercept the system clock every tick (18.2 per second).

I wrote some code that uses the bios call to do a programmable delay that has
resolution of less than one second. If I remeber, I'll bring it in from 
home and post it here.

I was uses MSC 6.0a. The bios calls offer the advantage of working on 
all 80x86 machines.
  
  =====================================================================

    eversole@cadence.com