Need some help with the Keyboard

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
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Need some help with the Keyboard

Post by Pyrofan1 »

Okay, I have my IDT and my GDT set up. I know my IDT works because I can create divide by zero exceptions. Now my keyboard isn't work, i.e. it doesn't display the key that was hit like it's suppose to.
I have attached my IRQ files and my keyboard file, I was hoping someone could help me with this.

here's my main.c file

Code: Select all

#include "kernel/video.h"
#include "kernel/memory.h"
#include "kernel/gdt.h"
#include "kernel/idt.h"
#include "kernel/irq.h"
#include "kernel/timer.h"
#include "kernel/keyboard.h"

void _main(void* mbd,unsigned int magic)
{
	clrscr();
	timer_phase(100000);
	gdt_install();
	idt_install();
	irq_install();

	irq_install_handler(1,keyboard_handler);
	irq_install_handler(0,timer_handler);
	
	for(;;);
}
Attachments
irq.h
kernel/irq.h
(1.83 KiB) Downloaded 46 times

[The extension s has been deactivated and can no longer be displayed.]

keyboard.h
kernel/keyboard.h
(1.58 KiB) Downloaded 40 times
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

the cli statement are not really needed if you use an interrupt descriptor instead of an gate descriptor. Next you don't enable interrupts as far as i could see. And also you need to acknowledge the interrupts.

search the wiki on how to do that.
Author of COBOS
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Post by Pyrofan1 »

Okay, I changed my code so that I acknowledge the interrupts, but the keyboard still doesn't work. I know interrupts are enabled because I can have code like

Code: Select all

a=a/0;
and that will cause a divide my zero exception.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

just for the record, your timer interrupt also does not work?

if that is the case did you enable the irq's in port 0x21 and 0xA1?
Author of COBOS
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

Pyrofan1 wrote:I know interrupts are enabled because I can have code like

Code: Select all

a=a/0;
and that will cause a divide my zero exception.
Exceptions aren't controlled by the IF even though they use the IDT. The IF (the flag cleared/set by cli/sti) only controls IRQs. Examples of IRQs are those for the timer, keyboard, floppy, mouse and so on. So if you want to get keyboard interrupts you need to "sti".
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Post by Pyrofan1 »

Okay now I know I have interrupts enabled because I have asm("sti"); in my code, but it still doesn't work

Code: Select all

#include "kernel/video.h"
#include "kernel/memory.h"
#include "kernel/gdt.h"
#include "kernel/idt.h"
#include "kernel/irq.h"
#include "kernel/timer.h"
#include "kernel/keyboard.h"
#include "kernel/errors.h"

void _main(void* mbd,unsigned int magic)
{
	asm("cli");
	timer_phase(100);
	gdt_install();
	idt_install();
	irq_install();

	irq_install_handler(1,keyboard_handler);
	irq_install_handler(0,timer_handler);
	
	clrscr();

	asm("sti");
	while(1);
}
When I run this code I get
Reserved exception
and my time doesn't work either. I think I'm not remapping the pic properly.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

I can't see an EOI anywhere, which you need for any interrupt triggered by hardware external to the processor. If that is missing the timer interrupt will fire once and then the PIC will hang (because it is waiting for you to tell it that processing of the first interrupt is complete).

Somewhere before the iret you need:

mov al, 20h
out 20h, al

For IRQ line 8 and above you also need

mov al, 20h
out 0a0h, al

Maybe you've already got them, or it, but I can't see it anywhere
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Post by Pyrofan1 »

I do acknowledge the interrupts with this code

Code: Select all

if(irq>=40)
{
	outportb(0xA0, 0x20);
}
outportb(0x20,0x20);
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

You don't seem to be clearing the stack after the call to irq_handler. (In C the called function will not do the job for you.)
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Post by Pyrofan1 »

I thought that's what iret does
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

It will pop whatever registers were (automatically) pushed when the interrupt was called, but not anything pushed after it was called.

BTW the interrupt flag is automatically cleared when an interrupt is generated, so cli isn't strictly necessary.
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Post by Pyrofan1 »

Okay, I did that and now I can press a key and have it displayed, but when I'm using the qwerty layout, it prints the qwerty key and the same key on a dvorak keyboard and when i'm using the dvorak layout I get the key and a weird character or with certain keys, the letter disappears. I have attached my code.
Attachments
keyboard.h
(4.83 KiB) Downloaded 80 times
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

Pyrofan1 wrote:Okay, I did that and now I can press a key and have it displayed, but when I'm using the qwerty layout, it prints the qwerty key and the same key on a dvorak keyboard and when i'm using the dvorak layout I get the key and a weird character or with certain keys, the letter disappears. I have attached my code.
Actually, I'd wager when using a qwerty layout it prints the qwerty key when you press it and the dvorak key when you release it, correct?
And the "weird character" on dvorak only shows up when you release as well?
You forgot to filter out the release codes, which are "0x80 | code" which is "128 + code" (since the top bit of the actual code is always 0). This causes your array index to be out of bounds when you try to translate them to ascii, and so you're accessing memory after the keymap. The qwerty map is followed directly by the dvorak map, so you get extra "dvorak characters" when you release keys. After the dvorak map is some other stuff, which when interpreted as a keymap causes the "weird characters" or control codes when you release keys while using a dvorak layout.
If you have no need for the release codes (yet), just put a big "if (scancode < 0x80) {}" around the if-statement (including else clause) in your keyboard_handler.
Post Reply