Mail Archives: djgpp/1999/02/16/00:31:56
Eli,
See the below program text. I compiled it using RHIDE (file name CFTEST.CC).
If you run it and then press a few keys, it will display the character (if
printable) and the getxkey() value for each key. The '1' key should be
translated to a '2' and the '0' key should be dropped, but isn't! BTW, in my
previous posting I stated 0x30 was the scan code for the '0' key, it is not 0x0B
is, 0x30 is the ASCII value ;-) This just doesn't seem to follow the docs....
KJohn
===================== start of CFTEST.CC ==================
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <keys.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <sys\movedata.h>
// required supporting data
_go32_dpmi_registers Regs;
static _go32_dpmi_seginfo info;
static _go32_dpmi_seginfo OldInt15Vector;
const unsigned short CarryFlagMask = 0x0001;
//
// This function is the ISR used to handle int 15 func 4f interrupts.
// Int 15 func 4f is called by the BIOS everytime it reads a character
// from the 8042 (keyboard controller). It places the scan code read
// in the AL register. On exit from this handler, if carry is cleared
// the BIOS will ignore the scan code. If carry is set, the BIOS will
// process the data in AL as the scan code (i.e. you can change the
// scan code if you want).
//
// This function does two things, if it sees a scancode 0x0B ('0' key)
// it clears the carry flag so the BIOS will ignore the '0' key. If it
// sees a scan code 0x02 ('1' key), it changes it to 0x03 ('2' key).
void Int15Handler( _go32_dpmi_registers *Regs )
{
// if we are being called for int 0x15, function 0x4f (BIOS key intercept)
// and the carry flag is set (it is clear for dropping this scan code)
if ( Regs->h.ah != 0x4f )
return;
// if this is the '0' key make code, ask BIOS to drop it
if ( Regs->h.al == 0x0b )
Regs->x.flags = Regs->x.flags & ~CarryFlagMask;
// if this is the '1' key scan code (0x02), change the '2' key scan code (0x03)
if ( Regs->h.al == 0x02 )
Regs->h.al = 0x03;
return;
}
//
// This function locks the Int15Handler() ISR code and data areas into memory
// so the DPMI server cannot swap them out to disk or move them in physical
// memory. It then adds this the Int15Handler address to the interrupt
// vector table so it will be called via int 15.
// NOTE: This function must be placed after the Int15Handler in this file
void StartInt15Handler()
{
// lock handler's memory
_go32_dpmi_lock_code( Int15Handler, (unsigned long)StartInt15Handler -
(unsigned long)Int15Handler );
_go32_dpmi_lock_data( &Regs, sizeof(Regs) );
// install int 15 handler
_go32_dpmi_get_real_mode_interrupt_vector( 0x15, &OldInt15Vector );
info.pm_offset = (long unsigned int)Int15Handler;
_go32_dpmi_allocate_real_mode_callback_iret( &info, &Regs );
_go32_dpmi_set_real_mode_interrupt_vector( 0x15, &info );
}
//
// This routine removes Int15Handler from the system interrupt table
// and frees any used resource
void StopInt15Handler()
{
_go32_dpmi_set_real_mode_interrupt_vector( 0x15, &OldInt15Vector );
_go32_dpmi_free_real_mode_callback( &info );
}
int main()
{
unsigned short Key;
printf( "Starting int 15 handler\n" );
StartInt15Handler();
printf( "\n\nPress any key, the getkey() values will be displayed.\n" );
printf( " Escape to exit.\n" );
printf( " '0' should do nothing.\n" );
printf( " '1' should show as '2'.\n" );
while( Key != K_Escape )
{
Key = getxkey();
if ( isprint( Key ) )
printf( "'%c'(%02x) ", (char) Key, Key );
else
printf( "N/A(%02x) ", Key );
}
StopInt15Handler();
return 0;
}
==================== end of CFTEST.CC ===============
Eli Zaretskii wrote:
>
> On Sun, 14 Feb 1999, John Scott Kjellman wrote:
>
> > Once I do this, if the BIOS generated an int 15 (func 4f) and the
> > scan code in AL is 0x30 (make code for '0' key), clearing the carry
> > flag and returning should cause the BIOS to ignore the '0' key scan
> > code. This does not work!
>
> It should work, though. The documentation for the function
> `_go32_dpmi_allocate_real_mode_callback_iret' says that any changes to
> the registers' struct will be reflected back to real mode. And the
> DPMI spec includes an example of a function that hooks Int 21h and
> sets the carry flag under certain conditions, so at least in theory
> this should have worked.
>
> It might be that the carry flag is cleared by the wrapper created by
> `_go32_dpmi_allocate_real_mode_callback_iret', but I don't see any
> instruction which does that. Maybe if you look at its source (the
> file gormcb.c in djlsr202.zip) you will see some bug like that.
>
> Are you sure that the carry flag not being set is your problem? Maybe
> some other cause is at work here?
>
> > If this is too confusing (I know it is a l-o-n-g explanation), please let me
> > know and I'll write a simpler program to demonstrate what I am trying to
> > accomplish.
>
> It's not confusing, but a simple test program might help to
> investigate the problem.
- Raw text -