Announcement

Collapse
No announcement yet.

MTIMER function

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • MTIMER function

    I'm using Power Basic 3.1 and am compiling and running a program on a Windows 98 machine.

    I'm trying to create a routine that performs a user-defined time delay within a program. The range of the delay is zero (no delay) to about 10 milliseconds (10,000 microseconds).

    I've been playing with the MTIMER statement and function and it seems to me that the MTIMER statement itself takes some (large) amount of time to execute (repetitively anyways).

    What I'm not clear on is what happens when the MTIMER statement is executed without at some point executing the corresponding MTIMER function (my limited trials so far do just that, and the MTIMER statement seems to take quite some time to execute).

    So, again while running a compiled PB program in a full-screen MS-DOS session under Windows 98 SE, is MTIMER reliable or what?

  • #2
    MTIMER is accurate within the specs you provided, but: That
    function is useful for checking how long something takes.

    Using MTIMER to set up a delay is gonna be a tough nut to crack.
    Have you checked out the "DELAY" function? That might be more
    useful.


    ------------------
    There are no atheists in a fox hole or the morning of a math test.
    If my flag offends you, I'll help you pack.

    Comment


    • #3
      I was thinking that the execution of the MTIMER statement (to zero the timer) would take a negligable amount of time. I would then perform some dummy instruction (like perform a dozen cosine calculations) and then perform an MTIMER function (ie d = MTIMER).

      I would then add d to totald and if totald reaches some value I'd exit the routine. Otherwise zero the timer, perform the cosine calc's, etc.

      I find that the execution time of the MTIMER statement is large. In tests running in DOS mode (not under Windows) I find that it takes 55 seconds to perform 500 MTIMER statement-function commands. That's 110 milliseconds of overhead. No difference if I run the test routine in the PowerBasic interpreter or compiled from the DOS prompt.

      The DELAY function won't work because it's resolution is 54 milliseconds (I wanted a time-delay from zero to 10 milliseconds max, with a resolution of 100 microseconds or better).

      It looks like I will build a time-delay routine by simply performing a variable amount of cosine calculations.


      Comment


      • #4
        This old function works fine under DOS. Don't know if it's supported under Windows...
        Code:
        '====================================================================
        ' uS_Wait: Waits for [uS] time before returning.
        ' Uses the special DOS timer function 0x15, ax= 0x8300/01
        '--------------------------------------------------------------------
        SUB uS_Timer(uS AS Long) PUBLIC
          DIM uSec AS LOCAL LONG
          uSec = uS
          REG %AX, &H8301
          CALL INTERRUPT &H15
         
          REG %AX, &H8300
          REG %DX, uSec AND &H0000FFFF
          SHIFT RIGHT uSec, 16
          REG %CX, uSec& AND &H0000FFFF
          uSec = 0
          REG %ES, VARSEG (uSec)
          REG %BX, VARPTR (uSec)
          CALL INTERRUPT &H15
          WHILE ISFALSE uSec : WEND
        END SUB
        ------------------
        Regards,
        Peter
        Regards,
        Peter

        Comment


        • #5
          I suppose (correct me if I am mistaken) that MTIMER always waits
          until the next system timer tick (the one which occurs about
          18 times a second), before it actually begins counting
          time.

          Regards,

          Hans Ruegg

          ------------------

          Comment


          • #6
            A long, long time ago (my first paying contract, in fact)....

            I had to put in some fairly small delays to control a piece of measuring equipment...

            What I ended up doing was using empty FOR...NEXT loops; but of course this would cause problems on different-speed machines... so I added a user-defined "timer delay" in the INI file which represented "number of empty loops for machine delay."

            Since my delay for this equipment was neither 'absolute' time sensitive (that is, exactly "how long" the delay had to be, it only had to be 'enough') nor varied once the program started, this worked fine.

            If you do have absolute and/or variable time requirements, you could set a variable to specify "loops per millisecond" or "loops per microsecond" and either let the user 'tune' it or run some routine yourself when the program starts up to calculate this number.

            It's a thought.

            MCM
            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              tim,
              1) mtimer is only good for one off timings. i think it waits until the 55ms pit timer passes zero and then returns. the mtimer function then just reads the pit registers to see how many clock ticks have passed since the start and that's the value returned.
              this method means that, regardless of how fast your code is, if you call mtimer twice or more then the minimum delay between consecutive calls is 55ms.


              2) if you're running under windows timings will not be reliable.


              3) check out these for
              a) a much more accurate delay routine (but you don't really want a delay routine as a delay will not return to allow you to do your calculations while the delay is in progress) http://www.powerbasic.com/support/pb...ad.php?t=22773

              b) a proper high resolution timer which is what you really want.. but it'll still only work under dos, not windows. http://www.powerbasic.com/support/pb...ad.php?t=23521


              4) you're probably better off using the normal timer once to find how many calculations you can do in 1 second and then using that calculation rate to set the limit on the number of total calculations you do before exiting.

              paul.


              ------------------

              Comment


              • #8
                Hi Tim, This work very well in Windows real mode (DOS 7.02), I don´t
                test in protected mode.

                Code:
                '==============================================================================
                ' FILE NAME   : HR_TIMER.INC
                '==============================================================================
                ' DESCRIPTION :
                ' High Resolution time measurement.
                ' Include File For Using in Real DOS mode.
                '
                '==============================================================================
                ' COMPILER VERSION : PB DOS 3.5
                ' CREATION DATE    : May , 2004
                '==============================================================================
                ' E-MAIL : [email protected]
                '==============================================================================
                ' AUTHOR  : Gustavo D. Asplanatti.
                '
                ' LICENCE/TERMS AND CONDITIONS
                '
                ' This code is free for all PB user     
                ' Use it at your own risk.
                '==============================================================================
                
                DECLARE SUB DoSleep(TimeToSleep AS EXT)
                DECLARE FUNCTION MyTime(Decimal AS BYTE) AS STRING
                DECLARE FUNCTION GetTime() AS EXT
                DECLARE FUNCTION GetTickCount() AS EXT
                
                DIM TickFreq AS SHARED EXT
                
                TickFreq = 1193181.7/65536
                
                SUB DoSleep(TimeToSleep AS EXT)
                   DIM ATime AS LOCAL EXT
                   DIM BTime AS LOCAL EXT
                   DIM DeltaAB AS LOCAL EXT
                   ATime = GetTime()
                   DO
                      BTime = GetTime()
                      IF BTime >= ATime THEN DeltaAB = BTime - ATime ELSE DeltaAB = (86400 - ATime) + BTime
                      IF DeltaAB >= TimeToSleep THEN EXIT LOOP
                   LOOP
                END SUB
                
                FUNCTION MyTime(Decimal AS BYTE) AS STRING
                   DIM CountTime AS LOCAL EXT, resto AS LOCAL EXT
                   DIM Hora AS LOCAL STRING, Minu AS LOCAL STRING
                   DIM Secu AS LOCAL STRING, Mili AS LOCAL STRING
                   FLEXCHR$ = "0"
                   Hora = STRING$(2, FLEXCHR$)
                   Minu = STRING$(2, FLEXCHR$)
                   Secu = STRING$(2, FLEXCHR$)
                   Mili = STRING$(Decimal, FLEXCHR$)
                   CountTime = GetTime()
                   RSET Hora = TRIM$(STR$(CountTime \ 3600))
                   Resto = CountTime MOD 3600##
                   RSET Minu = TRIM$(STR$(Resto \ 60##))
                   Resto = Resto MOD 60##
                   RSET Secu = TRIM$(STR$(FIX(Resto)))
                   IF Decimal > 0 THEN
                      RSET Mili = TRIM$(STR$(FIX(FRAC(Resto)*(VAL("1" & STRING$(Decimal,"0"))))))
                      MyTime = Hora & ":" & Minu & ":" & Secu & "." & Mili
                   ELSE
                      MyTime = Hora & ":" & Minu & ":" & Secu
                   END IF
                END FUNCTION
                
                FUNCTION GetTime() AS EXT
                   DIM AuxTick1 AS EXT, AuxTick2 AS EXT
                   AuxTick1 = GetTickCount() : AuxTick2 = AuxTick1
                   WHILE AuxTick2<=AuxTick1
                      AuxTick2 = GetTickCount()
                      IF AuxTick2 > 1573038## THEN EXIT LOOP    ' 1573040 Eq. 24 hs.
                   WEND
                   GetTime = AuxTick2 / TickFreq
                END FUNCTION
                
                FUNCTION GetTickCount() AS EXT
                   DIM ClockState AS LOCAL BYTE
                   DIM LoByteTickC AS LOCAL WORD, HiByteTickC AS LOCAL WORD
                   DIM LoByte40 AS LOCAL BYTE, HiByte40 AS LOCAL BYTE
                
                   ! PUSHF
                   ! CLI
                
                   ! MOV AH, &H00                      ; Interroga Tick counter
                   ! INT &H1A
                   ! MOV HiByteTickC, CX
                   ! MOV LoByteTickC, DX
                
                   ! MOV AX,&HE2                       ; Estado del Out de clock 0
                   ! MOV DX, &H043
                   ! OUT DX, AL
                   ! IN  AX, &H040
                   ! MOV ClockState, AX
                
                   ! MOV AX,&H0
                   ! MOV DX, &H043
                   ! OUT DX, AL
                   ! IN  AX, &H040
                   ! MOV LoByte40, AX
                   ! IN  AX, &H040
                   ! MOV HiByte40, AX
                
                   ! POPF
                
                   GetTickCount = (LoByteTickC + HiByteTickC * 65536) + _
                                  ((65535-(LoByte40 + HiByte40 * 256)) / 2 / 65536) + 0.5 * NOT(BIT(ClockState,7))
                END FUNCTION




                ------------------
                Gustavo Asplanatti
                [email protected]
                Gustavo Asplanatti
                gustavoa at computecsrl.com.ar

                Comment


                • #9
                  Test with this test program

                  Code:
                  '==============================================================================
                  ' FILE NAME   : TEST_HR.BAS
                  '==============================================================================
                  ' DESCRIPTION :
                  ' Test High Resolution time measurement.
                  '
                  '==============================================================================
                  ' COMPILER VERSION : PB DOS 3.5
                  ' CREATION DATE    : May , 2004
                  '==============================================================================
                  ' E-MAIL : [email protected]
                  '==============================================================================
                  ' AUTHOR  : Gustavo D. Asplanatti.
                  '
                  ' LICENCE/TERMS AND CONDITIONS
                  '
                  ' This code is free for all PB user     
                  ' Use it at your own risk.
                  '==============================================================================
                  
                  
                  $ERROR ALL ON
                  $DIM ALL
                  $CPU 80386
                  $FLOAT NPX
                  $OPTIMIZE SPEED
                  $INCLUDE "HR_TIMER.INC"
                  
                  CLS
                  
                  LOCATE 06,02 : PRINT " HR_TIMER - TIMER :"
                  LOCATE 08,02 : PRINT "Power Basic TIMER :"
                  LOCATE 10,02 : PRINT " HR_TIMER -  TIME :"
                  LOCATE 12,02 : PRINT "Power Basic TIME$ :"
                  
                  DO
                     IF INSTAT THEN IF INKEY$ = CHR$(27) THEN EXIT LOOP
                  
                     LOCATE 06,24 : PRINT GetTime()
                     LOCATE 08,24 : PRINT TIMER
                     LOCATE 10,24 : PRINT MyTime(0)
                     LOCATE 12,24 : PRINT TIME$
                     DoSleep 0.010          ' Delay 10 milliseconds
                  LOOP
                  
                  END
                  Hope be luck...


                  ------------------
                  Gustavo Asplanatti
                  [email protected]
                  Gustavo Asplanatti
                  gustavoa at computecsrl.com.ar

                  Comment

                  Working...
                  X