Introduction.
See edit.com. Peaceful, serene edit.com. Edit.com, I think I love you. Anyways, the old, dos 5+ version of edit.com, not the new, arguably nicer Windows 95 version, had a nice feature: it kept track of keystates, and it told you when certain keys were active, or inactive, like all the lock keys and insert.
Well, BIOS tends to keep track of certain keys for you, and with a little talent, and/or a technical reference, or if you prefer, this text ("phlegm-text") will teach you how to reflect the states of these keys or change the states without much difficulty to you.
Essay.
Right. Now, BIOS has it's own special data-segment, it's 0040h. If you want to be technical about it, BIOS has several data segments, like 0F000h, 0040h, and various other little tidbits, but it keeps it's variables in 0040h. Included are the keystate flags.
Here is a list of the offsets into 0040h that can be of some use to you, assuming you plan to do something with the keyboard:
| Offset | Length | Value |
| 17h | Byte | Keyboard Shift State flags, #1 |
| 18h | Byte | Keyboard Shift State flags, #2 |
| 19h | Byte | Alt-Key work area |
| 1ah | Word | Head Keyboard Buffer Pointer |
| 1ch | Word | Tail Keyboard Buffer Pointer |
| 1eh | 16 Words | Keyboard input buffer |
| 71h | Byte | Control-break flag |
| 80h | Word | Offset of Keyboard Buffer |
| 82h | Word | Offset of End of Keyboard Buffer |
| 96h | Byte | Keyboard Status Byte, #1 |
| 97h | Byte | Keyboard Status Byte, #2 |
And this is all the keyboard information in the 0040h segment. It is your friend (if you live in an asylum).
Further analysis of these structures:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Meaning |
| X | Insert is active, if x=1, otherwise, inactive | |||||||
| X | Caps Lock is active, if x=1, otherwise, inactive | |||||||
| X | Num Lock is active, if x=1, otherwise, inactive | |||||||
| X | Scroll Lock is active, if x=1, otherwise, inactive | |||||||
| X | Alt Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Ctrl Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Left Shift Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Right Shift Key is pressed (x=1), or not pressed (x=0) |
For your comprehension, a little program that shows how to fuddle with this data.
assuming ds is 40h, of course:
mov al, byte ptr ds:[17h]
or al, 0F0h
mov byte ptr ds:[17h], al
This code will read the byte at 40:0017 and set all the locks, as well as insert, and it will annoy the hell out of most people.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Meaning |
| X | Insert Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Caps Lock is pressed (x=1), or not pressed (x=0) | |||||||
| X | Num Lock is pressed (x=1), or not pressed (x=0) | |||||||
| X | Scroll Lock is pressed (x=1), or not pressed (x=0) | |||||||
| X | A pause is in effect (x=1) (pause = ctrl-num lock) | |||||||
| X | SysRq Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Left Alt Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Right Alt Key is pressed (x=1), or not pressed (x=0) |
This byte won't be really important to you, unless you rely on the ALT keys for menuing and such, in which case, the last two bits will be quite important to you. Here is some code to detect whether an alt key is pressed or not:
mov al, byte ptr ds:[18h]
and al, 3
or al, al
jnz @@some_alt_keys_are_pressed
The words at 1ah and 1ch are the head and tail pointers in the keyboard data. The head pointer points to the oldest key in the buffer, while the tail pointer points to the next availible word space to deposit a keystroke into. Here's some code that 'resets' the buffer:
mov ax, word ptr ds:[1ah]
mov word ptr ds:[1ch], ax
By setting the tail pointer equal to the head pointer, you can start the data over, in an essence. But who gives a shit? This is kind of boring. The most informative part of this document has passed in the first two analyses of the bytes at :0017 and :0018
:001E is the default for the start of the keyboard buffer, which means, this is where the data from keypresses accumulates, and if this isn't cleared periodically or if the data isn't read out of it, it will fill up. This is why if you type 16 characters while your machine is booting, the speaker will beep and anything after the 15th character you typed will be ignored. The remaining 15 characters will be dumped onto the command prompt immediately.
:0071 is the Ctrl-Break flag. If the user pressed control and break at the same time, ANY TIME SINCE THE OS BOOTED, this byte will be set to 80h. Note that this doesn't reset itself. You can do it manually, of course.
:0080 and :0082 contain the offsets of the keyboard storage area. These offsets are assumed to be in the segment :0040h, so don't do any funny stuff and try to make yourself a big buffer inside of your program. You'll most likely crash the machine badly. Note that these aren't the same as the head and tail pointers, :0080 is the start of the data area, not the start of the relative buffer inside of the data area, and :0082 is the end of the buffer, not the next availible space to deposit a character.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Meaning |
| X | The keyboard id is being read (x=1) | |||||||
| X | The last keyboard code wasn't an id code | |||||||
| X | Forced num-lock condition is in action | |||||||
| X | Enhanced keyboard (x=1), standard (x=0) | |||||||
| X | Right Alt Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | Right Ctrl Key is pressed (x=1), or not pressed (x=0) | |||||||
| X | The last keyboard code recieved was 0e0h (x=1) | |||||||
| X | The last keyboard code recieved was 0e1h (x=1) |
This is, for the most part, an utterly worthless byte. Almost as bad as this next one:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Meaning |
| X | An error has occurred sending to the keyboard (x=1) | |||||||
| X | The LEDs on the keyboard are being updated (x=1) | |||||||
| X | A resend request occured from the keyboard (x=1) | |||||||
| X | An acknowledge code was recieved from the keyboard (x=1) | |||||||
| X | Reserved | |||||||
| X | The Caps Lock LED is illuminated (x=1) | |||||||
| X | The Num Lock LED is illuminated (x=1) | |||||||
| X | The Scroll Lock LED is illuminated (x=1) |
Why is this so worthless? Because, it's stupid information, and it's only for reference, you can't change this by setting the bits. Same thing with the last byte, that's why I didn't put anything between the formats of the two bytes.
Code.
I included some programs that you can look at as a reference, but they're both elementary stuff anyways, i.e. I went over it in this text.
References.
Wyatt, Allen L, Sr. _Advanced Assembly Language._ 1992. Que Corporation.
Greetings.
Zen/CrackZ, for not taking me seriously, ever .. that's a good thing, if you don't know me :-)
CoRN, for being so leet, I lub' ya to death, stay leet
Blorght, for being so blorghty, and where are you, anyways?
Cali, for being nice and giving me warez. Visit codeoasis.home.ml.org.
Vizion, for being there to talk to me after I smoke hash.
Tin, you may not be leet, and let's just leave it at that ;--)
Iczelion, please zip up your brain for me, I need a copy.
Same goes for The_Owl.
End.
That's the end of this document. I hope you can do something you couldn't before because of this. A lot of this information was taken from Wyatt's book in the references, but I think the book may be out of print... oh well.
_y/+YOSHi, 10:37 PM, 1/14/99