source: rtems/c/src/lib/libbsp/i386/pc386/console/inch.c @ 084369e

4.104.11
Last change on this file since 084369e was 084369e, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 22, 2008 at 9:49:43 PM

2008-09-22 Joel Sherrill <joel.sherrill@…>

  • Makefile.am, configure.ac, console/inch.c, console/keyboard.c, include/bsp.h: Use standardized bsp_cleanup() which can optionally print a message, poll for user to press key, and call bsp_reset(). Using this eliminates the various bsp_cleanup() implementations which had their own implementation and variety of string constants.
  • 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| With the following copyright notice:
20| **************************************************************************
21| *  COPYRIGHT (c) 1989-1998.
22| *  On-Line Applications Research Corporation (OAR).
23| *
24| *  The license and distribution terms for this file may be
25| *  found in found in the file LICENSE in this distribution or at
26| *  http://www.rtems.com/license/LICENSE.
27| **************************************************************************
28|
29|  $Id$
30+--------------------------------------------------------------------------*/
31
32#include <bsp.h>
33#include <bsp/bootcard.h>
34#include <bsp/irq.h>
35
36/*-------------------------------------------------------------------------+
37| Constants
38+--------------------------------------------------------------------------*/
39#define KBD_CTL      0x61  /* -------------------------------- */
40#define KBD_DATA     0x60  /* Ports for PC keyboard controller */
41#define KBD_STATUS   0x64  /* -------------------------------- */
42
43#define KBD_BUF_SIZE 256
44
45/*-------------------------------------------------------------------------+
46| Global Variables
47+--------------------------------------------------------------------------*/
48static char key_map[] =
49{
50  0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
51  'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
52  'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
53  0134,'z','x','c','v','b','n','m',',','.','/',0x80,
54  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
55  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
56  0x80,0x80,0x80,'0',0177
57}; /* Keyboard scancode -> character map with no modifiers.       */
58
59static char shift_map[] =
60{
61  0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
62  'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
63  'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
64  '|','Z','X','C','V','B','N','M','<','>','?',0x80,
65  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
66  0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
67  '1','2','3','0',177
68}; /* Keyboard scancode -> character map with SHIFT key modifier. */
69
70static unsigned short   kbd_buffer[KBD_BUF_SIZE];
71static uint16_t         kbd_first = 0;
72static uint16_t         kbd_last  = 0;
73static uint16_t         kbd_end   = KBD_BUF_SIZE - 1;
74
75/*-------------------------------------------------------------------------+
76|         Function: _IBMPC_scankey
77|      Description: This function can be called during a poll for input, or by
78|                   an ISR. Basically any time you want to process a keypress.
79| Global Variables: key_map, shift_map.
80|        Arguments: outChar - character read in case of a valid reading,
81|                   otherwise unchanged.
82|          Returns: TRUE in case a valid character has been read,
83|                   FALSE otherwise.
84+--------------------------------------------------------------------------*/
85static bool
86_IBMPC_scankey(char *outChar)
87{
88  unsigned char inChar;
89  static int alt_pressed   = 0;
90  static int ctrl_pressed  = 0;
91  static int shift_pressed = 0;
92  static int caps_pressed  = 0;
93  static int extended      = 0;
94
95  *outChar = '\0'; /* default value if we return false */
96
97  /* Read keyboard controller, toggle enable */
98  inport_byte(KBD_CTL, inChar);
99  outport_byte(KBD_CTL, inChar & ~0x80);
100  outport_byte(KBD_CTL, inChar | 0x80);
101  outport_byte(KBD_CTL, inChar & ~0x80);
102
103  /* See if it has data */
104  inport_byte(KBD_STATUS, inChar);
105  if ((inChar & 0x01) == 0)
106    return false;
107
108  /* Read the data.  Handle nonsense with shift, control, etc. */
109  inport_byte(KBD_DATA, inChar);
110
111  if (extended)
112    extended--;
113
114  switch (inChar)
115  {
116    case 0xe0:
117      extended = 2;
118      return false;
119      break;
120
121    case 0x38:
122      alt_pressed = 1;
123      return false;
124      break;
125    case 0xb8:
126      alt_pressed = 0;
127      return false;
128      break;
129
130    case 0x1d:
131      ctrl_pressed = 1;
132      return false;
133      break;
134    case 0x9d:
135      ctrl_pressed = 0;
136      return false;
137      break;
138
139    case 0x2a:
140      if (extended)
141        return false;
142    case 0x36:
143      shift_pressed = 1;
144      return false;
145      break;
146    case 0xaa:
147      if (extended)
148        return false;
149    case 0xb6:
150      shift_pressed = 0;
151      return false;
152      break;
153
154    case 0x3a:
155      caps_pressed = 1;
156      return false;
157      break;
158    case 0xba:
159      caps_pressed = 0;
160      return false;
161      break;
162
163    case 0x53:
164      if (ctrl_pressed && alt_pressed)
165        bsp_reset(); /* ctrl+alt+del -> reboot */
166      break;
167
168    /*
169     * Ignore unrecognized keys--usually arrow and such
170     */
171    default:
172      if ((inChar & 0x80) || (inChar > 0x39))
173      /* High-bit on means key is being released, not pressed */
174        return false;
175      break;
176  } /* switch */
177
178  /* Strip high bit, look up in our map */
179  inChar &= 0x7f;
180  if (ctrl_pressed)
181  {
182    *outChar = key_map[inChar];
183    *outChar &= 037;
184  }
185  else
186  {
187    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
188    if (caps_pressed)
189    {
190      if (*outChar >= 'A' && *outChar <= 'Z')
191        *outChar += 'a' - 'A';
192      else if (*outChar >= 'a' && *outChar <= 'z')
193        *outChar -= 'a' - 'A';
194    }
195  }
196
197  return true;
198} /* _IBMPC_scankey */
199
200/*-------------------------------------------------------------------------+
201|         Function: _IBMPC_chrdy
202|      Description: Check keyboard ISR buffer and return character if not empty.
203| Global Variables: kbd_buffer, kbd_first, kbd_last.
204|        Arguments: c - character read if keyboard buffer not empty, otherwise
205|                   unchanged.
206|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
207+--------------------------------------------------------------------------*/
208static bool
209_IBMPC_chrdy(char *c)
210{
211  /* FIX ME!!! It doesn't work without something like the following line.
212     Find out why! */
213  printk("");
214
215  /* Check buffer our ISR builds */
216  if (kbd_first != kbd_last)
217  {
218    *c = kbd_buffer[kbd_first];
219
220    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
221    return true;
222  }
223  else
224    return false;
225} /* _IBMPC_chrdy */
226
227/*-------------------------------------------------------------------------+
228|         Function: _IBMPC_inch
229|      Description: Poll keyboard until a character is ready and return it.
230| Global Variables: None.
231|        Arguments: None.
232|          Returns: character read from keyboard.
233+--------------------------------------------------------------------------*/
234char
235_IBMPC_inch(void)
236{
237    char c;
238    while (!_IBMPC_chrdy(&c))
239      continue;
240
241    return c;
242} /* _IBMPC_inch */
243
244 /*
245  * Routine that can be used before interrupt management is initialized.
246  */
247
248char
249BSP_wait_polled_input(void)
250{
251  char c;
252  while (!_IBMPC_scankey(&c))
253    continue;
254
255  return c;
256}
257
258/*
259 * Check if a key has been pressed. This is a non-destructive
260 * call, meaning, it keeps the key in the buffer.
261 */
262int rtems_kbpoll( void )
263{
264  int                    rc;
265  rtems_interrupt_level level;
266
267  rtems_interrupt_disable(level);
268
269  rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
270
271  rtems_interrupt_enable(level);
272
273  return rc;
274}
275
276int getch( void )
277{
278  int c;
279
280  while( kbd_first == kbd_last )
281  {
282     rtems_task_wake_after( 10 );
283  }
284  c = kbd_buffer[ kbd_first ];
285  kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
286  return c;
287}
288
289void add_to_queue( unsigned short b )
290{
291 unsigned int next;
292 kbd_buffer[ kbd_last ] = b;
293 next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
294 if( next != kbd_first )
295 {
296    kbd_last = next;
297 }
298}
Note: See TracBrowser for help on using the repository browser.