Read keyboard directly

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
kendfrey
Member
Member
Posts: 45
Joined: Mon Oct 17, 2011 7:44 am

Read keyboard directly

Post by kendfrey »

How do I read key presses from the keyboard without using BIOS? I suspect the first part would be

Code: Select all

mov dx, 0060h
in al, dx
but after that I'm not so sure. I get a scan code in al, right? I want to read the scan code, and only accept the cursor keys and the enter key, and only key down codes. All others should be ignored. Is there something that I should be doing, like calling back to the keyboard, or doing something with the ignored codes?
I'm a major n00b, so help would be appreciated greatly!
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Read keyboard directly

Post by Brendan »

Hi,
kendfrey wrote:How do I read key presses from the keyboard without using BIOS? I suspect the first part would be

Code: Select all

mov dx, 0060h
in al, dx
That would read the latest byte from the keyboard; but you won't know if it's old data that you already read or new data.

To avoid that problem, you have to check a status flag to see if there's new data that hasn't been read yet. The PS2 Keyboard article in the OSdev wiki has example code that shows how to do that (the example is for real mode, but for polling it doesn't make much difference).

The next step is to use an IRQ. When there's a byte to read, you get an IRQ and the IRQ handler reads the byte and does something with it. This means you don't waste CPU time checking for something that hasn't happened.

The next step is to initialise the device properly, rather than hoping that the keyboard and the keyboard controller were left in a state that you want. This is where it gets a bit trickier.

After that, the next step would be realising that most computers use USB keyboards, and that the "legacy PS2 emulation" done by the BIOS isn't very reliable. This means USB support, which is a whole complicated mess (starting from scanning PCI buses to detect any USB controllers, providing drivers for each type of USB controller, then writing a driver for USB keyboards).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
rdos
Member
Member
Posts: 3310
Joined: Wed Oct 01, 2008 1:55 pm

Re: Read keyboard directly

Post by rdos »

Brendan wrote: After that, the next step would be realising that most computers use USB keyboards, and that the "legacy PS2 emulation" done by the BIOS isn't very reliable. This means USB support, which is a whole complicated mess (starting from scanning PCI buses to detect any USB controllers, providing drivers for each type of USB controller, then writing a driver for USB keyboards).
It is even messier as the keyboard in the USB-world is called a "HID" (a Human Interface Device), which have a specification compatible with a interpreter. Luckily, there is still legacy keyboard support for USB keyboards, but it is largely depreciated.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Read keyboard directly

Post by turdus »

It's a bit complicated than reading a port. You have to check if data is ready (with a timeout), and you have to acknowledge the fact that you processed the scancode.

Code: Select all

getscancodefromps2keyboard:
		push			ecx
		;waiting for data with timeout
		xor			ecx, ecx
		mov			cx, 1000
		xor			eax, eax
.waitkey:	in			al, 64h
		dec			cl
		jnz			@f
		xor			eax, eax
		stc
		jmp			.nothing
@@:		and			al, 01h
		jz			.waitkey
		;read the scancode
		in			al, 60h
		mov			cl, al
		;acknowledge
		in			al, 61h
		out			61h, al
		mov			al, cl
		clc
.nothing:	pop			ecx

;scancode in al, or zero (and carry set) on communication error

egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Read keyboard directly

Post by egos »

Code: Select all

		in			al, 61h
		out			61h, al
Wow! It's extraneous code for keyboard controller. A first reading tells that data has received.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Read keyboard directly

Post by Brendan »

Hi,
egos wrote:

Code: Select all

		in			al, 61h
		out			61h, al
Wow! It's extraneous code for keyboard controller. A first reading tells that data has received.
I'm not too sure, but that (incorrect) code may have been derived from code to handle an ancient/obsolete XT keyboard; where you had to disable then reenable the keyboard on every scancode. The correct code for this "disable then re-enable" should look like this:

Code: Select all

    in al,0x61         ;Save keyboard status
    mov ah,al
    or al,0x80
    out 0x61,al        ;Disable keyboard
    mov al,ah
    out 0x61,al        ;Restore/enable original state
This is needed for XT keyboards (for both polling and IRQ driven code), but XT keyboards are extremely rare and any computer that supports protected mode won't support XT keyboards (they were obsolete well before 80386 was introduced).

For AT keyboards it's unnecessary (and code that does it wrong might seem like it works because it wasn't necessary to begin with ;) ).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Read keyboard directly

Post by egos »

Thanks, Brendan. You are right as always. I know the history too. But what relation has this code to our days?
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Read keyboard directly

Post by turdus »

Brendan wrote: This is needed for XT keyboards (for both polling and IRQ driven code), but XT keyboards are extremely rare and any computer that supports protected mode won't support XT keyboards (they were obsolete well before 80386 was introduced).

For AT keyboards it's unnecessary (and code that does it wrong might seem like it works because it wasn't necessary to begin with ;) ).
You're right, it's an obsolete piece of code that's not necessary, but it does not hurt, so I was too lazy to investigate if it can be removed or not... The first machine I was tested my first os (i dunno, ca. 10 years ago a 386DX) it definitely required to refresh the value on port 61h, else no more interrupt fired. Could be a firmware problem, I'm not sure. Anyway thanks, I removed it.
Post Reply