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

4.104.114.84.95
Last change on this file since 69537ca9 was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

  • Property mode set to 100644
File size: 9.4 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-1999.
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
69static char             kbd_buffer[KBD_BUF_SIZE];
70static rtems_unsigned16 kbd_first = 0;
71static rtems_unsigned16 kbd_last  = 0;
72static rtems_unsigned16 kbd_end   = KBD_BUF_SIZE - 1;
73
74/*-------------------------------------------------------------------------+
75|         Function: rtemsReboot
76|      Description: Reboot the PC.
77| Global Variables: None.
78|        Arguments: None.
79|          Returns: Nothing.
80+--------------------------------------------------------------------------*/
81void rtemsReboot(void)
82{
83  /* shutdown and reboot */
84  outport_byte(0x64, 0xFE);      /* use keyboard controler to do the job... */
85} /* rtemsReboot */
86
87/*-------------------------------------------------------------------------+
88|         Function: _IBMPC_scankey
89|      Description: This function can be called during a poll for input, or by
90|                   an ISR. Basically any time you want to process a keypress.
91| Global Variables: key_map, shift_map.
92|        Arguments: outChar - character read in case of a valid reading,
93|                   otherwise unchanged.
94|          Returns: TRUE in case a valid character has been read,
95|                   FALSE otherwise.
96+--------------------------------------------------------------------------*/
97rtems_boolean
98_IBMPC_scankey(char *outChar)
99{
100  unsigned char inChar;
101  static int alt_pressed   = 0;
102  static int ctrl_pressed  = 0;
103  static int shift_pressed = 0;
104  static int caps_pressed  = 0;
105  static int extended      = 0;
106
107  *outChar = NULL; /* default value if we return FALSE */
108
109  /* Read keyboard controller, toggle enable */
110  inport_byte(KBD_CTL, inChar);
111  outport_byte(KBD_CTL, inChar & ~0x80);
112  outport_byte(KBD_CTL, inChar | 0x80);
113  outport_byte(KBD_CTL, inChar & ~0x80);
114
115  /* See if it has data */
116  inport_byte(KBD_STATUS, inChar);
117  if ((inChar & 0x01) == 0)
118    return FALSE;
119
120  /* Read the data.  Handle nonsense with shift, control, etc. */
121  inport_byte(KBD_DATA, inChar);
122
123  if (extended)
124    extended--;
125
126  switch (inChar)
127  {
128    case 0xe0:
129      extended = 2;
130      return FALSE;
131      break;
132
133    case 0x38:
134      alt_pressed = 1;
135      return FALSE;
136      break;
137    case 0xb8:
138      alt_pressed = 0;
139      return FALSE;
140      break;
141
142    case 0x1d:
143      ctrl_pressed = 1;
144      return FALSE;
145      break;
146    case 0x9d:
147      ctrl_pressed = 0;
148      return FALSE;
149      break;
150
151    case 0x2a:
152      if (extended)
153        return FALSE;
154    case 0x36:
155      shift_pressed = 1;
156      return FALSE;
157      break;
158    case 0xaa:
159      if (extended)
160        return FALSE;
161    case 0xb6:
162      shift_pressed = 0;
163      return FALSE;
164      break;
165
166    case 0x3a:
167      caps_pressed = 1;
168      return FALSE;
169      break;
170    case 0xba:
171      caps_pressed = 0;
172      return FALSE;
173      break;
174
175    case 0x53:
176      if (ctrl_pressed && alt_pressed)
177        rtemsReboot(); /* ctrl+alt+del -> reboot */
178      break;
179
180    /*
181     * Ignore unrecognized keys--usually arrow and such
182     */
183    default:
184      if ((inChar & 0x80) || (inChar > 0x39))
185      /* High-bit on means key is being released, not pressed */
186        return FALSE;
187      break;
188  } /* switch */
189
190  /* Strip high bit, look up in our map */
191  inChar &= 0x7f;
192  if (ctrl_pressed)
193  {
194    *outChar = key_map[inChar];
195    *outChar &= 037;
196  }
197  else
198  {
199    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
200    if (caps_pressed)
201    {
202      if (*outChar >= 'A' && *outChar <= 'Z')
203        *outChar += 'a' - 'A';
204      else if (*outChar >= 'a' && *outChar <= 'z')
205        *outChar -= 'a' - 'A';
206    }
207  }
208
209  return TRUE;
210} /* _IBMPC_scankey */
211
212/*-------------------------------------------------------------------------+
213|         Function: _IBMPC_keyboard_isr
214|      Description: Interrupt Service Routine for keyboard (0x01) IRQ.
215| Global Variables: kbd_buffer, kbd_first, kbd_last.
216|        Arguments: vector - standard RTEMS argument - see documentation.
217|          Returns: standard return value - see documentation.
218+--------------------------------------------------------------------------*/
219void _IBMPC_keyboard_isr()
220{
221  if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
222  {
223    /* Got one; save it if there is enough room in buffer. */
224    unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
225
226    if (next != kbd_first)
227      {
228        kbd_last = next;
229      }
230  }
231} /* _IBMPC_keyboard_isr */
232
233
234/*-------------------------------------------------------------------------+
235|         Function: _IBMPC_chrdy
236|      Description: Check keyboard ISR buffer and return character if not empty.
237| Global Variables: kbd_buffer, kbd_first, kbd_last.
238|        Arguments: c - character read if keyboard buffer not empty, otherwise
239|                   unchanged.
240|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
241+--------------------------------------------------------------------------*/
242rtems_boolean
243_IBMPC_chrdy(char *c)
244{
245  /* FIX ME!!! It doesn't work without something like the following line.
246     Find out why! */
247  printk("");
248
249  /* Check buffer our ISR builds */
250  if (kbd_first != kbd_last)
251  {
252    *c = kbd_buffer[kbd_first];
253
254    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
255    return TRUE;
256  }
257  else
258    return FALSE;
259} /* _IBMPC_chrdy */
260
261
262/*-------------------------------------------------------------------------+
263|         Function: _IBMPC_inch
264|      Description: Poll keyboard until a character is ready and return it.
265| Global Variables: None.
266|        Arguments: None.
267|          Returns: character read from keyboard.
268+--------------------------------------------------------------------------*/
269char
270_IBMPC_inch(void)
271{
272    char c;
273    while (!_IBMPC_chrdy(&c))
274      continue;
275
276    return c;
277} /* _IBMPC_inch */
278
279 
280 /*
281  * Routine that can be used before interrupt management is initialized.
282  */
283 
284char
285BSP_wait_polled_input(void)
286{
287  char c;
288  while (!_IBMPC_scankey(&c))
289    continue;
290
291  return c;
292}
293
294/*-------------------------------------------------------------------------+
295|         Function: _IBMPC_inch_sleep
296|      Description: If charcter is ready return it, otherwise sleep until
297|                   it is ready
298| Global Variables: None.
299|        Arguments: None.
300|          Returns: character read from keyboard.
301+--------------------------------------------------------------------------*/
302char
303_IBMPC_inch_sleep(void)
304{
305    char           c;
306    rtems_interval ticks_per_second;
307
308    ticks_per_second = 0;
309
310    for(;;)
311      {
312        if(_IBMPC_chrdy(&c))
313          {
314            return c;
315          }
316 
317        if(ticks_per_second == 0)
318          {
319            rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND,
320                            &ticks_per_second);
321          }
322        rtems_task_wake_after((ticks_per_second+24)/25);
323      }
324       
325    return c;
326} /* _IBMPC_inch */
327
328
329
330
331
332
Note: See TracBrowser for help on using the repository browser.