update keyboard leds

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
7 posts • Page 1 of 1
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

update keyboard leds

Post by bubach »

Hello, i recently added code in my keyboard irq to update teh leds when caps, num or scroll lock is pressed..

the problem is that bosch gives me a "keyboard buffer full"-error when i have this function enabled..

something i am missing?
thanks in advance..

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:update keyboard leds

Post by distantvoices »

i wouldn't do this kind of operation in the isr. I'd do it in a sort of task - or a tasklet, which does the work after the isr has fetched the scancodes from kbd port 60 (iirc)

are you still reading scancodes from port 60?

If not, no wonder that bochs doesn't like it.

are you issueing the correct combo of command/data sequence? I don't know it by heart, but can lookup.

is your code caught in a condition which never/always becomes true?

just check it out. Without more info about *how* your kbd isr looks like (a rough sketch in human language or pseudocode suffices), we canna give that much help as we want to. :-)

ha en bra dag
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:update keyboard leds

Post by bubach »

Hmm. I?ll try to describe the process..

I read the scan code from port 0x60

I check if key is released or pressed. save status as bit in "special-byte"
If ctrl is pressed or not, saved as bit in the "special-byte"
if shift - ||-
if alt - || -
if ctrl+alt+del is pressed, add bit in special-byte..

if caps is pressed, save status in "status-byte"
if num - || -
if scroll - || -

at the end i add the scan code to a buffer, and updates the status and special bytes, after that i "call update_leds" and exits the isr as usual; ack to pic(?) with out 0x20 something..

the update_leds function is adapted from a swedish os, that have a keyboard isr that looks almost excatly like mine.
it sends some bytes (the status-byte and maybe something else) and call a simple "kbd_wait" function 2(?) times in between..

to bad i don?t have my source with me..

[edit] to cold in sweden right now for a "bra dag" (eng: good day).. :-)
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:update keyboard leds

Post by distantvoices »

Below are the crucial pieces of code from my own kbd led handling.

Basically you send a bitmask to the controller which tells, which led is on and which one is off.

How are you setting the corresponding bit in status byte say for caps lock?

Code: Select all

void kbd_ack(void){ 
 while(!(inport(0x60)==0xfa));
}
void kbd_led_handling(uchar_t ledstatus){;
 outport(0x60,0xed); 
 kbd_ack();
 outport(0x60,ledstatus);
}
Here in vienna, sun shines but it is cooold as in devils arse.

But that shall not hinder us from enjoying a biiig snow feast. :-)
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:update keyboard leds

Post by bubach »

hmm. can?t remeber the right order right now, but its something like:
bit 1= 1 for num on, 0 for num off
bit 2= 1 for scroll on, 0 for scroll off
bit 3= 1 for caps on, 0 for caps off
bits 4-8 = 0

i think thats how it?s done.. but as i don?t have my sources right here...
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:update keyboard leds

Post by bubach »

Okay, now i have my source.
Lets see.. Here?s how i check and set the bits in the "kbd_status" byte... (u can?t turn them of yet..)

Code: Select all

;----------------------;
; Keyboard IRQ ;
;----------------------;
keyboard_isr:
 push eax
 ;-----------------------------------;
 ; get the scancode and statusbyte ;
 ;-----------------------------------;
 xor eax, eax
 in al, 0x60
 mov ah, byte [kbd_special] ; for ctrl+alt+del etc..
 ;------------------------------;
 ; check if key was released ;
 ;------------------------------;
 test al, 0x80
 jz .key_down
 or ah, 10000000b 
;............... some code..............
 ;----------------------------------------------;
 ; a key was pressed, check for special keys ;
 ;----------------------------------------------;
 .key_down:
 and ah, 01111111b 
;............... some code..............
 .check_caps:
 cmp al, 58
 jnz .check_num
 or byte [kbd_status], 00000100b
 jmp .end
 .check_num:
 cmp al, 69
 jnz .check_scroll
 or byte [kbd_status], 00000010b
 jmp .end
 .check_scroll:
 cmp al, 70
 jnz .end
 or byte [kbd_status], 00000001b
 jmp .end 
;.............. some more code...................
 .end:
 mov [kbd_raw_buffer], al
 mov [kbd_special], ah
 movzx eax, [kbd_status] ; to check if the statusbyte was correct..
 call print_hex32
; call update_leds
 mov al, 0x20
 out 0x20, al
 pop eax
 ret
the (current) update_leds function

Code: Select all

;------------------------------;
; Update the keyboard LED?s ;
;------------------------------;
update_leds:
 push ax
 .l1:
 in al, 0x64
 and al, 0x02
 jnz .l1
 mov al, 0xED
 out 0x60, al
 .l2:
 in al, 0x64
 and al, 02
 jnz .l2
 mov al,[kbd_status]
 out 0x60, al
 pop ax
 ret
Do you have any links to information about "advanced" keyboard programming? Becasue i would also like to know how to test the type of keyboard, know how to set diffrent "scan-modes(?) etc.

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re:update keyboard leds

Post by bubach »

[EDIT] For future forum viewers with the same problem, i now update this post with the correct and fully working code.. :-D

variable defined:

Code: Select all

 ;-------------------------------------------------------------------------;
 ; _________________ LED status byte: ;
 ; |0|0|0|0|0|1|1|1| ;
 ; +---------------+ 1 = True 0 = False ;
 ; | | +---> scroll lock ;
 ; | +-----> num lock ;
 ; +-------> caps lock ;
 ;-------------------------------------------------------------------------;
  kbd_status  db 0    ; LED statusbyte
In the keyboard IRQ:

Code: Select all

 ;-------------------------------------;
 ; toggle caps, num and scroll lock ;
 ;-------------------------------------;
 .check_caps:
  cmp  al, 58
  jnz  .check_num
  xor  byte [kbd_status], 4
  call  update_leds
  jmp  .end
 .check_num:
  cmp  al, 69
  jnz  .check_scroll
  xor  byte [kbd_status], 2
  call  update_leds
  jmp  .end
 .check_scroll:
  cmp  al, 70
  jnz  .end
  xor  byte [kbd_status], 1
  call  update_leds
  jmp  .end
And the functions required to change the LEDs:

Code: Select all

;------------------------------;
; Update the keyboard LED?s ;
;------------------------------;
update_leds:
  push  ax
  call  kbd_wait
  mov  al, 0xED
  out  0x60, al
  call  kbd_wait
  mov  al, [kbd_status]
  out  0x60, al
  call  kbd_wait
  pop  ax
  ret
;------------------;
; keyboard wait ;
;------------------;
kbd_wait:
  jmp  $+2
  in  al,64h
  test  al,1
  jz  .ok
  jmp  $+2
  in  al,60h
  jmp  kbd_wait
 .ok:
  test  al,2
  jnz  kbd_wait
  ret

anyway, thanks for the help and major input.. :P ;)

/ Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
Post Reply

7 posts • Page 1 of 1

Return to "OS Development"