Keyboard I/O

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.
Post Reply
newwen
Posts: 16
Joined: Sun Feb 03, 2008 3:04 am

Keyboard I/O

Post by newwen »

HI. Sorry fro the newbie questions, but I am having a terrible time implementing keyboard I/O.

What I have Done:

Enable a20
Enable GDT
Enable IDT
Jump to Pmode
Remap PICs

My goal:
Show splash screen, "Blah, blah, blah... Press any key to continue..." (done)
Wait for keypress and do stuff

My questions:

Code: Select all

void KeyboardIsr()
{
   char key = in(0x60); //get key press

   if(key==0x5a) //enter key
   {
		cls(0x70);
        printf(0x70, "Test", 1, 2);   
		} else {
		cls(0x70);
		printf(0x70, "Not Enter", 1, 2);
   }

    out(0x20,0x20);
}
How do I make this function fire when a key is pressed? That's it. :p
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post by 01000101 »

I have installed IRQ handlers or rather ISR's? if you have no way of detecting the keyboard interrupt, then you need to implement some sort of interrupt request handling. I suppose you may be able to poll the keyboard buffer, but that is very unorthodox and probably not very wise.
newwen
Posts: 16
Joined: Sun Feb 03, 2008 3:04 am

Post by newwen »

I looked into that, but I am not exactly sure where to do that in my project.. should I have done that in my loader or in my kernel? Also, and I will keep looking, but does anyone know of any good links for beginners in regards to the ISR thing? I looked at the wiki, which is a great thing, but it leaves me with too many questions. thanks
newwen
Posts: 16
Joined: Sun Feb 03, 2008 3:04 am

Post by newwen »

After some searching, somehow I found some ASM code and I tried to translate it to C, but I am very green. Can someone help me with this:
video.c: In function 'IOHandler': video.c:78: error: 'KeyboardIsr' undeclared (first use in this function) video.c:78: error: (Each undeclared identifier is reported only once video.c:78: error: for each function it appears in.) video.c:79: error: 'cs' undeclared (first use in this function)
My in() and out() functions:

Code: Select all

unsigned char in(unsigned short _port) //input a byte
{
  // "=a" (result) means: put AL register in variable result when finished
  // "d" (_port) means: load EDX with _port
  unsigned char result;
  __asm__ __volatile__("in %%dx, %%al" : "=a" (result) : "d" (_port));
  return result;
}

void out(unsigned short _port, unsigned char _data) //output a byte to a port
{
  // "a" (_data) means: load EAX with _data
  // "d" (_port) means: load EDX with _port
  __asm__ __volatile__("out %%al, %%dx" : :"a" (_data), "d" (_port));
}
My Attempt:

Code: Select all

void IOHandler()
{
// Install keyboard handler
in("push ds");
in("push word 0");
in("pop ds");
in("cli");
out(4 * 0x09, KeyboardIsr); // line 78
out(4 *0x09 + 2, cs);  // line 79
in("sti");
in("pop ds");
}

void KeyboardIsr()
{
   char key = in(0x60); //get key press

   if(key==0x5a) //enter key
   {
		cls(0x70);
        printf(0x70, "Test", 1, 2);   
		} else {
		cls(0x70);
		printf(0x70, "Not Enter", 1, 2);
   }

    out(0x20,0x20);
}
Here is the code I translated, or tried to translate is more like it: (in fact the only thing I think I successfully translated was the comment line) :oops:

Code: Select all

; Install keyboard handler
push ds
push word 0
pop ds
cli
mov [4 * KEYBOARD_INTERRUPT], word keyboardHandler
mov [4 * KEYBOARD_INTERRUPT + 2], cs
sti
pop ds
Link: keyboard_kernel.asm

As you can see, I am very desperate to make this work. ;)
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Post by thepowersgang »

You do not use in and out for assembler commands, try putting that piece of code into an assembler file OR convert it to AT&T syntax (for GCC) and put it in an __asm__ call.
newwen
Posts: 16
Joined: Sun Feb 03, 2008 3:04 am

Post by newwen »

Where is my mind? I swear I need sleep. Sorry for asking stupid questions, I will try to tone it down next time, and sleep more often. Thanks
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi,

To get the IRQ to fire, you first need to ensure that no bytes are currently waiting to be read. The next IRQ will only fire when the buffer is empty (not full), and it is possible that a key has been pressed e.g. before you installed your ISR that is filling up the buffer.

Try, just after mapping your keyboard IRQ handler, doing a:

Code: Select all

while (inb(0x64) & 0x1)
  inb(0x60);
So that reads: While the keyboard status register indicates data is available, read data. That should flush the buffer out and hopefully you'll recieve IRQs.
newwen
Posts: 16
Joined: Sun Feb 03, 2008 3:04 am

Post by newwen »

I found some good examples, but they are in asm, which makes me believe that I should do this ISR in my boot loader, correct?

[EDIT]One more question, should I define my ISRs in 16 or 32 bit mode?[/EDIT]
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

If your kernel is going to be 32 bit protected mode, implement the 32 bit handlers in your kernel.

Cheers,
Adam
Post Reply