Page 1 of 1

[SOLVED] issues with kbd driver.

Posted: Thu Feb 12, 2015 1:51 pm
by jtokarchuk
Hi,

In my attempts to make a keyboard driver (modified from brans kern dev, wanted to add a buffer system), I've come up with this.

If I pull the while out of my getch() and do it in the interrupt itself, I can get the characters to print out.

However, set up this way, the while seems to block the keyboard? in my main.c I do
keyboard_buffer_clear();
getch();
puts("hello world"); <- never gets here.

Unsure what I am doing wrong at this point. Need a bump. Thanks!


Code: Select all

/* 
* slightly modified bkerndev driver 
*  Desc: Keyboard driver
*
*  														 */
#include <system.h>

unsigned char *kbdbuf[255];     // keyboard buffer
int bufcount = 0;				// position in buffer
int i;							// iterator var

int shift = 0;
int capslock = 0;
int control = 0;


/* KBDUS means US Keyboard Layout. This is a scancode table
*  used to layout a standard US keyboard. I have left some
*  comments in to give you an idea of what key is what, even
*  though I set it's array index to 0. You can change that to
*  whatever you want using a macro, if you wish! */

unsigned char kbdus[128] =
{
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'q', 'w', 'e', 'r',	/* 19 */
  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',		/* Enter key */
    0,			/* 29   - Control */
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'z', 'x', 'c', 'v', 'b', 'n',			/* 49 */
  'm', ',', '.', '/',   0,					/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */

};

unsigned char kbdcapsus[128] =
{

    0,  27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
    '(', ')', '_', '+', '\b', /* Backspace */
    '\t',         /* Tab */
    'Q', 'W', 'E', 'R',   /* 19 */
    'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',     /* Enter key */
      0,          /* 29   - Control */
    'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
    '\"', '~',   0,        /* Left shift */
    '|', 'Z', 'X', 'C', 'V', 'B', 'N',            /* 49 */
    'M', '<', '>', '?',   0,                  /* Right shift */
    '*',
    0,  /* Alt */
    ' ',  /* Space bar */
    0,  /* Caps lock */
    0,  /* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,  /* < ... F10 */
    0,  /* 69 - Num lock*/
    0,  /* Scroll Lock */
    0,  /* Home key */
    0,  /* Up Arrow */
    0,  /* Page Up */
    '-',
    0,  /* Left Arrow */
    0,
    0,  /* Right Arrow */
    '+',
    0,  /* 79 - End key*/
    0,  /* Down Arrow */
    0,  /* Page Down */
    0,  /* Insert Key */
    0,  /* Delete Key */
    0,   0,   0,
    0,  /* F11 Key */
    0,  /* F12 Key */
    0,  /* All other keys are undefined */

};

// TODO: Third keyboard handler for capslock behavior?

/* Handles the keyboard interrupt */
void keyboard_handler(struct regs *r)
{
    unsigned char scancode;

    /* Read from the keyboard's data buffer */
    scancode = inportb(0x60);

    /* If the top bit of the byte we read from the keyboard is
    *  set, that means that a key has just been released */
    if (scancode & 0x80)
    {
        /* You can use this one to see if the user released the
        *  shift, alt, or control keys... */
        switch(scancode)
        {
            case 0xAA:
                // 0xAA == 0x2A | 0x80 - the left shift key break code
                shift = 0;
                break;
            case 0xB6:
				// right shift key break code
                shift = 0;
                break;
        }
    }
    else
    {
       // KEYPRESS: SHIFT
	   
       if(scancode == 0x2A || scancode == 0x36)
       {
            shift = 1;
        }

        bufcount += 1;
        kbdbuf[bufcount - 1] = kbdus[scancode];

        if(shift == 1) {
            kbdbuf[bufcount - 1] = kbdcapsus[scancode];
        }

         if(bufcount == 255) {
            keyboard_clear_buffer();
        }


    }
}

void keyboard_clear_buffer()
{
    for(i=0;i<=255;i++)
    {
        kbdbuf[i - 1] = '00';
    }

    bufcount = 0;
}

unsigned char getch()
{
	unsigned char retval = 0;
	
	while(bufcount == 0);
	
    retval = kbdbuf[bufcount - 1];
    kbdbuf[bufcount - 1] = '00';
    bufcount -= 1;
	return retval;
}


/* Installs the keyboard handler into IRQ1 */
void keyboard_install()
{
    irq_install_handler(1, keyboard_handler);
}


Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:18 pm
by Techel
Maybe your Compiler optimizes 'while(bufcount == 0);' to an infinity loop, since it doesn't see 'bufcount' changing in the loop and doesn't know your interrupt handler. Adding 'volatile' to the declaration of 'bufcount' could solve the problem.

Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:19 pm
by kzinti
Shouldn't this:

Code: Select all

unsigned char *kbdbuf[255];     // keyboard buffer
be this instead:

Code: Select all

unsigned char kbdbuf[255];     // keyboard buffer
?

You sure aren't allocating memory for it...

Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:20 pm
by jtokarchuk
Roflo wrote:Maybe your Compiler optimizes 'while(bufcount == 0);' to an infinity loop. Adding 'volatile' to the declaration of 'bufcount' could solve the problem.
beautiful, thank you very much.

Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:21 pm
by jtokarchuk
kzinti wrote:Shouldn't this:

Code: Select all

unsigned char *kbdbuf[255];     // keyboard buffer
be this instead:

Code: Select all

unsigned char kbdbuf[255];     // keyboard buffer
?

You sure aren't allocating memory for it...
yeah, you're right. Switched. Haven't worked on a memory manager yet.

Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:22 pm
by ExeTwezz

Code: Select all

    for(i=0;i<=255;i++)
    {
        kbdbuf[i - 1] = '00';
    }
Initially, `i' is zero, and entry `i - 1' = 0 - 1 = -1, so you're accessing kbdbuf[-1], which is incorrect.

Also, why is it '00'? Only one character can be inside '', so you must change it to '\0' (I assume you wanted it to be zero byte).

Re: issues with kbd driver.

Posted: Thu Feb 12, 2015 2:24 pm
by jtokarchuk
ExeTwezz wrote:

Code: Select all

    for(i=0;i<=255;i++)
    {
        kbdbuf[i - 1] = '00';
    }
Initially, `i' is zero, and entry `i - 1' = 0 - 1 = -1, so you're accessing kbdbuf[-1], which is incorrect.

BLAH. Amazing what a second (third, fourth) set of eyes does, eh?

Thank you as well. Fuzzy head, recovering from pneumonia -_-