/[gxemul]/trunk/src/devices/dev_pckbc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_pckbc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_pckbc.c,v 1.48 2005/08/16 06:49:27 debug Exp $   *  $Id: dev_pckbc.c,v 1.64 2006/01/01 13:17:16 debug Exp $
29   *     *  
30   *  Standard 8042 PC keyboard controller (and a 8242WB PS2 keyboard/mouse   *  Standard 8042 PC keyboard controller (and a 8242WB PS2 keyboard/mouse
31   *  controller), including the 8048 keyboard chip.   *  controller), including the 8048 keyboard chip.
# Line 65  Line 65 
65    
66  #define PS2     100  #define PS2     100
67    
68  #define PCKBC_TICKSHIFT         14  #define PCKBC_TICKSHIFT         15
69    
70  struct pckbc_data {  struct pckbc_data {
71          int             console_handle;          int             console_handle;
# Line 74  struct pckbc_data { Line 74  struct pckbc_data {
74          int             reg[DEV_PCKBC_LENGTH];          int             reg[DEV_PCKBC_LENGTH];
75          int             keyboard_irqnr;          int             keyboard_irqnr;
76          int             mouse_irqnr;          int             mouse_irqnr;
77            int             currently_asserted[2];
78          int             type;          int             type;
79          int             pc_style_flag;          int             pc_style_flag;
80    
# Line 83  struct pckbc_data { Line 84  struct pckbc_data {
84          int             tx_int_enable;          int             tx_int_enable;
85    
86          int             keyscanning_enabled;          int             keyscanning_enabled;
87            int             translation_table;
88          int             state;          int             state;
89          int             cmdbyte;          int             cmdbyte;
90          int             output_byte;          int             output_byte;
# Line 96  struct pckbc_data { Line 98  struct pckbc_data {
98  #define STATE_LDCMDBYTE                 1  #define STATE_LDCMDBYTE                 1
99  #define STATE_RDCMDBYTE                 2  #define STATE_RDCMDBYTE                 2
100  #define STATE_WAITING_FOR_TRANSLTABLE   3  #define STATE_WAITING_FOR_TRANSLTABLE   3
101  #define STATE_LDOUTPUT                  4  #define STATE_WAITING_FOR_F3            4
102  #define STATE_RDOUTPUT                  5  #define STATE_WAITING_FOR_FC            5
103    #define STATE_WAITING_FOR_AUX           6
104    #define STATE_WAITING_FOR_AUX_OUT       7
105    #define STATE_LDOUTPUT                  8
106    #define STATE_RDOUTPUT                  9
107    
108    
109  /*  /*
# Line 132  int pckbc_get_code(struct pckbc_data *d, Line 138  int pckbc_get_code(struct pckbc_data *d,
138    
139    
140  /*  /*
141   *  ascii_to_scancodes():   *  ascii_to_scancodes_type3():
142     *
143     *  Conversion from ASCII codes to default (US) keyboard scancodes.
144     *  (See http://www.computer-engineering.org/ps2keyboard/scancodes3.html)
145     */
146    static void ascii_to_pc_scancodes_type3(int a, struct pckbc_data *d)
147    {
148            int old_head;
149            int p = 0;      /*  port  */
150            int shift = 0, ctrl = 0;
151    
152            if (a >= 'A' && a <= 'Z') { a += 32; shift = 1; }
153            if ((a >= 1 && a <= 26) && (a!='\n' && a!='\t' && a!='\b' && a!='\r'))
154                    { a += 96; ctrl = 1; }
155            if (a=='!')  {  a = '1'; shift = 1; }
156            if (a=='@')  {  a = '2'; shift = 1; }
157            if (a=='#')  {  a = '3'; shift = 1; }
158            if (a=='$')  {  a = '4'; shift = 1; }
159            if (a=='%')  {  a = '5'; shift = 1; }
160            if (a=='^')  {  a = '6'; shift = 1; }
161            if (a=='&')  {  a = '7'; shift = 1; }
162            if (a=='*')  {  a = '8'; shift = 1; }
163            if (a=='(')  {  a = '9'; shift = 1; }
164            if (a==')')  {  a = '0'; shift = 1; }
165            if (a=='_')  {  a = '-'; shift = 1; }
166            if (a=='+')  {  a = '='; shift = 1; }
167            if (a=='{')  {  a = '['; shift = 1; }
168            if (a=='}')  {  a = ']'; shift = 1; }
169            if (a==':')  {  a = ';'; shift = 1; }
170            if (a=='"')  {  a = '\''; shift = 1; }
171            if (a=='|')  {  a = '\\'; shift = 1; }
172            if (a=='<')  {  a = ','; shift = 1; }
173            if (a=='>')  {  a = '.'; shift = 1; }
174            if (a=='?')  {  a = '/'; shift = 1; }
175    
176            if (shift)
177                    pckbc_add_code(d, 0x12, p);
178            if (ctrl)
179                    pckbc_add_code(d, 0x11, p);
180    
181            /*
182             *  Note: The ugly hack used to add release codes for all of these
183             *  keys is as follows:  we remember how much of the kbd buf that
184             *  is in use here, before we add any scancode. After we've added
185             *  one or more scancodes (ie an optional shift + another key)
186             *  then we add 0xf0 + the last scancode _if_ the kbd buf was altered.
187             */
188    
189            old_head = d->head[p];
190    
191            if (a==27)      pckbc_add_code(d, 0x08, p);
192    
193            if (a=='1')     pckbc_add_code(d, 0x16, p);
194            if (a=='2')     pckbc_add_code(d, 0x1e, p);
195            if (a=='3')     pckbc_add_code(d, 0x26, p);
196            if (a=='4')     pckbc_add_code(d, 0x25, p);
197            if (a=='5')     pckbc_add_code(d, 0x2e, p);
198            if (a=='6')     pckbc_add_code(d, 0x36, p);
199            if (a=='7')     pckbc_add_code(d, 0x3d, p);
200            if (a=='8')     pckbc_add_code(d, 0x3e, p);
201            if (a=='9')     pckbc_add_code(d, 0x46, p);
202            if (a=='0')     pckbc_add_code(d, 0x45, p);
203            if (a=='-')     pckbc_add_code(d, 0x4e, p);
204            if (a=='=')     pckbc_add_code(d, 0x55, p);
205    
206            if (a=='\b')    pckbc_add_code(d, 0x29, p);
207    
208            if (a=='\t')    pckbc_add_code(d, 0x0d, p);
209            if (a=='q')     pckbc_add_code(d, 0x15, p);
210            if (a=='w')     pckbc_add_code(d, 0x1d, p);
211            if (a=='e')     pckbc_add_code(d, 0x24, p);
212            if (a=='r')     pckbc_add_code(d, 0x2d, p);
213            if (a=='t')     pckbc_add_code(d, 0x2c, p);
214            if (a=='y')     pckbc_add_code(d, 0x35, p);
215            if (a=='u')     pckbc_add_code(d, 0x3c, p);
216            if (a=='i')     pckbc_add_code(d, 0x43, p);
217            if (a=='o')     pckbc_add_code(d, 0x44, p);
218            if (a=='p')     pckbc_add_code(d, 0x4d, p);
219    
220            if (a=='[')     pckbc_add_code(d, 0x54, p);
221            if (a==']')     pckbc_add_code(d, 0x5b, p);
222    
223            if (a=='\n' || a=='\r') pckbc_add_code(d, 0x5a, p);
224    
225            if (a=='a')     pckbc_add_code(d, 0x1c, p);
226            if (a=='s')     pckbc_add_code(d, 0x1b, p);
227            if (a=='d')     pckbc_add_code(d, 0x23, p);
228            if (a=='f')     pckbc_add_code(d, 0x2b, p);
229            if (a=='g')     pckbc_add_code(d, 0x34, p);
230            if (a=='h')     pckbc_add_code(d, 0x33, p);
231            if (a=='j')     pckbc_add_code(d, 0x3b, p);
232            if (a=='k')     pckbc_add_code(d, 0x42, p);
233            if (a=='l')     pckbc_add_code(d, 0x4b, p);
234    
235            if (a==';')     pckbc_add_code(d, 0x4c, p);
236            if (a=='\'')    pckbc_add_code(d, 0x52, p);
237    /*      if (a=='~')     pckbc_add_code(d, 0x29, p);  ?  */
238            if (a=='\\')    pckbc_add_code(d, 0x5c, p);
239    
240            if (a=='z')     pckbc_add_code(d, 0x1a, p);
241            if (a=='x')     pckbc_add_code(d, 0x22, p);
242            if (a=='c')     pckbc_add_code(d, 0x21, p);
243            if (a=='v')     pckbc_add_code(d, 0x2a, p);
244            if (a=='b')     pckbc_add_code(d, 0x32, p);
245            if (a=='n')     pckbc_add_code(d, 0x31, p);
246            if (a=='m')     pckbc_add_code(d, 0x3a, p);
247    
248            if (a==',')     pckbc_add_code(d, 0x41, p);
249            if (a=='.')     pckbc_add_code(d, 0x49, p);
250            if (a=='/')     pckbc_add_code(d, 0x4a, p);
251    
252            if (a==' ')     pckbc_add_code(d, 0x29, p);
253    
254            /*  Add release code, if a key was pressed:  */
255            if (d->head[p] != old_head) {
256                    int code = d->key_queue[p][d->head[p]];
257                    pckbc_add_code(d, 0xf0, p);
258                    pckbc_add_code(d, code, p);
259            }
260    
261            /*  Release shift and ctrl:  */
262            if (shift) {
263                    pckbc_add_code(d, 0xf0, p);
264                    pckbc_add_code(d, 0x12, p);
265            }
266            if (ctrl) {
267                    pckbc_add_code(d, 0xf0, p);
268                    pckbc_add_code(d, 0x11, p);
269            }
270    }
271    
272    
273    /*
274     *  ascii_to_scancodes_type2():
275   *   *
276   *  Conversion from ASCII codes to default (US) keyboard scancodes.   *  Conversion from ASCII codes to default (US) keyboard scancodes.
277   *  (See http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html)   *  (See http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html)
278     *
279     *  NOTE/TODO: This seems to be type 2, not type 1.
280   */   */
281  static void ascii_to_pc_scancodes(int a, struct pckbc_data *d)  static void ascii_to_pc_scancodes_type2(int a, struct pckbc_data *d)
282  {  {
283          int old_head;          int old_head;
284          int p = 0;      /*  port  */          int p = 0;      /*  port  */
285          int shift = 0, ctrl = 0;          int shift = 0, ctrl = 0;
286    
287            if (d->translation_table == 3) {
288                    ascii_to_pc_scancodes_type3(a, d);
289                    return;
290            }
291    
292            if (d->translation_table != 2) {
293                    fatal("[ ascii_to_pc_scancodes: unimplemented type! ]\n");
294                    return;
295            }
296    
297          if (a >= 'A' && a <= 'Z') { a += 32; shift = 1; }          if (a >= 'A' && a <= 'Z') { a += 32; shift = 1; }
298          if ((a >= 1 && a <= 26) && (a!='\n' && a!='\t' && a!='\b' && a!='\r'))          if ((a >= 1 && a <= 26) && (a!='\n' && a!='\t' && a!='\b' && a!='\r'))
299                  { a += 96; ctrl = 1; }                  { a += 96; ctrl = 1; }
300    
301            if (a=='!')  {  a = '1'; shift = 1; }
302            if (a=='@')  {  a = '2'; shift = 1; }
303            if (a=='#')  {  a = '3'; shift = 1; }
304            if (a=='$')  {  a = '4'; shift = 1; }
305            if (a=='%')  {  a = '5'; shift = 1; }
306            if (a=='^')  {  a = '6'; shift = 1; }
307            if (a=='&')  {  a = '7'; shift = 1; }
308            if (a=='*')  {  a = '8'; shift = 1; }
309            if (a=='(')  {  a = '9'; shift = 1; }
310            if (a==')')  {  a = '0'; shift = 1; }
311            if (a=='_')  {  a = '-'; shift = 1; }
312            if (a=='+')  {  a = '='; shift = 1; }
313            if (a=='{')  {  a = '['; shift = 1; }
314            if (a=='}')  {  a = ']'; shift = 1; }
315            if (a==':')  {  a = ';'; shift = 1; }
316            if (a=='"')  {  a = '\''; shift = 1; }
317            if (a=='|')  {  a = '\\'; shift = 1; }
318            if (a=='<')  {  a = ','; shift = 1; }
319            if (a=='>')  {  a = '.'; shift = 1; }
320            if (a=='?')  {  a = '/'; shift = 1; }
321            if (a=='~')  {  a = '`'; shift = 1; }
322    
323          if (shift)          if (shift)
324                  pckbc_add_code(d, 0x2a, p);                  pckbc_add_code(d, 0x2a, p);
325          else          else
# Line 199  static void ascii_to_pc_scancodes(int a, Line 372  static void ascii_to_pc_scancodes(int a,
372                          pckbc_add_code(d, 0x09, p); }                          pckbc_add_code(d, 0x09, p); }
373          if (a=='(')  {  pckbc_add_code(d, 0x2a, p);          if (a=='(')  {  pckbc_add_code(d, 0x2a, p);
374                          pckbc_add_code(d, 0x0a, p); }                          pckbc_add_code(d, 0x0a, p); }
         if (a==')')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x0b, p); }  
         if (a=='_')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x0c, p); }  
         if (a=='+')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x0d, p); }  
