bubach wrote:
I have written a simple keyboard ISR that already, after just normal and shift keymaps, looks like ****... (spaghetti)
Is there a simple way to check for all shift, alt, ctrl versions (without 500 "cmp" and "jne"/"je")?
It prints the char directly to screen after puting the char in one db var and the scan code in another.
Yes, the most obvious solution (which somebody probably patented in the US, but here she goes):
You make an array containing shift/alt/caps keypresses. Then you do not use cmp/jmp (which is unpredictable and thus also slow), you use an index.
Try:
Code: Select all
getkeycode:
// call as getkeycode(int keycode, int shiftaltcaps) or first push shiftaltcaps, then keycode, then call
xor ebx, ebx
mov bl, [esp+4]
mov bh, [esp+8]
mov al, byte [keytable + ebx]
ret
The simplest possible scenario: My "shell" doesen?t want the char for a while, then after doing some things it will start listening for keypresses again, how will i determine if the key in the buffer is a new or old one?
By having a FIFO for it, which isn't a structure taught at school but very important. FIFO is like a queue, you always add to the front, and you remove from the back (conversely, you can swap the names front and back and keep some teachers your friend). The point why a FIFO isn't a queue is that a queue should never block. A fifo might block and be full.
Using this stuff, you can make a circular buffer with a write and a read pointer. You can lock both of them separately, making this good for multiprocessor systems (watch out for cache line conflicts! Try making the FIFO at least 256bytes, or preferably 4k-8k). You write at the write pointer and you read at the read pointer. If they are equal, the buffer is empty. If the write pointer is just before the read pointer, or the write pointer is at the absolute end and the read pointer at the absolute start (the combination of which is equivalent to doing (read-write) % count) it's full.
You put stuff in the buffer from the kernel-side of the code and you can read it out from the user-side. Notify the user if it's sleeping on the input that there's input, and that rounds it up for the kernel side.
The user side reads from the FIFO until it's empty, and if the function definition defines you should wait for more, wait.
And when i have multitasking, how will i make it know witch app to "send" it to?
which app
the app you send it to has the focus. You can timestamp all input items to be able to work out the exact order in which things went, so all keypresses arrive where the user expects them to. You can also not do that but just assume they arrive at the current app, or just plain ignore those where you don't know where to send them.
Windows and Linux are examples of the latter type. AtlantisOS of course tries to do the first
And if i make for example a game, shoots with CTRL and jumps with Space+LeftArrow, how can i dectect "hard" combinations like that?
These are normally not handled by the keyboard input API, but by a separate game-type input layer. This layer keeps a pressed-state for each key and offers the userlevel app a chance to just ask for a key being pressed, or a list of pressed keys. This way, these applications can use space-left for jumping left and ctrl-space-left for shooting while jumping left.
Note that most keyboards have a hardware limitation on the amount of keys they can detect at a time, my Compaq keyboard being the most crappy at that. If you type a space and an O at the same time an I comes out with a " on it.
HTH, Candy