keyboard ?

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
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

keyboard ?

Post by Sam111 »

I have been reading the keyboard wiki and also stuff on art of asm ...etc

My problem is that I am getting confused with scan codes and the exact ascii values ...etc
Basically from what I know when you do

Code: Select all

inb(0x60);
This will read the scancode but after that I have to convert it to the equivalent ascii value.
I am curious how you take this scan code and determine what the ascii value or key that was pressed?

Also is their a port that you can use to write a key instead of just reading a key....
Like if you wanted to simulate a keypress or something would I just have to outb( 0x60 , 0x1E ).
for an 'a' pressed. (basically can port 60h be used for writing and simulateing a keypressed.)

Thanks
I have been using basically one port 60h for reading keys. Is their any other ports the keyboard uses besides
port 64h. Basically from what I understand port 64h is for sending commands to the keyboard (like turning on leds ,...etc ) and port 60h is for reading keys.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: keyboard ?

Post by Gigasoft »

To convert it to an ASCII value, you'll have to use a table for the keyboard layout you want to use, and you must also take into account the shift state and use the right table accordingly. In my OS, I first convert the scan code to a key code that I have defined, and then convert the resulting code using a series of tables specifying the range of key codes and shift states that they apply to.

To simulate a byte coming from the keyboard port, you should write 0d2h to port 64h. For the mouse port, write 0d3h. The desired byte should then be written to port 60h.

Port 61h controls the beeper as well as some other useless things. With bit 7 set, the keyboard will be disabled and port 60h will return the number of floppy drives installed in bits 0, 6 and 7 (bit 0 clear means no floppy drives, otherwise bits 6 and 7 contain the number of them). Other bits are useless. Port 62h is a read only port, completely useless. Port 63h is not used.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

Thanks

But I am still a little confused on how to write the conversion table.
Because I also want to have the ability to know if a key is held down and when it is release.
i.e keydown function keyreleased function etc..

My main problem also is that the scancodes for an A or a is the same so how do you tell the difference?
Is it just watching to see if the shift key is pressed down then check for the next key value if it is an 'a' then it will be a capital 'a'. The only thing is if I use a global varible to set this shift_down =0 or 1 then I don't know when I should turn it back off. What interrupt iteration ....

I have been looking at these 2 charts not knowning which one I should use
http://maven.smith.edu/~thiebaut/ArtOfA ... HEADING1-5

Or if I should make 2 charts or if these charts contain ever possible key value I will ever need ....

Thanks for the help first time trying to do keyboard stuff....
I mean I can display scan codes and lower case letters etc
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: keyboard ?

Post by Gigasoft »

As you can see from the chart, when a key is released, the scan code with bit 7 set is returned from the controller. Then you'll know when shift is released.

The first chart shows scan codes only. The second chart shows the translation of scan codes into BIOS key codes. The book is quite old, so it doesn't have information on new keys.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

So basically I am looking for an up to data chart.
Is their any ones out their I want the one that has all the current key values.

Also I have looked on the wiki and it shows you how to do a cpu reset.
Is the cpu reset the same as doing a restart.

Because in my system.c files I want to add some power functions like turning off the computer , restarting ,...sleep mode ,...etc

Do you know what the most common way of implementing this if not using the keyboard controller in someway.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: keyboard ?

Post by neon »

Hello,

Power functions are handled by APM and ACPI. The system reset function does work as a solution to resetting a PC, but I personally dont recommend it as a permanent solution. The most common way is ACPI.

You know the difference between if 'A' or 'a' is down by keeping track of CAPS LOCK or SHIFT key state. Here is a complete list of make and break codes. Look at the 1st table - the XT scan code set is the default and is the one to use.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

Ok , my problem now is I just finished the scancode to ascii table conversion.

Here it is

Code: Select all

