Listing 5

/*  KB_TEST - Read Scan Codes from Keyboard  */
#include <stdio.h>
#include <dos.h>

#define KB_BUF_SIZ 32          /*  ring buffer size  */

unsigned short int kb_buff[KB_BUF_SIZ];
                           /*  char output buffer  */

unsigned char kb_front=0, kb_back=0;
                           /*  queue pointers  */

#define PORT_A    0x60         /*  8255 PIC Port A */
#define PORT_B    0x61         /*  8255 PIC Port B */
#define ICR       0x20         /*  Interrupt Command Register */
#define H_ENABLE  0x20         /*  Enable hardware interrupts */
#define ACK_BIT   0x80         /*  ACK bit for PORT B */
#define BRK_BIT   0x80         /*  Scan code break bit */
#define CH_BITS   0x7F         /*  Scan code key number */

void interrupt kb_interrupt(void)
    
    {
    unsigned char scan_code, ack;
    
    /*  Read scan code and send ACK to keyboard */
    
    scan_code = inportb(PORT_A);
    ack = inportb(PORT_B);
    outportb(PORT_B, ack | ACK_BIT);
    outportb(PORT_B, ack);
    
    kb_buff[kb_back] = scan_code;
    kb_back = (kb_back + 1) % KB_BUF_SIZ;
    
    /*  Re-enable hardware interrupts (and exit ISR)  */
    
    outportb(ICR,H_ENABLE);
    }

/*  Install the ISR  */

#define KB_VECTOR (0x9)

static void interrupt (*old_interrupt)(); /*  DOS interrupt vector  */

void kb_install(void)
    {
    old_interrupt = getvect(KB_VECTOR);
    setvect(KB_VECTOR,kb_interrupt);
    }

/*  Restore DOS ISR  */

void kb_restore(old_interrupt)
    {
    setvect(KB_VECTOR,old_interrupt);
    }

/*  Read a char (with wait) */

int kb_read(void)
    
    {
    int ch;
    while (kb_front == kb_back)
        ;
    ch = kb_buff[kb_front];
    kb_front = (kb_front + 1) % KB_BUF_SIZ;
    return(ch);
    }

int main()
    
    {
    int scan_code;
    
    kb_install ();
    printf("\nPress ESC to Quit\n\n");
    
    while ( (scan_code = kb_read()) != 1) /*  ESC key scan code */
        {
        if (scan code & BRK_BIT)
            printf(" ^%d\n", (scan_code & 127));
                                  /*  break code */
        else
            printf(" %d",scan_code); /*  made code */
        }
    
    kb_restore();
    return 0;                         /*  for lint */
    }

**********