Mail Archives: djgpp/1998/02/13/09:19:23
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 //
- Raw text -