From 7150f00f5be87fa8e37f7d00fbbef35645081138 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 1 Dec 1997 22:06:48 +0000 Subject: Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano and Jose Rufino of NavIST (http://pandora.ist.utl.pt/). --- c/src/lib/libbsp/i386/pc386/console/inch.c | 260 +++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 c/src/lib/libbsp/i386/pc386/console/inch.c (limited to 'c/src/lib/libbsp/i386/pc386/console/inch.c') diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c new file mode 100644 index 0000000000..e87e45728c --- /dev/null +++ b/c/src/lib/libbsp/i386/pc386/console/inch.c @@ -0,0 +1,260 @@ +/*-------------------------------------------------------------------------+ +| inch.c v1.1 - PC386 BSP - 1997/08/07 ++--------------------------------------------------------------------------+ +| (C) Copyright 1997 - +| - NavIST Group - Real-Time Distributed Systems and Industrial Automation +| +| http://pandora.ist.utl.pt +| +| Instituto Superior Tecnico * Lisboa * PORTUGAL ++--------------------------------------------------------------------------+ +| Disclaimer: +| +| This file is provided "AS IS" without warranty of any kind, either +| expressed or implied. ++--------------------------------------------------------------------------+ +| This code is based on: +| inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP +| With the following copyright notice: +| ************************************************************************** +| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. * +| * On-Line Applications Research Corporation (OAR). * +| * All rights assigned to U.S. Government, 1994. * +| * * +| * This material may be reproduced by or for the U.S. Government pursuant * +| * to the copyright license under the clause at DFARS 252.227-7013. This * +| * notice must appear in all copies of this file and its derivatives. * +| ************************************************************************** ++--------------------------------------------------------------------------*/ + +#include +#include + +/*-------------------------------------------------------------------------+ +| Constants ++--------------------------------------------------------------------------*/ +#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 char kbd_buffer[KBD_BUF_SIZE]; +static rtems_unsigned16 kbd_first = 0; +static rtems_unsigned16 kbd_last = 0; + + +/*-------------------------------------------------------------------------+ +| 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. ++--------------------------------------------------------------------------*/ +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 = NULL; /* 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_keyboard_isr +| Description: Interrupt Service Routine for keyboard (0x01) IRQ. +| Global Variables: kbd_buffer, kbd_first, kbd_last. +| Arguments: vector - standard RTEMS argument - see documentation. +| Returns: standard return value - see documentation. ++--------------------------------------------------------------------------*/ +rtems_isr +_IBMPC_keyboard_isr(rtems_vector_number vector) +{ + if (_IBMPC_scankey(&kbd_buffer[kbd_last])) + { + /* Got one; save it if there is enough room in buffer. */ + unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE; + + if (next != kbd_first) + kbd_last = next; + } + + PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */ +} /* _IBMPC_keyboard_isr */ + + +/*-------------------------------------------------------------------------+ +| 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. ++--------------------------------------------------------------------------*/ +rtems_boolean +_IBMPC_chrdy(char *c) +{ + /* 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 */ -- cgit v1.2.3