Hello! I'm trying to write some MASM code that is equivalent to this C code:

int main() {
  int ch;

  do {
    if (kbhit()) {
      ch = getch();
    }
  } while (ch != 27);

  printf("done\n");
  return(0);
}
Since
kbhit
(
_kbhit
) and
getch
(
_getch
) are C runtime functions and not Win32 API functions, I had to find some Win32API equivalents for these functions. I found this article on Microsoft's web site that contained this information: They are:
_kbhit
is equivalent to
PeekConsoleInput
; and
_getch
is equivalent to
ReadConsoleInput
. First, I wanted to test the conversion in C, just to make sure it still works:

int ReadKey(void) {
  INPUT_RECORD inpR;
  DWORD numRecsRead;  
  int ret = 0;
      
  //Get a handle to the console
  HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);

  //Set up the console for input
  SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT);

  //Here is equivalent the kbhit() call.
  PeekConsoleInput(hIn, &inpR, 1, &numRecsRead);

  //numRecsRead being 0 is equivalent to kbhit() returning false;
  if (numRecsRead == 0) return(ret);

  //Only interested in keyboard input, and when a key is pressed
  if (inpR.EventType == KEY_EVENT && inpR.Event.KeyEvent.bKeyDown) {
    if (inpR.Event.KeyEvent.uChar.AsciiChar != 0 &&
    inpR.Event.KeyEvent.uChar.AsciiChar != 27) {
      //ReadConsole() is the equivalent getch() call
      ReadConsole(hIn, &ret, 1, &numRecsRead, NULL);
      ret = ret & 0xFF;
    } else {
      //Catches other keys (like ESC, ALT, CTRS, SHIFT, etc).
      ReadConsoleInput(hIn, &inpR, 1, &numRecsRead);
      ret = inpR.Event.KeyEvent.uChar.AsciiChar;
    }
  } else {
    ReadConsoleInput(hIn, &inpR, 1, &numRecsRead);
  }  
  return(ret);
}

int main() {
  int key;

  do {
    key = ReadKey();
  } while(key != 27);

  printf("done\n");
  return(0);
}
No problems here. I have two issues with the conversion over to MASM (well, one really): 1). WINDOWS.INC doesn't include everything. The two Win32 API functions mentioned above require the INPUT_RECORD structure, which I added. (Saw a discussion on this in an earlier thread, too :-)) No problem here. 2).
PeekConsoleInput
almost always sets
numRecsRead
to one, even if I didn't press any keys! I don't know what that's all about. Furthermore, when it does set
numRecsRead
to zero, and I press a key, it's set one, but ReadConsole()
 and 
ReadConsoleInput()
do not seem to remove the last character from the input buffer like they should. That would make the next call set
numRecsRead
to 0 (or the number of pending records/characters minus one). Can anyone shed some light on this? Thanx!
Posted on 2001-06-04 12:34:00 by Zir0
I'll take a look. Something similar happens in DOS: the device CON always returns after getting just one byte. You can see asm source for a skeletal (but working) console driver at www.hammick.com/hcs/computer.html
Posted on 2001-06-04 13:46:00 by Larry Hammick