If you want to detect multiple keypresses at the same time, the BIOS keyboard routines are useless. Allegro can install a replacement keyboard handler, which provides both buffered input and a set of flags storing the state of each key. Note that it is not possible to correctly detect every combination of keys, due to the design of the PC keyboard. Up to two or three keys at a time will work fine, but if you press more than that the extras are likely to be ignored (exactly which combinations are possible seems to vary from one keyboard to another).
int install_keyboard();
   Installs the Allegro keyboard interrupt handler. You must call this 
   before using any of the keyboard input routines. Once you have set up the 
   Allegro handler, you can no longer use DOS/BIOS calls or C library 
   functions to access the keyboard.
void remove_keyboard();
   Removes the keyboard handler, returning control to the BIOS. You don't 
   normally need to bother calling this, because allegro_exit() will do it 
   for you.
void install_keyboard_hooks(int (*keypressed)(), int (*readkey)());
   You should only use this function if you *aren't* using the rest of the 
   keyboard handler. It should be called in the place of install_keyboard(), 
   and lets you provide callback routines to detect and read keypresses, 
   which will be used by the main keypressed() and readkey() functions. This 
   can be useful if you want to use Allegro's GUI code with a custom 
   keyboard handler, as it provides a way for the GUI to access keyboard 
   input from your own code. If you want to use the BIOS keyboard routines, 
   the libc function _bios_keybrd(_KEYBRD_READ) returns keypresses in the 
   correct format.
extern volatile char key[128];
   Array of flags indicating the state of each key, ordered by scancode. The 
   scancodes are defined in allegro.h as a series of KEY_* constants. For 
   example, you could write:
      if (key[KEY_SPACE])
         printf("Space is pressed\n");
   Each of these values is actually a bitfield containing either or both of 
   the flags KB_NORMAL and KB_EXTENDED, allowing you to determine which key 
   is pressed even when there are two with the same scancode. For example, 
   you could write:
      if (key[KEY_ENTER] & KB_NORMAL)
         printf("Enter (next to the right shift key) is pressed\n");
      if (key[KEY_ENTER] & KB_EXTENDED)
         printf("Enter (on the numeric keypad) is pressed\n");
extern volatile int key_shifts;
      KB_SHIFT_FLAG
      KB_CTRL_FLAG
      KB_ALT_FLAG
      KB_LWIN_FLAG
      KB_RWIN_FLAG
      KB_MENU_FLAG
      KB_SCROLOCK_FLAG
      KB_NUMLOCK_FLAG
      KB_CAPSLOCK_FLAG
      KB_INALTSEQ_FLAG
      KB_ACCENT1_FLAG
      KB_ACCENT1_S_FLAG
      KB_ACCENT2_FLAG
      KB_ACCENT2_S_FLAG
int keypressed();
   Returns TRUE if there are keypresses waiting in the input buffer. This is 
   equivalent to the libc kbhit() function.
int readkey();
   Returns the next character from the keyboard buffer. If the buffer is 
   empty, it waits until a key is pressed. The low byte of the return value 
   contains the ASCII code of the key, and the high byte the scancode. The 
   scancode remains the same whatever the state of the shift, ctrl and alt 
   keys. The ASCII code is affected by shift and ctrl in the normal way 
   (shift changes case, ctrl+letter gives the position of that letter in the 
   alphabet, eg. ctrl+A = 1, ctrl+B = 2, etc). Pressing alt+key returns only 
   the scancode, with a zero ASCII code in the low byte. For example:
      if ((readkey() & 0xff) == 'd')         // by ASCII code
         printf("You pressed 'd'\n");
      if ((readkey() >> 8) == KEY_SPACE)     // by scancode
         printf("You pressed Space\n");
      if ((readkey() & 0xff) == 3)           // ctrl+letter
         printf("You pressed Control+C\n");
      if (readkey() == (KEY_X << 8))         // alt+letter
         printf("You pressed Alt+X\n");
void simulate_keypress(int key);
extern int (*keyboard_callback)(int key);
   If set, this function is called by the keyboard handler in response to 
   every keypress. It is passed a copy of the value that is about to be 
   added into the input buffer, and can either return this value unchanged, 
   return zero to cause the key to be ignored, or return a modified value to 
   change what readkey() will later return. This routine executes in an 
   interrupt context, so it must be in locked memory.
extern void (*keyboard_lowlevel_callback)(int key);
   If set, this function is called by the keyboard handler in response to 
   every keyboard event, both presses and releases. It will be passed a raw 
   keyboard scancode byte, with the top bit clear if the key has been 
   pressed or set if it was released. This routine executes in an interrupt 
   context, so it must be in locked memory.
void set_leds(int leds);
   Overrides the state of the keyboard LED indicators. The parameter is a 
   bitmask containing any of the values KB_SCROLOCK_FLAG, KB_NUMLOCK_FLAG, 
   and KB_CAPSLOCK_FLAG, or -1 to restore the default behavior.
void clear_keybuf();
   Empties the keyboard buffer.
extern int three_finger_flag;
   The Allegro keyboard handler provides an 'emergency exit' sequence which 
   you can use to kill off your program. If you are running under DOS this 
   is the three finger salute, ctrl+alt+del. Most multitasking OS's will 
   trap this combination before it reaches the Allegro handler, in which 
   case you can use the alternative ctrl+alt+end. If you want to disable 
   this behaviour in release versions of your program, set this flag to 
   FALSE.
extern int key_led_flag;
   By default, the capslock, numlock, and scroll-lock keys toggle the 
   keyboard LED indicators when they are pressed. If you are using these 
   keys for input in your game (eg. capslock to fire) this may not be 
   desirable, so you can clear this flag to prevent the LED's being updated.
extern int switch_standard_kb_key;
extern int switch_standard_kb_flags;
extern int switch_custom_kb_key;
extern int switch_custom_kb_flags;
   Scancode and shift flag combinations used for the custom to standard 
   keyboard mapping switch. By default, pressing ctrl+alt+F1 will select the 
   standard US layout, while ctrl+alt+F2 selects the custom mapping. 
   These values allow you to alter the hotswap keys, or you can set them to 
   zero to disable the swapping.
void set_standard_keyboard();
   Forces Allegro to use the standard US keyboard mapping, regardless of 
   what custom keyboard layout is currently loaded.
void set_custom_keyboard();
   Forces a switch to the current custom keyboard layout, reversing the 
   effect of any previous calls to set_standard_keyboard().