#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 */
}