SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2005  Thomas Petazzoni
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007 
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012 
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.
017 */
018 
019 #include <sos/types.h>
020 #include <sos/errno.h>
021 #include <sos/assert.h>
022 #include <hwcore/irq.h>
023 #include <hwcore/ioports.h>
024 
025 #include "tty.h"
026 
027 /*
028  * Keyboard ports and commands.
029  * 
030  * @see Ralf Brown's interrupt (and port) list   
031  * http://www-2.cs.cmu.edu/~ralf/files.html      
032  */
033 
034 #define KBD_DATA_PORT               0x60
035 
036 #define KBD_BREAKCODE_LIMIT         0x80
037 #define KBD_EXTENDED_SCANCODE       0xE0
038 
039 #define KBD_IS_MAKECODE(c)          ((c) < KBD_BREAKCODE_LIMIT)
040 #define KBD_IS_BREAKCODE(c)         ((c) >= KBD_BREAKCODE_LIMIT)
041 #define KBD_BREAKCODE_2_MAKECODE(c) ((c) ^ KBD_BREAKCODE_LIMIT)
042 
043 #define KBD_LEFTSHIFT_SCANCODE      0x2a
044 #define KBD_RIGHTSHIFT_SCANCODE     0x36
045 
046 typedef sos_ui8_t scancode_t;
047 
048 extern const char *kbd_regular_translate_table [];
049 extern const char *kbd_shift_translate_table [];
050 
051 static const char **kbd_current_translate_table = kbd_regular_translate_table;
052 static int is_ext = FALSE;
053 
054 static struct tty_device *tty;
055 
056 static void kbd_irq_handler (int irq_level)
057 {
058   scancode_t scancode;
059   const char *key = NULL;
060 
061   scancode = inb (KBD_DATA_PORT);
062 
063   /* Mark that next interrupt wil give an extended scancode */
064   if (scancode == KBD_EXTENDED_SCANCODE)
065     {
066       is_ext = TRUE;
067     }
068 
069   /* Handle extended scancode */
070   else if (is_ext)
071     {
072       is_ext = FALSE;
073     }
074 
075   /* Normal scancode */
076   else
077     {
078       /* Keypressed */
079       if (KBD_IS_MAKECODE(scancode))
080         {
081           /* If shift, change translation table */
082           if ((scancode == KBD_LEFTSHIFT_SCANCODE) ||
083               (scancode == KBD_RIGHTSHIFT_SCANCODE))
084             kbd_current_translate_table = kbd_shift_translate_table;
085 
086           /* If normal key, compute the result using the translation
087              tables and the booleans */
088           else if (kbd_current_translate_table[scancode])
089             {
090               key = kbd_current_translate_table[scancode];
091             }
092         }
093 
094       /* Key released */
095       else
096         {
097           scancode_t makecode = KBD_BREAKCODE_2_MAKECODE(scancode);
098 
099           if ((makecode == KBD_LEFTSHIFT_SCANCODE) ||
100               (makecode == KBD_RIGHTSHIFT_SCANCODE))
101             kbd_current_translate_table = kbd_regular_translate_table;
102         }
103     }
104 
105   if (key)
106     tty_add_chars (tty, key);
107 }
108 
109 
110 sos_ret_t sos_kbd_subsystem_setup(struct tty_device *t)
111 {
112   tty = t;
113 
114   sos_irq_set_routine (SOS_IRQ_KEYBOARD, kbd_irq_handler);
115 
116   return SOS_OK;
117 }
118 

source navigation ] diff markup ] identifier search ] general search ]