375    
376          if (a=='\b')    pckbc_add_code(d, 0x0e, p);          if (a=='\b')    pckbc_add_code(d, 0x0e, p);
377    
# Line 221  static void ascii_to_pc_scancodes(int a, Line 388  static void ascii_to_pc_scancodes(int a,
388          if (a=='p')     pckbc_add_code(d, 0x19, p);          if (a=='p')     pckbc_add_code(d, 0x19, p);
389    
390          if (a=='[')     pckbc_add_code(d, 0x1a, p);          if (a=='[')     pckbc_add_code(d, 0x1a, p);
         if (a=='{')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x1a, p); }  
391          if (a==']')     pckbc_add_code(d, 0x1b, p);          if (a==']')     pckbc_add_code(d, 0x1b, p);
         if (a=='}')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x1b, p); }  
392    
393          if (a=='\n' || a=='\r') pckbc_add_code(d, 0x1c, p);          if (a=='\n' || a=='\r') pckbc_add_code(d, 0x1c, p);
394    
# Line 240  static void ascii_to_pc_scancodes(int a, Line 403  static void ascii_to_pc_scancodes(int a,
403          if (a=='l')     pckbc_add_code(d, 0x26, p);          if (a=='l')     pckbc_add_code(d, 0x26, p);
404    
405          if (a==';')     pckbc_add_code(d, 0x27, p);          if (a==';')     pckbc_add_code(d, 0x27, p);
         if (a==':')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x27, p); }  
