Announcement

Collapse
No announcement yet.

INKEY$ and INSTAT Timing

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

  • INKEY$ and INSTAT Timing

    howdy, all.

    a year ago, tom kuurstra posted a question about how to get faster
    keyboard response. various suggestions were made, but no conclusions
    were drawn.
    http://www.powerbasic.com/support/pb...ead.php?t=1206

    i've recently had to look into the same question and have come up with
    some answers. i'm doing a dedicated test unit and use a soyo k7vem motherboard
    with a 1 ghz piii, w98se, and use the isa bus for hardware control.
    this allows me to look at system performance on a scope by issuing io writes and
    looking for the pulses.

    first, both inkey$ and instat give the same abysmal performance.

    do while instat
    out &h210,0
    loop
    a$ = inkey$

    runs in about 55 milliseconds.

    using inkey$ produces the same result.

    and i don't think that it's a coincidence that this is an 18-hz rate. it seems clear
    that both functions are mediated by the system clock. presumably, either command
    causes a wait until the system clock occurs, which will be essentially a random wait
    of from 0 - 55 msec, depending on exactly when the command occurs.

    if, instead, i look at io address &h60, things get a _lot_ better. the following loop:

    do while ((x% <> 0) and (x% < 128)) 'looking for x% < 128 avoids responding to key release
    x% = inp(&h60)
    out &h210,0 'this is just my port write address
    loop
    a$ = inkey$ 'remember to flush the buffer

    runs in 8 microseconds. that's nearly 4 orders of magnitude improvement.

    i hope this comes in handy for someone.

    jim martin



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

  • #2
    The operating system polls various activities, including the
    keyboard for key presses, so the updates are based on when the
    OS gets around to checking on them. Some gamerz crank up the
    cycle rate of this polling proces for faster reaction times.
    Your approach is the first I've heard of its kind.

    ------------------
    Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired

    Comment


    • #3
      Wrote up a small test program:
      Code:
      $lib all off
      color 14,1
      cls
      mtimer
      If Instat > 0 then
      a$ = inkey$
      end if
      print;mtimer;
      end
      The print statement showed an elapsed time of an average of
      5 microeconds over several runs. Of course, in this example,
      inkey$ is never executed. All it tests is the speed of the
      INSTAT function.

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


      [This message has been edited by Mel Bishop (edited January 19, 2005).]
      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


      • #4
        Mel -

        Your results were so at odds with my own that I rechecked.

        I'm afraid I don't believe MTIMER.

        I set up a loop that uses MTIMER to measure 10 successive calls of
        INSTAT, and does it 25 times in succession, printing out the result
        on a different line each time. I ran this repeatedly.

        The result is often an average of about 4-6 microseconds per INSTAT,
        but sometimes as high as 40.

        And sometimes 0 or 1 for the entire loop, indicating .1 usec per isntruction.

        Like I say, I don't think MTIMER is credible here. I reran my hardware test
        on a loop which only calls INSTAT and writes to a port, and I get 55 msec
        consistently.

        Does anybody have any idea what's going on?

        Jim

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

        Comment


        • #5
          Tim:

          Are you using pure DOS or are you running under Windows? My
          bet is that it is the latter. Timing is much more variable
          under Windows.

          By the way, I have a cute routine for speeding up the clock;
          if anyone is interested I'll post it. Windows will not allow
          this routine to run, but under DOS you can literally see the
          time (and calendar) fly by.


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

          Comment


          • #6
            Emile -

            As stated in the first post, W98SE. And, yes, I know that Windows
            produces variable timing. All that background stuff that the OS
            just _has_ to do.

            That misses the point, I think. According to the docs, MTIMER uses
            a hardware counter. I'll buy the idea of long duration for a simple
            loop if the OS interrupts it to handle background tasks, but how do
            you get the extremely short readings?

            And to get back to my original findings, I note that making 25 loops
            and printing each result on a new line takes well over a second.

            This is consistent with a 55 msec response time for INSTAT, and is
            hard to understand if INSTAT only takes 5 microseconds. Printing a
            value to screen doesn't take THAT long.

            Jim

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

            Comment


            • #7
              Jim,
              mtimer itselt waits for the 55msec. If you call any fast code repeatedly it'll always take 55msec / call.
              Use mtimer once, and measure just 1 loop OR start mtimer, do 20 loops THEN read mtimer for the result and see it that shows the difference.

              As I remember it (perhaps not very well) the initial MTIMER statement waits for the internal timer to roll over. The subsequent mtimer function call just reads the timer to see how far it got since it rolled over.

              Paul.

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

              Comment


              • #8
                The timing associated with the video card is the most critical
                time of all. It HAS to be stable at a specific frequency, or the
                monitor will show jitter and waivy lines, or other distortions on
                the screen. Under DOS, many programmers have resorted to checking
                the Vertical Resync or Horizontal Resync signals and establishing
                a lapsed time reference based on either of these.

                Aside from that, you can look for and find code that already gives
                you the type of stable and rapid timing reference that you seem to
                be looking for. Gaming languages already employee these in their
                structure, and also offer alternate keyboard mapping schemes so
                that the keyboard is a more effective instrument for user input
                during game play. They allow for simultaneous key depressions,
                where normally you need sequential key inputs when typing.

                ------------------
                Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired

                Comment

                Working...
                X