Keyboard Input

This section details replacing the keyboard interrupt for player input. Only basic programming knowledge is assumed. We recommend users to go through the tutorial in sequence and check all the examples.

 All of the code snippets and downloadable examples are written in C

The Theory

When a key is pressed or released, the keyboard sends the information about this key and the action (pressed or relased) to the CPU. This data is processed by the B.I.O.S. interrupt '9H' which sends the translated information to programs.

Just put your key detection function over the BIOS keyboard handler and your code will be called every time a key event occurs. The keyboard event can be read from port 60h. It's a byte size port and is divided in to the Scancode and the Key Event.

The Scancode is 7-bits and represents the key ID. The key event is the most significant bit (bit-7). When this is true the key was released, otherwise the key was pressed. You must control whether keys are pressed or released by yourself.

Key Event Scan Code
.7 .6 .5 .4 .3 .2 .1 .0

The Code

Here is the new interrupt code. This is using the keys Q, A, O, P, M and ESCAPE. Change the case values to use different keys. Its also easy to add more or remove keys from this code.

void key_handler(void)
{
	unsigned char al, ah;
	asm("cli; pusha"); //assembly lang. statement
	raw_key = inportb(0x60);
	al = inportb(0x61);
	al |= 0x82;
	outportb(0x61, al);
	al &= 0x7f;
	outportb(0x61, al);
	switch (raw_key) //optionally put this outside this function
	{
	    case 16:  key_table[UP] = 1; break; //press codes
	    case 31:  key_table[DOWN] = 1; break;
	    case 50:  key_table[FIRE] = 1; break;
	    case 24:  key_table[LEFT] = 1; break;
	    case 25:  key_table[RIGHT] = 1; break;
	    case 1:   key_table[QUIT] = 1; break;
	    case 144: key_table[UP] = 0; break; //release codes (+128)
	    case 159: key_table[DOWN] = 0; break;
	    case 178: key_table[FIRE] = 0; break;
	    case 152: key_table[LEFT] = 0; break;
	    case 153: key_table[RIGHT] = 0; break;
	    case 129: key_table[QUIT] = 0; break;
	    default:break;
	}
	outportb(0x20, 0x20);
	asm("popa; sti");
}

You will also need to install this code - not forgetting to put the old interrupt back at the end!

  Download a working example