detecting Keyboard in P mode: how do I do it

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.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

How about prompting "If you are using a keyboard, press ENTER now, or please hold.." and count down 3 seconds.
My OS is Perception.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Reminds me of the an error message from when I had an Apricot 286 - "Keyboard controller error or no keyboard found. Press F1 to Continue or Esc to Enter Setup..." :roll:

Cheers,
Adam
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Post by naiksidd_85 »

(MessiahAndrw)I thought of it earlier but i am trying to embed a diagnosis of some type that will check the hardware(basic) before loading kernel...

and as AJ said it is some what the same error..
but i think if i see the specification and change log may get some thing
Learning a lot these days THANKS to OSdev users
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

Why not assume there is no keyboard detected until the first key is pressed?

E.g. imagine an OS for a HTPC that enters "remote control mode" assuming there is no keyboard and not requiring a keyboard to operate. However once the user presses a key on the keyboard the OS knows there is a keyboard (the GUI no more shows the on-screen keyboard). Except after a timeout of 5 minutes the OS assumes the user has unplugged or put away the keyboard (the GUI now shows the on-screen keyboard again).
My OS is Perception.
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Post by inflater »

@AJ: Award BIOS (4.51PG?), Pentium II MMX: "Keyboard failure" and on the bottom of the screen "Press F1 to continue, DEL to enter SETUP" :lol:

Why in the world you would detect the keyboard for presence?... Almost any BIOS will halt if a keyboard is not present (it can be configurable through its setup utility though), and when the user would realize that the keyboard isn't responding, he would turn off the PC and reattach it in. /Or he would reattach it without turning the PC off, for a PS/2 style it's pretty dangerous :twisted:/

Regards
inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
Osbios
Member
Member
Posts: 116
Joined: Fri Jun 10, 2005 11:00 pm

Post by Osbios »

Well, I fight with the detection of PS2 devices. ]:/

The End Result: As long as you don't have running USB drivers, you never can tell if there really is a PS2 Keyboard/Mouse.

There are commands to get the device ID from PS2 device. And I use it to detect keyboard and mouse.

Most boards use USB Legacy Support. This is some sort of virtual PS2 devices. The board connects the real PS2 devices and USB devices to this virtual devices. Every board dos this on its own way. So you can't even tell if the USB Legacy Support is on if you have no USB devices attached.
But if USB Legacy Support is on then the virtual devices are present!

