Keyboard IRQs Squelching the PIT

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
User avatar
charliegreen
Posts: 3
Joined: Sun Jul 28, 2013 1:43 am
Location: Goleta, CA
Contact:

Keyboard IRQs Squelching the PIT

Post by charliegreen »

Hello!

So, my timer code works perfectly, and my IRQ0 handler gets called regularly and on time.. until I start typing. Then my handler only gets called when an IRQ1 comes through from the keyboard. My keyboard IRQs work just fine, and I know there are no issues with the IDT; I've remapped the PIC properly, and I do reset it after IRQs come through.

So, I initialize all my interrupts and whatnot, then do this in main (some is snipped out, but it's trivial):

Code: Select all

    while(true){
        asm volatile ("hlt");
        console_putChar('a');
    }
I run asm("sti") before this, and my console happily prints 'a's off into the sunset at 20Hz.

Then I start typing; 'a's don't get printed anymore, QEMU begins nomming up 100% CPU, and the number of ticks displayed (how many times IRQ0 has been run) only increments upon a keypress.

My IRQ1 handler code follows, and is called by my generic IRQ handling function; I reset the master (and slave, if necessary) PIC chips properly at the end of this function.

Code: Select all

#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_COMM_PORT 0x64
#define KEYBOARD_STAT_PORT 0x64

#define KEYBOARD_READ_READY  0x1
#define KEYBOARD_WRITE_READY 0x2

#define KEYBOARD_COMM_ACK  0xFA
#define KEYBOARD_COMM_NACK 0xFE

static bool irq1(__UNUSED registers_t regs){
    char c = keyboard_getc();
    if(c)
        console_putChar(c);
    return true;
}

char keyboard_getc(void){
    // snip snip. Basically just calls keyboard_scanByte and messes with its output to get a character instead of a scancode.
}

uint8_t keyboard_scanByte(void){
    uint8_t b;
    do{
        b = inb(KEYBOARD_STAT_PORT);
    }while((b & KEYBOARD_READ_READY) == 0);
    return inb(KEYBOARD_DATA_PORT);
}
Any thoughts on this? Any and all input is greatly appreciated!

UPDATE: It appears that the timer only stops firing when a key becomes unpressed (so, a keyup event)
My OS is called Moss. This was originally because I wasn't creative and smashed together "MyOS", but eventually became a commentary on its development speed.
User avatar
charliegreen
Posts: 3
Joined: Sun Jul 28, 2013 1:43 am
Location: Goleta, CA
Contact:

Re: Keyboard IRQs Squelching the PIT

Post by charliegreen »

I am dumb. I wasn't handling key-up events. Here's keyboard_getc:

Code: Select all

// NOTE: this assumes keyboard scan code set 1                                                                                                                
char keyboard_getc(void){
    const char*keymap = _keymap;
    char ret = 0;

    uint8_t scancode;
 top:
    scancode = keyboard_scanByte();

    if(scancode>=sizeof(_keymap) || _keymap[scancode]==0){
        // our key requires special treatment                                                                                                                 
        switch(scancode){
        case 0x36:
            _rightShift=true;
            break;
        case 0x2a:
            _leftShift=true;
            break;
        case 0xc6:
            _rightShift=false;
            break;
        case 0xaa:
            _leftShift=false;
            break;
        case 0x3a:
            _capsLock=!_capsLock;
            break;
        case 0x0e:
            console_backspace();
            break;
        }
        [color=#BF8040]goto top;[/color]               // oh god, what have I done                                                                                                   

    }else{
        if(_leftShift || _rightShift)
            keymap = _keymapShifted;

        // we use the shifted keymap if we're typing a letter and _capsLock                                                                                   
        char c = _keymapShifted[scancode];
        if('A'<=c && c<='Z' && _capsLock)
            keymap = _keymapShifted;

	ret = keymap[scancode];
    }

    return ret;
}
With the goto, a keyup scancode gets us caught in an infinite loop of polling the keyboard. I don't know what I was thinking....
Thanks, folks, and I apologize for bothering you!
My OS is called Moss. This was originally because I wasn't creative and smashed together "MyOS", but eventually became a commentary on its development speed.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Keyboard IRQs Squelching the PIT

Post by Combuster »

"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply