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

4.104.114.84.95
Last change on this file since d57c04e was d57c04e, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 5, 2000 at 4:49:23 PM

2000-12-05 Eric Valette <valette@…>

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