Page 1 of 1
Keyboard I/O
Posted: Sun Feb 03, 2008 4:02 pm
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
Posted: Sun Feb 03, 2008 4:17 pm
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.
Posted: Sun Feb 03, 2008 9:31 pm
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
Posted: Sun Feb 03, 2008 10:07 pm
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)
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.
Posted: Sun Feb 03, 2008 11:46 pm
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.
Posted: Mon Feb 04, 2008 12:15 am
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
Posted: Mon Feb 04, 2008 2:36 am
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.
Posted: Mon Feb 04, 2008 4:47 pm
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]
Posted: Tue Feb 05, 2008 2:48 am
by AJ
Hi,
If your kernel is going to be 32 bit protected mode, implement the 32 bit handlers in your kernel.
Cheers,
Adam