# ============================================================================= # play_saolei.tcl —— 没有 VGA 显示器时,在 xsim 命令行里"玩"扫雷 # # 用法(建议用 source -encoding utf-8 加载本文件,否则 xsim 默认按 GBK 读,中文注释会乱): # cd <某个空目录,例如 _tmp/saolei_sim> # xvlog -d SAOLEI_ROM -i -i \ # \ # # xelab -d SAOLEI_ROM -top tb_saolei_play -snapshot saolei_play # xsim saolei_play -tclbatch <本脚本绝对路径> # # 然后在 xsim 提示符下敲命令(一个字母就是一步,会立刻重画棋盘): # k c 左键点击(= 板上 BTNC) # k u / k d / k l / k r 光标 上/下/左/右(也认 w s a d) # k f 插旗模式点击(点一下插旗,再点取消;= 按住 SW3 再点) # k p 只切换插旗模式开关(不点击) # k z 复位(等于重新上电,回到开始界面) # k uucc 可以连写:上、上、点、点 # shot 不按键,只重画一遍当前画面 # help 键位说明 # # 原理:k 把字符写进 cmd.txt;tb_saolei_play 每 100 us 仿真时间轮询一次并执行按键, # 同时每 1 ms 把显存 dump 到 now.txt;k 再调 fb2png.py --term 把画面画到终端。 # 仿真速度大约是 1 ms 仿真时间 = 0.5 s 墙钟,所以每步等 1~2 秒,比真实慢很多, # 但足够用来验证"这个程序真的能玩"。 # ============================================================================= set script_dir [file dirname [file normalize [info script]]] set fb2png [file normalize [file join $script_dir .. .. saolei tools fb2png.py]] # 按键字符 -> 人类可读的动作(只用于回显) array set KEYNAME { c "左键点击" u "上" w "上" d "下" s "下" l "左" a "左" r "右" f "插旗点击" p "切插旗开关" g "go 键" z "复位" } # 每次只把一个字符写进 cmd.txt(TB 每 100 us 读走一个,读完就清空) proc send_char {c} { set fh [open "cmd.txt" "w"] puts -nonewline $fh $c close $fh } # 先确保 cmd.txt 存在,否则 TB 每 100 us 都会刷一条 could not be opened 警告 if {![file exists "cmd.txt"]} { set fh [open "cmd.txt" "w"] close $fh } # 把 now.txt 渲染到终端(ANSI 彩色棋盘) proc render {} { global fb2png if {![file exists "now.txt"]} { puts " (now.txt not ready yet - run a bit first)" return } if {[catch { exec py $fb2png --term now.txt >@stdout 2>@stderr } err]} { puts " render failed: $err" puts " try manually: py \"$fb2png\" --term now.txt" } } proc help {} { puts " ---------------- SAOLEI controls (type at the xsim prompt) ----------------" puts " k c left click (board BTNC)" puts " k u/d/l/r move cursor up/down/left/right (w/s/a/d work too)" puts " k f click in flag mode k p toggle flag switch only" puts " k z reset k uucc several actions at once" puts " shot redraw help this text quit exit" puts " PNG screenshot: py \"$::fb2png\" now.txt shot.png" puts " ---------------------------------------------------------------------------" } # one step: send the key -> advance simulation -> redraw proc k {keys} { set s [string map {" " "c"} [string tolower $keys]] foreach ch [split $s ""] { if {[string length $ch] == 0} { continue } puts " >> $ch" send_char $ch run 1500 us } render } proc shot {} { render } # ---- opening: run a little so the start screen is drawn, then show it ---- help puts "booting... (init + draw start screen)" run 3 ms render