#define SIZE_BUF 16        // valores posibles: 2,4,8,16,32,64,128
													 // n£m caracteres:   1,3,7,15,31,63,127

#include "KEYB.H"
#define MASK_SIZE_BUF (SIZE_BUF-1)

#include<dos.h>
#include<conio.h>
#include<stdio.h>



void interrupt KeyHandler(void);
void actualiza_pantalla(void);



int index_read_kbuf=0;
int index_write_kbuf=0;
unsigned char key_buffer[SIZE_BUF];

int data;
void interrupt ( *keyb_oldhandler)();

// TABLA: ej:  13 = key_ascii[KEY_PAD_ENTER]
//        ej   'F'= key_ascii[Mgetch()]

int key_ascii[256] = {
	'±',ESC,'1','2','3','4','5','6','7','8','9','0',APOSTROFE,ADMIRACION,DELETE,
	TAB, 'Q','W','E','R','T','Y','U','I','O','P','[',']',ENTER,
	CONTROL_IZQ, 'A','S','D','F','G','H','J','K','L','¥','{',BARRA_INV,SHIFT_IZQ,'}',
	'Z','X','C','V','B','N','M',',','.','-',SHIFT_DER,
	PAD_POR, ALT,' ',BLOQ_MAYUS, F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,BLOQ_NUM,
	BLOQ_DESPL, PAD_7, PAD_8, PAD_9, PAD_MENOS, PAD_4, PAD_5, PAD_6, PAD_MAS,
	PAD_1, PAD_2, PAD_3, PAD_0, PAD_PUNTO, ALT_IMPR_PANT, '±','<', F11, F12,

	0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,PAD_ENTER,CONTROL_DER,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xB4,PAD_DIV,0xB6,IMPR_PANT,ALT_GR,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,INICIO,CUR_ARR,RE_PAG,0xCA,CUR_IZQ,0xCC,CUR_DER,0xCE,FIN,

CUR_ABJ,AV_PAG,INSERT,SUPR,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
	};



unsigned char key[256]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0};



//////////////////////////////////////////////////////////////////////////

int Mgetch(void) {
	while(index_write_kbuf == index_read_kbuf);

	index_read_kbuf = (++index_read_kbuf) & MASK_SIZE_BUF;
	return key_buffer[index_read_kbuf];
}
//////////////////////////////////////////////////////////////////////////

int Mkbhit(void) {
	return !(index_write_kbuf == index_read_kbuf);
}
//////////////////////////////////////////////////////////////////////////

void IniKeyb(void) {

	keyb_oldhandler = getvect(9);
	setvect(9, KeyHandler);
}
//////////////////////////////////////////////////////////////////////////

void CloseKeyb(void) {
	setvect(9, keyb_oldhandler);
}
//////////////////////////////////////////////////////////////////////////

void interrupt KeyHandler(void) {
	static int extended=0;
	static int aux;

	data = inportb(0x60);

	if( data==0xe0 ) {
		extended = 1;
		goto salida;
	}
	else if( data==0xe1 ) {
		extended = 2;
		goto salida;
	}

	if(!extended) {

		if( (key[ data&0x7F ] = !(data&0x80) ) && (index_write_kbuf != ((index_read_kbuf-1)&MASK_SIZE_BUF))) {
			index_write_kbuf = (1+index_write_kbuf) & MASK_SIZE_BUF;
			key_buffer[index_write_kbuf] = (data&0x7F);
		}
	}
	else {
		extended = 0;
		aux = (data&0x7F);
		if(aux==0x2A || aux==0x36) goto salida;

		if((key[ 128 + aux ] = !(data&0x80)) && (index_write_kbuf != ((index_read_kbuf-1)&MASK_SIZE_BUF))) {
			index_write_kbuf = (1+index_write_kbuf) & MASK_SIZE_BUF;
			key_buffer[index_write_kbuf] = 128 + aux;
		}

	}


salida:
//	oldhandler();

	outport(0x20,0x20);     // acknowledge interrupt

}
