2025年10月1日 星期三

游標控制

游標控制


曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
2 October 2025


在 Forth 系統中,由於控制游標是一個與硬體顯示視窗有關的問題,控制游標的指令不被列入標準指令中。

Forth 系統在印出訊息時,控制印出訊息之格式的能力是很強的,這在此前本網頁的眾多例題中可以看得出來。與印出訊息有關的指令是 EMIT, SPACE, SPACES, CR, TYPE..... 等,以及所有與印出數字有關的指令 . (dot), U. (U dot), D. (D dot), R. (R dot), D.R, U.R, # (sharp), <#, #s, #>..... 等等指令。

上述指令均使用於系統游標到達當時所處位置後的控制,不需要將游標跳往視窗中其他的任意位置。能辦到任意跳動之功能所需要的指令,傳統上將其名稱定名為 gotoxy ( x y -- ),意思很直接,不需要特別解釋。橫是列,直是行, x 是第幾列的數字,y 是第幾行的數字。

只要是跟硬體有關的操作指令,通常都不在初建 Forth 核心基本系統時被列入考慮,以簡化發展。因此,許多精簡的 Forth 系統都不具有 gotoxy 指令,我個人愛用的 32 位元 Win32Forth 系統具有,但轉入 64 位元後的 Lina64 Forth 系統沒有。

很幸運, Lina64 Forth 系統的作者,根據 Linux OS 的性能,提供了一個易於借用作業系統中現成功能軟體來完成某些特定工作的指令,名稱叫作 system ( sc -- )。它很有用,善用它,就知道如何來擴充系統各種的功能,想設計出 gotoxy, !xy, @xy 這一組指令時,就能靠 system 指令完成設計。

要如何設計? 寫一大堆說明,不如給大家實際範例。讀過本文中的下列程式,使用過簡單範例 main 後,大家就很容易了解這種程式技術,它在許多場合能被依樣畫葫蘆,例如:我在設計語音輸出、操控其他語言或系統或軟體、取放與硬體相關的數據.....等等等問題時都派上用場。

這一個簡例,可作為如何運用 system 指令的標準範例。實際上,我在想要觀察記憶體內容會高速變化的狀況時,它會非常有用,否則,只能採用一直橫列印出數據的方式高速滾動列印出結果,對高速動態變化內容的數據變化狀況很難觀察與體會,其感覺係寒天飲水,冷暖自知。這樣的使用實例,在2025年5月2日貼出的網文 『時基』一文中展示過。但該文內未提及此 gotoxy 指令組的來源,它係加裝 tput 公益應用軟體後獲得的可加裝功能,加裝 tput 軟體按下列操作便能獲得:

$ sudo apt-get install tput

至於有關 tput 使用時該如何給予指定參數與指定的文字命令? 這些規定不在此處的討論範圍,讀者必須從網上自行了解,以下設計內容是在熟讀資料後才進行設計。

我們在發展與同一作業系統中並存於世之公益軟體的應用時,必須學會這種本領。沒有同時並存於世的公益軟體可用時,想自行設計出同樣的功能,並不是一件很容易的事情。所以我們在獲得了這許多的好處時,應該感謝那些貢獻者,我無法一一點名致謝,只能在用到時宣告。

我剛檢查過,使用 Ubuntu 20.04 版本的作業系統時有 tput 軟體可自由加裝,在 ARM 環境的作業系統,均暫時尚無類似 tput 的軟體可供加裝。

在某些 Forth 系統中也許不採用 gotoxy 指令命名,且功能略異,但共同目的都是設法便於控制游標,例如一次性的把游標跳到往下數列、數行的位置,其指令名稱可能是 at-xy,他有別於此處討論的 gotoxy 性能,at-xy 所提供的性能,因為游標只能往下跳,設計時可以不涉及硬體控制,使用時,請自行注意。

另外,具有多工性能的 Forth 系統,就能根據游標可以前往任意指定位置再回到原本位置的特性,而設計出可在同一視窗內能同時顯示多項內容的畫面,這樣,執行 gotoxy 後的顯示效果,就可以是動態的,或者是可以瞬間就暫態變化的。這一部份,涉及多工應用,不在本文討論範圍之列。


 
\ gotoxy

: test
  s" tput sc " system
  begin 
  s" tput cup 0 40 " system
  getticks 0 20 D.R
  key? 
  until 
  s" tput rc " system 
;

: !xy  s" tput sc " system ;
: @xy  s" tput rc " system ;
: gotoxy ( x y -- )
  s" tput cup " $buf $!
  swap
  (.) $buf $+!
  32  $buf $c+
  (.) $buf $+!
    0 $buf $C+		\ must to be used at the end
  $buf $@ system ;

: main
  !xy
     begin
           0 40 gotoxy 
           getticks 
           0 20 D.R
     key?
     until
  @xy 
;


沒有留言: