Page 3 of 3

Re:Keyboard input...How do I get keys?

Posted: Fri Oct 11, 2002 11:10 am
by Tom
your code didn't work :o

Re:Keyboard input...How do I get keys?

Posted: Fri Oct 11, 2002 11:40 am
by Whatever5k
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...

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:

Code: Select all

...
shift = FALSE;
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:06 am
by Whatever5k

Code: Select all

if (code & 0x80) /* released */
{
  code &= 0x7F; /* need to do that ! */
  if (code == LSHIFT ....)
      shift = 1;
...
This works then...

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

Re:Keyboard input...How do I get keys?

Posted: Mon Oct 14, 2002 6:34 am
by Pype.Clicker
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:

Code: Select all

push eax
mov al,0x20
out 0x20,al
pop eax
iretd

Re:Keyboard input...How do I get keys?

Posted: Mon Oct 14, 2002 6:49 am
by Whatever5k
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?

Posted: Mon Oct 14, 2002 4:21 pm
by Ozguxxx
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?

Posted: Mon Oct 14, 2002 6:02 pm
by Tom
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?

Re:Keyboard input...How do I get keys?

Posted: Tue Oct 15, 2002 3:38 am
by Pype.Clicker
Tom 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?
how do you expect both

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;
and

Code: Select all

    if( scan==KRLEFT_SHIFT || scan == KRRIGHT_SHIFT )
            shift=true;
to have a chance to be true ? either KRLEFT_SHIFT will have its 0x80 bit set or it won't. If it is, only break codes will be interpreted correctly and if it's not, only make code will work ... seems there's a need for a mask around here !

Re:Keyboard input...How do I get keys?

Posted: Tue Oct 15, 2002 6:32 am
by Whatever5k
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 ;)

Code: Select all

if (code & 0x80) /* released */
{
  code &= 0x7F; /* need to do that ! */
  if (code == LSHIFT ....)
      shift = 1;
...