Page 1 of 1

Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 3:11 am
by dav7
Hey there.

I'm working on, shall we say, "patching" GRUB Legacy for some specific requirements (I might as well make an unofficial release at some point since it isn't being actively developed anymore, heehee) and since I've dived into the code and sortakinda know my way around I thought I might add this feature I've wanted for a little while.

I'd like to create a function that will figure out if Shift is being held down and immediately return with an appropriate status (not a loop or code that needs to be executing before the key is pressed in order to return a value). I have a funny feeling it won't be that hard. If it's helpful to know, GRUB executes in real mode, AFAIK.

I'm not afraid to get my hands dirty since I already have to a fair bit (I've really ripped the code to shreds, heh, I plan to move my tree out of the way, unpack 0.97 to a fresh tree and apply my changes to that when I'm done), but please do realize that my assembly and low-level C is... undeveloped, to say the least. While a lot of you will probably cringe, (commented! Learning FTW :P) code would be awesome, but I don't mind tutorials.

Thanks in advance!

-dav7

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 3:36 am
by Combuster
hook yourself onto the keyboard IRQ so that you can keep a list of current key statuses.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 6:08 am
by ru2aqare
If your code runs in real mode, and the BIOS handles the keyboard IRQ, there is a status byte in the BDA you can use to figure out the state of the modifier keys (Ctrl, Alt, Shift). I don't remember if you can distinguish between left and right keys. For the exact location, check RBIL.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 8:18 am
by Walling
I think most of the code in GRUB is made to run in protected mode (with interrupts disabled), but it actually runs in real mode most of the time (waiting for a key press using BIOS). They made a system to call real mode code: it switches to real mode, invokes the real mode code and when it returns it switches to protected mode and returns. Key handling is implemented by using the BIOS int 0x16. I just peeked in the code. You can see the key handling in stage2/asm.S at line 1991 and 2025. Maybe you can hack that code to return a special value, when the shift key status is changed.

There are no tutorials telling you how to do a special job like this... go learn some assembly and low-level C. RBIL is a must-have reference.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 1:44 pm
by mathematician
mov ax, 40h
mov es,ax
test byte ptr es:[17h], 3
jnz shift_key_down

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 2:05 pm
by bewing
Address 0x417 in the BDA (as said above) should give you the current instantaneous value of the Left and Right shift state (bits 0 and 1). If you can't poll this address, however, then you are limited to guessing whether the bits have remained unchanged the entire time between the moments that you check them. There are some ways to avoid guessing, but they are much harder.

The C parts of GRUB are compiled by GCC, which produces pmode code only, as said above. There is a "thunk" that makes a small realmode ASM loop be the part of GRUB that allows the BIOS to run and collect interrupts. I really do think that just checking address 0x417 every time through your ASM loop will be the simplest way to handle your issue.

BTW: I'm glad to hear that someone wants to adopt/improve the GRUB legacy code. :wink:

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Sun Jun 14, 2009 11:58 pm
by dav7
*dies*

Thanks for your replies, everyone, but I am soo outta my depth here. :cry:
Combuster wrote:hook yourself onto the keyboard IRQ so that you can keep a list of current key statuses.
*blinks*
ru2aqare wrote:If your code runs in real mode, and the BIOS handles the keyboard IRQ, there is a status byte in the BDA you can use to figure out the state of the modifier keys (Ctrl, Alt, Shift).
I see. This is something I can run with, and I've tried to, but not gotten very far (probably because of the next bit of info):
Walling wrote:I think most of the code in GRUB is made to run in protected mode (with interrupts disabled), but it actually runs in real mode most of the time (waiting for a key press using BIOS). They made a system to call real mode code: it switches to real mode, invokes the real mode code and when it returns it switches to protected mode and returns. Key handling is implemented by using the BIOS int 0x16. I just peeked in the code. You can see the key handling in stage2/asm.S at line 1991 and 2025. Maybe you can hack that code to return a special value, when the shift key status is changed.
Oooh.
Walling wrote:There are no tutorials telling you how to do a special job like this... go learn some assembly and low-level C. RBIL is a must-have reference.
:x
mathematician wrote:mov ax, 40h
mov es,ax
test byte ptr es:[17h], 3
jnz shift_key_down
*Reaches for the Intel-to-AT&T syntax translator*
bewing wrote:Address 0x417 in the BDA (as said above) should give you the current instantaneous value of the Left and Right shift state (bits 0 and 1). If you can't poll this address, however, then you are limited to guessing whether the bits have remained unchanged the entire time between the moments that you check them.
Oh ok.
bewing wrote:There are some ways to avoid guessing, but they are much harder.
One half of me is asking "what are they" while the other is RUNNING in the other direction and shouting over my shoulder "and these methods are EASY?"
bewing wrote:The C parts of GRUB are compiled by GCC, which produces pmode code only, as said above.
:? :|
bewing wrote:I really do think that just checking address 0x417 every time through your ASM loop will be the simplest way to handle your issue.
*hears "your" and "asm" in the same sentence and spontaneously combusts*
*hears "simplest" in the same context and sends a nuclear-sized shock wave in all directions*
bewing wrote:BTW: I'm glad to hear that someone wants to adopt/improve the GRUB legacy code. :wink:
Well, I would like to. :P

There was a time when I didn't understand C. Tutorials would make no sense to me, I couldn't understand pointers, and I wrote extremely long monologues on forums about my problems. While a little unusual, it took me 3 or 4 sessions of pushing myself beyond my own abilities of comprehension - to the point of crying, actually - before something sparked and I went "ooooh". (Except I'm still going "oooh", approx 3 or so months after the fact).

I can write simple programs in C, such as a bandwidth checker for my ISP (bigpond) because libraries like cURL exist - just basic string processing, really - and I've also written a (really) basic X task list program (like a panel, except it's vertical, doesn't double-buffer, doesn't use a toolkit (homespun button code FTW), and is extremely hacky in that it asks the X server for the whole window list whenever a window is created or killed), but beyond that I'm kinda... yeah. I'd probably have to push myself to the point of tears again to understand low-level C/asm/etc, heh. Although I'd probably be better for it... :|

</quandry>

-dav7

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Mon Jun 15, 2009 6:47 pm
by bewing
ASM is mostly a very trivial translation of C. Pushing yourself that hard is a symptom of being in some kind of hurry. You can have your shiny new version of GRUB legacy running in a year and a half or so. It would take anyone a while to do a good rewrite on it. So take a deep breath, and practice writing some easy C and translating it by hand into ASM for a few months. It'll get much easier with practice.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Mon Jun 15, 2009 8:36 pm
by dav7
Yeah, I have a problem with time - I don't properly comprehend that day/night isn't the end of the world ;) (or something like that) so yeah I generally find myself in a stressed out hurry. Knowing what the problem is is half the battle though (and I think that's what my problem is), so that's half the battle won.

I also don't feel entirely ready to learn asm yet; my biggest issue is that at the moment I have no motivation to dive into it, probably because I see it as an overwhelming sea of concepts nonsensically linked together (although I've had these kinds of problems before, and know it's a mindset issue). This unfortunately runs off into my memory as well, so whenever I do learn a concept, I usually go and forget it pretty quickly. I should eventually find the correct mindset, interest, motivation and so on to learn it, and that will be a fun day. I must admit I've wanted to understand asm for a while :D

And I think there's a little bit of a misunderstanding - I don't plan to rewrite GRUB Legacy, I just want to add a couple of features to it that will in my opinion be a good "sign off" on the old code - and up to this point, that plan's worked out pretty well.

-dav7

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Tue Jun 16, 2009 5:37 pm
by mathematician
bewing wrote:ASM is mostly a very trivial translation of C.
That reminds me of Microsoft classifying the English spoken on this side of the Atlantic as a dialect of American English. One could be forgiven for thinking it is the other way around.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Tue Jun 16, 2009 9:00 pm
by NickJohnson
mathematician wrote:
bewing wrote:ASM is mostly a very trivial translation of C.
That reminds me of Microsoft classifying the English spoken on this side of the Atlantic as a dialect of American English. One could be forgiven for thinking it is the other way around.
I believe the difference is that C is translated to ASM frequently, but rarely the other way around. Therefore, ASM would be the translation of C. You could say that C is a very trivial abstraction of ASM, but not vice versa.

Re: Detecting whether a key is being held down in realmode asm/C

Posted: Wed Jun 17, 2009 4:15 am
by dav7
This is kinda OT, but NickJohnson's avatar reminded me of a screensaver I, shall we say, "created" :P

It was basically me fooling around with some graphics code I had. One "ooh, that looks pretty" later, and I had a box that looked strikingly similar to said avatar (except it was a vertical rectangle) bouncing around the screen. Fun times :P

PS. I haven't done anything with GRUB yet, still playing with the Linux kernel and so on (my requirements kinda went sailing out the window at the point I discovered the kernel is a bootloader, at least for floppies, but since I made this thread I'll follow up... at some point :P)

Also, because of my interest in old versions of Linux, I found oldlinux.org and from there a VMware Linux 0.11 image... and a Minix 1.1 floppy image set... :D

-dav7