unsigned char kbdus[128] = { 0 , 27 , '1' , '2' , '3' , '4' ,'5' ,'6' ,'7' , '8' , '9' , '0' ,
 '-' , '=' , '\b' , '\t' , 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , 'o' , 'p' , '[' , ']' ,
'\n' , 0 , 'a' , 's' , 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , '\'' , '`' , 0 , '\\' , 'z' , 'x' ,
'c' , 'v' , 'b' , 'n' , 'm' , ',' , '.' , '/' , 0 , '*' , 0 , ' ' , 0 , 0, 0 , 0,0,0,0,0,0,0 ,
0 , 0,0,0,0,0,'-',0,0,0,'+' , 0,0,0,0,0,0,0,0,0 } ;
What I want to know is I have just put zeros in the keys that I don't know their ascii equivalent.
I would still like to differentiate between them.
Like if somebody press's the f1 , or the pause/break key , ...etc.
Their seems to be no ascii code so I don't know what to do in the table for these.

Also on most computer keyboards they have 2 shift keys , 2 enter keys ,...etc I am wondering if their is away to differentiate between which enter key was press. Correct me if I am wrong they send the same scancode to port 0x60 so don't know how to differentiate it if it is possible...

Also I was thinking about implementing many different scancode to ascii conversion tables for many different languages or keyboard models is their away once I get these tables working to query the keyboard to find out what keyboard scancode table I should use. Maybe some port 0x64 thing could give me this info?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: keyboard ?

Post by neon »

Hello,

I personally dont recommend a keyboard driver to return ASCII equivalents. This might cause problems later on if you try to put the system into a world market where multibyte character sets may be used.

Nontheless, all that you need to do is to provide a scancode table of the different keys to test with and a way of obtaining the scan code from the driver. The software then just has to do a isKeyDown (KEY_F1) or similar to test if the F1 key is currently down.

The left and right shift keys do have different make codes as displayed in the table I linked you to.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: keyboard ?

Post by Gigasoft »

The keyboard layout can't be detected, it must be configured. The difference between the two enter keys is that the right enter key sends E0 1C while the left enter key sends just 1C. (When releasing the right enter key, it sends E0 9C.)

To differentiate between keys that do not correspond to characters, you could use the original scan code, or convert the scan codes to a made up key code. Then you return the key code along with the character code (if there's one). Returning a key code is important so that applications can assign a function to the key Y, for example, without caring if the character assigned to key Y is a small Y, capital Y, or maybe a Ŧ (as on Northern Sámi keyboards).

In my OS, the keyboard driver only converts scan codes to key codes that are independent of keyboard type, and the system itself maps the key codes into Unicode characters taking into account the states of Shift, Right Alt, Caps Lock and Num Lock.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: keyboard ?

Post by Brendan »

Hi,
Sam111 wrote:So basically I am looking for an up to data chart.
I'd be looking for code that can handle an arbitrary set of charts (e.g. by loading the keyboard mappings from a file), where the same keyboard driver can be used for any keyboard (regardless of which keys happen to correspond with which ASCII/Unicode characters under which conditions), and so that (with no need to modify any code) people can create new files that describe keyboard mappings to add support for other keyboard layouts.

I'd also have a directory of "files that describe keyboard mappings" to make it easy for users to choose which keyboard mapping to use (either during OS installation, or when customising). For example, the administrator might set a default keyboard layout, and different users are able to override this default with their own (and when a user logs in, the keyboard driver loads and uses that user's keyboard mapping).

I'd also be tempted to write a graphical utility to make it easy for people to create a new files that describes a keyboard mapping. For an example (picture from http://www.klm32.com/KbdEdit.html):

Image

Basically, you want to be able to say "this OS supports any/all keyboards", and you don't want to say "this OS only supports one US "QWERTY" keyboard layout because I haven't written hundreds of different keyboard drivers yet".


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.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

Well if I just use the XT chart how portable will this be on US keyboards?
Also for different keyboard scancodes charts if I up for doing all the scancode charts.
How do I know what keyboards are using what scancode charts. Is their away from port 0x64 or something
to find out what scancode chart applies to a particular keyboard .... so I don't use the wrong one....
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: keyboard ?

