source: rtems/c/src/lib/libbsp/i386/pc386/console/inch.c @ 7150f00f

4.104.114.84.95
Last change on this file since 7150f00f was 7150f00f, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 1, 1997 at 10:06:48 PM

Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@…> and Jose Rufino <ruf@…>
of NavIST (http://pandora.ist.utl.pt/).

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*-------------------------------------------------------------------------+
2| inch.c v1.1 - PC386 BSP - 1997/08/07
3+--------------------------------------------------------------------------+
4| (C) Copyright 1997 -
5| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
6|
7| http://pandora.ist.utl.pt
8|
9| Instituto Superior Tecnico * Lisboa * PORTUGAL
10+--------------------------------------------------------------------------+
11| Disclaimer:
12|
13| This file is provided "AS IS" without warranty of any kind, either
14| expressed or implied.
15+--------------------------------------------------------------------------+
16| This code is based on:
17|   inch.c,v 1.3 1995/12/19 20:07:25 joel Exp - go32 BSP
18| With the following copyright notice:
19| **************************************************************************
20| * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.                      *
21| * On-Line Applications Research Corporation (OAR).                       *
22| * All rights assigned to U.S. Government, 1994.                          *
23| *                                                                        *
24| * This material may be reproduced by or for the U.S. Government pursuant *
25| * to the copyright license under the clause at DFARS 252.227-7013.  This *
26| * notice must appear in all copies of this file and its derivatives.     *
27| **************************************************************************
28+--------------------------------------------------------------------------*/
29
30#include <bsp.h>
31#include <irq.h>
32
33/*-------------------------------------------------------------------------+
34| Constants
35+--------------------------------------------------------------------------*/
36#define KBD_CTL      0x61  /* -------------------------------- */
37#define KBD_DATA     0x60  /* Ports for PC keyboard controller */
38#define KBD_STATUS   0x64  /* -------------------------------- */
39
40#define KBD_BUF_SIZE 256
41
42/*-------------------------------------------------------------------------+
43| Global Variables
44+--------------------------------------------------------------------------*/
45static char key_map[] =
46{
47  0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
48  'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
49  'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
50  0134,'z','x','c','v','b','n','m',',','.','/',0x80,
51  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
52  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
53  0x80,0x80,0x80,'0',0177
54}; /* Keyboard scancode -> character map with no modifiers.       */
55
56static char shift_map[] =
57{
58  0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
59  'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
60  'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
61  '|','Z','X','C','V','B','N','M','<','>','?',0x80,
62  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
63  0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
64  '1','2','3','0',177
65}; /* Keyboard scancode -> character map with SHIFT key modifier. */ 
66
67static char             kbd_buffer[KBD_BUF_SIZE];
68static rtems_unsigned16 kbd_first = 0;
69static rtems_unsigned16 kbd_last  = 0;
70
71
72/*-------------------------------------------------------------------------+
73|         Function: _IBMPC_scankey
74|      Description: This function can be called during a poll for input, or by
75|                   an ISR. Basically any time you want to process a keypress.
76| Global Variables: key_map, shift_map.
77|        Arguments: outChar - character read in case of a valid reading,
78|                   otherwise unchanged.
79|          Returns: TRUE in case a valid character has been read,
80|                   FALSE otherwise.
81+--------------------------------------------------------------------------*/
82rtems_boolean
83_IBMPC_scankey(char *outChar)
84{
85  unsigned char inChar;
86  static int alt_pressed   = 0;
87  static int ctrl_pressed  = 0;
88  static int shift_pressed = 0;
89  static int caps_pressed  = 0;
90  static int extended      = 0;
91
92  *outChar = NULL; /* default value if we return FALSE */
93
94  /* Read keyboard controller, toggle enable */
95  inport_byte(KBD_CTL, inChar);
96  outport_byte(KBD_CTL, inChar & ~0x80);
97  outport_byte(KBD_CTL, inChar | 0x80);
98  outport_byte(KBD_CTL, inChar & ~0x80);
99
100  /* See if it has data */
101  inport_byte(KBD_STATUS, inChar);
102  if ((inChar & 0x01) == 0)
103    return FALSE;
104
105  /* Read the data.  Handle nonsense with shift, control, etc. */
106  inport_byte(KBD_DATA, inChar);
107
108  if (extended)
109    extended--;
110
111  switch (inChar)
112  {
113    case 0xe0:
114      extended = 2;
115      return FALSE;
116      break;
117
118    case 0x38:
119      alt_pressed = 1;
120      return FALSE;
121      break;
122    case 0xb8:
123      alt_pressed = 0;
124      return FALSE;
125      break;
126
127    case 0x1d:
128      ctrl_pressed = 1;
129      return FALSE;
130      break;
131    case 0x9d:
132      ctrl_pressed = 0;
133      return FALSE;
134      break;
135
136    case 0x2a:
137      if (extended)
138        return FALSE;
139    case 0x36:
140      shift_pressed = 1;
141      return FALSE;
142      break;
143    case 0xaa:
144      if (extended)
145        return FALSE;
146    case 0xb6:
147      shift_pressed = 0;
148      return FALSE;
149      break;
150
151    case 0x3a:
152      caps_pressed = 1;
153      return FALSE;
154      break;
155    case 0xba:
156      caps_pressed = 0;
157      return FALSE;
158      break;
159
160    case 0x53:
161      if (ctrl_pressed && alt_pressed) 
162        rtemsReboot(); /* ctrl+alt+del -> reboot */
163      break;
164
165    /*
166     * Ignore unrecognized keys--usually arrow and such
167     */
168    default:
169      if ((inChar & 0x80) || (inChar > 0x39))
170      /* High-bit on means key is being released, not pressed */
171        return FALSE;
172      break;
173  } /* switch */
174
175  /* Strip high bit, look up in our map */
176  inChar &= 0x7f;
177  if (ctrl_pressed)
178  {
179    *outChar = key_map[inChar];
180    *outChar &= 037;
181  }
182  else
183  {
184    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
185    if (caps_pressed)
186    {
187      if (*outChar >= 'A' && *outChar <= 'Z')
188        *outChar += 'a' - 'A';
189      else if (*outChar >= 'a' && *outChar <= 'z')
190        *outChar -= 'a' - 'A';
191    }
192  }
193
194  return TRUE;
195} /* _IBMPC_scankey */
196
197
198/*-------------------------------------------------------------------------+
199|         Function: _IBMPC_keyboard_isr
200|      Description: Interrupt Service Routine for keyboard (0x01) IRQ.
201| Global Variables: kbd_buffer, kbd_first, kbd_last.
202|        Arguments: vector - standard RTEMS argument - see documentation.
203|          Returns: standard return value - see documentation.
204+--------------------------------------------------------------------------*/
205rtems_isr
206_IBMPC_keyboard_isr(rtems_vector_number vector)
207{
208  if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
209  {
210    /* Got one; save it if there is enough room in buffer. */
211    unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE;
212
213    if (next != kbd_first)
214      kbd_last = next;
215  }
216
217  PC386_ackIrq(vector - PC386_IRQ_VECTOR_BASE); /* Mark interrupt as handled. */
218} /* _IBMPC_keyboard_isr */
219
220
221/*-------------------------------------------------------------------------+
222|         Function: _IBMPC_chrdy
223|      Description: Check keyboard ISR buffer and return character if not empty.
224| Global Variables: kbd_buffer, kbd_first, kbd_last.
225|        Arguments: c - character read if keyboard buffer not empty, otherwise
226|                   unchanged.
227|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
228+--------------------------------------------------------------------------*/
229rtems_boolean
230_IBMPC_chrdy(char *c)
231{
232  /* Check buffer our ISR builds */
233  if (kbd_first != kbd_last)
234  {
235    *c = kbd_buffer[kbd_first];
236
237    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
238    return TRUE;
239  }
240  else
241    return FALSE;
242} /* _IBMPC_chrdy */
243
244
245/*-------------------------------------------------------------------------+
246|         Function: _IBMPC_inch
247|      Description: Poll keyboard until a character is ready and return it.
248| Global Variables: None.
249|        Arguments: None.
250|          Returns: character read from keyboard.
251+--------------------------------------------------------------------------*/
252char
253_IBMPC_inch(void)
254{
255    char c;
256    while (!_IBMPC_chrdy(&c))
257      continue;
258
259    return c;
260} /* _IBMPC_inch */
Note: See TracBrowser for help on using the repository browser.