406          if (a=='\'')    pckbc_add_code(d, 0x28, p);          if (a=='\'')    pckbc_add_code(d, 0x28, p);
407          if (a=='"')  {  pckbc_add_code(d, 0x2a, p);          if (a=='`')     pckbc_add_code(d, 0x29, p);
                         pckbc_add_code(d, 0x28, p); }  
         if (a=='~')     pckbc_add_code(d, 0x29, p);  
   
408          if (a=='\\')    pckbc_add_code(d, 0x2b, p);          if (a=='\\')    pckbc_add_code(d, 0x2b, p);
         if (a=='|')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x2b, p); }  
409    
410          if (a=='z')     pckbc_add_code(d, 0x2c, p);          if (a=='z')     pckbc_add_code(d, 0x2c, p);
411          if (a=='x')     pckbc_add_code(d, 0x2d, p);          if (a=='x')     pckbc_add_code(d, 0x2d, p);
# Line 260  static void ascii_to_pc_scancodes(int a, Line 416  static void ascii_to_pc_scancodes(int a,
416          if (a=='m')     pckbc_add_code(d, 0x32, p);          if (a=='m')     pckbc_add_code(d, 0x32, p);
417    
418          if (a==',')     pckbc_add_code(d, 0x33, p);          if (a==',')     pckbc_add_code(d, 0x33, p);
         if (a=='<')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x33, p); }  
