Re:Keyboard input...How do I get keys?
Posted: Sun Oct 13, 2002 9:58 am
by Tom
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;
}
}
Re:Keyboard input...How do I get keys?
Posted: Sun Oct 13, 2002 10:33 am
by Whatever5k
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):
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?
Posted: Sun Oct 13, 2002 3:10 pm
by Ozguxxx
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...
Re:Keyboard input...How do I get keys?
Posted: Sun Oct 13, 2002 5:01 pm
by Tom
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;
Re:Keyboard input...How do I get keys?
Posted: Mon Oct 14, 2002 5:11 am
by Whatever5k
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