今回はループを使ってみます。
とりあえずの要件として、1tickごとにカウントアップし
接続しているレッドストーンランプを点滅させる、
そんな感じのものを作ってみましょう。
何はともあれループをさせてみないと何も始まりません。
ループにはBEGIN~AGAIN文を使います。
VARIABLE X
: LOOP003
0 X !
BEGIN
X @ .
X @ 1 + X !
AGAIN
;
とりあえずループさせるだけのWORD。
VARIABLEは変数を宣言するためのWORDです。
Xはここではループ変数として利用します。
3行目の 0 X ! は、変数Xに0を代入する、という意味です。
0からループさせたいので、最初に初期化させておきます。
4行目のBEGINからAGAINまでがループ処理。
X @ . は変数Xの値を表示します。
X @ 1 + X ! は変数Xの値を引き出し、それに1を足したものを再びXに代入する、
という処理です。1 X +! でもOKです。
実行させてみます。
こうなります。
1ループごとに表示・カウントアップを繰り返します。
ちなみにこれはほんとにループさせるだけで、
停止等は一切できません。無限ループです。
FORTH起動ディスク等でRESETをかけてやらないと復帰しないので、注意が必要です。
さて、ループはできたんですが制御不能のループです。
それでは使い勝手が悪いですよね。
では、とりあえず手動で止められるようにしましょう。
VARIABLE X
: LOOP004
0 X !
BEGIN
X @ .
1 X +!
KEY? IF
EXIT
THEN
AGAIN
;
KEY? IF~THENのくだりを追加しました。
KEY?はキーが押されていればTRUE、そうでなければFALSEを返すWORDです。
IF文はTRUEかFALSEかで条件分岐するので、
KEY? IF だけで正しく動作します。
では動かしてみましょう。
はい、どうでしょう?
今度は途中でaと入力したため、処理を途中で停止します。
2度目の実行も問題無く行えます。0から始まってますね。
この止め方はあくまでも一例で、
IF文を使うぐらいならWHILEを使えだとか、
BEGIN UNTILがあるじゃないかとかあるかもしれませんがあくまでも一例です。
最適な構文を自分で考えるのも、プログラミングの楽しみの一つです。
手動停止ができるようになったので、次はレッドストーン信号との連携です。
: LOOP005
0 X !
BEGIN
65535 IOXRST
X @ IOXSET
X @ . 1 X +!
KEY? IF EXIT THEN
AGAIN
;
まず 65535 IOXRST で全ランプを消します。
次に X @ IOXSET で該当ランプを付けます。
あとはループ制御するだけです。
改行がめんどくさくなってきたので、ループ制御の部分は2行に縮めました。
さて、これでどうなるでしょう?
こんな感じになりました。
表示処理より処理速度が速いせいか、白信号のランプは付きっぱなしです。
でもなんとなくこんな感じにしたかったっていうのは
お分かり頂けたのではないでしょうか。
もう少しだけ手を加えます。
白信号が点滅できていないので、処理の最高速度を10tickまで落とそうと思います。
: LOOP006
0 X !
BEGIN
65535 IOXRST
X @ IOXSET
10 TICKS
X @ . 1 X +!
KEY? IF EXIT THEN
AGAIN
;
10 TICKS を入れただけです。
TICKSは指定tick数だけ処理を一時停止するWORDとなります。
1TICKSでも点滅しなかったので10TICKSまで落としてみましたが、
今度はちょっと遅いような気も。2~3TICKSでもよかったかもしれませんが、
まぁいいでしょう。