fix(ps2): 鼠标 dy 方向取负(PS/2 正 dy = 上,软件正 dy = 下);键盘补 W/A/S/D 别名
上板实测:鼠标已能操作(说明“奇校验 + 帧按位的下标对齐”那个修复就是根因),
但上下是反的、左右正确 —— 这是两套约定的差异,不是解码错:
* PS/2 鼠标原生约定:dx 正 = 右、**dy 正 = 上**
* saolei.c 的约定:正 dx = 列 +1、**正 dy = 行 +1(向下)**,和 cpu21_pointer 的
BTND = +8 一致
所以 cpu21_ps2_mouse 在拼包时把 dy 取负(dx 不动),三种事件源(板载按键 / PS/2 鼠标 /
PS/2 键盘)方向统一。
键盘:另加 W/A/S/D = 方向键(与 tools/play_saolei.tcl 里的别名保持一致),这样用普通
字母键也能测。
自测同步更新(都 ALL PASS):
* tb_ps2_mouse:改发“鼠标向上”的 dy=+8,事件里必须得到 dy=-8;向下 dy=-5 -> +5
* tb_ps2_kbd:新增 W(1D) -> dy=-8 用例
This commit is contained in:
@@ -6,9 +6,13 @@
|
||||
// 键盘只要产出**同样格式**的事件,软件一行都不用改。
|
||||
//
|
||||
// ↑ ↓ ← → 光标移动(dx/dy = ±8,恰好是软件里的"一格")
|
||||
// W A S D 同上(别名,与 tools/play_saolei.tcl 一致)
|
||||
// Enter / 空格 左键(开格)
|
||||
// 左 Shift / F / C 右键(软件里右键 = 插旗)
|
||||
//
|
||||
// 方向约定跟软件对齐:**dy = +8 是向下**(与 cpu21_pointer 的 BTND、cpu21_ps2_mouse 一致),
|
||||
// 所以 ↑ 发 dy = 248(= -8 的补码)。
|
||||
//
|
||||
// PS/2 键盘发扫描码(集 2):
|
||||
// 0xF0 前缀 -> 下一个码是"松开"(break);0xE0 前缀 -> 下一个码是扩展键
|
||||
// 方向键是扩展键:↑ = E0 75、↓ = E0 72、← = E0 6B、→ = E0 74
|
||||
@@ -89,6 +93,11 @@ module cpu21_ps2_kbd (
|
||||
8'h12: begin ev_dx_o <= 8'd0; ev_dy_o <= 8'd0; ev_btn_o <= 5'b00010; ev_valid_o <= 1'b1; end // 左 Shift
|
||||
8'h2B: begin ev_dx_o <= 8'd0; ev_dy_o <= 8'd0; ev_btn_o <= 5'b00010; ev_valid_o <= 1'b1; end // F
|
||||
8'h2E: begin ev_dx_o <= 8'd0; ev_dy_o <= 8'd0; ev_btn_o <= 5'b00010; ev_valid_o <= 1'b1; end // C
|
||||
// W/A/S/D 也当方向键(和 tools/play_saolei.tcl 里的别名保持一致)
|
||||
8'h1D: begin ev_dx_o <= 8'd0; ev_dy_o <= 8'd248; ev_btn_o <= 5'd0; ev_valid_o <= 1'b1; end // W = ↑
|
||||
8'h1B: begin ev_dx_o <= 8'd0; ev_dy_o <= 8'd8; ev_btn_o <= 5'd0; ev_valid_o <= 1'b1; end // S = ↓
|
||||
8'h1C: begin ev_dx_o <= 8'd248; ev_dy_o <= 8'd0; ev_btn_o <= 5'd0; ev_valid_o <= 1'b1; end // A = ←
|
||||
8'h23: begin ev_dx_o <= 8'd8; ev_dy_o <= 8'd0; ev_btn_o <= 5'd0; ev_valid_o <= 1'b1; end // D = →
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
// 所以字节 = frame_q[8:1](frame_q[1] 就是 d0),校验 = frame_q[9]。
|
||||
// 注意 PS/2 是**奇校验**:data + parity 9 位里 1 的个数为奇数。
|
||||
// 2) 解析:byte0 = 标志(bit0 左键、bit1 右键、bit3 固定 1),byte1 = dx,
|
||||
// byte2 = dy,bit7 为符号位;
|
||||
// byte2 = dy,bit7 为符号位;dx 正 = 右,**dy 正 = 上**(PS/2 的原生方向),
|
||||
// 而软件里正 dy = 下,所以上报前把 dy 取负,让鼠标和板载按键/键盘方向一致;
|
||||
// 3) 上报:当 dx/dy 非 0 或按键状态变化时产生一个事件(单位与
|
||||
// cpu21_pointer 相同,即原始计数 = 1/8 格);
|
||||
// 4) 本模块只做"接收",不实现主机→鼠标的命令发送(0xF4 使能上报)。多数
|
||||
@@ -131,8 +132,10 @@ module cpu21_ps2_mouse (
|
||||
end
|
||||
8'd2: begin
|
||||
byte_cnt_q <= 8'd0;
|
||||
ev_dx_o <= pkt_q[15:8]; // byte1 = dx
|
||||
ev_dy_o <= frame_q[8:1]; // byte2 = dy
|
||||
ev_dx_o <= pkt_q[15:8]; // byte1 = dx(正 = 右,与软件一致)
|
||||
// byte2 = dy:**PS/2 的正 dy 是鼠标上移**,而软件里正 dy = 光标下移
|
||||
// (与 cpu21_pointer 的 BTND = +8 一致),所以这里要取负。
|
||||
ev_dy_o <= 8'd0 - frame_q[8:1];
|
||||
// 与 cpu21_mmio / mmio.h 一致:bit0=左键, bit1=右键, bit2=中键
|
||||
ev_btn_o <= {2'b0, pkt_q[2], pkt_q[1], pkt_q[0]};
|
||||
ev_valid_o <= 1'b1;
|
||||
|
||||
Reference in New Issue
Block a user