Keyboard led problem

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.
espenfjo

Keyboard led problem

Post by espenfjo »

I`ve been trying to write a keyboard led function. I think i got it all right, but dont seem to work, atleast not in qemu/bochs/vmware.
This is the code:

Code: Select all

if(scancode == 69) /* Numlock */
        {
                while(inportb(0x64) & 0x2);
                        outportb(0x60, 0xed);
                        outportb(0x60, 1);
         }

pini

Re:Keyboard led problem

Post by pini »

I would replace your last outportb by :

Code: Select all

outportb(0x60, 2);
If I remember good, NUM is 2, CAPS is 4 and SCROLL is 0.
espenfjo

Re:Keyboard led problem

Post by espenfjo »

Yeah, thats correct, but '1' should, as far as i know, turn all lights off.
pini

Re:Keyboard led problem

Post by pini »

According to my book (PC Bible, 2nd edition 1989 :P) :

bit 0 is Scroll lock
bit 1 is Num lock
bit 2 is Caps lock

The light is on when the corresponding bit is set, so setting '1' will light SCROLL on and turning all lights on is done with '7'.
Num alone is set with '2' and Caps alone with '4'
espenfjo

Re:Keyboard led problem

Post by espenfjo »

Ok, i've tried nearly all the combinations, but no changes what so ever. :\
B.E

Re:Keyboard led problem

Post by B.E »

Try reading the state and the oring the bit

I am not quite show on this but don't you have to wait before you send the next byte after you send the set LED command

Which light come on when you press this button
pini

Re:Keyboard led problem

Post by pini »

B.E wrote: I am not quite show on this but don't you have to wait before you send the next byte after you send the set LED command
Right, and one could also check he receives an ACK (0xFA) after sending both bytes.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:Keyboard led problem

Post by bubach »

"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
Poseidon

Re:Keyboard led problem

Post by Poseidon »

Code: Select all

#define scrollock   (unsigned char) 0x01
#define numlock    (unsigned char) 0x02
#define capslock   (unsigned char) 0x04

void kbd_updateleds(unsigned char led) {
   if(led == 0) {
      leds = 0;
   } else {
      if (leds == (leds | led)) {   //If led is already on
         leds = leds ^ led;   // turn led off
      } else {
         leds = leds | led;   // else turn led on
      }
   }
   
   kbd_senddata(0xED);
   kbd_senddata(leds);         //update led status
}
My code for switching LEDs, maybe it helps you.
espenfjo

Re:Keyboard led problem

Post by espenfjo »

It's still not working, so i'm beginning to wonder if the problem could be Linux or maybe qemu/bochs/vmware
pini

Re:Keyboard led problem

Post by pini »

You will probably not be able to switch on/off leds when using a emulator.
Try to make a "real" test to check if it works.
B.E

Re:Keyboard led problem

Post by B.E »

Go to the following website and download the Ebook:
[link]http://webster.cs.ucr.edu/AoA/Windows/index.html[/link]

Goto chaptor 20. This will give you a full in depth tutorial on how to program the keyboard.
aladdin

Re:Keyboard led problem

Post by aladdin »

here is the part of code of my keyboard driver to switch on/of keyboard leds, it works on all emulators and real machines

Code: Select all

...
static char kbdstatus = 0;
static short caps=0;   //variable to acces caps lock status
static short num=0;   //variable to access num lock status
...

void kbd_led(char status)
{
   int st;

   do {
      st = inb(0x64);
   } while (st&0x02);

   outb(0x60, 0x0ed);
   do {
      st = inb(0x64);
   } while (st&0x02);

   outb(0x60, status&0x07);

}

void switch_num_lock()
{
   if (num) num=0; else num=1; //is numlock on or off ?

   if(!(kbdstatus&NUM_LOCK))  
   {
      kbdstatus |= NUM_LOCK;
   }
   else    
      kbdstatus &= (CAPS_LOCK|SCROLL_LOCK);


   kbd_led(kbdstatus);   
}


void switch_caps_lock()
{
   if (caps) caps=0; else caps=1;
   if(!(kbdstatus&CAPS_LOCK)) 
   {
      kbdstatus |= CAPS_LOCK;
   }
   else    
      kbdstatus &= (NUM_LOCK|SCROLL_LOCK);


   kbd_led(kbdstatus);   
}

void switch_scroll_lock()
{

   if(!(kbdstatus&SCROLL_LOCK)) 
   {
      kbdstatus |= SCROLL_LOCK;
   }
   else    
      kbdstatus &= (NUM_LOCK|CAPS_LOCK);


   kbd_led(kbdstatus);   
}

espenfjo

Re:Keyboard led problem

Post by espenfjo »

Ok, it think i got it to work, it seems to work in vmware atleast. :)
proxy

Re:Keyboard led problem

Post by proxy »

this is more for aladdin, just wanted to let you know that your code could be MUCH simpler.

Code: Select all

void switch_num_lock()
{
  if (num) num=0; else num=1; //is numlock on or off ?

  if(!(kbdstatus&NUM_LOCK)) 
  {
      kbdstatus |= NUM_LOCK;
  }
  else   
      kbdstatus &= (CAPS_LOCK|SCROLL_LOCK);


  kbd_led(kbdstatus); 
}
coudl easily be written like this:

Code: Select all

void switch_num_lock()
{
  if (num) num=0; else num=1; //is numlock on or off ?

  if(!(kbdstatus&NUM_LOCK)) 
  {
      kbdstatus |= NUM_LOCK;
  }
  else   
      kbdstatus &= (~NUM_LOCK);


  kbd_led(kbdstatus); 
}
which could lead to a generic function doing thr real work and your "flip_whatever fuction just calling that with the right flag passed..but it get's better. XOR will flip bits just like you want so...

Code: Select all

void switch_num_lock()
{
  if (num) num=0; else num=1; //is numlock on or off ?

  kbdstatus ^= NUM_LOCK;

  kbd_led(kbdstatus); 
}
finally, what's with the conditional logic to invert a boolean?!

Code: Select all

void switch_num_lock()
{
  num = !num; //is numlock on or off ?
  kbdstatus ^= NUM_LOCK;
  kbd_led(kbdstatus); 
}
as you can see your solution is far more complicated than neccessary.

proxy
Post Reply