From: "Anthony.Appleyard" Organization: Materials Science Centre To: DJGPP AT delorie DOT com Date: Fri, 13 Feb 1998 14:17:43 GMT Subject: Hooking interrupt 9 clashing with new types of BIOS? Reply-to: Anthony DOT Appleyard AT umist DOT ac DOT uk Message-ID: Precedence: bulk I wrote in Gnu C++ a program called SPATRL which reads the keyboard events directly by hooking interrupt 9 directly as listed at the end of this message. On a 486 desktop PC with DOS 6.22 that I bought about 3 years ago SPATRL always worked OK with no trouble. Recently I bought a laptop with a Pentium in. It has DOS 6.22. On it, SPATRL runs OK and on exit as intended goes duly back to a DOS prompt; but sometimes a few seconds after returning to DOS it says something like this:- C:\LIT\DIV\SPATRL>Invalid TSS in RMCB at eip=107f; flags=3002 eax=01fd0000 ebx=000020d4 ecx=00000000 edx=00022800 esi=00001c18 edi=0001cfe0 ebp=00000000 esp=0000310c cs=2b ds=3b es=b7 fs=33 gs=0 ss=33 error=00b4 Last week my desktop's D: disk went wrong, so I took the opportunity for a major upgrade of it, including a Pentium II chip and a new motherboard. On it SPATRL sometimes causes the same `Invalid TSS ...' error print a few seconds after it has exited. Also sometimes I get odd occurences such as programs dropping unexpectedly out to DOS, and lockups needing rebooting. I asked about this at a PC suppliers and he said that `interrupt 9 is referred internally to interrupt 2' and suchlike. But books about programming in assembler that I have don't warn about this, and indeed one very common type of assembler programming example is how to hook interrupt 9. What is happening? Is it some new misfeature that has been put into BIOSes? Has this bug/whatever been cured in Windows 95? ------------------------------------------------------- void I9handler() {uns char c,d; c=inportb(0x60); if(c==0xe0) {k_after0xe0=128; return;} d=(c&127)+k_after0xe0; if(c&128) Keydown[d]=0; else {if(!Keydown[d]) Keypressed[d]++; Keydown[d]=1;} k_after0xe0=0;} /*-----*/ int keypressed(uns char c){int i=Keypressed[c]; Keypressed[c]=0; return i;} /*-----*/ void setreadkeys(void H()=I9handler){int i; for(i=0;i<256;i++) Keydown[i]=Keypressed[i]=0; _go32_dpmi_get_protected_mode_interrupt_vector(9,&old_I9handler); new_I9handler.pm_offset=(int)H; new_I9handler.pm_selector=_go32_my_cs(); _go32_dpmi_chain_protected_mode_interrupt_vector(9,&new_I9handler);}; /*-----*/ void clearreadkeys(){int i; for(i=0;i<256;i++) Keydown[i]=0; _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_I9handler);}; // use while(typahead()) get_key(); to keep the character buffer empty //