Keyboard input...How do I get keys?
Re:Keyboard input...How do I get keys?
Well, it works fine on my PC...
I think you haven't correctly set up interrupt handlers...or you haven't enabled the keyboard...or you haven't remapped the PICS...
I think you haven't correctly set up interrupt handlers...or you haven't enabled the keyboard...or you haven't remapped the PICS...
Re:Keyboard input...How do I get keys?
here is my code, I can't get upper shift letters and if i press j it prints it forever :O
int shift = FALSE;
#define KMETA_SHIFT 0x0800 // Shift is pressed
UCHAR const getch()
{
UINT scan = NULL; // The keyboard's scancode
UCHAR retchar = NULL; // The char that returns the ASCII code
// Define keys:
// Non-Shifted:
static const unsigned char asciiNonSh[] = { NULL, 0x1B, '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm',
',', '.', '/', 0, 0, 0, ' ', 0, KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP,
KPGUP,'-', KLFT, '5', KRT, '+', KEND, KDN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 };
// Shifted:
static const unsigned char asciiShift[] = { NULL, 0x1B, '!', '@', '#', '$', '%', '^', '&', '*', '(',
')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A',
'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<',
'>', '?', 0, 0, 0, ' ', 0, KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP, KPGUP,
'-', KLFT, '5', KRT, '+', KEND, KDN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 };
while ( TRUE )
{
scan = inportb( 0x60 ); // Port 0x60 is the keyboard
// If a key is unpressed, skip
if ( scan & 0x80 )
continue;
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift = TRUE;
// If it's a shift, use the shifted character map
if ( shift == TRUE )
retchar = asciiShift[ scan ];
// it's not, use then unshifted character map
else
retchar = asciiNonSh[ scan ];
shift = FALSE;
return retchar;
}
}
int shift = FALSE;
#define KMETA_SHIFT 0x0800 // Shift is pressed
UCHAR const getch()
{
UINT scan = NULL; // The keyboard's scancode
UCHAR retchar = NULL; // The char that returns the ASCII code
// Define keys:
// Non-Shifted:
static const unsigned char asciiNonSh[] = { NULL, 0x1B, '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm',
',', '.', '/', 0, 0, 0, ' ', 0, KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP,
KPGUP,'-', KLFT, '5', KRT, '+', KEND, KDN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 };
// Shifted:
static const unsigned char asciiShift[] = { NULL, 0x1B, '!', '@', '#', '$', '%', '^', '&', '*', '(',
')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A',
'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<',
'>', '?', 0, 0, 0, ' ', 0, KF1, KF2, KF3, KF4, KF5, KF6, KF7, KF8, KF9, KF10, 0, 0, KHOME, KUP, KPGUP,
'-', KLFT, '5', KRT, '+', KEND, KDN, KPGDN, KINS, KDEL, 0, 0, 0, KF11, KF12 };
while ( TRUE )
{
scan = inportb( 0x60 ); // Port 0x60 is the keyboard
// If a key is unpressed, skip
if ( scan & 0x80 )
continue;
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift = TRUE;
// If it's a shift, use the shifted character map
if ( shift == TRUE )
retchar = asciiShift[ scan ];
// it's not, use then unshifted character map
else
retchar = asciiNonSh[ scan ];
shift = FALSE;
return retchar;
}
}
Re:Keyboard input...How do I get keys?
First of all, this is no interrupt handler...you are just polling the keyboard controller, I'm not sure if a inportb(0x60) is correct when polling...so you should better write an interrupt handler that does it...
Secondly, I cannot quite understand why you do this:
It's obvious that you don't get shifted keys...If you get a LSHIFT or RSHIFT, you turn on the shift bit, that's okay - but then you should immediately return/continue because there is no need to translate the shift code into ASCII, it doesn't make sense...
Anyway, at the end you turn off the shift bit...why the hell do you do this? And why do you wonder that you cannot get any shifted keys if you turn off this bit...?
This here would work (as said, you should better implement a keyboard handler that does this here):
Secondly, I cannot quite understand why you do this:
Code: Select all
...
shift = FALSE;
Anyway, at the end you turn off the shift bit...why the hell do you do this? And why do you wonder that you cannot get any shifted keys if you turn off this bit...?
This here would work (as said, you should better implement a keyboard handler that does this here):
Code: Select all
int getch(void)
{
while (1)
{
if (scan & 0x80) /* key released */
{
if (scan == LSHIFT || scan == RSHIFT)
shift = FALSE; /* no more big letters */
continue;
}
if (scan == LSHIFT || scan == RSHIFT)
{
shift = TRUE;
continue;
}
/* user didn't press shift, but a normal character */
if (shift)
retchar = asciiShift[scan];
else
retchar = asciiNonShift[scan];
}
}
Re:Keyboard input...How do I get keys?
Hi abless, I have visited your web page, I have downloaded your source code, but I could not understand what really enabling keyboard means. (Am ia stupid? :-\) The code below should get an echo from keyboard but it does not... I could not find out why. It is taken from where the kernel gets into pmode and does this stuff (at least it should, but it doesnt).
...
mov ax,LINEAR_SEL
mov es,ax
mov fs,ax
;Send init. command words
mov al, 020h
mov bl, 0a0h
;ICW1
mov al, 0x11
out 020h, al
out 0a0h, al
;ICW2
mov al, 0x20
out 021h, al
mov al, 0x28
out 0a1h, al
;ICW3
mov al, 4
out 021h, al
mov al, 2
out 0a1h, al
;ICW4
mov al, 01h
out 021h, al
out 0a1h, al
;OCW1; Enable all IRQs
mov al, 0
out 021h, al
WaitLoop:
in al, 64h ; Read Status byte
and al, 01b ; Test OBF flag (Status<0>)
jnz WaitLoop ; Wait for OBF = 0
mov al, 0eeh
out 60h, al ; Write data to output buffer
WaitLoop2:
in al, 64h ; Read Status byte
and al, 10b ; Test IBF flag (Status<1>)
jz WaitLoop2 ; Wait for IBF = 1
in al, 60h ; Read input buffer
cmp al, 0eeh
jne stop
cmp al, 0feh
je WaitLoop
mov esi, msgKeyboard
call PRINTMSG32
jmp halt
stop:
mov esi, msgNotKeyboard
call PRINTMSG32
halt:
jmp $ ; halt
Any ideas? Sure you have, but I need to know what they are...
...
mov ax,LINEAR_SEL
mov es,ax
mov fs,ax
;Send init. command words
mov al, 020h
mov bl, 0a0h
;ICW1
mov al, 0x11
out 020h, al
out 0a0h, al
;ICW2
mov al, 0x20
out 021h, al
mov al, 0x28
out 0a1h, al
;ICW3
mov al, 4
out 021h, al
mov al, 2
out 0a1h, al
;ICW4
mov al, 01h
out 021h, al
out 0a1h, al
;OCW1; Enable all IRQs
mov al, 0
out 021h, al
WaitLoop:
in al, 64h ; Read Status byte
and al, 01b ; Test OBF flag (Status<0>)
jnz WaitLoop ; Wait for OBF = 0
mov al, 0eeh
out 60h, al ; Write data to output buffer
WaitLoop2:
in al, 64h ; Read Status byte
and al, 10b ; Test IBF flag (Status<1>)
jz WaitLoop2 ; Wait for IBF = 1
in al, 60h ; Read input buffer
cmp al, 0eeh
jne stop
cmp al, 0feh
je WaitLoop
mov esi, msgKeyboard
call PRINTMSG32
jmp halt
stop:
mov esi, msgNotKeyboard
call PRINTMSG32
halt:
jmp $ ; halt
Any ideas? Sure you have, but I need to know what they are...
Re:Keyboard input...How do I get keys?
here is my new code, when I don't press shift the first time I don't get shift letters...never mind, it does't work right all the way. it does this:
(without shift) press a-> a (with shift now) press shift & a -> A
but when I release shift it doesn't go unshifted. here is the code:
// Keep looping until there is a key that's available
while ( ( inportb( 0x64 ) & 1 ) == 0 )
EMPTY;
scan = inportb( 0x60 ); // Port 0x60 is the keyboard
// Check to see if a key is unpressed
if ( scan & 0x80 )
{
// If the shift key is up, then don't use upper-case letters, or numbers & symbols
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift = FALSE;
continue;
}
// If the shift key is down, use upper-case letters
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
{
shift = TRUE;
return;
}
// If it's a shift, use the shifted character map
if ( shift == TRUE )
retchar = asciiShift[ scan ];
// it's not, use then unshifted character map
else
retchar = asciiNonSh[ scan ];
return retchar;
(without shift) press a-> a (with shift now) press shift & a -> A
but when I release shift it doesn't go unshifted. here is the code:
// Keep looping until there is a key that's available
while ( ( inportb( 0x64 ) & 1 ) == 0 )
EMPTY;
scan = inportb( 0x60 ); // Port 0x60 is the keyboard
// Check to see if a key is unpressed
if ( scan & 0x80 )
{
// If the shift key is up, then don't use upper-case letters, or numbers & symbols
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift = FALSE;
continue;
}
// If the shift key is down, use upper-case letters
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
{
shift = TRUE;
return;
}
// If it's a shift, use the shifted character map
if ( shift == TRUE )
retchar = asciiShift[ scan ];
// it's not, use then unshifted character map
else
retchar = asciiNonSh[ scan ];
return retchar;
Re:Keyboard input...How do I get keys?
Code: Select all
if (code & 0x80) /* released */
{
code &= 0x7F; /* need to do that ! */
if (code == LSHIFT ....)
shift = 1;
...
Re:Keyboard input...How do I get keys?
Ozguxx:
Where do you have this assembler code from? That's sure not my kernel
Well, has you may know, if a hardware interrupt occurs (for example keyboard), the first PIC gets the signal and sends it to the CPU which stops execution and jumps to the keyboard handler...now you can tell the PIC to disable keyboard interrupts. That is, when you press a key, the PIC doesn't send a signal to the CPU...
I've looked quickly through your code, and noticed this here:
Why do you enable all IRQs? Do you really want to do that? It would mean that, for example, the PIC would generate clock interrupts. Do you have an interrupt handler for this IRQ? If not, you are lost - and if yes, does this interrupt handler send an EOI?
I think this is the problem...I'd recommend to disable all IRQs but the keyboard...
best regards,
A. Blessing
Where do you have this assembler code from? That's sure not my kernel
Well, has you may know, if a hardware interrupt occurs (for example keyboard), the first PIC gets the signal and sends it to the CPU which stops execution and jumps to the keyboard handler...now you can tell the PIC to disable keyboard interrupts. That is, when you press a key, the PIC doesn't send a signal to the CPU...
I've looked quickly through your code, and noticed this here:
Why do you enable all IRQs? Do you really want to do that? It would mean that, for example, the PIC would generate clock interrupts. Do you have an interrupt handler for this IRQ? If not, you are lost - and if yes, does this interrupt handler send an EOI?
I think this is the problem...I'd recommend to disable all IRQs but the keyboard...
best regards,
A. Blessing
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Keyboard input...How do I get keys?
if i remember well, a few interrupts on the PIC *cannot* be disabled by masking, and the timer & keyboard are some of these (i.e. masking them will have no effect on some hardware)
So you should defintively have a proper interrupt handler for your irq0:
So you should defintively have a proper interrupt handler for your irq0:
Code: Select all
push eax
mov al,0x20
out 0x20,al
pop eax
iretd
Re:Keyboard input...How do I get keys?
No Pype, this isn't right...I think you confounded the PIC with the NMI...the IRQs of the PIC can *all* be masked, no problem with that...the NMI (non maskable interrupt) is something else, that cannot be masked - but that has nothing to do with keyboard or PIC...
Re:Keyboard input...How do I get keys?
I am sorry for disturbing this thread but I have to ask this question. Abless, first of all, this is not your code of course, I had written it myself. Question: Is it necessary to program 8042 to make it interrupt system whenever data is ready in its output buffer? Or is that done automatically when IRQ1 is set? Thanx...
Re:Keyboard input...How do I get keys?
Ive' found the prob, the getch thinks the shift key is down after the second shift-letter/num/symbol press.
Is there away to fix this?
Is there away to fix this?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Keyboard input...How do I get keys?
how do you expect bothTom wrote: Ive' found the prob, the getch thinks the shift key is down after the second shift-letter/num/symbol press.
Is there away to fix this?
Code: Select all
if ( scan & 0x80 )
{
// If the shift key is up, then don't use upper-case letters, or numbers & symbols
if ( scan == KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift=false;
Code: Select all
if( scan==KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
shift=true;
Code: Select all
Re:Keyboard input...How do I get keys?
Ozguxxx:
What do you mean exactly? Of course, you needn't enable the IRQ1 (keyboard interrupt). But when you do that, you get a keyboard interrupt on every key-press and on every key-release. On the other hand, if you don't enable IRQ1, you have to poll the keyboard controller if someone has pressed a key (that's what you do). This is not the best design, because it wastes a lot of time...
Tom:
I already showed you the code that works
What do you mean exactly? Of course, you needn't enable the IRQ1 (keyboard interrupt). But when you do that, you get a keyboard interrupt on every key-press and on every key-release. On the other hand, if you don't enable IRQ1, you have to poll the keyboard controller if someone has pressed a key (that's what you do). This is not the best design, because it wastes a lot of time...
Tom:
I already showed you the code that works
Code: Select all
if (code & 0x80) /* released */
{
code &= 0x7F; /* need to do that ! */
if (code == LSHIFT ....)
shift = 1;
...