flat assembler
Message board for the users of flat assembler.

Index > OS Construction > OS Development?

Goto page Previous  1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 30 May 2010, 18:53
baldr wrote:

xlat+tables; several cmps and subtables for ranges.

What is the table? Is it the keymap?
baldr wrote:

Are you done with IRQ setup already? Probably polling keyboard instead could be easier.

Yes. I tagged it to int 09h. With polling, don't I only wait for the device if it is busy?
Post 30 May 2010, 18:53
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 30 May 2010, 19:16
MeshNix wrote:
What is the table? Is it the keymap?
It can be called so. For xlat you can use something like
Code:
db 0, 27, "1234567890-=", 9, 8; 00…0F
db "qwertyuiop[]", 13, 0, "as"; 10…1F
db "dfghjkl;'`", 0, "\zxcv"   ; 20…2F
db "bnm,./"                   ; 30…35    
This is for unshifted layout without CapsLock.

Probably you may try to correctly ignore (it's not so easy, several keys send quite long sequences, notably Pause) all keys except NumLock and toggle LED properly? Wink
MeshNix wrote:
With polling, don't I only wait for the device if it is busy?
Yes. Test status register until it says byte is available, then read it.
Post 30 May 2010, 19:16
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 30 May 2010, 21:00
As baldr hinted, a single key will produce between 1 and 8 bytes to read from buffer depending on the sequence as you read. You can find tables of these values here: http://www.computer-engineering.org/ps2keyboard/scancodes2.html . So you check for special 0xE0/0xE1 codes then the break (key up) code 0xF0 then you do lookup on the rest [this changes with layout].
Post 30 May 2010, 21:00
View user's profile Send private message Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 31 May 2010, 01:19
Thanks, cod3b453. These are for extended scan codes I believe.

Keys like "Q","W","E", ... "\" can be ignored but special keys like Caps Lock and NumLock, etc. have to be handled specially. Is that what your saying?

--------------
Would the lookup be something like this?

Code:
...

jmp start:

keymap_table:
     db 0, 27, "1234567890-=", 9, 8; 00…0F 
     db "qwertyuiop[]", 13, 0, "as"; 10…1F 
     db "dfghjkl;'`", 0, "\zxcv"   ; 20…2F 
     db "bnm,./"                   ; 30…35

char db ?                          ; store lookup char

start:
      in al,60h

      mov bx,keymap_table
;     mov al,al                    ; just to simplify
      xlatb
      mov [char],al
...    


I just realise that the keymap is arranged according to the key press hex value.
cod3b453 wrote:
[this changes with layout]
The layout of a keyboard is a big factor in the layout of a keymap. Should it be the same as the keyboard it self, or the range of the scancode?
Post 31 May 2010, 01:19
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 31 May 2010, 12:49
Well, you need to handle all cases correctly so that you read exactly the right number of bytes for the scan code - reading allows another byte to be put on the keyboard buffer for other key events; if you read too many/too few you will get unpredictable results.

The scan codes are the same for physical keys but the keys and therefore the keymap will alter with language layout e.g. english use "qwerty", german use "qwertz"; simply load different tables for different layouts without any more code.
Post 31 May 2010, 12:49
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 31 May 2010, 15:46
The keyboard driver is basically a very boring long routine full of comparisons and jumps.

Start by checking a few status bytes such as the acknowledge code, then test if you have a make code or a break code.

If it's a make code, check for locks, shift, controls, etc. and switch on "status variables" (for later use). Check for 0xe0 and 0xe1 extended keys. The rest should now be normal keys. Just check your "status variables" and xlat the keys accordingly using different tables if for example caps lock is on or shift is pressed.

If it's a break code, check for shift, alt, etc. and switch off the "status variables".

That's more or less it.
Post 31 May 2010, 15:46
View user's profile Send private message Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 01 Jun 2010, 17:29
Okay (thanks ) Very Happy. Do I HAVE TO set the driver so that if an extended key is pressed it is has to handle that key, or can I leave for later Confused ?
Post 01 Jun 2010, 17:29
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 01 Jun 2010, 18:59
for exetended keys, you should remember special scan code, quit interrupt and wait for next scan code.
instead of threading the key as a single byte, you should thread it as multiple bytes. that's all.
Post 01 Jun 2010, 18:59
View user's profile Send private message Visit poster's website Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 02 Jun 2010, 00:50
Thanks edfed. I think I will ignore keys like print, insert until I get a full grasp on the whole keyboard driver thing. But I am still confused with the interrupt setup. I have done it.
Code:
mov word [es:09h*4],KbdHandler
mov [es:09h*4+2],cs    

Does this mean that when ever a key is pressed, the handler will be invoke, or do I have to use:
Code:
int 09h    
to invoke the interrupt?
Post 02 Jun 2010, 00:50
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Jun 2010, 07:12
MeshNix,

That code is good for RM (if cs:KbdHandler is a valid 16:16 pointer to handler). Whenever keyboard sends something, IRQ1 will be fired and if it isn't masked, processor will perform the same routine as for int 09h (which, as you've said, corresponds to IRQ1).
Post 02 Jun 2010, 07:12
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 02 Jun 2010, 12:34
MeshNix, you should never call an IRQ manually. It's called automatically by the hardware. Instead, within the IRQ routine, you should store the key in a known memory location and setup a software interrupt that will read that memory location for keys. Do you remember BIOS interrupt 0x16? Well, you should have a similar thing for your OS.
Post 02 Jun 2010, 12:34
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Jun 2010, 16:56
ManOfSteel,

