OOStuBS - Technische Informatik II (TI-II)  2.4
keyctrl.cc
gehe zur Dokumentation dieser Datei
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2  * Technische Informatik II *
3  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4  * *
5  * K E Y B O A R D _ C O N T R O L L E R *
6  * *
7 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8 
9 /* INCLUDES */
10 #include "machine/keyctrl.h"
11 #include "object/lock.h"
12 #include "locking/scopedLock.h"
13 
14 /* GLOBALE VARIABLS */
15 
16 /* STATIC MEMERS */
17 unsigned char Keyboard_Controller::normal_tab[] = {
18  0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b',
19  0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n',
20  0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#',
21  'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0,
22  '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-',
23  0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, '<', 0, 0
24 };
25 
26 unsigned char Keyboard_Controller::shift_tab[] = {
27  0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0,
28  0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0,
29  0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39,
30  'Y', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_', 0,
31  0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '>', 0, 0
33 };
34 
35 unsigned char Keyboard_Controller::alt_tab[] = {
36  0, 0, 0, 253, 0, 0, 0, 0, '{', '[', ']', '}', '\\', 0, 0,
37  0, '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', 0,
38  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39  0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0,
40  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0
42 };
43 
44 unsigned char Keyboard_Controller::asc_num_tab[] = {
45  '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','
46 };
47 
48 unsigned char Keyboard_Controller::scan_num_tab[] = {
49  8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51
50 };
51 
52 /* PRIVATE METHODS */
54  bool done = false;
55 
56  // keys of MF II keyboards start sending one of two prefix bytes
57  if (code == prefix1 || code == prefix2) {
58  prefix = code;
59  return false;
60  }
61 
62  // releasing a key is important for the modifier keys (SHIFT, CTRL, ALT, ...)
63  // break codes from other keys are ignored
64  if (code & break_bit) {
65  // break code of a key is equal to the make code but additionaly the
66  // break_bit is set
67  code &= ~break_bit;
68  switch (code) {
69  case 42:
70  case 54:
71  gather.shift (false);
72  break;
73  case 56:
74  if (prefix == prefix1)
75  gather.alt_right (false);
76  else
77  gather.alt_left (false);
78  break;
79  case 29:
80  if (prefix == prefix1)
81  gather.ctrl_right (false);
82  else
83  gather.ctrl_left (false);
84  break;
85  }
86 
87  // a prefix is only valid for the following code
88  prefix = 0;
89 
90  // returns false since the break codes gives no additional information
91  return false;
92  }
93 
94  // a key has been pressed, if it was a modifier key like SHIFT, ALT, NUM_LOCK
95  // eg. only the internal state is changed. Return value 'false' shows that
96  // the input is not finished yet. If other keys have been pressed the ASCII
97  // and Scancode is read and 'ture' is returned.
98  switch (code) {
99  case 42:
100  case 54:
101  gather.shift (true);
102  break;
103  case 56:
104  if (prefix == prefix1)
105  gather.alt_right (true);
106  else
107  gather.alt_left (true);
108  break;
109  case 29:
110  if (prefix == prefix1)
111  gather.ctrl_right (true);
112  else
113  gather.ctrl_left (true);
114  break;
115  case 58:
118  break;
119  case 70:
122  break;
123  case 69: // NUM_LOCK or BREAK ?
124  if (gather.ctrl_left ()) { // BREAK
125  get_ascii_code ();
126  done = true;
127  } else { // NUM_LOCK
130  }
131  break;
132  default: // other keys
133  // get ASCII codes from table, DONE
134  get_ascii_code ();
135  done = true;
136  }
137 
138  // a prefix is only valid for the following code
139  prefix = 0;
140 
141  if (done)
142  return true;
143  else
144  return false;
145 }
146 
151  if (code == 53 && prefix == prefix1) { // special case scancode 53
152  gather.ascii ('/');
154  } else if (gather.num_lock () && !prefix && code>=71 && code<=83) {
155  gather.ascii (asc_num_tab[code-71]);
156  gather.scancode (scan_num_tab[code-71]);
157  } else if (gather.alt_right ()) {
158  gather.ascii (alt_tab[code]);
159  gather.scancode (code);
160  } else if (gather.shift ()) {
161  gather.ascii (shift_tab[code]);
162  gather.scancode (code);
163  } else if (gather.caps_lock ()) {
164  //Linux CapsLock, nur Buchstaben gross
165  if ((code>=16 && code<=26) || (code>=30 && code<=40) || (code>=44 && code<=50)) {
166  gather.ascii (shift_tab[code]);
167  gather.scancode (code);
168  } else {
169  gather.ascii (normal_tab[code]);
170  gather.scancode (code);
171  }
172  } else {
173  gather.ascii (normal_tab[code]);
174  gather.scancode (code);
175  }
176 }
177 
178 /* PUBLIC METHODS */
179 Keyboard_Controller::Keyboard_Controller () : ctrl_port (0x64), data_port (0x60) {
180  // switch all LEDs off (some PCs switch LEDs on)
181  set_led (caps_lock, false);
182  set_led (scroll_lock, false);
183  set_led (num_lock, false);
184 
185  // set maximal speed and delay of keyboard
186  set_repeat_rate (0, 0);
187 
188  while(true){
189  unsigned char status=ctrl_port.inb();
190  if(status&outb){
191  data_port.inb();
192  continue;
193  }
194  if(!(status&inpb))
195  break;
196  }
197 }
198 
200  int status;
201 
202  // The BIOS has to be told that reset is real and no memory test.
203  *(unsigned short*) 0x472 = 0x1234;
204 
205  // keyboard controller has to send a reset
206  do { // wait until last command was processed
207  status = ctrl_port.inb ();
208  } while ((status & inpb) != 0);
209  ctrl_port.outb (cmd_cpu_reset); // reset
210 }
211 
213  //Var init
214  Key invalid; // invalid default key
215  unsigned char ucStatus;
216 
217  // tests if there is keyboard data
218  ucStatus = ctrl_port.inb ();
219  if( ((ucStatus & outb) != 0) && ((ucStatus & auxb) == 0) ){
220  //get the data and interprete it
221  code = data_port.inb();
222  if(key_decoded ()){
223  return gather;
224  }
225  }
226 
227  return invalid;
228 }
229 
230 void Keyboard_Controller::set_repeat_rate (unsigned char speed, unsigned char delay) {
231 
232  unsigned char status, reply;
233 
234  ScopedLock scopedLock(lock);
235 
236  data_port.outb (cmd_set_speed); // send command to keyboard
237  do {
238  status = ctrl_port.inb (); // wait for reply
239  } while ((status & outb) == 0);
240  reply = data_port.inb (); // get reply from controller
241  if (reply == ack) { // ok
242  data_port.outb (((delay & 3) << 5) | (speed & 31)); // set parameter
243  do {
244  status = ctrl_port.inb (); // wait for reply
245  } while ((status & outb) == 0);
246  reply = data_port.inb (); // get reply from controller
247  }
248 }
249 
250 void Keyboard_Controller::set_led (Leds led, bool on) {
251 
252  unsigned char status, reply;
253 
254  ScopedLock scopedLock(lock);
255 
256  data_port.outb (cmd_set_led); // send command to keyboard
257  do {
258  status = ctrl_port.inb (); // wait for reply
259  } while ((status & outb) == 0);
260  reply = data_port.inb (); // get reply from controller
261  if (reply == ack) { // ok
262  if (on)
263  leds |= led;
264  else
265  leds &= ~led;
266  data_port.outb (leds); // set parameter
267  do {
268  status = ctrl_port.inb (); // wait for reply
269  } while ((status & outb) == 0);
270  reply = data_port.inb (); // get reply from controller
271  }
272 }