419          if (a=='.')     pckbc_add_code(d, 0x34, p);          if (a=='.')     pckbc_add_code(d, 0x34, p);
         if (a=='>')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x34, p); }  
420          if (a=='/')     pckbc_add_code(d, 0x35, p);          if (a=='/')     pckbc_add_code(d, 0x35, p);
         if (a=='?')  {  pckbc_add_code(d, 0x2a, p);  
                         pckbc_add_code(d, 0x35, p); }  
421    
422          if (a==' ')     pckbc_add_code(d, 0x39, p);          if (a==' ')     pckbc_add_code(d, 0x39, p);
423    
# Line 294  void dev_pckbc_tick(struct cpu *cpu, voi Line 444  void dev_pckbc_tick(struct cpu *cpu, voi
444          if (d->in_use && console_charavail(d->console_handle)) {          if (d->in_use && console_charavail(d->console_handle)) {
445                  ch = console_readchar(d->console_handle);                  ch = console_readchar(d->console_handle);
446                  if (ch >= 0)                  if (ch >= 0)
447                          ascii_to_pc_scancodes(ch, d);                          ascii_to_pc_scancodes_type2(ch, d);
448          }          }
449    
450          ints_enabled = d->rx_int_enable;          ints_enabled = d->rx_int_enable;
# Line 311  void dev_pckbc_tick(struct cpu *cpu, voi Line 461  void dev_pckbc_tick(struct cpu *cpu, voi
461                          debug("[ pckbc: interrupt port %i ]\n", port_nr);                          debug("[ pckbc: interrupt port %i ]\n", port_nr);
462                          cpu_interrupt(cpu, port_nr==0? d->keyboard_irqnr                          cpu_interrupt(cpu, port_nr==0? d->keyboard_irqnr
463                              : d->mouse_irqnr);                              : d->mouse_irqnr);
464                            d->currently_asserted[port_nr] = 1;
465                  } else {                  } else {
466                          cpu_interrupt_ack(cpu, port_nr==0? d->keyboard_irqnr                          if (d->currently_asserted[port_nr])
467                              : d->mouse_irqnr);                                  cpu_interrupt_ack(cpu, port_nr==0?
468                                        d->keyboard_irqnr : d->mouse_irqnr);
469                            d->currently_asserted[port_nr] = 0;
470                  }                  }
471          }          }
472  }  }
# Line 332  static void dev_pckbc_command(struct pck Line 485  static void dev_pckbc_command(struct pck
485                  cmd = d->reg[PS2_TXBUF];                  cmd = d->reg[PS2_TXBUF];
486    
487          if (d->state == STATE_WAITING_FOR_TRANSLTABLE) {          if (d->state == STATE_WAITING_FOR_TRANSLTABLE) {
488                  debug("[ pckbc: switching to translation table 0x%02x ]\n",                  debug("[ pckbc: (port %i) switching to translation table "
489                      cmd);                      "0x%02x ]\n", port_nr, cmd);
490                    switch (cmd) {
491                    case 2:
492                    case 3: d->translation_table = cmd;
493                            break;
494                    default:fatal("[ pckbc: (port %i) translation table "
495                                "0x%02x is NOT YET IMPLEMENTED ]\n",
496                                port_nr, cmd);
497                    }
498                    pckbc_add_code(d, KBR_ACK, port_nr);
499                    d->state = STATE_NORMAL;
500                    return;
501            }
502    
503            if (d->state == STATE_WAITING_FOR_F3) {
504                    debug("[ pckbc: (port %i) received '0xf3' data: "
505                        "0x%02x ]\n", port_nr, cmd);
506                    pckbc_add_code(d, KBR_ACK, port_nr);
507                    d->state = STATE_NORMAL;
508                    return;
509            }
510    
511            if (d->state == STATE_WAITING_FOR_FC) {
512                    debug("[ pckbc: (port %i) received '0xfc' data: "
513                        "0x%02x ]\n", port_nr, cmd);
514                  pckbc_add_code(d, KBR_ACK, port_nr);                  pckbc_add_code(d, KBR_ACK, port_nr);
515                  d->state = STATE_NORMAL;                  d->state = STATE_NORMAL;
516                  return;                  return;
517          }          }
518    
519            if (d->state == STATE_WAITING_FOR_AUX) {
520                    debug("[ pckbc: (port %i) received aux data: "
521                        "0x%02x ]\n", port_nr, cmd);
522                    /*  Echo back.  */
523                    pckbc_add_code(d, cmd, port_nr);
524                    d->state = STATE_NORMAL;
525                    return;
526            }
527    
528            if (d->state == STATE_WAITING_FOR_AUX_OUT) {
529                    debug("[ pckbc: (port %i) received aux out data: "
530                        "0x%02x ]\n", port_nr, cmd);
531                    /*  Echo back.  */
532                    pckbc_add_code(d, cmd, port_nr);
533                    d->state = STATE_NORMAL;
534                    return;
535            }
536    
537          switch (cmd) {          switch (cmd) {
538          case 0x00:          case 0x00:
539                  pckbc_add_code(d, KBR_ACK, port_nr);                  pckbc_add_code(d, KBR_ACK, port_nr);
# Line 362  static void dev_pckbc_command(struct pck Line 557  static void dev_pckbc_command(struct pck
557          case KBC_SETDEFAULT:          case KBC_SETDEFAULT:
558                  pckbc_add_code(d, KBR_ACK, port_nr);                  pckbc_add_code(d, KBR_ACK, port_nr);
559                  break;                  break;
560            case 0xf3:
561                    pckbc_add_code(d, KBR_ACK, port_nr);
562                    d->state = STATE_WAITING_FOR_F3;
563                    break;
564            case 0xfa:      /*  Just ack?  */
565                    pckbc_add_code(d, KBR_ACK, port_nr);
566                    break;
567            case 0xfc:
568                    pckbc_add_code(d, KBR_ACK, port_nr);
569                    d->state = STATE_WAITING_FOR_FC;
570                    break;
571          case KBC_RESET:          case KBC_RESET:
572                  pckbc_add_code(d, KBR_ACK, port_nr);                  pckbc_add_code(d, KBR_ACK, port_nr);
573                  pckbc_add_code(d, KBR_RSTDONE, port_nr);                  pckbc_add_code(d, KBR_RSTDONE, port_nr);
574                  break;                  break;
575          default:          default:
576                  fatal("[ pckbc: UNIMPLEMENTED 8048 command 0x%02x ]\n", cmd);                  fatal("[ pckbc: (port %i) UNIMPLEMENTED 8048 command"
577                        " 0x%02x ]\n", port_nr, cmd);
578          }          }
579  }  }
580    
# Line 375  static void dev_pckbc_command(struct pck Line 582  static void dev_pckbc_command(struct pck
582  /*  /*
583   *  dev_pckbc_access():   *  dev_pckbc_access():
584   */   */
585  int dev_pckbc_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(pckbc)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
586  {  {
587          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
588          int i, port_nr = 0;          int port_nr = 0;
589            size_t i;
590          struct pckbc_data *d = extra;          struct pckbc_data *d = extra;
591    
592          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
593                    idata = memory_readmax64(cpu, data, len);
594    
595  #ifdef PCKBC_DEBUG  #ifdef PCKBC_DEBUG
596          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 456  if (x&1) Line 663  if (x&1)
663                                  }                                  }
664                          }                          }
665                          /*  debug("[ pckbc: read from DATA: 0x%02x ]\n",                          /*  debug("[ pckbc: read from DATA: 0x%02x ]\n",
666                              odata);  */                              (int)odata);  */
667                  } else {                  } else {
668                          debug("[ pckbc: write to DATA:");                          debug("[ pckbc: write to DATA:");
669                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
# Line 505  if (x&1) Line 712  if (x&1)
712                          d->reg[relative_addr] = idata;                          d->reg[relative_addr] = idata;
713    
714                          switch (idata) {                          switch (idata) {
715                            case 0x10:
716                            case 0x11:
717                                    /*  TODO: For now, don't print warnings about
718                                        these. NetBSD sends these.  */
719                                    break;
720                          case K_RDCMDBYTE:                          case K_RDCMDBYTE:
721                                  d->state = STATE_RDCMDBYTE;                                  d->state = STATE_RDCMDBYTE;
722                                  break;                                  break;
# Line 523  if (x&1) Line 735  if (x&1)
735                          case 0xaa:      /*  keyboard self-test  */                          case 0xaa:      /*  keyboard self-test  */
736                                  pckbc_add_code(d, 0x55, port_nr);                                  pckbc_add_code(d, 0x55, port_nr);
737                                  break;                                  break;
738                            case 0xab:      /*  keyboard interface self-test  */
739                                    pckbc_add_code(d, 0x00, port_nr);
740                                    break;
741                          case 0xad:                          case 0xad:
742                                  d->cmdbyte |= KC8_KDISABLE;                                  d->cmdbyte |= KC8_KDISABLE;
743                                  break;                                  break;
# Line 535  if (x&1) Line 750  if (x&1)
750                          case 0xd1:                          case 0xd1:
751                                  d->state = STATE_LDOUTPUT;                                  d->state = STATE_LDOUTPUT;
752                                  break;                                  break;
753                            case 0xd3:      /*  write to auxiliary device
754                                                output buffer  */
755                                    debug("[ pckbc: CONTROL 0xd3, TODO ]\n");
756                                    d->state = STATE_WAITING_FOR_AUX_OUT;
757                                    break;
758                          case 0xd4:      /*  write to auxiliary port  */                          case 0xd4:      /*  write to auxiliary port  */
759                                  debug("[ pckbc: CONTROL 0xd4, TODO ]\n");                                  debug("[ pckbc: CONTROL 0xd4, TODO ]\n");
760                                    d->state = STATE_WAITING_FOR_AUX;
761                                  break;                                  break;
762                          default:                          default:
763                                  fatal("[ pckbc: unknown CONTROL 0x%x ]\n",                                  fatal("[ pckbc: unknown CONTROL 0x%x ]\n",
764                                      idata);                                      (int)idata);
765                                  d->state = STATE_NORMAL;                                  d->state = STATE_NORMAL;
766                          }                          }
767                  }                  }
# Line 550  if (x&1) Line 771  if (x&1)
771           *  8242 (PS2):           *  8242 (PS2):
772           */           */
773    
 /*  
  *  BIG TODO: The following should be rewritten to use dev_pckbc_command()  
  *  etc, like the 8042 code above does.  
  */  
   
