• C

Reset Keyboard Controller (8042)

How do I reset the keyboard controller (8042) using the "outp" function through ports 0x60 - 0x64? Can anybody help me?
ravipalAsked:
Who is Participating?
 
imladrisConnect With a Mentor Commented:
There is no supported mechanism for "polling" the keyboard port. The PC Architecture assumes it will be serviced using an interrupt.
I'm guessing that what is happening is that you have a program that checks the port at regular (really small) intervals until it finds the scan codes it is interested in. Having processed one, you have found that, at least in some cases, the scan code is still there, which is what you're interpreting as "data pending".

Assuming I'm guessing in the right corner, your best bet is probably just not process the port contents if it equals the character you just found.

If I'm not guessing correctly, please let me know how you are ascertaining whether there is data pending or not.

0
 
svsCommented:
Look at function initialize_kbd() in linux/drivers/char/pc_keyb.c
from Linux kernel.
0
 
ravipalAuthor Commented:
Thanks svs, but i could not locate the initizlize_kbd2() function definition. What I am doing is, I am polling the keyboard data register using the inp(0x60) until one of three particular make codes are detected, then in a switch section I take the necessary action. I then have to get back to polling, but I find there are some data still peinding in the 0x60 port. So I want to clear that and get back to polling. I am only a novice programmer, so could you give me a little more details as to wether i am doing the correct thing
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
ravipalAuthor Commented:
I could not locate the initizlize_kbd2() function definition. I need more details.
0
 
NicoLaanCommented:
As long as the key is pressed, it will send the scancode for that key.

Try the following as a test:

char: ch, chOld;
while (ch != 1)
{
 ch = inp(0x60);
 if (ch != chOld)
  printf("\n%0X", ch);
 chOld = ch;
}

1 = scancode for Esc, so it will run till you press escape.
When a key is released, it will return the scancode of the key + 0x80
When you remove the if-statement, you will see the scancodes continue scrolling on and on and on....

On some keyboards however, you do need to reset the port using port 0x61.
Are you looking for that?
I'll see if I can find some info about it.

And please be reminded, playing with this (probebly) won't cause damage, but you just might hang-up your computer a few times, while learning and testing. :-)

0
 
NicoLaanCommented:
As long as the key is pressed, it will send the scancode for that key.

Try the following as a test:

char: ch, chOld;
while (ch != 1)
{
 ch = inp(0x60);
 if (ch != chOld)
  printf("\n%0X", ch);
 chOld = ch;
}

1 = scancode for Esc, so it will run till you press escape.
When a key is released, it will return the scancode of the key + 0x80
When you remove the if-statement, you will see the scancodes continue scrolling on and on and on....

On some keyboards however, you do need to reset the port using port 0x61.
Are you looking for that?
I'll see if I can find some info about it.

And please be reminded, playing with this (probebly) won't cause damage, but you just might hang-up your computer a few times, while learning and testing. :-)

0
 
ravipalAuthor Commented:
Thanks Imladris,Nicolaan,

What I really want, is to know what mechanism to employ in order to effectivelly process key strokes for a user interface "inside a TSR". I know that DOS is not re-entrant and that I cannot use the normal C library functions in a TSR. That is why I resorted to geting down to the controller level. Is there another way to process key strokes safelly inside a TSR.

I already did something similar to what Nicolaan had sudgested and I find that for some keys such as Page Up, Page Down, its sending multiples of their scan codes. This is what causes my switch code section for Page Down to repeate and give wrong results.

What I really want to know is, what is the proper mechanism to employ to process keys inside TSR's, or will I have to resort only to handing keys at the controller level?
0
 
imladrisCommented:
I would be inclined to use the keyboard bios routines. They will cope with reentrancy. The keyboard bios interface is through software interrupt 0x16. If AH is set to 0 it will return the next keystroke in AL (and the scan code in AH).
You may have library routines to access bios routines, else in assembler it would be:

MOV AH,0
INT  16H

0
 
NicoLaanCommented:
If you want to use ports: wait until the key is released before you do something.

You can check this by waiting for the value to get above 0x80 and checking that it doesn't change.

ch = inp(0x60);
if (ch > 0x80)
{
  ch2 = inp(0x60)
  if (ch2 == ch)
    DoWhatYouWantToDoWithThisKey(ch);
}

You could also decide to use keys that act a bit normal, not like pageUp and pageDown :-)
But that's a 'workaround' the problem.
0
 
ravipalAuthor Commented:
I would also prefer to use Keyboard Bios routines as well since handling the Keyboard controller seems to be pretty difficult and I dont have all the information of the 8042 keyboard protocall.

But my TSR is going to be hooked to Interrupt 9. Do you think I will be able to call Keyboard Bios routines which calls INT 16 to get the Scan Code within my interrupt 9 TSR sucessfully ??
0
 
imladrisCommented:
Yup. Shouldn't be a problem. Interrupts will probably have to be reenabled, but you could always mask 9 specifically if reinterrupting is a problem.

0
 
ravipalAuthor Commented:
Thats great !!, although I am still a novice, could you enlighten me a bit on what is "Masking" ??
0
 
imladrisCommented:
I'm not quite sure how you are hooking into interrupt 9, so I can't be real specific to your situation. However, in general there are two levels of interrupt control in the PC architecture. Firstly there are two assembler instructions: CLI and STI; clear interrupt and set interrupt. CLI clears the interrupt enable flag in the CPU which prevents the CPU from "noticing" any interrupt whatsoever. This is the state in which the processor will arrive at the first instruction of an interrupt routine. If nothing is done the the flag will be returned to its previous state when the interrupt routine exits (and the processor flags are restored from the stack). However, it is frequently desirable to allow the CPU to be interrupted, even when it is in an interrupt routine. For instance if a higher priority interrupt occurs during servicing. This is usually accomplished by reenabling interrupts (STI) as soon as it is safe or convenient to do so.
Sometimes, it is OK to take interrupts in general, but one specific one cannot be handled. In this case you can set the PIC (programmable interrupt controller) to "mask" certain interrupts by writing a byte to the IMR (interrupt mast register).

However, in retrospect I don't think you need to get involved in any of this. I don't think you need to issue an STI to enable software interrupts. Even if you do, interrupt 9 can't be reissued until you have signalled completion. The PIC will only issue higher priority interrupts.

In short, I hope I was interesting and/or enlightening, but I don't think you actually need to deal with any of this.

0
 
ravipalAuthor Commented:
Thank you imladris, I have managed to jump this barrier in my TSR finally. My first problem was output which I had to resort to writing to video directly, then it was input, which with your help I managed to overcome through Bios routines. Now the rest is more or less pure logic which I think I can handle.
Thanks again for being a great help.
Bye for now.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.