fix(vkernel): 修复 PS/2 鼠标位移符号误判(|位移|≥128 时方向翻转、光标向左飞没)

根因(静态定位,非速度问题):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 有符号,原解释正确。
This commit is contained in:
TermiNexus committed 2026-10-14 15:12:19 +08:00
1 parent a44f55574c
commit cc061b2ad3
2 files changed
+14 -6

No files matched your search

+4 -4
View File
@@ -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
+10 -2
View File
@@ -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