774          case PS2 + PS2_TXBUF:          case PS2 + PS2_TXBUF:
775                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
776                          odata = random() & 0xff;                          odata = random() & 0xff;
# Line 565  if (x&1) Line 781  if (x&1)
781                              "0x%llx ]\n", port_nr, (long long)idata);                              "0x%llx ]\n", port_nr, (long long)idata);
782    
783                          /*  Handle keyboard commands:  */                          /*  Handle keyboard commands:  */
784                          switch (idata) {                          d->reg[PS2_TXBUF] = idata;
785                          /*  These are incorrect, the second byte of                          dev_pckbc_command(d, port_nr);
                             commands should be treated better:  */  
                         case 0x00:      /*  second byte of 0xed,  
                                             SGI-IP32's prom  */  
                                 pckbc_add_code(d, 0x03, port_nr);/*  ack  (?) */  
                                 break;  
                         case 0x14:      /*  second byte of 0xfc,  
                                             SGI-IP32's prom  */  
                         case 0x28:      /*  second byte of 0xf3,  
                                             SGI-IP32's prom  */  
                         case 0x76:      /*  third byte of 0xfc,  
                                             SGI-IP32's prom  */  
                         case 0x03:      /*  second byte of  
                                             ATKBD_CMD_GSCANSET (?)  */  
                         case 0x04:  
                                 pckbc_add_code(d, 0x03, port_nr);/*  ?  */  
                                 break;  
   
                         /*  Command bytes:  */  
                         case 0xf0:      /*  ATKBD_CMD_GSCANSET (?)  */  
                                 pckbc_add_code(d, 0x03, port_nr);/*  ?  */  
                                 break;  
                         case 0xf2:      /*  Get keyboard ID  */  
                                 /*  The keyboard should generate 2  
                                     status bytes.  */  
                                 pckbc_add_code(d, 0xab, port_nr);  
                                 pckbc_add_code(d, 0x83, port_nr);  
                                 break;  
                         case 0xed:      /*  "ATKBD_CMD_SETLEDS",  
                                             takes 1 byte arg  */  
                         case 0xf3:      /*  "PSMOUSE_CMD_SETRATE",  
                                             takes 1 byte arg  */  
                         case 0xf4:      /*  "ATKBD_CMD_ENABLE" (or  
                                             PSMOUSE_CMD_ENABLE), no args  */  
                         case 0xf5:      /*  "ATKBD_CMD_RESET_DIS" (keyboard,  
                                             according to Linux sources)  */  
                         case 0xf6:      /*  "PSMOUSE_CMD_RESET_DIS" (mouse,  
                                             according to Linux sources)  */  
                                 /*  TODO: what does this do?  */  
                                 pckbc_add_code(d, 0xfa, port_nr);/*  ack  (?) */  
                                 break;  
                         case 0xfa:      /*  "ATKBD_CMD_SETALL_MBR" (linux)  */  
                                 pckbc_add_code(d, 0xfa, port_nr);/*  ack  (?) */  
                                 break;  
                         case 0xfc:      /*  ?  */  
                                 pckbc_add_code(d, 0xfa, port_nr);/*  ack  (?) */  
                                 break;  
                         case 0xff:      /*  Keyboard reset  */  
                                 /*  The keyboard should generate 2  
                                     status bytes.  */  
                                 pckbc_add_code(d, 0xfa, port_nr);/*  ack  (?) */  
                                 pckbc_add_code(d, 0xaa, port_nr);  
                                         /*  battery ok (?)  */  
                                 break;  
                         default:  
                                 debug("[ pckbc: UNIMPLEMENTED keyboard command"  
                                     " 0x%02x (port %i) ]\n", (int)idata,  
                                     port_nr);  
                         }  
