delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/05/04/13:49:08

Xref: news2.mv.net comp.os.msdos.djgpp:3428
From: Shawn Hargreaves <slh100 AT york DOT ac DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Newbie probs : hooking keyboard int
Date: Fri, 3 May 1996 10:35:46 +0100
Organization: The University of York, UK
Lines: 46
Message-ID: <Pine.SGI.3.91.960503101459.21607D-100000@tower.york.ac.uk>
NNTP-Posting-Host: tower.york.ac.uk
Mime-Version: 1.0
In-Reply-To: <1996May1.130121@topaz>
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

On 1 May 1996, Thunder Child wrote:

> static void newint9_code(void)        //New interrupt 9 handler code.
> {                                     //(INT9 is triggered by keyboard input)
>   asm("
>     cli                               ;//Disable interrupts.
>     inb $0x60,%al                     ;//Read the keyboard input.
> 				      ;//(Port 60h is the keyboard port).
>     xorw  %bx,%bx                     ;//Clear BX.

I'm not sure exactly what the rules are for saving and restoring 
registers (is this documented anywhere, anyone?) but from examining the 
code output by gcc, I've deduced that functions can alter eax, ecx, and 
edx freely, but have to restore ebx, esi, and edi. Since you use bx, it 
would be a good idea to save and restore it.

> void installkeyboardint(void)
> {
>   __dpmi_get_protected_mode_interrupt_vector(0x09, &oldint9_addr);
>   //Store old keyboard interrupt vector.
>   
>   newint9_addr.offset32 = (int)newint9_code;
>   newint9_addr.selector = _my_cs();
>   
>   __dpmi_set_protected_mode_interrupt_vector(0x09, &newint9_addr);
>    //Hook our new handler to interrupt 9.
> }

You can't do that! You are passing the address of your C function 
directly as the hardware interrupt handler, which is no good because 
interrupt routines need special treatment to save and restore _all_ 
registers, set up the stack and segment selectors, etc. Either you can 
write your own wrappers to do this (there is an example in my Allegro 
library, in irq.s) or call the libc function that will create a wrapper 
for you (can't remember what it is called, _go32_dpmi_allocate_iret_wrapper() 
or something like that). You pass the address of your C function to this 
routine, it constructs some wrapper code for you, then you install this 
wrapper as the hardware interrupt handler.


/*
 *	Shawn Hargreaves.        Why is 'phonetic' spelt with a ph?
 *	Check out Allegro and FED on http://www.york.ac.uk/~slh100/
 */


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019