Subversion Repositories shark

Rev

Rev 105 | Rev 927 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
105 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
398 giacomo 23
 CVS :        $Id: keyb.c,v 1.2 2004-01-17 13:17:52 giacomo Exp $
105 pj 24
 
25
 File:        $File$
398 giacomo 26
 Revision:    $Revision: 1.2 $
27
 Last update: $Date: 2004-01-17 13:17:52 $
105 pj 28
 ------------
29
 
30
 Author:      Giuseppe Lipari
31
 Start date:  19/6/96
32
 
33
 File:        Keyb.C
34
 Revision:    1.5.1
35
 
36
 Last update  : 14/Apr/1999
37
 
38
 This file contains :
39
   -- A fast handler that get the scan code from the key interface      
40
   and put it in a port (non blocking) ; Inside this handler we can't  
41
   make any primitive call; it runs with interrupt enabled, so that the
42
   timer cannot be blocked. Its priority is 1 (from hardware).          
43
   -- A sporadic soft process that gets the data from the port and      
44
   tries to recognize any scan code. With the help of a table that varies
45
   from keyboad to keyboard (e.g. italian vs american) it puts the ascii
46
   code intoanother port, with a byte that indicates the pression of any
47
   control key (Shift, Ctrl, Alt). I tried to make the initialization  
48
   of this table as standard as possible, so that one has to change only
49
   the include file with all the codes                                  
50
   -- Some functions (exported) to initialize the interface and get the
51
   ascii code
52
 
53
   Revision 1.4 (Gerardo) Added support for italian keyboard; required
54
        to add a new status variable rightalt to cope with italian keybs
55
        assignment! Added the keyb_set_map function to select the keymaps
56
        and finally build the english & italian keymaps
57
 
58
   Revision 1.5 (Giorgi)
59
 
60
   Split the file into keyb.c and 8042.c:
61
   8042.c low level hardware interface
62
   keyb.c user interface to kerboard routines
63
   (8042.c is the "source" of data that keyb.c must interpretate)
64
 
65
   Modification made:
66
   -- fast handler remove (now in 8042.c)
67
   -- all function that make direct I/O with hardware now in 8042.c
68
   -- keyb_init() modified (to interfaces with 8042.c)
69
   -- key_sendKeyCmd() removed; key_sendCtrCmd() removed
70
   -- scanCode() & KeyProc modified (keyboard ACK are tested in KeyProc)
71
   -- actled() removed (now in 8042.c with name 8042_keyboardleds); all
72
      reference changed
73
   -- Key_1 port removed (comunication in handled by functions in 8042.c)
74
   -- added functions to enable/disable keyboard
75
 
76
   PS: the modification are marked with "MG"
77
 
78
   Revision 1.5.1 (Giorgi)
79
 
80
   Modification to compile on 3.2.0
81
   -- added wcet time to all task
82
   -- RECEIVE port now are STREAM port
83
 
84
**/
85
 
86
/*
87
 * Copyright (C) 2000 Paolo Gai
88
 *
89
 * This program is free software; you can redistribute it and/or modify
90
 * it under the terms of the GNU General Public License as published by
91
 * the Free Software Foundation; either version 2 of the License, or
92
 * (at your option) any later version.
93
 *
94
 * This program is distributed in the hope that it will be useful,
95
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
96
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
97
 * GNU General Public License for more details.
98
 *
99
 * You should have received a copy of the GNU General Public License
100
 * along with this program; if not, write to the Free Software
101
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
102
 *
103
 */
104
 
105
//#define __KEYB_DEBUG__ 1
106
 
107
//#include <string.h>
108
//#include <stdlib.h>
109
//#include <cons.h>
110
 
111
#include <kernel/kern.h>
112
#include <signal.h>
113
#include <modules/hartport.h>
114
 
115
#include <drivers/keyb.h>
116
#include <drivers/keycode.h>
117
#include "8042.h"
118
 
119
char engMap[] = {
120
  '1','2','3','4','5','6','7','8','9','0',
121
  '!','@','#','$','%','^','&','*','(',')',
122
  '-','_','=','+','[','{',']','}',';',':','\'','\"','`','~','/','?',',',
123
  '<','.','>','\\','|',' ',' ',8,8,9,9,27,27,13,13,24,
124
  '1','2','3','4','5','6','7','8','9','0','.','+','*','/','-','+','*','-',
125
  'a','A','b','B','c','C','d','D','e','E','f','F','g','G','h','H','i',
126
  'I','j','J','k','K','l','L','m','M','n','N','o','O','p','P','q','Q',
127
  'r','R','s','S','t','T','u','U','v','V','w','W','x','X','y','Y','z','Z',
128
  /*
129
    These are the strange keys used in the italian keyboard
130
    When you press Alt-Right to obtain [,], @ or #. They are left
131
    unbind with English Keyboard
132
    */
133
  ' ',' ',' ',' '
134
};
135
 
136
char itaMap[] = {
137
  '1','2','3','4','5','6','7','8','9','0',
138
  '!','\"','','$','%','&','/','(',')','=',
139
  '\'','?','','^','','','+','*','','','','','\\','|','<','_',',',
140
  ':','.',';','','',' ',' ',8,8,9,9,27,27,13,13,24,
141
  '1','2','3','4','5','6','7','8','9','0','.','+','*','/','-','+','*','-',
142
  'a','A','b','B','c','C','d','D','e','E','f','F','g','G','h','H','i',
143
  'I','j','J','k','K','l','L','m','M','n','N','o','O','p','P','q','Q',
144
  'r','R','s','S','t','T','u','U','v','V','w','W','x','X','y','Y','z','Z',
145
  /*
146
    These are the strange keys used in the italian keyboard
147
    When you press Alt-Right to obtain [,], @ or #
148
    */
149
  '[',']','@','#'
150
};
151
 
398 giacomo 152
#define MAX_KEY_EXC     25
105 pj 153
 
154
static struct keyexctable {
155
  KEY_EVT evt;
156
  void (*func)(KEY_EVT *k);
157
} keyExcTable[MAX_KEY_EXC];
158
 
159
static int lastExc;
160
 
161
/* the following tables contains the ascii code corresponding to the    */
162
/* scan codes, with shift & no shift...                                 */
163
static char keyTable[NUM_OF_KEY];
164
static char keyShiftTable[NUM_OF_KEY];
165
static char keyRightAltTable[NUM_OF_KEY];
166
 
167
static char *actualMap = engMap;
168
 
169
/* Status variables */
170
static BYTE e0 = FALSE;
171
static BYTE sh = FALSE;
172
static BYTE rightalt = FALSE;
173
static BYTE cps = FALSE;
174
static BYTE numlock = TRUE;
175
static BYTE scrolllock = FALSE;
176
static int keyb_installed = FALSE;
177
 
178
/* Keyboard Flags (if shift alt or control are pressed...); */
179
static BYTE keyFlag = 0x00;
180
 
181
/* Communication port between the handler & the extern process  */
182
/* MG: port not needed! */
183
//static PORT keyHandPort, keyProcPort;
184
 
185
/* Communication port between the extern process & the user     */
186
static PORT pkeyPort, ukeyPort;
187
 
