From cc061b2ad31567265cb9cbfabfe61aeaf156ed7a Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 15:12:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(vkernel):=20=E4=BF=AE=E5=A4=8D=20PS/2=20?= =?UTF-8?q?=E9=BC=A0=E6=A0=87=E4=BD=8D=E7=A7=BB=E7=AC=A6=E5=8F=B7=E8=AF=AF?= =?UTF-8?q?=E5=88=A4=EF=BC=88|=E4=BD=8D=E7=A7=BB|=E2=89=A5128=20=E6=97=B6?= =?UTF-8?q?=E6=96=B9=E5=90=91=E7=BF=BB=E8=BD=AC=E3=80=81=E5=85=89=E6=A0=87?= =?UTF-8?q?=E5=90=91=E5=B7=A6=E9=A3=9E=E6=B2=A1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因(静态定位,非速度问题):PS/2 协议里第 2/3 字节是位移“幅值”,符号在第 1 字节的 bit4(X)/bit5(Y)。而驱动把位移按 int8 存储/解释,于是 |位移| ≥ 128 时字节最高位被当成 符号位: - 向右快移(幅值 0x80~0xFF)被读成负数 → _cursor_x 一路减小 → 撞上 if _cursor_x<0 被夹成 0 → 表现为“光标往左飞没了”; - int8 装不下 9 位有符号位移(符号位在 flags 里),结构上必然丢符号。 修改: - drivers/input/mouse/mouse.vp:mouse_packet.dx/dy 与 byte2/byte3 改为 uint8,保存原始 幅值字节,消除 int8 截断;flags(含符号位)照旧保留。 - services/desktop.vp::_update_mouse:按协议用“幅值 + 符号位”重建带符号位移 (命中 flags.bit4/bit5 时幅值 -256),再做屏幕 Y 轴反向。 - USB HID 分支不动:USB 报告的 X/Y 本身即 int8 有符号,原解释正确。 --- VKernel/Kernel/drivers/input/mouse/mouse.vp | 8 ++++---- VKernel/Kernel/services/desktop.vp | 12 ++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/VKernel/Kernel/drivers/input/mouse/mouse.vp b/VKernel/Kernel/drivers/input/mouse/mouse.vp index f6c950a..aa730bd 100644 --- a/VKernel/Kernel/drivers/input/mouse/mouse.vp +++ b/VKernel/Kernel/drivers/input/mouse/mouse.vp @@ -17,8 +17,8 @@ define MOUSE_MIDDLE = 0x04 class mouse_packet: flags: uint8 - dx: int8 - dy: int8 + dx: uint8 # 原始幅值字节(符号在 flags.bit4) + dy: uint8 # 原始幅值字节(符号在 flags.bit5) buttons: uint8 packets: [MOUSE_BUF_SIZE]mouse_packet @@ -29,8 +29,8 @@ mse_irq_cnt: static uint64 = 0 cycle: static uint8 = 0 byte1: static uint8 = 0 -byte2: static int8 = 0 -byte3: static int8 = 0 +byte2: static uint8 = 0 +byte3: static uint8 = 0 mouse_x: static int32 = 0 mouse_y: static int32 = 0 diff --git a/VKernel/Kernel/services/desktop.vp b/VKernel/Kernel/services/desktop.vp index bcd45b8..baa302a 100644 --- a/VKernel/Kernel/services/desktop.vp +++ b/VKernel/Kernel/services/desktop.vp @@ -913,8 +913,16 @@ def _update_mouse() -> int: if mouse.has_data(): pkt: mouse.mouse_packet mouse.read_packet(&pkt) - pkt_dx = int32(pkt.dx) - pkt_dy = -int32(pkt.dy) + # PS/2 协议:dx/dy 字节是“幅值”,符号在 flags 的 bit4(X)/bit5(Y)。 + # 若按 int8 直接解释,|位移| ≥ 128 时字节最高位会被当成符号位 → 方向翻转 + # (向右快移被读成负数 → 光标一路向左撞到 x=0,“飞没了”)。 + # 故按协议用“幅值 + 符号位”重建真正的带符号位移(驱动存的是原始 uint8 幅值)。 + dx_mag: int = int(pkt.dx) + dy_mag: int = int(pkt.dy) + if (pkt.flags & 0x10) != 0: dx_mag = dx_mag - 256 + if (pkt.flags & 0x20) != 0: dy_mag = dy_mag - 256 + pkt_dx = int32(dx_mag) + pkt_dy = -int32(dy_mag) pkt_btn = pkt.buttons elif usb_mouse.has_data(): upkt: usb_mouse.usb_mouse_packet