Reading a Cursor Key.

H. Paul Roach, Morgan State University

Program GETKEY.C illustrates how to fetch a character from the keyboard, notably, how to fetch the cursor keys.

Of course, the reader might be confused as to why a special function would be required when such functions as getch() are in the TurboC library. The answer is that getch() works for ordinary keystrokes; that is, the characters you see on your keyboard. It doesn't work for the function and cursor keys.

Some interrupts may be executed from software using the int86 function. Interrupt level 21 was developed by the original developers of DOS as a standard interface in fetching specific information. The identity of the specific information is passed in th e high byte of the A register (in.h.ah). For example, if in.h.ah is 0x2a, the year, month, day and day of the week are returned in various registers.

The value of in.h.ah for reading the keyboard is 0x08 and the value of the character is returned in the low byte of A (out.h.al). This works for ordinary keystrokes.

However, IBM needed more than the 256 characters that can be accommodated in a byte. Thus, they defined an "extended ASCII" by reserving the return code of 0x00 to mean, "there is more, do it again.". Thus, if a user depresses the character c', out.h.a l will be 0x63 which is the ASCII value of the character c'. However, if the user depresses the right arrow key, out.h.al will be 0x00 and a second call using int86 will return 0x4d. That is, one might think of the ASCII code for the right arrow as be ing 0x00 0x4d.

Note in the following program, if out.h.al is equal to zero, the function getkey() is again called (line 27). I happened to add 0x100 to the result to indicate the result is extended ASCII. Thus, in running the program, you should find that depressing a c' causes the value 0x63 to be displayed. Depressing the right arrow should cause 0x14d to be displayed.

You may use program GETKEY.C to determine the extended codes for such keys as the cursors, DEL, INS, PgUp, PgDn and the function keys.

/*
** Program GETKEY.C
**
** Illustrates how to fetch scan code from keyboard.
**
** H. Paul Roach, Morgan State University, July 30, '96
*/

#include <stdio.h>                                            /* 1 */
#include <conio.h>  /* for kbhit */                           /* 2 */
#include <dos.h>                                              /* 3 */
                                                              /* 4 */
int getkey(void);                                             /* 5 */
                                                              /* 6 */
void main(void)                                               /* 7 */
{                                                             /* 8 */
   int key;                                                   /* 9 */
   while(1)                                                   /* 10 */
   {                                                          /* 11 */
      if (kbhit)                                              /* 12 */
      {                                                       /* 13 */
         key=getkey();                                        /* 14 */
         printf("%d %x\n", key, key);                         /* 15 */
      }                                                       /* 16 */
   }                                                          /* 17 */
}                                                             /* 18 */
                                                              /* 19 */
int getkey(void)                                              /* 20 */
{                                                             /* 21 */
   union REGS in, out;                                        /* 22 */
   in.h.ah = 0x08;                                            /* 23 */
   int86(0x21, &in, &out);                                    /* 24 */
   if (out.h.al == 0)                                         /* 25 */
   {                                                          /* 26 */
      return(getkey()+0x100);                                 /* 27 */
   }                                                          /* 28 */
   else                                                       /* 29 */
   {                                                          /* 30 */
      return(out.h.al);                                       /* 31 */
   }                                                          /* 32 */
}                                                             /* 33 */