188
/* This function get a scan code, return an ascii code and set          */
189
/* the status vars in order to handle the special keys of the AT keyboard */
190
/* (I write this code several time !!). When it finds a special code    */
191
/* (Insert, Del, Up, Down, ecc) it return a code with the first byte    */
192
/* at ffh and the second byte with the scan code, while normally it     */
193
/* return only the ascii code                                           */
194
WORD scanCode(BYTE c)
195
{
196
  /* if it's an ack, advice the actLed routine */
197
  /* MG: test removed (it's in "KeyProc") */
198
  //if (c == 0xfa) actLed(0);
199
 
200
  /* If the previous key was an 0xe0...       */
201
  if (e0) {
202
    /* throw away the pairs 0xe0-0x2a and 0xe0-0xaa */
203
    if (c == 0x2a || c == 0xaa) {
204
      e0 = FALSE;
205
      return 0;
206
    }
207
    /* throw away the pairs 0xe0-0x36 and 0xe0-0xb6 */
208
    if (c == 0x36 || c == 0xb6) {
209
      e0 = FALSE;
210
      return 0;
211
    }
212
    /* if it's a break code ... */
213
    else if (c & 0x80) {
214
      e0 = FALSE;
215
      /* Right Alt */
216
      if (c == (KEY_ALTL | 0x80)) {
217
        keyFlag = keyFlag & (!ALTR_BIT);
218
        rightalt = FALSE;
219
      }
220
      /* Right Ctrl */
221
      else if (c == (KEY_CTRLL | 0x80)) {
222
        keyFlag = keyFlag & (!CNTR_BIT);
223
      }
224
      return 0;
225
    }
226
    else {
227
      e0 = FALSE;
228
      /* Right Alt */
229
      if (c == KEY_ALTL) {
230
        keyFlag |= ALTR_BIT ;
231
        rightalt = TRUE;
232
        return 0;
233
      }
234
      /* Right Ctrl */
235
      else if (c == KEY_CTRLL) {
236
        keyFlag |= CNTR_BIT ;
237
        return 0;
238
      }
239
      /* Numeric keypad */
240
      else if (c == PAD_SCRLOCK) return keyTable[c];
241
      else if (c == KEY_ENT) return keyTable[c];
242
      /* simply return scan code */
243
      else return(0xff00 | c);
244
    }
245
  }
246
  else {
247
    /* it's an 0xe0, we must remember */
248
    if (c == 0xe0) {
249
      e0 = TRUE;
250
      return 0;
251
    }
252
    else if (c == KEY_SHL || c == KEY_SHR) {
253
      /* it's the shift : adjust flags */
254
      sh = TRUE;
255
      if (c == KEY_SHL) keyFlag = keyFlag | SHFL_BIT ;
256
      else if (c == KEY_SHR) keyFlag = keyFlag | SHFR_BIT ;
257
      return 0;
258
    }
259
    else if (c == (KEY_SHL | 0x80) || c == (KEY_SHR | 0x80)) {
260
      /* it's the shift break code */
261
      sh = FALSE;
262
      if (c == (KEY_SHL | 0x80)) keyFlag = keyFlag & (!SHFL_BIT);
263
      else if (c == (KEY_SHR | 0x80)) keyFlag = keyFlag & (!SHFR_BIT);
264
      return 0;
265
    }
266
    else if (c == KEY_SCRLOCK) {
267
      if (scrolllock == TRUE) scrolllock = FALSE;
268
      else scrolllock = TRUE;
269
      /* light the scroll lock led */
270
      /* MG: changed */
271
      C8042_keyboardleds(numlock,cps,scrolllock);
272
      return 0;
273
    }
274
  }
275
 
276
  /* Hovewer ...*/
277
  if (c == KEY_CPSLOCK) {
278
    if (cps == TRUE) cps = FALSE;
279
    else cps = TRUE;   
280
    /* MG: changed */
281
    C8042_keyboardleds(numlock,cps,scrolllock);
282
    return 0;
283
  }
284
  if (c == PAD_NUMLOCK) {
285
    if (numlock == TRUE) numlock = FALSE;
286
    else numlock = TRUE;
287
    /* MG: changed */
288
    C8042_keyboardleds(numlock,cps,scrolllock);
289
    return 0;
290
  }
291
  if (c == KEY_CTRLL) {
292
    keyFlag = keyFlag | CNTL_BIT ;
293
    return 0;
294
  }
295
  else if (c == KEY_ALTL) {
296
    keyFlag = keyFlag | ALTL_BIT ;
297
    return 0;
298
  }
299
  else if (c == (KEY_CTRLL | 0x80)) {
300
    keyFlag = keyFlag & (!CNTL_BIT);
301
    return 0;
302
  }
303
  else if (c == (KEY_ALTL | 0x80)) {
304
    keyFlag = keyFlag & (!ALTL_BIT);
305
    return 0;
306
  }
307
  else if (c & 0x80) {
308
    return 0;
309
  }
310
  else if ((c == PAD_INS) || (c == PAD_END) || (c == PAD_DEL) ||
311
           (c == PAD_DOWN) || (c == PAD_PGDW) || (c == PAD_LEFT) ||
312
           (c == PAD_5) || (c == PAD_RIGHT) || (c == PAD_HOME) ||
313
           (c == PAD_UP) || (c == PAD_PGUP)) {
314
    if (numlock || sh) return keyShiftTable[c];
315
    else return (0xff00 | c);
316
  }
317
  else if (cps &&
318
           (((c >= KEY_Q) && (c <= KEY_P)) ||
319
            ((c >= KEY_A) && (c <= KEY_L)) ||
320
            ((c >= KEY_Z) && (c <= KEY_M))) ) {
321
    if (sh) return keyTable[c];
322
    else return keyShiftTable[c];
323
  }
324
  else if (sh) return keyShiftTable[c];
325
  else if (rightalt) return keyRightAltTable[c];
326
  else return keyTable[c];
327
}
328
 
329
TASK keyProc(void)
330
{
331
  WORD code;
332
  BYTE dato,found;
333
  KEY_EVT dt;
334
  int i,res;
335
 
336
  while (1) {
337
//    kern_printf("K");
338
    /* MG: used C8042_keyboardget() */
339
    res=C8042_keyboardget(&dato,NON_BLOCK);
340
    if (res) {
341
      code = scanCode(dato);
342
      if (code != 0) {
343
        /* if it's a scan code , set the right bit ...*/
344
        if (code & 0xff00) dt.flag = (keyFlag | SCAN_BIT);
345
        /* ... else simply send the keyFlag status*/
346
        else dt.flag = keyFlag;
347
        dt.ascii = (BYTE)(code & 0x00FF);
348
        dt.scan  = dato;
349
        found = FALSE;
350
        for (i = 0; i < lastExc; i++)
351
          if ((keyExcTable[i].evt.scan == dt.scan) && (keyExcTable[i].evt.flag == dt.flag)) {
352
            keyExcTable[i].func(&dt);
353
            found = TRUE;
354
          }
355
        /* when the port is full, data is lost */
356
        if (!found) port_send(pkeyPort,(BYTE *)(&dt),NON_BLOCK);
357
      }
358
    }
359
    task_endcycle();
360
  }
361
}
362
 
363
void keyb_set_map(char *t)
364
{
365
  actualMap = t;
366
 
367
  keyTable[KEY_1] = actualMap[0];
368
  keyTable[KEY_2] = actualMap[1];
369
  keyTable[KEY_3] = actualMap[2];
370
  keyTable[KEY_4] = actualMap[3];
371
  keyTable[KEY_5] = actualMap[4];
372
  keyTable[KEY_6] = actualMap[5];
373
  keyTable[KEY_7] = actualMap[6];
374
  keyTable[KEY_8] = actualMap[7];
375
  keyTable[KEY_9] = actualMap[8];
376
  keyTable[KEY_0] = actualMap[9];
377
 
378
  keyShiftTable[KEY_1] = actualMap[10];
379
  keyShiftTable[KEY_2] = actualMap[11];
380
  keyShiftTable[KEY_3] = actualMap[12];
381
  keyShiftTable[KEY_4] = actualMap[13];
382
  keyShiftTable[KEY_5] = actualMap[14];
383
  keyShiftTable[KEY_6] = actualMap[15];
384
  keyShiftTable[KEY_7] = actualMap[16];
385
  keyShiftTable[KEY_8] = actualMap[17];
386
  keyShiftTable[KEY_9] = actualMap[18];
387
  keyShiftTable[KEY_0] = actualMap[19];
388
 
389
  keyTable[KEY_SUB] = actualMap[20];
390
  keyShiftTable[KEY_SUB] = actualMap[21];
391
  keyTable[KEY_PLUS] = actualMap[22];
392
  keyShiftTable[KEY_PLUS] = actualMap[23];
393
  keyTable[KEY_BRL] = actualMap[24];
394
  keyShiftTable[KEY_BRL] = actualMap[25];
395
  keyTable[KEY_BRR] = actualMap[26];
396
  keyShiftTable[KEY_BRR] = actualMap[27];
397
  keyTable[KEY_COL] = actualMap[28];
398
  keyShiftTable[KEY_COL] = actualMap[29];
399
  keyTable[KEY_API] = actualMap[30];
400
  keyShiftTable[KEY_API] = actualMap[31];
401
  keyTable[KEY_TIL] = actualMap[32];
402
  keyShiftTable[KEY_TIL] = actualMap[33];
403
  keyTable[KEY_SLH] = actualMap[34];
404
  keyShiftTable[KEY_SLH] = actualMap[35];
405
  keyTable[KEY_LT] = actualMap[36];
406
  keyShiftTable[KEY_LT] = actualMap[37];
407
  keyTable[KEY_GT] = actualMap[38];
408
  keyShiftTable[KEY_GT] = actualMap[39];
409
 
410
  keyTable[KEY_BSL] = actualMap[40];
411
  keyShiftTable[KEY_BSL] = actualMap[41];
412
  keyTable[KEY_SPC] = actualMap[42];
413
  keyShiftTable[KEY_SPC] = actualMap[43];
414
 
415
  keyTable[KEY_BKS] = actualMap[44];
416
  keyShiftTable[KEY_BKS] = actualMap[45];
417
  keyTable[KEY_TAB] = actualMap[46];
418
  keyShiftTable[KEY_TAB] = actualMap[470];
419
  keyTable[KEY_ESC] = actualMap[48];
420
  keyShiftTable[KEY_ESC] = actualMap[49];
421
  keyTable[KEY_ENT] = actualMap[50];
422
  keyShiftTable[KEY_ENT] = actualMap[51];
423
 
424
  keyShiftTable[KEY_DEL] = actualMap[52];
425
  keyShiftTable[PAD_END] = actualMap[53];
426
  keyShiftTable[PAD_DOWN] = actualMap[54];
427
  keyShiftTable[PAD_PGDW] = actualMap[55];
428
  keyShiftTable[PAD_LEFT] = actualMap[56];
429
  keyShiftTable[PAD_5] = actualMap[57];
430
  keyShiftTable[PAD_RIGHT] = actualMap[58];
431
  keyShiftTable[PAD_HOME] = actualMap[59];
432
  keyShiftTable[PAD_UP] = actualMap[60];
433
  keyShiftTable[PAD_PGUP] = actualMap[61];
434
  keyShiftTable[PAD_INS] = actualMap[62];
435
  keyShiftTable[PAD_DEL] = actualMap[63];
436
 
437
  keyTable[PAD_PLUS] = actualMap[64];
438
  keyTable[PAD_AST] = actualMap[65];
439
  keyTable[PAD_SCRLOCK] = actualMap[66];
440
  keyTable[PAD_SUB] = actualMap[67];
441
 
442
  keyShiftTable[PAD_PLUS] = actualMap[68];
443
  keyShiftTable[PAD_AST] = actualMap[69];
444
  keyShiftTable[PAD_SUB] = actualMap[70];
445
 
446
  keyTable[KEY_A] = actualMap[71];
447
  keyShiftTable[KEY_A] = actualMap[72];
448
  keyTable[KEY_B] = actualMap[73];
449
  keyShiftTable[KEY_B] = actualMap[74];
450
  keyTable[KEY_C] = actualMap[75];
451
  keyShiftTable[KEY_C] = actualMap[76];
452
  keyTable[KEY_D] = actualMap[77];
453
  keyShiftTable[KEY_D] = actualMap[78];
454
  keyTable[KEY_E] = actualMap[79];
455
  keyShiftTable[KEY_E] = actualMap[80];
456
  keyTable[KEY_F] = actualMap[81];
457
  keyShiftTable[KEY_F] = actualMap[82];
458
  keyTable[KEY_G] = actualMap[83];
459
  keyShiftTable[KEY_G] = actualMap[84];
460
  keyTable[KEY_H] = actualMap[85];
461
  keyShiftTable[KEY_H] = actualMap[86];
462
  keyTable[KEY_I] = actualMap[87];
463
  keyShiftTable[KEY_I] =  actualMap[88];
464
  keyTable[KEY_J] = actualMap[89];
465
  keyShiftTable[KEY_J] = actualMap[90];
466
  keyTable[KEY_K] = actualMap[91];
467
  keyShiftTable[KEY_K] = actualMap[82];
468
  keyTable[KEY_L] = actualMap[93];
469
  keyShiftTable[KEY_L] = actualMap[94];
470
  keyTable[KEY_M] = actualMap[95];
471
  keyShiftTable[KEY_M] = actualMap[96];
472
  keyTable[KEY_N] = actualMap[97];
473
  keyShiftTable[KEY_N] = actualMap[98];
474
  keyTable[KEY_O] = actualMap[99];
475
  keyShiftTable[KEY_O] = actualMap[100];
476
  keyTable[KEY_P] = actualMap[101];
477
  keyShiftTable[KEY_P] = actualMap[102];
478
  keyTable[KEY_Q] = actualMap[103];
479
  keyShiftTable[KEY_Q] = actualMap[104];
480
  keyTable[KEY_R] = actualMap[105];
481
  keyShiftTable[KEY_R] = actualMap[106];
482
  keyTable[KEY_S] = actualMap[107];
483
  keyShiftTable[KEY_S] = actualMap[108];
484
  keyTable[KEY_T] = actualMap[109];
485
  keyShiftTable[KEY_T] = actualMap[110];
486
  keyTable[KEY_U] = actualMap[111];
487
  keyShiftTable[KEY_U] = actualMap[112];
488
  keyTable[KEY_V] = actualMap[113];
489
  keyShiftTable[KEY_V] = actualMap[114];
490
  keyTable[KEY_W] = actualMap[115];
491
  keyShiftTable[KEY_W] = actualMap[116];
492
  keyTable[KEY_X] = actualMap[117];
493
  keyShiftTable[KEY_X] = actualMap[118];
494
  keyTable[KEY_Y] = actualMap[119];
495
  keyShiftTable[KEY_Y] = actualMap[120];
496
  keyTable[KEY_Z] = actualMap[121];
497
  keyShiftTable[KEY_Z] = actualMap[122];
498
 
499
  keyRightAltTable[KEY_BRL] = actualMap[123];
500
  keyRightAltTable[KEY_BRR] = actualMap[124];
501
  keyRightAltTable[KEY_COL] = actualMap[125];
502
  keyRightAltTable[KEY_API] = actualMap[126];
503
}
504
 
505
/* default function called on ctrl-c */
506
void default_ctrlChandler(KEY_EVT *k)
507
{
508
  set_active_page(0);
509
  set_visual_page(0);
510
  cputs("Ctrl-C pressed!\n");
511
  sys_end();
512
//  exit(1);
513
}
514
 
515
/* This is the interface to application */
516
/* Initialize keyboard driver */
517
/* MG: this function return: */
518
/*  0  - OK */
519
/*  <0 - error code */
520
 
521
/* TRUE when the 8042 keyboard initialization done */
522
static int init8042flag=FALSE;
523
 
524
 
525
/* keyboard task PID */
526
static PID keybpid;
527
 
528
int KEYB_init(KEYB_PARMS *s)
529
{
530
  KEYB_PARMS kparms=BASE_KEYB;
531
  WORD i;
532
  int status=0;
533
 
534
  SOFT_TASK_MODEL base_m;
535
  TASK_MODEL *m;
536
 
537
  if (keyb_installed) return 0;
538
 
539
  for (i = 0; i < NUM_OF_KEY; i++) {
540
    keyTable[i] = 0;
541
    keyShiftTable[i] = 0;
542
  }
543
 
544
  /* if a NULL is passed */
545
  if (s==NULL) s=&kparms;
546
 
547
  /* keymap */
548
  if (s->keybmap==(char*)KEYB_DEFAULT) s->keybmap=engMap;
549
  keyb_set_map(s->keybmap);
550
 
551
  /* MG: Key_1 port not needed! */
552
  //keyHandPort = port_create("Key_1",1,50,RECEIVE,WRITE);
553
  //keyProcPort = port_connect("Key_1",1,RECEIVE,READ);
554
 
555
  /* MG: changed RECEIVE to STREAM port - added a failure test */
556
  pkeyPort = port_create("KeybPort",3,20,STREAM,WRITE);
557
  if (pkeyPort==-1) return -2;
558
  ukeyPort = port_connect("KeybPort",3,STREAM,READ);
559
  if (ukeyPort==-1) {
560
    port_delete(pkeyPort);
561
    return -3;
562
  }
563
 
564
  /* remove all key pressed handlers */
565
  lastExc = 0;
566
  /* and add a ctrl-c handler if requested */
567
  if (s->ctrlcfunc == (void*)KEYB_DEFAULT)
568
    s->ctrlcfunc=(void*)default_ctrlChandler;
569
  if (s->ctrlcfunc!=NULL) {
570
    KEY_EVT emerg;
571
    emerg.ascii = 'c';
572
    emerg.scan = KEY_C;
573
    emerg.flag = CNTL_BIT;
574
    keyb_hook(emerg,s->ctrlcfunc);
575
    emerg.flag = CNTR_BIT;
576
    keyb_hook(emerg,s->ctrlcfunc);
577
  }
578
 
579
 
580
  /* keyb task */
581
  if (s->tm == (TASK_MODEL *)KEYB_DEFAULT) {
582
    soft_task_default_model(base_m);
583
    soft_task_def_wcet(base_m,2000);
584
    soft_task_def_met(base_m,800);
585
    soft_task_def_period(base_m,25000);
586
    soft_task_def_system(base_m);
587
    soft_task_def_nokill(base_m);
588
    soft_task_def_aperiodic(base_m);
589
    m = (TASK_MODEL *)&base_m;
590
  }
591
  else
592
    m = s->tm;
593
 
594
  //cprintf("keyb task: %li %li %li %li\n",
595
  //        (long)s->pclass,(long)APERIODIC,(long)s->dline,(long)s->wcet);
596
 
597
  keybpid = task_create("KeyTask", keyProc, m, NULL);
598
  if (keybpid==-1) {
599
    port_delete(pkeyPort);
600
    port_delete(ukeyPort);
601
    return -1;
602
  }
603
 
604
  /* MG: 8042 keyboard controller initialization */
605
  if (!init8042flag) {
606
    status=C8042_keyboardinit(keybpid);
607
    if (status) {
608
      port_delete(pkeyPort);
609
      port_delete(ukeyPort);
610
      task_kill(keybpid);
611
      return -4;
612
    }
613
    init8042flag=TRUE;
614
  } else {
615
    C8042_keyboardenable();
616
  }
617
 
618
  /* MG: and keyboard led management */
619
  C8042_keyboardleds(numlock,cps,scrolllock);
620
 
621
  keyb_installed = TRUE;
622
  return status;
623
}
624
 
