News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

wait_key.asm

Started by rkhb, April 27, 2012, 06:57:19 PM

Previous topic - Next topic

rkhb

Hi there,

I had a look at \masm32\m32lib\wait_key.asm and I wonder for what purpose the crt__kbhit loop is used. The function crt__getch waits for a keystroke already and I see no change with or without the loop.

viele grüße
ralph

dedndave

that's a good question, Ralph   :bg

jj2007

Warum einfach wenn's auch umständlich geht :bg

MichaelW

I think the kbhit loop was an attempt to limit the CPU utilization while waiting, based on the apparently incorrect (as tested under Windows 2000) assumption that getch would not limit the CPU utilization. Perhaps earlier versions of MSVCRT do not.
eschew obfuscation

hutch--

If this is the version you are talking about,



; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

wait_key proc

    invoke FlushConsoleInputBuffer, rv(GetStdHandle,STD_INPUT_HANDLE)

  @@:
    invoke Sleep, 1
    call crt__kbhit
    test eax, eax
    jz @B

    call crt__getch     ; recover the character in the keyboard
                        ; buffer and return it in EAX
    ret

wait_key endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««


Its actually a "Sleep" API loop to ensure the idle loop yields while waiting for a keystroke.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

now, if we could only come up with a 16-bit version that wasn't a CPU hog   :P
if you let NTVDM wait for a key - no problem
but if you try to do other stuff, there is no way to block execution

MichaelW

In 16-bit code calling the MS-DOS Idle Handler from the wait loop might be worth a try. I seem to recall testing this at some point, under NTVDM I think, but I don't recall what the results were.
eschew obfuscation

jj2007

Quote from: hutch-- on April 28, 2012, 02:25:36 AM
Its actually a "Sleep" API loop to ensure the idle loop yields while waiting for a keystroke.

What the OP and Michael indicate is that crt__getch does yield even without the loop. And indeed the CPU stays put at 0% while waiting for the keystroke, so we can send the loop into retirement :wink

dedndave

Quote from: MichaelW on April 28, 2012, 06:05:13 AM
In 16-bit code calling the MS-DOS Idle Handler from the wait loop might be worth a try. I seem
to recall testing this at some point, under NTVDM I think, but I don't recall what the results were.

any idea how to do that ?
i didn't know there was such a thing

Neil

Dave if you remember when I was having problems with that text adventure you came up with the idea of using crt__kbhit to check whether a keypress was in the keyboard buffer, if there was then use crt__getch to extract the key value, otherwise carry on with other code before looping back to check crt__kbhit again.

MichaelW

Dave,

To call the Idle Handler you simply issue an Interrupt 28h. The Microsoft MS-DOS Programmer's Reference, version 5, recommends also issuing an MS-DOS Idle Call (Interrupt 2Fh, Function 1680h).
eschew obfuscation

dedndave

thanks, Michael   :U

Neil - yah - that is a valid use of crt__kbhit - we wanted to do something else if the keyboard was idle
but - we need something similar for 16-bit programs
it's really easy to write a CPU hog in 16-bit

Neil

For 16 bit programs this is what I used :-

PUSH ES                        ;Save segment.
SUB AX,AX                     ;Get bottom
MOV ES,AX                     ;of memory.
MOV AL,ES:[041A]           ;Get head pointer.
MOV AH,ES:[041C]           ;Get tail pointer.
POP ES                           ;Restore segment.
CMP AH,AL                      ;Are they equal ?
JNE GETKEY                    ;No, get keyboard input.
Do other code then Loop again

sinsi


again:  mov ah,1
        int 16h
        jnz gotkey
        int 28h
        jmp again
gotkey:

For running DOS in a VM I setup a new int 28h

int28:  sti
        hlt
        jmp old28

CPU usage afterward is 0 instead of one core.
Light travels faster than sound, that's why some people seem bright until you hear them.

MichaelW

Running this code under NTVDM, only the MS-DOS Idle Call (Interrupt 2Fh, Function 1680h) drops the NTVDM CPU usage to 0. The other attempts left the usage at 99%.

.model small
.386
.stack
.data
.code
.startup
  @@:
    ;hlt
    ;int 28h
    mov ax, 1680h
    int 2Fh
    jmp @B
.exit
end

eschew obfuscation