Post by Gigasoft »

All standard keyboards use the same scan codes. For example, backspace, enter, space, home etc will always have the same scan code. The difference between keyboard layouts are the symbols that each key is labeled with. There is no way to identify which labeling a PS2 keyboard uses, so the user must choose which layout he wants to use. Many people need to frequently switch between different layouts anyway to be able to write in different languages.

There are three scan code sets that can be selected, but many keyboards only support the AT scan code set, which is the default. The motherboard translates AT scan codes into XT scan codes from devices connected to the keyboard port by default, so you should use the XT scan code chart unless you turn translation off.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

Ok , I am all set with my irq keyboard function , my scancode chart etc....

But now I am trying to figure out away I can have a function that somebody can implement or use to get a hook into the keyboard irq function.
Basically I want to have the ability to read keys globally .... if I just create a function that reads port 0x60
then I have the problem of not knowing if I am reading the same key or if it is a key that is held down.

If I put it in a global structure variable then I never know how fast I should read the varible ,...etc
to slow and I won't get all the key strokes to fast and I get duplicates....

Is their a way to create an event function or have the ability to have someone implement a function that gets notified of a keyboard event ,...etc
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: keyboard ?

Post by neon »

Hello,

Im personally not sure what it is that you are requesting. "Hooking an IRQ" is easily done by chaining the IRQ but I am not sure if that is what you want.

I am thinking you are asking about implementing an interface that will allow proper polling of the keyboard. By providing the capability of obtaining the last key stroke (set by the IRQ when its called) in your keyboard driver, you can later support both polling (like getch()) and buffered types of input.

For an example...

Code: Select all

KEYCODE	getch () {

	KEYCODE key = KEY_UNKNOWN;

	//! wait for a keypress
	while (key==KEY_UNKNOWN)
		key = kkybrd_get_last_key ();

	//! discard last keypress (we handled it) and return
	kkybrd_discard_last_key ();
	return key;
}
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: keyboard ?

Post by Sam111 »

well , basically I wanted to create a non irq/interrupt function that process keyboard keystrokes ,...etc

But if I create a non irq/interrupt function and just use port 0x60 to read the scancodes I never know if I am reading the same scancode twice or more ,.... I guess it is what you call polling as you put it.

Is their someway I can check if a new key was pressed before I start reading from port 0x60 for the scancode for it. I am running into the problem of also not knowning if somebody pushed the same button twice or if I am just reading it to fast from port 0x60.

That is my main question above.

Anyway I am also creating callback functions that the keyboard irq calls (so I have event handleing methods I can use at anytime. And it gives the programmer the ability to get the keyboard event calls when the irq keyboard method is called.

Code: Select all


struct KEYBOARD_DATA  
{
int shift_state         ;
int escaped             ;
unsigned char scancode ;
}

KEYBOARD_DATA key_data ;

int shift_state   = 0 ;
int escaped       = 0 ;

/* Handles the keyboard interrupt */
void keyboard_handler( void (*CALLBACKFUNC[])( KEYBOARD_DATA ) , int callback_function_size )
{
    unsigned char scancode;
    /* Read from the keyboard's data buffer */
    scancode = inb(0x60);
    
	
    switch(scancode) 
	{
        case 0x2a: 
            shift_state = 1; 
            break;
 
        case 0xaa: 
            shift_state = 0;
            break;
					
		case 0xe0:
		    escaped = 1;
			break;

        default:
           if (scancode & 0x80) {
              /* Ignore the break code */
           } 
		   else
		   {
              
			 /* Do something with new_char. */
           }
           break;
     }
	 
     key_data.scancode    = scancode    ;	 
	 key_data.shift_state = shift_state ;
	 key_data.shift_state = escaped     ;
	 
	 for( int i = 0 ; i < callback_function_size ; i++ )
	 (*CALLBACKFUNC[i])( key_data ) ;
	 
     outportb(0x20,0x20);
	
}


Post Reply