Page 1 of 1

Keyboard input

Posted: Wed Jul 13, 2016 1:07 pm
by Sidneyy
Not sure if I'm missing something. Have followed the wiki - which seems to suggest that scan code set 2 will be enabled by default. My code sets up a function to catch interrupts from IRQ 1, and caught interrupts are converted into something meaningful for other functions in the OS and queued. For now the code simply prints on screen when a text key is pressed.

I'm able to catch the interrupts but for some reason scan code set 1 is used. I've even tried to manually set scan code 2 (with reference to the wiki, and here), but scan code 1 is still being used.

For example, when I press the ctrl, the letter 'w' appears (scan code 0x1D is retrieved - which is scan code set 1 ctrl, and scan code 2 set 'w').

My keyboard handler initialisation code:

Code: Select all

    // Initialise the event buffer
    kb = malloc(sizeof(KeyboardEvent_t *) * (KB_BUFFER_MAX_SIZE+1));
    kb[0] = malloc(sizeof(KeyboardEvent_t));
    KBEVENT_END(kb[0]->flags);

    // Initialise the flags
    kb_flags = 0x0;

    // Set the first event to the end of the event buffer
    KBEVENT_END(kb[0]);

    // Install the interupt handler
    irq_install_handler(1, keyboard_handler);
The code that I've added (before the above) to set the scan code to 2:

Code: Select all

    outportb(0x60, 0xF0);
    while (!(inportb(0x60) == 0xfa));
    outportb(0x60, 0x02);
The scan code is obtained by calling:

Code: Select all

scancode = inportb(0x60);
Any ideas?

Re: Keyboard input

Posted: Wed Jul 13, 2016 1:25 pm
by linuxyne
10.3 maybe?

Re: Keyboard input

Posted: Wed Jul 13, 2016 11:48 pm
by BenLunt
You may need to turn off translation.

Also, the keyboard controller (the PS2 controller) has a mechanism to check when a byte is available from the controller.

Simply doing

Code: Select all

while (!(inportb(0x60) == 0xfa));
may be sufficient here, but not recommended.

You should really wait for the controller to tell you the Output Buffer is full before you try to read a byte from it. With that in mind, you should also wait for the controller to tell you the Input Buffer is empty before you try to write a byte to it. Just saying.

Ben
http://www.fysnet.net/input_and_output_devices.htm

Re: Keyboard input

Posted: Thu Jul 14, 2016 1:26 pm
by Sidneyy
linuxyne wrote:10.3 maybe?
BenLunt wrote:You may need to turn off translation.

Also, the keyboard controller (the PS2 controller) has a mechanism to check when a byte is available from the controller.

Simply doing

Code: Select all

while (!(inportb(0x60) == 0xfa));
may be sufficient here, but not recommended.

You should really wait for the controller to tell you the Output Buffer is full before you try to read a byte from it. With that in mind, you should also wait for the controller to tell you the Input Buffer is empty before you try to write a byte to it. Just saying.

Ben
http://www.fysnet.net/input_and_output_devices.htm
Both helpful posts - thank you. I understand completely what the problem is, but I can't figure out how to turn translation off. I've made some attempts based on what I understand (needing to write to the sixth bit of the controller RAM - somehow? I'm not sure.) Looking into it has helped me in other ways; I've expanded my knowledge of the 8042 controller.

In the end I've given up and will be re-writing my code to accommodate scan code set 1 for now. Thank you anyway!

Re: Keyboard input

Posted: Thu Jul 14, 2016 6:11 pm
by BenLunt
Your read the controller's RAM using commands 20h -> 3Fh and write to the RAM using commands 60h -> 7Fh.

Using command 20h reads the first byte in the RAM, 21h reads the second, 22h reads the third and so on.
Same with the write, 60h writes to the first, 61h writes to the second, and so on.

Ben
http://www.fysnet.net/input_and_output_devices.htm