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

4.104.114.84.95
Last change on this file since a606b45 was a606b45, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 12, 2001 at 9:09:26 PM

2001-10-12 Joel Sherrill <joel@…>

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