Message-ID: <36C90198.90D8905C@ameritech.net> Date: Mon, 15 Feb 1999 23:26:48 -0600 From: John Scott Kjellman X-Mailer: Mozilla 4.04 [en] (Win95; I) MIME-Version: 1.0 To: Eli Zaretskii CC: djgpp AT delorie DOT com Subject: Re: How to check the carry flag? (long) References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com 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 #include #include #include #include #include #include #include // 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.