📄 pcvt_kbd.c
字号:
#endif /* PCVT_USEKBDSEC */ if (kbd_cmd(KBDINITCMD) != 0) printf("pcvt: doreset() - timeout writing keyboard init command\n"); /* * Discard any stale keyboard activity. The 0.1 boot code isn't * very careful and sometimes leaves a KEYB_R_RESEND. Versions * between 1992 and Oct 1996 didn't have the delay and sometimes * left a KEYB_R_RESEND. */ while (1) { if (inb(CONTROLLER_CTRL) & STATUS_OUTPBF) kbd_response(); else { DELAY(10000); if (!(inb(CONTROLLER_CTRL) & STATUS_OUTPBF)) break; } } /* Start keyboard reset */ opri = spltty (); if (kbd_cmd(KEYB_C_RESET) != 0) { printf("pcvt: doreset() - timeout for keyboard reset command\n"); outb(CONTROLLER_DATA, KEYB_C_RESET); /* force */ } /* Wait for the first response to reset and handle retries */ while ((response = kbd_response()) != KEYB_R_ACK) { if (response < 0) { if(!again) /* print message only once ! */ printf("pcvt: doreset() - response != ack and response < 0 [one time only msg]\n"); response = KEYB_R_RESEND; } else if (response == KEYB_R_RESEND) { if(!again) /* print message only once ! */ printf("pcvt: doreset() - got KEYB_R_RESEND response ... [one time only msg]\n"); } if (response == KEYB_R_RESEND) { if(++again > PCVT_NONRESP_KEYB_TRY) { printf("pcvt: doreset() - Caution - no PC keyboard detected!\n"); keyboard_type = KB_UNKNOWN; splx(opri); return; } if((kbd_cmd(KEYB_C_RESET) != 0) && (once == 0)) { once++; /* print message only once ! */ printf("pcvt: doreset() - timeout for loop keyboard reset command [one time only msg]\n"); outb(CONTROLLER_DATA, KEYB_C_RESET); /* force */ } } } /* Wait for the second response to reset */ while ((response = kbd_response()) != KEYB_R_SELFOK) { if (response < 0) { printf("pcvt: doreset() - response != OK and resonse < 0\n"); /* * If KEYB_R_SELFOK never arrives, the loop will * finish here unless the keyboard babbles or * STATUS_OUTPBF gets stuck. */ break; } } splx (opri);#if PCVT_KEYBDID opri = spltty (); if(kbd_cmd(KEYB_C_ID) != 0) { printf("pcvt: doreset() - timeout for keyboard ID command\n"); keyboard_type = KB_UNKNOWN; } else {r_entry: if((response = kbd_response()) == KEYB_R_MF2ID1) { if((response = kbd_response()) == KEYB_R_MF2ID2) { keyboard_type = KB_MFII; } else if(response == KEYB_R_MF2ID2HP) { keyboard_type = KB_MFII; } else { printf("\npcvt: doreset() - kbdid, response 2 = [%d]\n", response); keyboard_type = KB_UNKNOWN; } } else if (response == KEYB_R_ACK) { goto r_entry; } else if (response == -1) { keyboard_type = KB_AT; } else { printf("\npcvt: doreset() - kbdid, response 1 = [%d]\n", response); } } splx (opri);#else /* PCVT_KEYBDID */ keyboard_type = KB_MFII; /* force it .. */#endif /* PCVT_KEYBDID */#else /* _I386_ISA_KBDIO_H_ */ int c; int m; int s; if (!reset_keyboard) /* no, we are not ready to reset */ return; if (lost_intr_timeout_queued) { untimeout(check_for_lost_intr, (void *)NULL); lost_intr_timeout_queued = 0; } if (kbdc == NULL) kbdc = kbdc_open(IO_KBD); if (!kbdc_lock(kbdc, TRUE)) /* strange, somebody got there first */ return; /* remove any noise */ empty_both_buffers(kbdc, 10); s = spltty(); /* save the current controller command byte */ m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS; c = get_controller_command_byte(kbdc); if (c == -1) { /* CONTROLLER ERROR */ kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); kbdc = NULL; splx(s); printf("pcvt: unable to get the command byte.\n"); return; }#if PCVT_USEKBDSEC /* security enabled */# if PCVT_SCANSET == 2# define KBDINITCMD 0# else /* PCVT_SCANSET != 2 */# define KBDINITCMD KBD_TRANSLATION# endif /* PCVT_SCANSET == 2 */#else /* ! PCVT_USEKBDSEC */ /* security disabled */# if PCVT_SCANSET == 2# define KBDINITCMD KBD_OVERRIDE_KBD_LOCK# else /* PCVT_SCANSET != 2 */# define KBDINITCMD KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK# endif /* PCVT_SCANSET == 2 */#endif /* PCVT_USEKBDSEC */ /* disable the keyboard interrupt and the aux port and interrupt */ if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK, KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT | KBDINITCMD)) { /* CONTROLLER ERROR: there is very little we can do... */ kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); kbdc = NULL; splx(s); printf("pcvt: unable to set the command byte.\n"); return; } splx(s); /* reset keyboard hardware */ ledstate = LEDSTATE_UPDATE_PENDING; if (!reset_kbd(kbdc)) { /* KEYBOARD ERROR */ empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); /* * We could disable the keyboard port and interrupt now... * but, the keyboard may still exist. */ printf("pcvt: failed to reset the keyboard.\n"); /* try to restore the original command byte */ set_controller_command_byte(kbdc, 0xff, c); kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); kbdc = NULL; return; } #if PCVT_KEYBDID keyboard_type = KB_UNKNOWN; if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) == KBD_ACK) { DELAY(10000); /* 10msec delay */ switch (read_kbd_data(kbdc)) { case KEYB_R_MF2ID1: switch (read_kbd_data(kbdc)) { case KEYB_R_MF2ID2: case KEYB_R_MF2ID2HP: keyboard_type = KB_MFII; break; case -1: default: break; } break; case -1: keyboard_type = KB_AT; /* fall through */ default: /* XXX: should we read the second byte? */ empty_both_buffers(kbdc, 10); /* XXX */ break; } } else { /* * The send ID command failed. This error is considered * benign, but may need recovery. */ empty_both_buffers(kbdc, 10); test_controller(kbdc); test_kbd_port(kbdc); }#else /* PCVT_KEYBDID */ keyboard_type = KB_MFII; /* force it .. */#endif /* PCVT_KEYBDID */ /* enable the keyboard port and intr. */ if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { /* CONTROLLER ERROR * This is serious; we are left with the disabled * keyboard intr. */ printf("pcvt: failed to enable the keyboard port and intr.\n"); kbdc_set_device_mask(kbdc, m); kbdc_lock(kbdc, FALSE); kbdc = NULL; return; } kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); kbdc_lock(kbdc, FALSE); update_led(); timeout(check_for_lost_intr, (void *)NULL, hz); lost_intr_timeout_queued = 1;#endif /* !_I386_ISA_KBDIO_H_ */}/*---------------------------------------------------------------------------* * init keyboard code *---------------------------------------------------------------------------*/voidkbd_code_init(void){ doreset(); ovlinit(0); keyboard_is_initialized = 1;}/*---------------------------------------------------------------------------* * init keyboard code, this initializes the keyboard subsystem * just "a bit" so the very very first ddb session is able to * get proper keystrokes - in other words, it's a hack .... *---------------------------------------------------------------------------*/voidkbd_code_init1(void){ doreset(); keyboard_is_initialized = 1;}/*---------------------------------------------------------------------------* * init keyboard overlay table *---------------------------------------------------------------------------*/staticvoid ovlinit(int force){ register i; if(force || ovlinitflag==0) { if(ovlinitflag == 0 && (ovltbl = (Ovl_tbl *)malloc(sizeof(Ovl_tbl) * OVLTBL_SIZE, M_DEVBUF, M_WAITOK)) == NULL) panic("pcvt_kbd: malloc of Ovl_tbl failed"); for(i=0; i<OVLTBL_SIZE; i++) { ovltbl[i].keynum = ovltbl[i].type = 0; ovltbl[i].unshift[0] = ovltbl[i].shift[0] = ovltbl[i].ctrl[0] = ovltbl[i].altgr[0] = 0; ovltbl[i].subu = ovltbl[i].subs = ovltbl[i].subc = ovltbl[i].suba = KBD_SUBT_STR; /* just strings .. */ } for(i=0; i<=MAXKEYNUM; i++) key2ascii[i].type &= KBD_MASK; ovlinitflag = 1; }}/*---------------------------------------------------------------------------* * get original key definition *---------------------------------------------------------------------------*/static intgetokeydef(unsigned key, Ovl_tbl *thisdef){ if(key == 0 || key > MAXKEYNUM) return EINVAL; thisdef->keynum = key; thisdef->type = key2ascii[key].type; if(key2ascii[key].unshift.subtype == STR) { bcopy((u_char *)(key2ascii[key].unshift.what.string), thisdef->unshift, CODE_SIZE); thisdef->subu = KBD_SUBT_STR; } else { bcopy("", thisdef->unshift, CODE_SIZE); thisdef->subu = KBD_SUBT_FNC; } if(key2ascii[key].shift.subtype == STR) { bcopy((u_char *)(key2ascii[key].shift.what.string), thisdef->shift, CODE_SIZE); thisdef->subs = KBD_SUBT_STR; } else { bcopy("",thisdef->shift,CODE_SIZE); thisdef->subs = KBD_SUBT_FNC; } if(key2ascii[key].ctrl.subtype == STR) { bcopy((u_char *)(key2ascii[key].ctrl.what.string), thisdef->ctrl, CODE_SIZE); thisdef->subc = KBD_SUBT_STR; } else { bcopy("",thisdef->ctrl,CODE_SIZE); thisdef->subc = KBD_SUBT_FNC; } /* deliver at least anything for ALTGR settings ... */ if(key2ascii[key].unshift.subtype == STR) { bcopy((u_char *)(key2ascii[key].unshift.what.string), thisdef->altgr, CODE_SIZE); thisdef->suba = KBD_SUBT_STR; } else { bcopy("",thisdef->altgr, CODE_SIZE); thisdef->suba = KBD_SUBT_FNC; } return 0;}/*---------------------------------------------------------------------------* * get current key definition *---------------------------------------------------------------------------*/static intgetckeydef(unsigned key, Ovl_tbl *thisdef){ u_short type = key2ascii[key].type; if(key>MAXKEYNUM) return EINVAL; if(type & KBD_OVERLOAD) *thisdef = ovltbl[key2ascii[key].ovlindex]; else getokeydef(key,thisdef); return 0;}/*---------------------------------------------------------------------------* * translate keynumber and returns ptr to associated ascii string * if key is bound to a function, executes it, and ret empty ptr *---------------------------------------------------------------------------*/static u_char *xlatkey2ascii(U_short key){ static u_char capchar[2] = {0, 0};#if PCVT_META_ESC static u_char metachar[3] = {0x1b, 0, 0};#else static u_char metachar[2] = {0, 0};#endif static Ovl_tbl thisdef; int n; void (*fnc)(void); if(key==0) /* ignore the NON-KEY */ return 0; getckeydef(key&0x7F, &thisdef); /* get the current ASCII value */ thisdef.type &= KBD_MASK; if(key&0x80) /* special handling of ALT-KEYPAD */ { /* is the ALT Key released? */ if(thisdef.type==KBD_META || thisdef.type==KBD_ALTGR) { if(altkpflag) /* have we been in altkp mode? */ { capchar[0] = altkpval; altkpflag = 0; altkpval = 0; return capchar; } } return 0; } switch(thisdef.type) /* convert the keys */ { case KBD_BREAK: case KBD_ASCII: case KBD_FUNC: fnc = NULL; more_chars = NULL; if(altgr_down) { more_chars = (u_char *)thisdef.altgr; } else if(!ctrl_down && (shift_down || vsp->shift_lock)) { if(key2ascii[key].shift.subtype == STR) more_chars = (u_char *)thisdef.shift; else fnc = key2ascii[key].shift.what.func; } else if(ctrl_down) { if(key2ascii[key].ctrl.subtype == STR) more_chars = (u_char *)thisdef.ctrl; else fnc = key2ascii[key].ctrl.what.func; } else { if(key2ascii[key].unshift.subtype == STR) more_chars = (u_char *)thisdef.unshift; else fnc = key2ascii[key].unshift.what.func; } if(fnc) (*fnc)(); /* execute function */ if((more_chars != NULL) && (more_chars[1] == 0)) { if(vsp->caps_lock && more_chars[0] >= 'a' && more_chars[0] <= 'z') { capchar[0] = *more_chars - ('a'-'A'); more_chars = capchar; } if(meta_down) {#if PCVT_META_ESC metachar[1] = *more_chars;#else metachar[0] = *more_chars | 0x80;#endif more_chars = metachar; } } return(more_chars); case KBD_KP: fnc = NULL; more_chars = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -