struggling to find good info on keyboard io

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
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

struggling to find good info on keyboard io

Post by maverick777 »

Hi Im struggling to find good info on keyboard IO . I want to write a pure assembly keyboard driver , at some point utilising in out and ports.

I figure I need a page that

Explains make codes and a formulae to change then to scan code(I did this way back maybe ive got that the wrong way around lol)

Shows how to put together a table of ascii values in nasm syntax asssembly so that when the scancode is realised it gets the relevant ascii value and then displays on screen

Edit-- its late here Im ofski hehe , anyway I did find:

edit------link removed for time being my brains been mashed today lol

Hopefully that will be of use to someone just wanting to experiment with making a crude assembly keyboard driver. Its still something I would be greatful for more info, but I figured I would at least add what I found in the hope it may help someone else.
Last edited by maverick777 on Sun Nov 25, 2007 1:48 pm, edited 4 times in total.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Why can't you translate the tons of C code around into assembly?
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

Art of Assembly Language Programming Chapter 20 has a good explantion (and code) of the keyboard. the link is Chapter 20

@maverick777: shorten your links please
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Thanks folks ) , I will check that information out. Apologies about the link Im going to sort that right now :-)

Actually the reason the link was so long was because I direct linked through a google search, tbh I didnt like the first link as it had an ip instead of a domain name and Im always wary of those sites. I figured it was because of the way I linked initially but the link is now changed :-) see above!

Actually James the plan is , just write a crude kb driver in asm just to make sure I can do it and my assembly coding is reasnable and then Im going to do your guide from the start :-) as from looking at your guide headings it seems that it covers the IDT which is the next thing I need to get to grips with :-)
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Hi I read the info given, some of it isnt exactly what Im trying to do, all I need is to print one letter onscreen when I press key A , I dont want nothing fancy at the momment so :

Read port 64h
input buffer is full (bit 1) = 1 data to read
output scancode in al to 64h to display the letter A when A key is pressed(Scode 1F)

I know my logic is probably flawed but thats why Ive posted again, I want to make a very crude minimilistic piece of code , heres what I have so far and its not working

Code: Select all

.waitkb
    ;data is available for reading
    ;from port 60h when bit one of port 64h contains a one
    in al, 64h
    cmp al,10b
    jnz .waitkb ;bit 1 != 1 input buffer not full , nothing to read so loop?
    
    mov al,1Eh ; scancode for keydown for letter A
    out 60h, al; 
Nothing happens when I run this know key shows, hehe Im guessing im a bit out with what I need to do any ideas how to fix this code to display the letter A when presssed in a minimum way possible? (In pure asm)
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

@maverick777:

You can shorten the link more, and provide a better description using BBCode. For example, (Without the spaces)...

[ url =http://davinci.newcs.uwindsor.ca/~angom/cs266/Lec26614.pdf ] I/O With Keyboard [/ url ]

Becomes:

I/O With Keyboard
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Ok sorting link. Ive just spent the whole day sifting through ambiguous texts regarding how port 60 and 64h interact as well as how and when status bits are changed.

Can anyone point me to a well explained document? that relates to assembly, heres what Ive came up with now , alot of which is a guess , in regards its like a dechiphering mission just to understand the english of the few keyboard io guides, they either have pure thoery and very abstract or pictures of the bits at 60 and 64h with a completely vague description of what actually happens or what there code is doing. Some time the articles mention microcontroller x without explicitly stating what port is relevant at the time.

Anyway going for a break :-) heres my code, I totally am clueless as to what is happening even though Ive been re ading a good few sites on keyboard IO

Code: Select all

 call kbRead 
  kbRead: 
.Waitloop:   in     al, 64h     ; Read Status byte 
             and    al, 10b     ; Test IBF flag (Status<1>) 
             jz     .WaitLoop    ; Wait for IBF = 1 
             in     al, 60h     ; Read input buffer 
  ;my guess here is bit 1 is being tested   input buffer, what that does knowone says, im guessing when a key is pressed hardware sets this bit to 1?? or it indicates the input buffer is full? 0 empty 1 full, and it loops again if its zero. So say it gets to one , and input buffer gets read into all from port 60h also, either there are 2 input buffers or some of the chinese guides as best I can translate means that 64h keeps the status in 64h but its the status for 60h?? (Add to that the guides start firing out microcontroller this and that and dont explicitly say which port its a knightmare to self teach)
;        
             
.kbWrite: 
.WaitLoop:   in     al, 64h     ; Read Status byte 
             and    al, 01b     ; Test OBF flag (Status<0>) 
             jnz    .WaitLoop    ; Wait for OBF = 0 
             out    60h, cl     ; Write data to output buffer

;Ok so the above code reads the status byte from 64h into al - again
this time checks for output buffer full - at which point did we go from output buffer full to input buffer full? So actually this code seems to be testing its empty , so rephrase that when did it fill up lol

(Need clear purpose explained for input and output buffer in ref to keyboard IO , input takes input , output outputs data thats my guess)

Right so OBF = empty then we out contents of 60h to cl and even though I copied this from a book it doesnt assemble.

Ive read lots of keyboard io stuff today , kinda disapointed the above is all I have gleamed from it and I couldnt get a working example even from a book

really stuck
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Code: Select all

 kbRead:
             xor eax,eax;
             .rd
             in     al, 64h     ; Read Status byte 
             and al, 10b     ; Test IBF flag (Status<1>) 
             jz     .rd    ; Wait for IBF = 1 
             in     al, 60h     ; Read input buffer 
------------------------------------------------
              mov ecx,p64;
             call Puts32b
-------------------------------------This part above prints an ascii code but never does it when I place the lines as above in the loop , so I never get it this loop, going over various pages again and again the above code all except the part encased in - signs is exact aand im starting to think theres something else up
             
             .kbWrite
             in     al, 64h     ; Read Status byte 
             and    al, 01b     ; Test OBF flag (Status<0>) 
             jnz    .kbWrite    ; Wait for OBF = 0 
             out    60h,al    ; Write data to output buffer 
             ret
check this page code is exact, and although I havent dealt with the make code at the end well I should be exiting the first loop but I am not, any ideas?? Its like the input buffer isnt filling even when I press keys so Im never getting out the loop yet the code on

http://www.computer-engineering.org/ps2keyboard/

is supposed to work, any idea whats going wrong? (By the way the ascii code I print has zero to do with the in out instructions I just wasnt getting anywhere so I in effect am printing a char to signify whether I am getting out of the first loop , which I am not :-(
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

If you had of read Art of Assembly Language Programming Chapter 20, it tells you how the whole thing works. From the problem you are having, I would say the code is not done when dos _interrupt_ 9 (IRQ 1). This is the interrupt that is fired when a keyboard event occurs.

EDIT: to make myself more clearer, from the link you just posted (above the code you posted):
When the 8042 recieves a valid scan code from the keyboard, it is converted to its set 1 equivalent. The converted scan code is then placed in the input buffer, the IBF (Input Buffer Full) flag is set, and IRQ 1 is asserted. Furthermore, when any byte is received from the keyboard, the 8042 inhibits further reception (by pulling the "Clock" line low), so no other scan codes will be received until the input buffer is emptied.

If enabled, IRQ 1 will activate the keyboard driver, pointed to by interrupt vector 0x09. The driver reads the scan code from port 0x60, which causes the 8042 to de-assert IRQ 1 and reset the IBF flag. The scan code is then processed by the driver, which responds to special key combinations and updates an area of the system RAM reserved for keyboard input.

If you don't want to patch into interrupt 0x09, you may poll the keyboard controller for input. This is accomplished by disabling the 8042's IBF Interrupt and polling the IBF flag. This flag is set (1) when data is available in the input buffer, and is cleared (0) when data is read from the input buffer. Reading the input buffer is accomplished by reading from port 0x60, and the IBF flag is at port 0x64, bit 1. The following assembly code illustrates this:
You wasting everyones time, if you copy and paste code, then want to know why the code on a website doesn't work (because as this example, shows you don't
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Hiya its the code from the brokenthorn development site Im using, I have know IDT immplemented but all I want to do is poll the whatever keyboard port stores than scancode and when it has a scancode of relevance then change it to an ascii code but both port 60 and 64h seem to be all status flags I dont understand where the make code and break code is actually stored ? I will read that assembly chapter for about the 5th time and hope something clicks

Im not sure what you mean by dos _interrupt_ 9 I dont think I have access to any ints, Im in protected mode, please elaborate how a dos interrupt comes into this? Im in computer terms probably making a fool of myself but Im a person who actually reads the english and computing terms seem to be based on their own made up form of english.
Last edited by maverick777 on Sun Nov 25, 2007 4:18 pm, edited 2 times in total.
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

the 8042 inhibits further reception (by pulling the "Clock" line low),
Thanks for clarifying im just reqading your addition but theres the first problem I have what port is the 8042 relevant to , they would be as well saying the big pink elephant inhibits further reception (by pulling the big yellow bus)

lol sorry thanks for your input its just I find the books dont go into enough depth many times

Sorry its annoying going through so much information thats written in a coherant manner then finding stuff that is intentionally vague, for example new terms are mentioned and never explained hence why I mostly buy books that I can see a few chapters of first.
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

There in may lie the problem then, if its the case I need to setup the IDT fair enough , but I wanted to be able to poll just a one character keypress out . I was going to poll at the end of the code I submitted to read the make code but its not even getting out the first loop
You wasting everyones time, if you copy and paste code, then want to know why the code on a website doesn't work (because as this example, shows you don't
Can see theres been post edit since my replys but since I dont what? sorry confused

the only change I made to that code apart from printing an ascii char set value was changed in port, cl to in port, al on the last line because in port,cl was giving a invalid operand, thats what Im getting at folk writing stuff up and its not 100% accurate , it wastes alot of time

Code: Select all

The following assembly code shows how to write to the output buffer.  (Remember, after you write to the output buffer, you should use int 9h or poll port 64h to get the keyboard's response.) 
kbRead: 
WaitLoop:    in     al, 64h     ; Read Status byte 
             and    al, 10b     ; Test IBF flag (Status<1>) 
             jz     WaitLoop    ; Wait for IBF = 1   (infinite loop)
             in     al, 60h     ; Read input buffer 


kbWrite: 
WaitLoop:    in     al, 64h     ; Read Status byte 
             and    al, 01b     ; Test OBF flag (Status<0>) 
             jnz    WaitLoop    ; Wait for OBF = 0 
             out    60h, cl     ; Write data to output buffer  ;OK so I poll here but I am not getting out the first loop kb read, this is my point
Just to illistrate my point further out 60h, cl (directly copied) gives invalid operand or the alike, so I changed that to al after numerous failures , but well as said the codes not even getting as far as that when it runs and the reason I asked why it didnt work as you mentioned is because it seemed like the best piece of protected mode keyboard code relevant to what I was doing and the fact it doesnt even assemble really worrys me in regards to getting anything close to good information on protected mode keyboard io, look on the web the vast majority is all to do with using real mode interrupts
maverick777
Member
Member
Posts: 65
Joined: Wed Nov 14, 2007 3:19 pm

Post by maverick777 »

Woohoo :-) I got it working , heres the code , its dam mcrude and un-elegant but hopefully it will save someone a bit of hassle:

Code: Select all

.waitempty
		xor dl,dl
		in al,64h; read status port byte into al
		test al,10b ; check input buffer full flag
		jnz .waitempty ; jump if nothings in the input buffer 
		in al,60h ;reads scancode into al,scode becauseIP
                                             ;  buffer full?
		mov cl,al ;scancode gets moved into cl
		
		.printa
		cmp cl,1Eh ; scancode for letter A = 1EH
jnz .waitempty ;if not 1eh loop to start
		mov [ecx],byte 41h ; ascii code for A 41h
		call Puts32b ; a print routine
This only works for 1 key "A" and doesnt account for the cursor, also the call to puts32b takes ecx as a paramater and prints out the ascii code to graphics memmory , the line cmp cl,1Eh is checking that the A scancode has been transmitted.

I realise there may be many reasons why this code isnt good, but I had to code certain parts myself as none other code I could find was doing exactly what I needed to do. This code from what Ive read would be no good for some keys that require more than 1 byte(I only wanted to start with small beggings though)

If anyone feels they seriously dont like the above code and wants to suggest and alternative way feel free. Im just so glad to get it working in however terribly small a way :-) . I am going to try and sort my links now and put quite a few kb io links here , however while I have learned I still dont feel I have as good an understanding of KB io as I would like. It would be great to have a site that has the ports drawn in an abstract way and has arrow swhowing specifically which ports are getting used and when .(Example: when certain bits are set in PORT X then show any other ports that are invoked because of that)

Maybe when I go back to some of the documents I will pick up more now that I have a limited but working piece of code , who knows :-). Anyway going to add keyboard io links but really need better ones , so if people want to add any feel free:

Assembly Programming C20

Technical Info KB Port Layout

Keyboard Referance

AO Assembly chap 20-7

Scancodes info 1

One of the better explained KB io articles in respect to theory

Info about Scancodes and KB and Ports

Havent fully checked out the final link but in the contents it appears to explain about each of the ports.

FINALLY! just thought I would quote part from the wiki
You have been fairly warned of the hard work ahead, but if you are still interested then proceed forward into the realm of the operating system programmer. Prepare yourself for ocassional bouts of confusion, discouragement, and for some of us... temporary insanity. In time, and with enough dedication, you will find yourself among the elite few who have contributed to a working operating system. If you do get discouraged along the way, refresh yourself with the contents of this book, hopefully it will remind you of why you started such an insane journey in the first place.
Couldnt stop running that through my head yesterday for some reason :-) (mostly the former part!)
Post Reply