625
/* KEYB module cleanup
626
 * (must be called if it's needed to re-call keyb_init() with other parameters)
627
 * -1 -> ERROR
628
 */
629
int keyb_end(void)
630
{
631
  if (!keyb_installed) return -1;
632
  C8042_keyboarddisable();
633
  task_kill(keybpid);
634
  port_delete(pkeyPort);
635
  port_delete(ukeyPort);
636
  return 0;
637
}
638
 
639
/* Function that returns the ascii code */
640
int keyb_getch(BYTE wait)
641
{
642
  KEY_EVT c;
643
  BYTE fl;
644
 
645
  fl = port_receive(ukeyPort,&c,wait);
646
  if (fl && !isScanCode(c)) return (c.ascii);
647
  else return 0;
648
}
649
 
650
/* Function that returns a structure containing the flags status, the ascii
651
   code, and the scan code */
652
int keyb_getcode(KEY_EVT *k,BYTE wait)
653
{
654
  return(port_receive(ukeyPort,(BYTE *)(k),wait));
655
}
656
 
657
void keyb_hook(KEY_EVT k, void (*f)(KEY_EVT *k))
658
{
659
  if (lastExc >= MAX_KEY_EXC) return;
660
  keyExcTable[lastExc].evt = k;
661
  keyExcTable[lastExc++].func = f;
662
  return;
663
}
664
 
665
/* MG: this function disable the keyboard */
666
int keyb_disable(void)
667
{
668
  return C8042_keyboarddisable();
669
}
670
 
671
/* MG: this function enable the keyboard */
672
int keyb_enable(void)
673
{
674
  return C8042_keyboardenable();
675
}