From 10d4836ad70acdb31f454dce425d38cb993c0d0a Mon Sep 17 00:00:00 2001 From: Alex-create-beep <2965312221@qq.com> Date: Wed, 23 Sep 2026 21:13:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(saolei):=20=E4=BF=AE=20hard=20=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E5=85=89=E6=A0=87=E5=88=B0=E6=9F=90=E4=B8=80=E6=A0=BC?= =?UTF-8?q?=E5=B0=B1=E8=B7=B3=E5=9B=9E=E6=9C=80=E5=B7=A6=E8=BE=B9=EF=BC=88?= =?UTF-8?q?=E5=88=97=E5=8F=AA=E6=9C=89=205=20=E4=BD=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象:只看 hard 模式时,光标移到某一排的某个格子后再往右,会跳回最左边。 原因:光标的列字段只有 5 位。 - 软件 update_cursor_reg():REG_CURSOR = (cur_c & 31u) | ... - RTL cpu21_vga.v:cursor_here = (cursor_i[4:0] == ccol) && ... hard 棋盘宽 30、左上角列 5,光标列能到 35,35 被掩成 3,于是画在第 3 列。 初级/中级列最大 25 以内,所以只有 hard 暴露出来;背景界面光标能走到列 39, 同样受影响。 改法: - saolei.c:列掩码 31u -> 63u(6 位,覆盖 0..39) - cpu21_vga.v:cursor_i[4:0] -> cursor_i[5:0] --- pipelined-cpu/srcs/board/cpu21_saolei_rom.vh | 2 +- pipelined-cpu/srcs/rtl/cpu21_vga.v | 4 +++- saolei/sw/saolei.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pipelined-cpu/srcs/board/cpu21_saolei_rom.vh b/pipelined-cpu/srcs/board/cpu21_saolei_rom.vh index edc6684..a802a7e 100644 --- a/pipelined-cpu/srcs/board/cpu21_saolei_rom.vh +++ b/pipelined-cpu/srcs/board/cpu21_saolei_rom.vh @@ -310,7 +310,7 @@ rom[307] = 32'h79402703; rom[308] = 32'h01F7F793; rom[309] = 32'h00879793; - rom[310] = 32'h01F77713; + rom[310] = 32'h03F77713; rom[311] = 32'h00E7E7B3; rom[312] = 32'h00001737; rom[313] = 32'h14F72223; diff --git a/pipelined-cpu/srcs/rtl/cpu21_vga.v b/pipelined-cpu/srcs/rtl/cpu21_vga.v index 7bb4a38..5a86bd7 100644 --- a/pipelined-cpu/srcs/rtl/cpu21_vga.v +++ b/pipelined-cpu/srcs/rtl/cpu21_vga.v @@ -280,7 +280,9 @@ module cpu21_vga #( // VGA 上和图里都能一眼看到指针。想改回闪动:把 blink_q 加回来, // 再在 cursor_box 里与上 blink 即可。 // --------------------------------------------------------------------------- - wire cursor_here = (cursor_i[4:0] == ccol) && (cursor_i[12:8] == crow); + // 列必须比 6 位(0..39):hard 难度的棋盘宽 30,光标能到列 35, + // 以前这里只取 [4:0],35 被当成 3,光标会“跳回最左边”。 + wire cursor_here = (cursor_i[5:0] == ccol) && (cursor_i[12:8] == crow); wire on_border = (hx[3:0] < 4'd2) || (hx[3:0] > 4'd13) || (vy[3:0] < 4'd2) || (vy[3:0] > 4'd13); wire cursor_box = cursor_here && ctrl_i[0] && on_border; diff --git a/saolei/sw/saolei.c b/saolei/sw/saolei.c index c9bd06e..a783705 100644 --- a/saolei/sw/saolei.c +++ b/saolei/sw/saolei.c @@ -199,7 +199,8 @@ static void draw_all_covered(void) static void update_cursor_reg(void) { - REG_W(REG_CURSOR) = (cur_c & 31u) | ((cur_r & 31u) << 8); + /* 列用 6 位(0..39):hard 棋盘宽 30,光标列能到 35,掩 31 会把它变成 3 */ + REG_W(REG_CURSOR) = (cur_c & 63u) | ((cur_r & 31u) << 8); } static void set_bg(unsigned color)