786                  }                  }
787                  break;                  break;
788    
# Line 689  if (x&1) Line 847  if (x&1)
847                  }                  }
848          }          }
849    
850            /*  SGI? TODO: fix  */
851            if (len == 8)
852                    odata |= (odata << 8) | (odata << 16) | (odata << 24) |
853                        (odata << 32) | (odata << 40) | (odata << 48) |
854                        (odata << 56);
855    
856          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
857                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
858    
# Line 718  int dev_pckbc_init(struct machine *machi Line 882  int dev_pckbc_init(struct machine *machi
882          memset(d, 0, sizeof(struct pckbc_data));          memset(d, 0, sizeof(struct pckbc_data));
883    
884          if (type == PCKBC_8242)          if (type == PCKBC_8242)
885                  len = 0x40;                  len = 0x18;
886    
887          if (type == PCKBC_JAZZ) {          if (type == PCKBC_JAZZ) {
888                  type = PCKBC_8042;                  type = PCKBC_8042;
889                  len = DEV_PCKBC_LENGTH + 0x60;                  len = DEV_PCKBC_LENGTH + 0x60;
890          }          }
891    
892          d->type           = type;          d->type              = type;
893          d->keyboard_irqnr = keyboard_irqnr;          d->keyboard_irqnr    = keyboard_irqnr;
894          d->mouse_irqnr    = mouse_irqnr;          d->mouse_irqnr       = mouse_irqnr;
895          d->in_use         = in_use;          d->in_use            = in_use;
896          d->pc_style_flag  = pc_style_flag;          d->pc_style_flag     = pc_style_flag;
897          d->console_handle = console_start_slave_inputonly(machine, "pckbc");          d->translation_table = 2;
898          d->rx_int_enable  = 1;          d->rx_int_enable     = 1;
899          d->output_byte    = 0x02;       /*  A20 enable on PCs  */          d->output_byte       = 0x02;    /*  A20 enable on PCs  */
900    
901            d->console_handle = console_start_slave_inputonly(
902                machine, "pckbc", d->in_use);
903    
904          memory_device_register(mem, "pckbc", baseaddr,          memory_device_register(mem, "pckbc", baseaddr,
905              len, dev_pckbc_access, d, MEM_DEFAULT, NULL);              len, dev_pckbc_access, d, DM_DEFAULT, NULL);
906          machine_add_tickfunction(machine, dev_pckbc_tick, d, PCKBC_TICKSHIFT);          machine_add_tickfunction(machine, dev_pckbc_tick, d, PCKBC_TICKSHIFT);
907    
908          return d->console_handle;          return d->console_handle;

Legend:
Removed from v.12  
changed lines
  Added in v.22

  ViewVC Help
Powered by ViewVC 1.1.26