detecting Keyboard in P mode: how do I do it
- AndrewAPrice
- Member
- Posts: 2309
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
How about prompting "If you are using a keyboard, press ENTER now, or please hold.." and count down 3 seconds.
My OS is Perception.
- naiksidd_85
- Member
- Posts: 76
- Joined: Thu Jan 17, 2008 1:15 am
(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
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
- AndrewAPrice
- Member
- Posts: 2309
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
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).
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.
@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"
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 /
Regards
inflater
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 /
Regards
inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English )
Derrick operating system: http://derrick.xf.cz (Slovak and English )
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
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
- naiksidd_85
- Member
- Posts: 76
- Joined: Thu Jan 17, 2008 1:15 am
- naiksidd_85
- Member
- Posts: 76
- Joined: Thu Jan 17, 2008 1:15 am
hi all,
I tried to write a code to detect the keyboard after reading the ps/2 protocol document.
the code is given below
the code tends to send me a garbage value can any one help me out why it may be hapening.
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
Learning a lot these days THANKS to OSdev users
- zaleschiemilgabriel
- Member
- Posts: 232
- Joined: Mon Feb 04, 2008 3:58 am
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.
- naiksidd_85
- Member
- Posts: 76
- Joined: Thu Jan 17, 2008 1:15 am
yup rightly said but it does not return 0 or 1 ..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.
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
- zaleschiemilgabriel
- Member
- Posts: 232
- Joined: Mon Feb 04, 2008 3:58 am
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.
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.
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.
- naiksidd_85
- Member
- Posts: 76
- Joined: Thu Jan 17, 2008 1:15 am
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.
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!
Then we enable the clock line of the PS2 Port.
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!
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
[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)
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)
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: