summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/console
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
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')
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c229
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/keyboard.c12
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/pc_keyb.c10
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/vt.c7
4 files changed, 239 insertions, 19 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 );
diff --git a/c/src/lib/libbsp/i386/pc386/console/keyboard.c b/c/src/lib/libbsp/i386/pc386/console/keyboard.c
index 5520ae7354..db9e0b6f1a 100644
--- a/c/src/lib/libbsp/i386/pc386/console/keyboard.c
+++ b/c/src/lib/libbsp/i386/pc386/console/keyboard.c
@@ -60,27 +60,27 @@ extern void rtemsReboot( void );
int set_bit(int nr, unsigned long * addr)
{
- int mask, retval;
+ int mask, retval,level;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
- cli();
+ _CPU_ISR_Disable(level)
retval = (mask & *addr) != 0;
*addr |= mask;
- sti();
+ _CPU_ISR_Enable (level);
return retval;
}
int clear_bit(int nr, unsigned long * addr)
{
- int mask, retval;
+ int mask, retval,level;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
- cli();
+ _CPU_ISR_Disable(level)
retval = (mask & *addr) != 0;
*addr &= ~mask;
- sti();
+ _CPU_ISR_Enable (level);
return retval;
}
diff --git a/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c b/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
index 0b94666504..d9feaca1b4 100644
--- a/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
+++ b/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
@@ -636,13 +636,15 @@ void pckbd_init_hw(void)
}
-
+/*
char BSP_wait_polled_input( void )
{
- int c;
- cli();
+ int c,level;
+
+ _CPU_ISR_Disable(level);
while ( ( c= kbd_wait_for_input() ) < 0 )
continue;
- sti();
+ _CPU_ISR_Enable (level);
return c;
}
+*/
diff --git a/c/src/lib/libbsp/i386/pc386/console/vt.c b/c/src/lib/libbsp/i386/pc386/console/vt.c
index eb8ec64c76..218a907c92 100644
--- a/c/src/lib/libbsp/i386/pc386/console/vt.c
+++ b/c/src/lib/libbsp/i386/pc386/console/vt.c
@@ -66,12 +66,13 @@ kd_nosound(unsigned long ignored)
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
- unsigned int count = 0;
+ unsigned int count = 0;
+ int level;
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
- cli();
+ _CPU_ISR_Disable(level);
/* del_timer(&sound_timer); */
if (count) {
/* enable counter 2 */
@@ -91,7 +92,7 @@ _kd_mksound(unsigned int hz, unsigned int ticks)
} else
kd_nosound(0);
- sti();
+ _CPU_ISR_Enable (level);
return;
}