I think your boolean algebra in mask_irq is wrong:
Code:
/*
???Just a note, 2^0 (for example) = 00000001, 2^1 = 00000010, so you can see where
???the 2 ^ (interrupt - 8) and 2 ^ (interrupt) statements come from.
*/
Yes, these two are true. But what if you try to mask interrupt 2? 2^2 = 0, so no interrupt will be affected. Or interrupt 3? 2^3 = 1, so interrupt 1 will be affected, not 3.
I think you want:
Code:
void mask_irq(int interrupt)
{
if (interrupt == 16)????????????//Code to unmask all
{
slave_pic = 0;
master_pic = 0;???
}
else if((interrupt > 7) && (interrupt < 16))???//If it's an interrupt handled by slave PIC
slave_pic |= 1 << (interrupt - 8);
else if((interrupt > -1) && (interrupt < 8)) //If it's an interrupt handled by master PIC
master_pic |= 1 << interrupt;
outportb(0x21, master_pic);
outportb(0xA1, slave_pic);
}
Same for unmask_irq. This technique is really common in C: to go from a bit index N to a mask with only bit N set, use mask = 1 << N.
--------
Does kbd.c compile? Cos it's not valid C -- at least, not valid C89. You're declaring map[] and shiftmap[] in the middle of keymap_us, which is a C++/C99 feature. In any case, the compiler is probably generating code which reinitialises these two arrays every time the keymap_us function is called.
What I'd suggest you do is move these two declarations outside of the function and have them global, or if you don't like too many global variables, move them to the top of the functions and declare them static, which will generate the same code. You could make them const while you're at it, because they presumably never need to be modified. The compiler will put the definitions for these two variables into the kernel itself, instead of generating code to regenerate these variables each time keymap_us is entered.