CODE: [Copy to clipboard]
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
#define MAXKEYQUEUE 0x40
static char kqQueue[MAXKEYQUEUE]; // 队列
static int kqFirst = 0; // 指向首个数据
static int kqLast = 0; // 指向首个空位
static int kqCount = 0; // 该队列有多少元素
#define KSC_PRESS 0x80
#define KSC_DATAMASK 0x7F
#define KSC_EXTEND 0xE0
#define KSC_ESC 1
void interrupt get_out(__CPPARGS); /* interrupt prototype */
void interrupt (*oldfunc)(__CPPARGS); /* interrupt function pointer */
int main(void)
{
unsigned char byKey;
int iEscCount=0;
puts("Esc*3: Exit\n");
/* save the old interrupt */
oldfunc = _dos_getvect(9);
/* install interrupt handler */
_dos_setvect(9,get_out);
/* do nothing */
while (iEscCount < 3){
/* show key queue */
while(kqCount > 0){
/* get curent ScanCode */
__asm cli;
byKey = kqQueue[kqFirst++];
if (kqFirst >= MAXKEYQUEUE) kqFirst -= MAXKEYQUEUE;
kqCount--;
__asm sti;
/* show */
printf("%X\t", byKey);
/* check Esc */
if (byKey & KSC_PRESS) {
if (KSC_ESC == (byKey & KSC_DATAMASK)) {
iEscCount++;
if (2 == iEscCount){
clrscr();
}
}else {
iEscCount = 0;
}
}
}
};
/* restore to original interrupt routine */
_dos_setvect(9,oldfunc);
puts("Success");
return 0;
}
void interrupt get_out(__CPPARGS)
{
{
unsigned char byKey;
/* get ScanCode */
byKey = inportb(0x60);
/* add to key queue */
if (kqCount < MAXKEYQUEUE){
kqQueue[kqLast++] = byKey;
if (kqLast >= MAXKEYQUEUE) kqLast -= MAXKEYQUEUE;
kqCount++;
}
}
oldfunc(__CPPARGS);
}