As far as I know the USB Legacy Support is disabled as son you initializing the USB Chip. (But I don't know for sure)


Do you want to see some of my code? (Assembler only)


Btw: If you have no USB Legacy Support or disable it -> it is possible to attach any PS2 device on the PS2 Ports, like switching keyboard and mouse, mouse + mouse, keyboard +keyboard
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Post by naiksidd_85 »

hi osbios ,
i wil be really helped if i can get to see some more codes.
Learning a lot these days THANKS to OSdev users
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Post by naiksidd_85 »

hi all,
I tried to write a code to detect the keyboard after reading the ps/2 protocol document.
the code is given below

Code: Select all

keybdpre:    xor eax,eax;
             mov al,0xAA; //(Controller self-test) - Returns 0x55 if okay. 

             out 64h,al;
ewait:      
	mov cx,0x100; // delay 
        dec cx;
	
        jnz ewait;
             
             
             
             in al,60h;
             cmp al,55h; // comparing to check if o/p is 55
	     jz print;
             jnz areho;

             

             print: mov ax,0x00

                ret

                areho: mov ax,0x01

                 ret

the code tends to send me a garbage value can any one help me out why it may be hapening.
Learning a lot these days THANKS to OSdev users
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Aside from the fact that your code has terrible formatting and that the jump conditionals are all messed up (they work, but I wouldn't make a habit of using jnz right after jz ;) ), your code should not return any values other than eax=0 or eax=1, which you can't really call "garbage". If it doesn't, then there must be something wrong with the way you're calling your code and/or checking the returned value.
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Post by naiksidd_85 »

your code should not return any values other than eax=0 or eax=1, which you can't really call "garbage". If it doesn't, then there must be something wrong with the way you're calling your code and/or checking the returned value.
yup rightly said but it does not return 0 or 1 ..
trying to sort the thing out.

would also like to know if any one done the BAT for keyboard.
Learning a lot these days THANKS to OSdev users
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

I'm not sure if anyone has pointed this out before, but you might also want to add a cli before doing any I/O to the keyboard and a sti after... ;) If you have interrupts setup and working, the keyboard might trigger something while you're waiting and perhaps that is what messes up eax before you check it. The interrupt that is triggered might also change keyboard registers before you attempt to read them.
To make sure that everything is OK inside the code you posted, I would change the last "mov ax, 0" and "mov ax, 1" to "mov eax, 0" and "mov eax, 1" respectively (and remove "xor eax, eax" from the top).
Finally, once your code is properly written (and hopefully properly justified :) ), if nothing works, just accept the fact that not all hardware is implemented the way you expect it to be. For example, some implementations might use PCI to assign different I/O ports to keyboards and mice.
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Post by ~ »

Here's another code. If the PS/2 mouse is enabled and working, that should be disabled first:

Code: Select all

;Disable INT's before test:
;Disable INT's before test:
  cli


;Send RESET command to the keyboard itself:
;Send RESET command to the keyboard itself:
  mov al,0xFF
  out 0x60,al


;Set a delay loop:
;Set a delay loop:
   .outPort60_1:   ;wait ready for command
     in al,0x64
     test al,00000010b
   jnz .outPort60_1


;Now read the answer. If OK, it's 0xAA, otherwise it's 0xFC:
;Now read the answer. If OK, it's 0xAA, otherwise it's 0xFC:
  in al,0x60
   cmp al,0xAA   ;See if OK, or 0xAA
   jnz .errork   ;If not, skip "setup" code

      ;;Here there should be code in case the keyboard is present.


      ;;Finally, we skip the rest of code in case of no keyboard:
      ;;Finally, we skip the rest of code in case of no keyboard:
          jmp .kend

.errork:
  ;;Here there should be code in case the keybard is NOT present.


.kend:
 ;;Nothing more about that here

Last edited by ~ on Wed Feb 27, 2008 8:36 am, edited 1 time in total.
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Post by naiksidd_85 »

hi ~ ,

thanks...
it is really helpful.
Learning a lot these days THANKS to OSdev users
Osbios
Member
Member
Posts: 116
Joined: Fri Jun 10, 2005 11:00 pm

Post by Osbios »

Ok my solution is a bit bigger.

At first you need some ground work. Therefor you need a working PIT driver.
The "pit.timer_count" is the PIT counter in 100/Sec. on my System.

The code is written in Fasm.

Code: Select all

kbc.read_date_byte.timeout = 20 ; 0.2 Sec.

;IN: -/-
;OUT: al=byte; ebx=result (0=ok; 1=parity error; 4=timeout(pit))
kbc.read_date_byte:
  mov  ebx, [pit.timer_count]
  add  ebx, kbc.read_date_byte.timeout
 .wait_for_recv:
  cmp  ebx, [pit.timer_count]
  jb   .pit_timeout_error
  in   al, 0x64
  test al, 10000000b
  jnz  .parity_error
  test al, 00000001b
  jz   .wait_for_recv
  in   al, 0x60
  xor  ebx, ebx
ret
.parity_error:
  xor eax, eax
  mov ebx, 1
ret
.kbc_timeout_error:
  xor eax, eax
  mov ebx, 2
ret
.pit_timeout_error:
  xor eax, eax
  mov ebx, 4
ret


kbc.wait_for_send:
  push eax
.waitloop:
  in   al, 0x64
  test al, 00000010b
  jne  .waitloop
  pop  eax
ret


;IN: al = command byte
kbc.send_command:
  call kbc.wait_for_send
  out  0x64, al
ret


;IN: al = byte
kbc.send:
kbc.psaux0.send:
  call kbc.wait_for_send
  out  0x60, al
ret


;IN: al = byte
kbc.psaux1.send:
  push eax
  mov  al, 0xD4
  call kbc.send_command
  pop  eax
  call kbc.send
ret


;IN: eax = sample rate (Valid sample rates are 10, 20, 40, 60, 80, 100, and 200 samples/sec.)
;ebx = @kbc.psaux0.send OR @kbc.psaux1.send
;OUT: eax=result (0=ok; 1=error)
kbc.set_mouse_sample_rate:
  pushad
  mov  edx, ebx ;save "kbc.psauxX.send"
  mov  ecx, eax ;save "sample rate"
  mov  ax, 0xF3 ;"set samplerate command"
  call edx ;kbc.psauxX.send
  call kbc.read_date_byte
  cmp  ebx, 0
  jne  .error
  cmp  al, 0xFA
  jne  .error
  
  mov  eax, ecx ;=the new samplerate
  call edx ;kbc.psauxX.send
  call kbc.read_date_byte
  cmp  ebx, 0
  jne  .error
  cmp  al, 0xFA
  jne  .error

  mov  eax, 0 ;ok
  jmp .end

.error:
  mov  eax, 1 ;error
  
.end:
  popad
ret
I detect any PS/2 device (keyboard/mouse) on any of the two ports. So the code for the first and second PS2 Port is the same. I will only post code for the first PS2 Port.

[edit]Oh, and yes of course: You have to disable the IRQs with cli.[/edit]
[edit2]Arg NO! Sry, you need IRQs because of the PIT to get the time ticks! x/
So enable IRQs!!![/edit2]

We don't want movement data from the user during the detection, so we disable user input. The "Disable data reporting" is the same for any PS2 device.
!!! The "Disable data reporting" command doesn't work on some emulators like VirtualBox or qemu. But it works on Bochs and real hardware!

Code: Select all

  ;Disable data reporting /dev/psaux0
  mov  al, 0xF5 ;disable data reporting
  call kbc.psaux0.send
  call kbc.read_date_byte ;0xFA (ACK)
Then we enable the clock line of the PS2 Port.

Code: Select all

  ;Enable psaux0 clock line (clear bit 4 of the Command byte)
  ;just to make sure psaux0 is enabled (CRAZY mainboards!!!)
   mov  al, 0xAE
   call kbc.send_command
   call kbc.read_date_byte ;0xFA (ACK)
So far I only needed this for the second PS2 Port on some boards (and Bochs). But you never know.




No we try to get the device ID. We send the "get device ID" command and look how many bytes we get. (Thats the reason I use the PIT to timeout the "kbc.read_date_byte")

Well... this code is a bit ugly. But it works fine so far!

Code: Select all

  mov  al, 0xF2 ;get device ID
  call kbc.psaux0.send
  call kbc.read_date_byte
  test ebx, 110b ;Timeout?
  jnz  kbc.init.detect_psaux0_nothing ;Timeout!  
  call crt.byte.write
  cmp  al, 0xFE ;Some Motherboards return 0xFE (resend) if no device is pluged in
  je   kbc.init.detect_psaux0_nothing
  cmp  al, 0xFA ;ack?
  jne  kbc.init.detect_psaux0_unknownError ;no ack!
  
  call kbc.read_date_byte
  test ebx, 110b ;Timeout?
  jnz  kbc.init.detect_psaux0_0byte ;Timeout!  
  ;we have 1 byte
  push eax ;push al
  
  call kbc.read_date_byte
  test ebx, 110b ;Timeout?
  jnz  kbc.init.detect_psaux0_1byte ;Timeout!
  ;we have 2 byte
  push eax ;push al
  
  call kbc.read_date_byte
  test ebx, 110b ;Timeout?
  jnz  kbc.init.detect_psaux0_2byte ;Timeout!
  ;remove trash from the stack
  pop eax
  pop eax
  
  ;3 byte or more id? I dont know what that could be. O_o
  jmp kbc.init.detect_psaux0_unknownDevice


  kbc.init.detect_psaux0_0byte: ;0 byte id, seems to be a at-keyboard
    ;-->We have a AT-Keyboard!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_1byte: ;1 byte id could be a mouse, do we know the mouse type?
    pop eax
    and eax, 0xFF
    cmp eax, 0x03 ;3=Intellimouse (This ID will return if the mouse was already initialized and the PC rebooted)
    je  kbc.init.detect_psaux0_1byte.detect_intelli
    cmp eax, 0 ;<> 0 oder 3
    jne kbc.init.detect_psaux0_unknownDevice ;it is a unknown device!

    ;it is at last a standard mouse!
    ;now test for extensions:
    
    ;set samplerate to 200, 100, 80
    mov  ebx, kbc.psaux0.send
    mov  eax, 200
    call kbc.set_mouse_sample_rate
    mov  eax, 100
    call kbc.set_mouse_sample_rate
    mov  eax, 80
    call kbc.set_mouse_sample_rate
    ;then getid
    mov  al, 0xF2 ;get device ID
    call kbc.psaux0.send
    call kbc.read_date_byte ;0xFA (ACK)
    call kbc.read_date_byte ;0 = standard mouse; 3=Intellimouse (scroll)
    
    cmp  al, 3
    je   kbc.init.detect_psaux0_1byte.detect_intelli
    
    ;-->We have a standard Mouse!
  jmp kbc.init.detect_psaux0_end
    kbc.init.detect_psaux0_1byte.detect_intelli:
    ;-->We have a mouse with intelli extension!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_2byte: ;2 byte id could be a mf2-keyboard, do we know the keyboard type?
    pop ebx
    pop eax
    shl eax, 8
    or  eax, ebx
    and eax, 0xFFFF
    cmp eax, 0xAB83
    je kbc.init.detect_psaux0_2byte.its_standard_mf2
    cmp eax, 0xAB41 ;some kbc "translate" the byte from the keyboard to Scancode1 (0x83=0x41)
    je kbc.init.detect_psaux0_2byte.its_standard_mf2
    jmp kbc.init.detect_psaux0_unknownDevice
  kbc.init.detect_psaux0_2byte.its_standard_mf2:
    ;-->We have a MF2 Keyboard!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_nothing:
    ;-->We have a unknown device or no device at all!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_unknownError:
    ;-->We have a unknown device or no device at all!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_unknownDevice:
    ;-->We have a unknown device or no device at all!
  jmp kbc.init.detect_psaux0_end
  
  kbc.init.detect_psaux0_end:
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Whoa! :shock:
Post Reply