Keyboard shift probolems

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
xarnze
Posts: 19
Joined: Thu Nov 02, 2006 4:45 pm
Location: United Kingdom
Contact:

Keyboard shift probolems

Post by xarnze »

I have writen a basic keyboard driver to get the key pressed and then outputit to the screen, but ive had a probolem when trying to add the shift keys, when ever i
press a key it now prints out the character from both keymaps, so if any of you get a chance to have a look at it for me i would be very greatful:

Code: Select all

void keyboard_handler(struct regs *r)

{

  unsigned char scancode;

  unsigned shift_state = 0;

  char asciicode;

  

  //read form the buffer

  scancode=inportb(0x60);



  if (scancode == (42|0x80) || scancode == (54|0x80))

    {

      //shift not pressed
      shift_state = 0;

    }

  else if (scancode == 42 || scancode == 54)

   {

      // shift
 pressed
      shift_state = 1;

   }

    else

    {

      if (shift_state)

      {

	asciicode = kbdus_upper[scancode];

      }

      else

      {

        asciicode = kbdus[scancode];

      }

      putch(asciicode);

    }

} 
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

Press a key it now prints out the character from both keymaps
Could it be that your code prints the make-code and break-code for each key ? Also make sure that 'shift_code' is either a global variable or a static local in your actual code.

regards,
gaf
xarnze
Posts: 19
Joined: Thu Nov 02, 2006 4:45 pm
Location: United Kingdom
Contact:

Stoping it printing the breakcodes

Post by xarnze »

Thanks, it now works fine when i press shift but still prints from both keymaps if shift is now pressed, you were right it is printing the breakcodes aswell, so how would i stop it fom printing the breakcodes?

Thatnks again for your help with this.
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Post by Midas »

I'm not certain I quite understand your code - why are you ORing with 0x80 at the start? You're looking for an AND I think - ORing will mean that it will always set shift as being down. Here's some heavily commented sample code (may well not compile - I've just typed it OTOH).

Code: Select all

unsigned char scancode;
unsigned shift_state = 0;
char asciicode;

scancode = inportb(0x60); // Read from keyboard controller

if(scancode & 0x80)
{
    // If bit 15 is set, then this is a key break code
    switch(scancode)
    {
        case 0xAA:
            // 0xAA == 0x2A | 0x80 - the shift key break code
            shift_state = 0;
            break;
        /* Note that the switch statement is overkill for just the shift key, but
         * there may well be other keys for which you wish to do similar
         * things (ctrl, alt, perhaps others peculiar to your OS). */
    }
}
else
{
    // If bit 15 isn't set, then it's a key make code
    switch(scancode)
    {
        case 0x2A:
            /* 0x2A is the shift key's scancode - we want to handle it specially
             * as it isn't a printable character. */
            shift_state = 1;
            break;
        default:
            /* Where we handle the non-special cases - usually all the
             * printable characters. */
           
            /* I prefer, through laziness, to do it this way - I doubt there's
             * much of a performance difference either way. */
           asciicode = kbdus[scancode];
           if(shift_state)
               asciicode = kbdus_upper[scancode];

           putch(asciicode); /* We'd want to replace this later, to place the
                              * key into a buffer of some sort, then read from
                              * it; or (later still, perhaps) send the key in a 
                              * message to the active process. */
           break;
    }
}

outportb(0x20, 0x20); // Acknowldge IRQ
Regards,
Angus [Óengus] 'Midas' Lepper
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

I'm not certain I quite understand your code - why are you ORing with 0x80 at the start?
From what I understand the line you're refering to compares the read-in scancode with the shift break-codes. The bitwise OR is only used to set the break-code bit for the comparison.

The code should actually work if you just add a last comparison before the table look-up:

Code: Select all

if(scancode == LEFT_SHIFT_BREAK || scancode == RIGHT_SHIFT_BREAK) 
{ 
    shift_state = 0; 
} 
else
{    
   if(scancode == LEFT_SHIFT_MAKE || scancode == RIGHT_SHIFT_MAKE) 
   { 
       shift_state = 1; 
   } 
   else 
   { 
       // TODO: Check if it's a make code -> if(~scancode &0x80)

       if(shift_state) 
       {
           asciicode = kbdus_upper[scancode]; 
       } 
       else 
       { 
           asciicode = kbdus[scancode]; 
       }
       putch(asciicode); 
    } 
}
Nevertheless I would recommend using a switch as Midas proposed. It will become much easier to read once you've added support for a few more modifier keys to your driver.

regards,
gaf
xarnze
Posts: 19
Joined: Thu Nov 02, 2006 4:45 pm
Location: United Kingdom
Contact:

Fixed

Post by xarnze »

I got it working now, i just added a check to see if it was a make code or not as gaf said, but i am going to add in switch functions later, i just wanted to get the basics done first. i will use what Midas has done to help with the more complex parts, and setting up all of the other keys.
Thanks for all your help everyone.
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Post by Midas »

gaf wrote:
I'm not certain I quite understand your code - why are you ORing with 0x80 at the start?
From what I understand the line you're refering to compares the read-in scancode with the shift break-codes. The bitwise OR is only used to set the break-code bit for the comparison.
Ah, right you are. Read it twice and managed to miss that. :oops: Thanks.
Regards,
Angus [Óengus] 'Midas' Lepper
Post Reply