News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Where to put delay code

Started by Magnum, January 08, 2015, 07:21:05 PM

Previous topic - Next topic

Magnum

This code needs a delay, but I do not know where the delay needs to go.

I have some delay code that is CPU independent.

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

unfortunately, there is no good way to relinquish processor time in 16-bit code
at least, not that i recall
you might look in the 16-bit section of the old forum for related posts by MichaelW, qWord, or FORTRANS

there is an INT that is supposed to work, but i didn't have any luck with it

it might be possible to thunk out to a 32-bit Sleep routine
or - maybe - there is some way to revector the keyboard INT 16h to make it work   :redface:

FORTRANS

Quote from: Magnum on January 08, 2015, 07:21:05 PM
This code needs a delay, but I do not know where the delay needs to go.

Quote from: dedndave on January 08, 2015, 10:38:13 PM
unfortunately, there is no good way to relinquish processor time in 16-bit code
at least, not that i recall
you might look in the 16-bit section of the old forum for related posts by MichaelW, qWord, or FORTRANS

there is an INT that is supposed to work, but i didn't have any luck with it

Hi,

   There is a difference between releasing CPU control to Windows
and a delay.  To relinquish processor time, see comments made by
a whole bunch of people when I was discussing my Viscalc program
in around April 2013.  Dave had complained about 100% CPU usage,
and some "fixes" were suggested.

   A simple delay routine will look at the clock tick values at 40:6C
maintained by the BIOS.  A short delay, as below, simply looks for
a change.  Count a number of ticks for a longer delay.

IF Delay
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Implies 200LX (or Windows 2k+) and no INT 15 delay routine,
; so we will use something similar to MsDelay from the PAL library.
; 15 November 2000 variable delay.
; 7 January 2001 used fixed medium delay (later chopped to min.).
DELAYER:
        PUSH    ES      ; ???
        PUSH    AX      ; After all this is a delay routine
        PUSH    BX
        PUSH    CX
        PUSH    DX

        PUSH    DS              ; Save DS and point to BIOS data area
        MOV     AX,40H          ; SEG BIOSSEG
        MOV     DS,AX
        MOV     AX,DS:[6CH]     ; ClockTic
        MOV     DX,AX   ; Save low word start time in DX
DLR_1:
        MOV     AX,DS:[6CH]
        CMP     AX,DX
        JE      DLR_1   ; Greater than Start?

        POP     DS      ; exit processing

        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     ES

        RET
ENDIF
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


   Since I save all used registers, it should be safe to put a call to
it in any convenient place.  Usually at the top or bottom of a
major routine.

Regards,

Steve N.

Gunther

Steve,

your code is good. I had forgotten the topic. I think it's not necessary to save es on entry, because that holds only a pointer to the environment (we're speaking about a native DOS application). But pushing it makes no harm.

Gunther
You have to know the facts before you can distort them.

FORTRANS

Quote from: Gunther on January 09, 2015, 01:17:51 AM
Steve,

your code is good. I had forgotten the topic. I think it's not necessary to save es on entry, because that holds only a pointer to the environment (we're speaking about a native DOS application). But pushing it makes no harm.

Hi Gunther,

   Thanks.  Right ES is not used in that version and need not be
saved.  Note the ??? in the comment there.  In an earlier version
I mentioned, it was more complex to cause a longer delay and I
used LES to load the tick count to ES:AX.

DLR_1:
        STI             ; 4 Sep 03
        HLT             ; 4 Sep 03
        LES     AX,DS:[ClockTic] ; Get timer 55 ms tick count
        CMP     AX,DX
        JE      DLR_1   ; Greater than Start?
        CMP     AX,BX
        JE      DLR_1   ; Greater than Start+1?


   It also had a HLT for power saving for the HP 200LX MS-DOS
palmtop computer.  (Which doesn't work with a Windows NTVDM.)
So I saved ES in that version.  So it was "used", but as it turned
out, never usefully.  So LES and HLT were dropped in the newer
version, and I thought about not saving ES, but not hard enough
apparently.

   As an aside to Dave, to reduce CPU usage, I ended up using the
DOS keyboard functions rather than the BIOS keyboard functions.
Using the BIOS routines was simpler, but did not give control to the
Windows NTVDM to save CPU cycles.

Cheers,

Steve N.

Magnum

;              Bios clock has a pulse rate of 18.2 times/second
;              18.2 x 5 seconds = 91  Useful for delays UNDER 14 seconds.
;                      .5   second = 9.1 pulses
;                      .1   second = 1.8
;                      .05  second = 1
;
;              The lowest two bytes can time up to 59 mins 59 secs.                                                               

.model       small
.stack       200h    ; 512 byte stack
.data

string       db           'Timer tick tocking...','$'

.code

start:             
             mov          ax,@data
             mov          ds,ax
             lea          dx,string
             mov          ah,9           
             int          21h
             mov          ah,0     ; function no. for read
             int          1ah      ; get the time of day count
             add          dx,9     ; add « second delay to low word 18 = 1 second
             mov          bx,dx    ; store end of delay value in bx
again:                           
             int          1ah
             cmp          dx,bx
             jne          again
exit:             
             mov          ax,4c00h
             int          21h

end          start
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Magnum

What kind of data is ClockTic ?

I tried byte and word.

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

if it's the RDTSC clock, it would be a QWORD
the old DOS tick was 3 bytes i think - usually stored as a DWORD

MichaelW

For a short delay, with a potential resolution of 15.9 microseconds, you can count memory refresh toggles. Some BIOS code uses this method (or at least at one time did), see this post.

But these days, at least on a system with a constant clock speed, RDTSC in a delay loop would probably be a better choice, but you need to know the clock speed to know the length of the delay (and on such a system this is fairly easy to do, at least approximately).
Well Microsoft, here's another nice mess you've gotten us into.

Magnum

Thanks.

Was your delay code for 55 milliseconds ?

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

MichaelW

Quote from: Magnum on January 16, 2015, 01:25:15 PM
Thanks.

Was your delay code for 55 milliseconds ?

For my code, on call the delay is the number of milliseconds in AX.
Well Microsoft, here's another nice mess you've gotten us into.