diff --git a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp index 3d630d9..b64983e 100644 --- a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp +++ b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp @@ -99,6 +99,16 @@ def _emit_csi_tilde(digit: uint8): _out_push(digit) _out_push(uint8(0x7E)) +# USB HID 等外部来源注入已解码字节,与 PS/2 IRQ 共用同一个 out_buf。 +def inject_byte(b: uint8): + _out_push(b) + +def inject_csi(final: uint8): + _emit_csi(final) + +def inject_csi_tilde(digit: uint8): + _emit_csi_tilde(digit) + # CapsLock 只翻转字母大小写(符号仍由 Shift 决定) def _is_letter_code(code: uint8) -> bool: if code >= uint8(0x10) and code <= uint8(0x19): return True diff --git a/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp b/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp index af8a12c..72e0381 100644 --- a/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp +++ b/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp @@ -2,6 +2,7 @@ import t, c import drivers.usb.usb as usb import drivers.usb.hid.hid as hid import drivers.usb.uhci as uhci +import drivers.input.keyboard.keyboard as keyboard import drivers.serial.uart.serial as serial define KBD_BUF_SIZE = 1024 @@ -22,6 +23,55 @@ kbd_report: hid.hid_kbd_report kbd_prev_keycodes: [6]uint8 kbd_initialized: int = 0 kbd_slot_id: int = -1 +kbd_caps: int = 0 +kbd_first_key: int = 0 + +# HID boot 报告 usage ID (0x04..0x38) -> ASCII;CapsLock / 方向键等在 _decode_press 单独处理。 +hid_ascii: [64]char = [ + '\0', '\0', '\0', '\0', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '\n', '\x1b', '\b', '\t', ' ', + '-', '=', '[', ']', '\\', '\0', ';', '\'', '`', ',', '.', '/', + '\0', '\0', '\0', '\0', '\0', '\0', '\0' +] + +hid_ascii_shift: [64]char = [ + '\0', '\0', '\0', '\0', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '\n', '\x1b', '\b', '\t', ' ', + '_', '+', '{', '}', '|', '\0', ':', '"', '~', '<', '>', '?', + '\0', '\0', '\0', '\0', '\0', '\0', '\0' +] + +# 按下沿调用一次:boot 报告 keycode -> ASCII / ANSI,直接进 PS/2 同一输出队列。 +def _decode_press(code: uint8, modifier: uint8): + global kbd_caps + if code == uint8(0x39): + kbd_caps = kbd_caps ^ 1 + return + if code == uint8(0x52): keyboard.inject_csi(uint8(0x41)) # Up + elif code == uint8(0x51): keyboard.inject_csi(uint8(0x42)) # Down + elif code == uint8(0x4F): keyboard.inject_csi(uint8(0x43)) # Right + elif code == uint8(0x50): keyboard.inject_csi(uint8(0x44)) # Left + elif code == uint8(0x4A): keyboard.inject_csi(uint8(0x48)) # Home + elif code == uint8(0x4D): keyboard.inject_csi(uint8(0x46)) # End + elif code == uint8(0x49): keyboard.inject_csi_tilde(uint8(0x32)) # Insert + elif code == uint8(0x4C): keyboard.inject_csi_tilde(uint8(0x33)) # Delete + elif code == uint8(0x4B): keyboard.inject_csi_tilde(uint8(0x35)) # PageUp + elif code == uint8(0x4E): keyboard.inject_csi_tilde(uint8(0x36)) # PageDown + elif int(code) < 64: + shifted: bool = (modifier & uint8(0x22)) != 0 + if kbd_caps != 0 and code >= uint8(0x04) and code <= uint8(0x1D): + shifted = not shifted + ch: char = hid_ascii[int(code)] + if shifted: + ch = hid_ascii_shift[int(code)] + if ch != '\0': + keyboard.inject_byte(uint8(ch)) def init() -> int: global kbd_dev, kbd_initialized, kbd_slot_id @@ -47,7 +97,7 @@ def init() -> int: return 0 def _on_int_complete() -> int: - global kbd_buf_head, kbd_buf_tail, kbd_buf_count, kbd_prev_keycodes + global kbd_buf_head, kbd_buf_tail, kbd_buf_count, kbd_prev_keycodes, kbd_first_key if kbd_initialized == 0: return 0 j: int for i in range(6): @@ -59,6 +109,11 @@ def _on_int_complete() -> int: found = 1 break if found == 0: + if kbd_first_key == 0: + kbd_first_key = 1 + serial.puts("[usb_kbd] first key\n") + # 只在按下沿解码,避免按住时重复入队。 + _decode_press(code, kbd_report.modifier) if kbd_buf_count < KBD_BUF_SIZE: kbd_buf[kbd_buf_tail].modifier = kbd_report.modifier kbd_buf[kbd_buf_tail].keycode = code