delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/02/15/00:16:47

Message-ID: <36C7AD11.24161EA4@ameritech.net>
Date: Sun, 14 Feb 1999 23:13:53 -0600
From: John Scott Kjellman <jkjellman AT ameritech DOT net>
X-Mailer: Mozilla 4.04 [en] (Win95; I)
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
To: djgpp AT delorie DOT com
Subject: Re: How to check the carry flag?
References: <Pine DOT SUN DOT 3 DOT 91 DOT 990214122025 DOT 11498I-100000 AT is>
Reply-To: djgpp AT delorie DOT com

Eli,

Sorry if I wasn't clear.  What I was referring to was when your program needs to
set the state of the carry flag so that the caller (i.e. the routine that
generated the interrupt) can check it.  For example, in my case I intercept BIOS
int 0x15, function 0x4f (Keyboard Intercept), which allows me to have a look at
any scan code passed from the int 9 handler *before* the BIOS acts on it.  If I
clear the carry flag before returning, the BIOS will ignore the scan code as if
it were never generated.  I use this to map special data coming from a
programmable keyboard I have.  Some code may explain this better, so here is
some code snippets that might explain it better (I changes this version to 
cause the number 0 make code to be ignored):


// 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 every time 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 will drop the make code for the '0' key
//
void Int15Handler( _go32_dpmi_registers *Regs )
{
 // if int 0x15, function 0x4f (BIOS keyboard intercept)
 if ( Regs->h.ah != 0x4f )
    return;

 // if scan code is '0' key make code, drop it
 if ( Regs->h.al == 0x30 )
    Regs->x.flags = Regs->x.flags & ~CarryFlagMask;
 return;
}

//
// This function installs the locks Int15Handler() ISR into memory 
// and then places it in the system interrupt table
void StartInt15Handler()
{
   // lock the handler's memory and install it
   _go32_dpmi_lock_code( Int15Handler, 
                        (unsigned long)Int15Handler - 
                        (unsigned long)StartInt15Handler );

   _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 );
}


In the above code I would call StartInt15Handler() to setup the int 15 handler. 
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!  I know the
logic of the code is OK from two perspectives:

1) I have done this in real mode (many times before ;-)

2) If I change AL to some dummy value, the BIOS acts on the dummy value.  For
example, if I put 0x31 in AL, the BIOS thinks the "1" key was pressed.

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.

Thanks,
KJohn



Eli Zaretskii wrote:
> 
> On Thu, 11 Feb 1999, John Scott Kjellman wrote:
> 
> > Along the same lines, how do you get the carry flag passed to the
> > routine that generated the interrupt?  This is a problem I am having
> > with a keyboard handler, I need to set/clear the carry flag before I
> > return control back to the BIOS.
> 
> How do you mean ``return control back to the BIOS''?  Please describe
> what your code does (it certainly does NOT do a simple __dpmi_int
> call), because the answer depends on that.

- Raw text -


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