How i use keyboard in my OS

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
richie

Re:How i use keyboard in my OS

Post by richie »

I use the following three functions:

Code: Select all

inline void outportb(unsigned int port,unsigned char value)  // Output a byte to a port 
{ 
    asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value)); 
}; 

inline void outportw(unsigned int port,unsigned int value)  // Output a word to a port 
{ 
    asm volatile ("outw %%ax,%%dx"::"d" (port), "a" (value)); 
}; 
 
inline unsigned char inportb(unsigned short port) 
{ 
   unsigned char ret_val; 
 
   asm volatile("inb %w1,%b0" 
      : "=a"(ret_val) 
      : "d"(port)); 
   return ret_val; 
};

Mastermind

Re:How i use keyboard in my OS

Post by Mastermind »

Richie: Thanks!!
Krisu

Re:How i use keyboard in my OS

Post by Krisu »

How can I compare, is ENTER key pressed?
I tried it with this code, but it won't work:

Code: Select all

while(1)
{
 c=getkey();
 if(c==13)
 {
  k_printf("\nENTER\n", 7);
 }
}
richie

Re:How i use keyboard in my OS

Post by richie »

No! That cannot work. As above mentioned port 0x60 returns only the scancode. Every key has a special scancode. The keyboard driver has the job to translate the scancode to the ascii value. Why the keyboard cannot provide the ascii-code is simple to understand. For example the key 'A' may produce always the same scancode. But there are two corresponding ascii-values 'a' and 'A'. The keyboard handler only gets the scancode. Since it knows whether SHIFT is currently pressed or not it can decide which ASCII-Value is correct.
What your function tests is if the key with scancode 13 is pressed and not scancode of the Enter-Key.
Every language have a different keyboard. For example the german keyboard has keys for '?', '?' and '?'. Because you will never need this letters in English they are left out on a English keyboard. So every kind of keyboard has another keymap ( a translation table between scancode and ascii). On a German keyboard ENTER has scancode 28 or 0x1C. (I think it's the same on American keyboards)
But there is a easy way to find that out. Write a function that prints you the current scancode value. Then you can press a key (on YOUR keyboard) and the the corresponding scancode.
Krisu

Re:How i use keyboard in my OS

Post by Krisu »

Thanks. 0x1C works. But... I don't get hex code when i using k_printf (only something indefinite text).
slacker

Re:How i use keyboard in my OS

Post by slacker »

i am also struggling to write a keyboard driver...what kind of data type is a scancode?
slacker

Re:How i use keyboard in my OS

Post by slacker »

also...how does the keyboard's user buffer get cleared?
richie

Re:How i use keyboard in my OS

Post by richie »

Everything is up to you.
what kind of data type is a scancode?
All you will get from the hardware is a byte value that represents the scancode.
how does the keyboard's user buffer get cleared?
There are two buffers: The firs obn eis in hardware on the keyboard controller. It collects all scancodes. Everytime you read from port 0x60 the buffer decreases. If it is empty you get 0x00 as scancode which actually is no scancode.
On the other hand there can be a buffer in your OS. Consider of a program which wants to read a string. Then your OS needs a buffer where it collects every "arriving" scancode (better to say its corresponding ASCII-Value). Normally the sign that input is finished is that the user presses ENTER. If your keyboard driver sees this scancode it gives control back to the user program (and copying the buffer to the user program).
And if the program is again requesing for user input, the keyboard driver starts over again. So there is no need to clear the buffer. It is simply overwritten when waiting for the next input.
But... I don't get hex code when i using k_printf (only something indefinite text).
I think you did a mistake when calling k_printf. I think this function can only print strings. But the scancode is no string. It's a number. You have to convert it to a string and then to print it.
k_printf has a pointer to a string as parameter. And you uses the scancode as this pointer. It just points somewhere in memory. This is why you get these strange characters.
slacker

Re:How i use keyboard in my OS

Post by slacker »

anyone have an example of a function that waits for a key to be pressed?
richie

Re:How i use keyboard in my OS

Post by richie »

Yes,Kirsu already posted it. He only got confused with ASCII and Scancode. Here is posible solution for waiting until ENTER is pressed.

Code: Select all

inline unsigned char inportb(unsigned short port) 
{ 
   unsigned char ret_val; 

   asm volatile("inb %w1,%b0" 
      : "=a"(ret_val) 
      : "d"(port)); 
   return ret_val; 
};

// ...


while(1)
{
c=inportb(0x60);
if(c==0x1C)
{
  k_printf("\nENTER\n", 7);
}
}
Krisu

Re:How i use keyboard in my OS

Post by Krisu »

Thanks for everyone! Now I can use keyboard in my OS without any problems.
richie

Re:How i use keyboard in my OS

Post by richie »

Yes, for a OS that is non-Multitasking (Singletasking?!?) this way works fine. But for a real Multitasking Os it is better to install a INT-handler. Every time a Key is pressed this handler is called and can get the scancode with inportb(0x60). But for a first version of the OS it is enough.
Post Reply