From: ceharris@csugrad.cs.vt.edu (Carl Harris)
Newsgroups: comp.os.msdos.programmer,alt.msdos.programmer
Subject: Re: HELP: Keyboard Interrupt 09H
Summary: Proper cleanup of keyboard interrupt.
Keywords: KEYBOARD ISR
Date: 12 Oct 92 21:31:28 GMT
Organization: Virginia Tech Computer Science Dept, Blacksburg, VA

In article <1992Oct9.154103.18137@sol.ctr.columbia.edu> 
jerry@connection.prospect.com (Jerry Shekhel) writes:
>Hello out there.  I'm creating a VGA game, and I need precise keyboard
>control, so the kbhit()/getch() functions are insufficient.  I need to know
>when keys are pressed and released.  I managed to do this by intercepting the
>keyboard hardware interrupt

   [lengthy code example deleted]

>This works, but the problem is that since I'm not using the BIOS to read the
>keystrokes (I'm just reading the key_map[] array), the BIOS buffers them up
>and starts clicking the speaker when the buffer overflows.  Needless to say,
>when I'm holding keys down, this click turns into a "drumroll" and slows down
>my game.  I tried removing the call to old_handler(), but then everything
>stopped working, as if the interrupt itself was no longer being generated.
>
>Can someone help me with this problem?  Thanks in advance.
>--
>+-------------------+-----------------------+--------------------------------+
>| Jerry J. Shekhel  | Molecular Simulations | Time just fades the pages      |
>| Drummers do it... | Inc.  Waltham, MA USA | in my book of memories.        |
>|    ... In rhythm! |     (617) 890-2888    |              -- Guns N' Roses  |
>+-------------------+-----------------------+--------------------------------+
>|           ...! [ princeton mit-eddie bu sunne ] !polygen!jerry             |
>|                            jerry@polygen.com                               |
>+----------------------------------------------------------------------------+


Before exiting your ISR, you may clear the keyboard's MAKE/BREAK status by
writing 0x80 to the keyboard control port.  This will 'remove' the key
press/release from the keyboard in the same manner as the BIOS keyboard ISR.
After doing this, you must *not* pass control to the BIOS ISR.  Rather, issue
the EOI to the interrupt controller and return from the interrupt via IRET.

For example:

	Int09ISR:
	   sti			;Allow higher priority INTs
	   push ax
           push bx
            .
	    .
            .
           push ds
           push es
	   in  al,60h		;Read scan code
           cmp al,80h
           jnb KeyRelease      	;Go deal with key release...
	    
	   ;Deal with key press here
            .
	    .
	    .
	   jmp Done
	   
	   ;Deal with key release here
KeyRelease:
	    .
 	    .
	    .

	   ;Reset keyboard status, and return from interrupt
Done:
	   in al,61h			;Read peripheral control port mask
	   mov ah,al
	   or al,80h			;Set the 'reset keyboard' bit
	   out 61h,al                	;...and write it
	   mov al,ah			;Recover old port mask
	   out 61h,al			;...and write it
	   
	   pop es
	   pop ds
	    .
	    .
	    .
           pop cx
 	   pop bx
	
	   mov al,20h
	   out 20h,al			;Write end-of-interrupt to PIC

	   pop ax
	   iret


Of course, with this approach, control is never passed to previously 
installed ISRs.  This may be desirable -- those pesky TSRs won't be
popping-up over your game screen.  On the other hand, you may not want
to completely disable the user's configuration.  If this is the case,
you could selectively reset the keyboard (i.e. examine the scan code,
determine whether the key is of interest to you.  If not, pass control
to the previously installed ISR, else process it locally and reset the
keyboard).

	   
-- 
+---------------+---------------------------------------------------+
| Carl Harris   |program (tv).  To engage in an activity similar to |
| CS @ VA TECH  |banging one's head against a wall, but with fewer  |
|               |opportunities for reward.                          |
Newsgroups: comp.os.msdos.programmer