summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/console/inch.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-12-05 16:49:23 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-12-05 16:49:23 +0000
commitd57c04e1f3a2c704d3479f85de706ad7de65b8b0 (patch)
treec950d8370cad1952893da1a3331be486a4c9d308 /c/src/lib/libbsp/i386/pc386/console/inch.c
parent2000-12-05 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-d57c04e1f3a2c704d3479f85de706ad7de65b8b0.tar.bz2
2000-12-05 Eric Valette <valette@crf.canon.fr>
* console/inch.c, console/keyboard.c, console/pc_keyb.c, console/vt.c, include/bsp.h: Correct incorrect interrupt level handling in new keyboard management code. Correct BSP_poll_char initialization routine. * start/start.S, startup/bspstart.c: Correct when the video is initialized. * timer/timer.c (Calibrate_1ms_loop): Address problem where this did not work correctly on all PC speeds. The new calibrate routine has been tested on Pentium 166, pentium II 200, pentium III 300 Mhz and does work as expected.
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/console/inch.c')
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c229
1 files changed, 223 insertions, 6 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c
index 3aa3ad706d..ac6cec61dd 100644
--- a/c/src/lib/libbsp/i386/pc386/console/inch.c
+++ b/c/src/lib/libbsp/i386/pc386/console/inch.c
@@ -36,7 +36,37 @@
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
-#define KBD_BUF_SIZE 256
+#define KBD_CTL 0x61 /* -------------------------------- */
+#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
+#define KBD_STATUS 0x64 /* -------------------------------- */
+
+#define KBD_BUF_SIZE 256
+
+/*-------------------------------------------------------------------------+
+| Global Variables
++--------------------------------------------------------------------------*/
+static char key_map[] =
+{
+ 0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
+ 'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
+ 'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
+ 0134,'z','x','c','v','b','n','m',',','.','/',0x80,
+ '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,'0',0177
+}; /* Keyboard scancode -> character map with no modifiers. */
+
+static char shift_map[] =
+{
+ 0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
+ 'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
+ 'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
+ '|','Z','X','C','V','B','N','M','<','>','?',0x80,
+ '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
+ '1','2','3','0',177
+}; /* Keyboard scancode -> character map with SHIFT key modifier. */
+
static unsigned short kbd_buffer[KBD_BUF_SIZE];
static rtems_unsigned16 kbd_first = 0;
@@ -57,25 +87,212 @@ void rtemsReboot(void)
} /* rtemsReboot */
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_scankey
+| Description: This function can be called during a poll for input, or by
+| an ISR. Basically any time you want to process a keypress.
+| Global Variables: key_map, shift_map.
+| Arguments: outChar - character read in case of a valid reading,
+| otherwise unchanged.
+| Returns: TRUE in case a valid character has been read,
+| FALSE otherwise.
++--------------------------------------------------------------------------*/
+static rtems_boolean
+_IBMPC_scankey(char *outChar)
+{
+ unsigned char inChar;
+ static int alt_pressed = 0;
+ static int ctrl_pressed = 0;
+ static int shift_pressed = 0;
+ static int caps_pressed = 0;
+ static int extended = 0;
+
+ *outChar = '\0'; /* default value if we return FALSE */
+
+ /* Read keyboard controller, toggle enable */
+ inport_byte(KBD_CTL, inChar);
+ outport_byte(KBD_CTL, inChar & ~0x80);
+ outport_byte(KBD_CTL, inChar | 0x80);
+ outport_byte(KBD_CTL, inChar & ~0x80);
+
+ /* See if it has data */
+ inport_byte(KBD_STATUS, inChar);
+ if ((inChar & 0x01) == 0)
+ return FALSE;
+
+ /* Read the data. Handle nonsense with shift, control, etc. */
+ inport_byte(KBD_DATA, inChar);
+
+ if (extended)
+ extended--;
+
+ switch (inChar)
+ {
+ case 0xe0:
+ extended = 2;
+ return FALSE;
+ break;
+
+ case 0x38:
+ alt_pressed = 1;
+ return FALSE;
+ break;
+ case 0xb8:
+ alt_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x1d:
+ ctrl_pressed = 1;
+ return FALSE;
+ break;
+ case 0x9d:
+ ctrl_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x2a:
+ if (extended)
+ return FALSE;
+ case 0x36:
+ shift_pressed = 1;
+ return FALSE;
+ break;
+ case 0xaa:
+ if (extended)
+ return FALSE;
+ case 0xb6:
+ shift_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x3a:
+ caps_pressed = 1;
+ return FALSE;
+ break;
+ case 0xba:
+ caps_pressed = 0;
+ return FALSE;
+ break;
+
+ case 0x53:
+ if (ctrl_pressed && alt_pressed)
+ rtemsReboot(); /* ctrl+alt+del -> reboot */
+ break;
+
+ /*
+ * Ignore unrecognized keys--usually arrow and such
+ */
+ default:
+ if ((inChar & 0x80) || (inChar > 0x39))
+ /* High-bit on means key is being released, not pressed */
+ return FALSE;
+ break;
+ } /* switch */
+
+ /* Strip high bit, look up in our map */
+ inChar &= 0x7f;
+ if (ctrl_pressed)
+ {
+ *outChar = key_map[inChar];
+ *outChar &= 037;
+ }
+ else
+ {
+ *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
+ if (caps_pressed)
+ {
+ if (*outChar >= 'A' && *outChar <= 'Z')
+ *outChar += 'a' - 'A';
+ else if (*outChar >= 'a' && *outChar <= 'z')
+ *outChar -= 'a' - 'A';
+ }
+ }
+
+ return TRUE;
+} /* _IBMPC_scankey */
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_chrdy
+| Description: Check keyboard ISR buffer and return character if not empty.
+| Global Variables: kbd_buffer, kbd_first, kbd_last.
+| Arguments: c - character read if keyboard buffer not empty, otherwise
+| unchanged.
+| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
++--------------------------------------------------------------------------*/
+static rtems_boolean
+_IBMPC_chrdy(char *c)
+{
+ /* FIX ME!!! It doesn't work without something like the following line.
+ Find out why! */
+ printk("");
+
+ /* Check buffer our ISR builds */
+ if (kbd_first != kbd_last)
+ {
+ *c = kbd_buffer[kbd_first];
+
+ kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
+ return TRUE;
+ }
+ else
+ return FALSE;
+} /* _IBMPC_chrdy */
+
+
+/*-------------------------------------------------------------------------+
+| Function: _IBMPC_inch
+| Description: Poll keyboard until a character is ready and return it.
+| Global Variables: None.
+| Arguments: None.
+| Returns: character read from keyboard.
++--------------------------------------------------------------------------*/
+char
+_IBMPC_inch(void)
+{
+ char c;
+ while (!_IBMPC_chrdy(&c))
+ continue;
+
+ return c;
+} /* _IBMPC_inch */
+
+
+ /*
+ * Routine that can be used before interrupt management is initialized.
+ */
+
+char
+BSP_wait_polled_input(void)
+{
+ char c;
+ while (!_IBMPC_scankey(&c))
+ continue;
+
+ return c;
+}
-#define disable __asm__ __volatile__("cli")
-#define enable __asm__ __volatile__("sti");
/*
* Check if a key has been pressed. This is a non-destructive
* call, meaning, it keeps the key in the buffer.
*/
int rtems_kbpoll( void )
{
- int rc;
- disable;
+ int rc,level;
+
+ _CPU_ISR_Disable(level);
+
rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
- enable;
+
+ _CPU_ISR_Enable (level);
+
return rc;
}
int getch( void )
{
int c;
+
while( kbd_first == kbd_last )
{
rtems_task_wake_after( 10 );