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

4.104.114.84.95
Last change on this file since 67a2288 was 67a2288, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 23, 1998 at 10:02:34 PM

Patch from Eric VALETTE <valette@…>:

Here is a enhanced version of my previous patch. This patch enables
to potentially share the new interrupt management code for all Intel targets
(pc386, go32 and force386) bsp.

Note : this patch is complete only for pc386. It still needs to

be completed for go32 and force386. I carrefully checked
that anything needed is in for force386 (only some function
name changes for IDT manipulation and GDT segment
manipulation). But anyway I will not be able to test any
of theses targets...

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