Listing 1
#include <dos.h> #include <conio.h> void show_char(); int poll_kb(); int readch(); int push_kb(); int kb_count(); int kb_peek(); void kb_clear(); void main(void) /* testing the KB functions */ { int x, y; /* Put some characters into the buffer */ /* For most applications the scan codes are not */ /* important, but for extended char it must have */ /* the scan code and 0 for the char: */ for (x : 0; x < 12; x++) push_kb(1,32 + x); push_kb(59,0); printf("\n%d key(s) in the buffer. \n\n",kb_count()); printf("Key number %d is '%c' \n\n", 5, kb peek(5)); printf("Key number %d is '%c' \n\n", 7, kb_peek(7)); show_char(); } void show_char(void) /* This is just a test function */ { int c; while((c = readch()) != 59 << 8) /* 27 = ESC */ { putch(c); printf(" the code for this is %d \n",c); } putch(c); printf(" the code for this is %d \n",c); } /* poll_kb(): returns 0 if the buffer is empty, */ /* else ascii code or scan codes * 256 for extended: */ int poll_kb(void) { int head, tail; unsigned int code; head = peek(0x40, 0x1A); tail = peek(0x40, 0x1C); if(head == tail) return(0); code = (peek(0x40,head) & 0xFF); if(code == 0) /* extended char */ code = (peek(0x40,head) & 0xFF00); if(head < 60) poke(0x40,0x1A,(head += 2)); else poke(0x40,0x1A,(head = 30)); return(code); } /* readch(): keep checking buffer until something */ /* is there. Can also be done with "kbhit()" */ int readch(void) { int code; while((code = poll_kb()) == 0) { /* can run any fast function here */ } return(code); } /* putsh_kb(): key = the key code, ascii = asc code */ int push_kb(int key, int ascii) { unsigned int code; int head, tail; head = peek(0x40, 0x1A); tail = peek(0x40, 0x1C); code = (key << 8) + ascii; poke(0x40,tail,code); if(tail < 60) { tail += 2; if(tail == head) return(0); poke(0x40,0x1C,tail); } else { tail = 30; if(tail == head) return(0); poke(0x40,0x1C,tail); } return(1); } int kb_count(void) { int head, tail; int count; head = peek(0x40, 0x1A); tail = peek(0x40, 0x1C); if(head == tail) /* buffer is empty */ return(0); if(head > tail) /* adjust for the roll over */ tail += 32; count = (tail - head) / 2; return(count); } /* "kb_peek" will return the ascii code of */ /* the number of keys back specified. */ /* If it is an extended char the scan code */ /* will be left shifted 8 and returned */ int kb_peek(int key_number) { int head, tail, code; /* see if key_number of items are in the buffer: */ if(key_number > kb_count()) return(0); head = peek(0x40, 0x1A); tail = peek(0x40, 0x1C); /* advance the desired number of words: */ head += (key_number - 1) * 2; if(head > 60) head -= 32; /* if head needs to wrap around */ code = (peek(0x40,head) & 0xFF); if(code == 0) /* exten. scan sent instead of ascii */ code = (peek(0x40,head) & 0xFF00); return(code); } void kb_clear(void) /* empty buffer data */ { int head, tail; head = peek(0x40, 0x1A); tail = peek(0x40, 0x1C); poke(0x40,0x1C,head); /* set tail = head */ }