He can't call IRQ, unless special hardware involved. He can call IRQ handler, though. Under circumstances that makes perfect sense.
Post 02 Jun 2010, 16:56
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 02 Jun 2010, 17:06
baldr wrote:
He can't call IRQ, unless special hardware involved. He can call IRQ handler, though.

What I meant.

baldr wrote:
Under circumstances that makes perfect sense.

What circumstances are we talking about?
I can't see any use for that. The IRQ handler is called after a hardware event, and a software interrupt retrieves the data, whether it's a keyboard keycode, mouse coordinates, sector read, etc.
Post 02 Jun 2010, 17:06
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 02 Jun 2010, 18:15
ManOfSteel wrote:
What circumstances are we talking about?
I can't see any use for that.
It appears that you didn't program under DOS. Interrupt handlers' chaining was common technique those days.
Post 02 Jun 2010, 18:15
View user's profile Send private message Reply with quote
ManOfSteel



Joined: 02 Feb 2005
Posts: 1154
ManOfSteel 02 Jun 2010, 19:15
Yes I did. But I thought we were talking about constructing modern OS, not emulating ones that belong right here along with the Morris worm. Razz
Post 02 Jun 2010, 19:15
View user's profile Send private message Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 02 Jun 2010, 23:25
Laughing MOS
(Sorry I am a bit interrogative when getting information on a technical subject)
Smile

baldr wrote:
Whenever keyboard sends something, IRQ1 will be fired and if it isn't masked

What do you mean by if it isn't masked?

ManOfSteel wrote:
MeshNix, you should never call an IRQ manually. It's called automatically by the hardware. Instead, within the IRQ routine, you should store the key in a known memory location and setup a software interrupt that will read that memory location for keys. Do you remember BIOS interrupt 0x16? Well, you should have a similar thing for your OS.

Great, so as long as I have the handler code for the keyboard in offset 09h*4, when IRQ1 is generated it will read the code from that offset?

_________________
meshnix
Post 02 Jun 2010, 23:25
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 02 Jun 2010, 23:55
MeshNix wrote:

What do you mean by if it isn't masked?

To mask the IRQs is to tell the PIC not to call your ISR. To mask an IRQ, you set the IRQ's corresponding bit in port 21h for the first 8 and a1h for the second 8. (Note: int 9==IRQ 1) Here's more on IRQs.
MeshNix wrote:

Great, so as long as I have the handler code for the keyboard in offset 09h*4, when IRQ1 is generated it will read the code from that offset?

No, you put a pointer to the handler code there. I think(NOT sure) that the first word holds the segment and the second holds the offset.
Post 02 Jun 2010, 23:55
View user's profile Send private message Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 03 Jun 2010, 01:52
Tyler wrote:
To mask the IRQs is to tell the PIC not to call your ISR. To mask an IRQ, you set the IRQ's corresponding bit in port 21h for the first 8 and a1h for the second 8. (Note: int 9==IRQ 1) Here's more on IRQs.

Shocked complicated stuff!

Tyler wrote:
No, you put a pointer to the handler code there. I think(NOT sure) that the first word holds the segment and the second holds the offset.

Huh? Doesn't es:0x09*4 store the offset of the label for the handler
Then, es:0x09*4+2, store the segment for that offset.
So:
Code:
seg = es:0x09*4+2
off = es:0x09*4

; when int 09h is invoke, wouldn't it be similar to this:
 call seg:off    
Post 03 Jun 2010, 01:52
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 03 Jun 2010, 02:02
I assume you're using real mode since it looks like you're patching the IVT. If, say you're int 9 handler is at 500h:0, then you would patch the word at 9*4 with 500h(segment) and patch the word at 9*4+2 with 0(offset). When interrupt 9 is called, the processor reads the segment and offset from 9*4(which you just patched) and executes a "jmp 500h:0".
Post 03 Jun 2010, 02:02
View user's profile Send private message Reply with quote
adroit



Joined: 21 Feb 2010
Posts: 252
adroit 03 Jun 2010, 02:11
Okay. So 500h:0 is a pointer to the handler code itself.
Post 03 Jun 2010, 02:11
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.