source: rtems/c/src/lib/libbsp/powerpc/shared/console/inch.c @ e831de8

4.104.114.84.95
Last change on this file since e831de8 was e831de8, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 18:52:38

2003-09-04 Joel Sherrill <joel@…>

  • bootloader/bootldr.h, bootloader/em86.c, bootloader/em86real.S, bootloader/exception.S, bootloader/head.S, bootloader/lib.c, bootloader/misc.c, bootloader/mm.c, bootloader/pci.c, clock/p_clock.c, console/console.c, console/consoleIo.h, console/inch.c, console/keyboard.h, console/polled_io.c, include/bsp.h, irq/i8259.c, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, motorola/motorola.c, motorola/motorola.h, openpic/openpic.c, openpic/openpic.h, pci/pci.c, residual/residual.c, start/start.S, startup/bspstart.c, vectors/vectors.h, vectors/vectors_init.c: URL for license changed.
  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 *  inch.c  -- keyboard minimal driver
3 *
4 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
5 *
6 * This code is based on the pc386 BSP inch.c so the following
7 * copyright also applies :
8 *
9 * (C) Copyright 1997 -
10 * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
11 *
12 * http://pandora.ist.utl.pt
13 *
14 * Instituto Superior Tecnico * Lisboa * PORTUGAL
15 *  The license and distribution terms for this file may be
16 *  found in found in the file LICENSE in this distribution or at
17 *  http://www.rtems.com/license/LICENSE.
18 *
19 * $Id$
20 */
21
22#include <bsp.h>
23#include <bsp/irq.h>
24
25#include "console.inl"
26
27/*-------------------------------------------------------------------------+
28| Constants
29+--------------------------------------------------------------------------*/
30#define KBD_CTL      0x1  /* -------------------------------- */
31#define KBD_DATA     0x0  /* Port offsets for PC keyboard controller */
32#define KBD_STATUS   0x4  /* -------------------------------- */
33
34#define KBD_BUF_SIZE 256
35
36/*-------------------------------------------------------------------------+
37| Global Variables
38+--------------------------------------------------------------------------*/
39static char key_map[] =
40{
41  0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
42  'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
43  'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
44  0134,'z','x','c','v','b','n','m',',','.','/',0x80,
45  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
46  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
47  0x80,0x80,0x80,'0',0177
48}; /* Keyboard scancode -> character map with no modifiers.       */
49
50static char shift_map[] =
51{
52  0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
53  'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
54  'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
55  '|','Z','X','C','V','B','N','M','<','>','?',0x80,
56  '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
57  0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
58  '1','2','3','0',177
59}; /* Keyboard scancode -> character map with SHIFT key modifier. */
60
61static char             kbd_buffer[KBD_BUF_SIZE];
62static rtems_unsigned16 kbd_first = 0;
63static rtems_unsigned16 kbd_last  = 0;
64static rtems_unsigned16 kbd_end   = KBD_BUF_SIZE - 1;
65
66/*-------------------------------------------------------------------------+
67|         Function: _IBMPC_scankey
68|      Description: This function can be called during a poll for input, or by
69|                   an ISR. Basically any time you want to process a keypress.
70| Global Variables: key_map, shift_map.
71|        Arguments: outChar - character read in case of a valid reading,
72|                   otherwise unchanged.
73|          Returns: TRUE in case a valid character has been read,
74|                   FALSE otherwise.
75+--------------------------------------------------------------------------*/
76rtems_boolean
77_IBMPC_scankey(char *outChar)
78{
79  unsigned char inChar;
80  static int alt_pressed   = 0;
81  static int ctrl_pressed  = 0;
82  static int shift_pressed = 0;
83  static int caps_pressed  = 0;
84  static int extended      = 0;
85
86  *outChar = 0; /* default value if we return FALSE */
87
88  /* Read keyboard controller, toggle enable */
89  inChar=kbd_inb(KBD_CTL);
90  kbd_outb(KBD_CTL, inChar & ~0x80);
91  kbd_outb(KBD_CTL, inChar | 0x80);
92  kbd_outb(KBD_CTL, inChar & ~0x80);
93
94  /* See if it has data */
95  inChar=kbd_inb(KBD_STATUS);
96  if ((inChar & 0x01) == 0)
97    return FALSE;
98
99  /* Read the data.  Handle nonsense with shift, control, etc. */
100  inChar=kbd_inb(KBD_DATA);
101
102  if (extended)
103    extended--;
104
105  switch (inChar)
106  {
107    case 0xe0:
108      extended = 2;
109      return FALSE;
110      break;
111
112    case 0x38:
113      alt_pressed = 1;
114      return FALSE;
115      break;
116    case 0xb8:
117      alt_pressed = 0;
118      return FALSE;
119      break;
120
121    case 0x1d:
122      ctrl_pressed = 1;
123      return FALSE;
124      break;
125    case 0x9d:
126      ctrl_pressed = 0;
127      return FALSE;
128      break;
129
130    case 0x2a:
131      if (extended)
132        return FALSE;
133    case 0x36:
134      shift_pressed = 1;
135      return FALSE;
136      break;
137    case 0xaa:
138      if (extended)
139        return FALSE;
140    case 0xb6:
141      shift_pressed = 0;
142      return FALSE;
143      break;
144
145    case 0x3a:
146      caps_pressed = 1;
147      return FALSE;
148      break;
149    case 0xba:
150      caps_pressed = 0;
151      return FALSE;
152      break;
153
154    case 0x53:
155      if (ctrl_pressed && alt_pressed)
156        rtemsReboot(); /* ctrl+alt+del -> reboot */
157      break;
158
159    /*
160     * Ignore unrecognized keys--usually arrow and such
161     */
162    default:
163      if ((inChar & 0x80) || (inChar > 0x39))
164      /* High-bit on means key is being released, not pressed */
165        return FALSE;
166      break;
167  } /* switch */
168
169  /* Strip high bit, look up in our map */
170  inChar &= 0x7f;
171  if (ctrl_pressed)
172  {
173    *outChar = key_map[inChar];
174    *outChar &= 037;
175  }
176  else
177  {
178    *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
179    if (caps_pressed)
180    {
181      if (*outChar >= 'A' && *outChar <= 'Z')
182        *outChar += 'a' - 'A';
183      else if (*outChar >= 'a' && *outChar <= 'z')
184        *outChar -= 'a' - 'A';
185    }
186  }
187
188  return TRUE;
189} /* _IBMPC_scankey */
190
191/*-------------------------------------------------------------------------+
192|         Function: _IBMPC_keyboard_isr
193|      Description: Interrupt Service Routine for keyboard (0x01) IRQ.
194| Global Variables: kbd_buffer, kbd_first, kbd_last.
195|        Arguments: vector - standard RTEMS argument - see documentation.
196|          Returns: standard return value - see documentation.
197+--------------------------------------------------------------------------*/
198void _IBMPC_keyboard_isr()
199{
200  if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
201  {
202    /* Got one; save it if there is enough room in buffer. */
203    unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
204
205    if (next != kbd_first)
206      {
207        kbd_last = next;
208      }
209  }
210} /* _IBMPC_keyboard_isr */
211
212
213/*-------------------------------------------------------------------------+
214|         Function: _IBMPC_chrdy
215|      Description: Check keyboard ISR buffer and return character if not empty.
216| Global Variables: kbd_buffer, kbd_first, kbd_last.
217|        Arguments: c - character read if keyboard buffer not empty, otherwise
218|                   unchanged.
219|          Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
220+--------------------------------------------------------------------------*/
221rtems_boolean
222_IBMPC_chrdy(char *c)
223{
224  /* Check buffer our ISR builds */
225  if (kbd_first != kbd_last)
226  {
227    *c = kbd_buffer[kbd_first];
228
229    kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
230    return TRUE;
231  }
232  else
233    return FALSE;
234} /* _IBMPC_chrdy */
235
236
237/*-------------------------------------------------------------------------+
238|         Function: _IBMPC_inch
239|      Description: Poll keyboard until a character is ready and return it.
240| Global Variables: None.
241|        Arguments: None.
242|          Returns: character read from keyboard.
243+--------------------------------------------------------------------------*/
244char
245_IBMPC_inch(void)
246{
247    char c;
248    while (!_IBMPC_chrdy(&c))
249      continue;
250
251    return c;
252} /* _IBMPC_inch */
253
254 
255 /*
256  * Routine that can be used before interrupt management is initialized.
257  */
258 
259char
260BSP_wait_polled_input(void)
261{
262  char c;
263  while (!_IBMPC_scankey(&c))
264    continue;
265
266  return c;
267}
268
269/*-------------------------------------------------------------------------+
270|         Function: _IBMPC_inch_sleep
271|      Description: If charcter is ready return it, otherwise sleep until
272|                   it is ready
273| Global Variables: None.
274|        Arguments: None.
275|          Returns: character read from keyboard.
276+--------------------------------------------------------------------------*/
277char
278_IBMPC_inch_sleep(void)
279{
280    char           c;
281    rtems_interval ticks_per_second;
282
283    ticks_per_second = 0;
284
285    for(;;)
286      {
287        if(_IBMPC_chrdy(&c))
288          {
289            return c;
290          }
291 
292        if(ticks_per_second == 0)
293          {
294            rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND,
295                            &ticks_per_second);
296          }
297        rtems_task_wake_after((ticks_per_second+24)/25);
298      }
299       
300    return c;
301} /* _IBMPC_inch */
302
303
304
305
306
307
Note: See TracBrowser for help on using the repository browser.