FuzzyBASICはWICSインタプリタからグラフィック処理を除き,T.T.L.の長所を取り入れ,少々の命令を加えたBASICインタプリタといえるものです。その少々の命令には,構造化したプログラムを書くのに必要なもの,逆にZ80の機械語に近いもの,“SWORD"のおかげで付け加えられたファイル処理関係ステートメントなどがあります。さらにステートメントを追加することもできるので,より強力なものにすることも可能です。
以下にわかりにくい点や細かな注意について説明します。おのおのの命令についてはマニュアルを参照してください。
WICSでいう配列とT.T.L.のメモリ変数・I/O変数のあいの子と思えば間違いないでしょう。機械語のインデックスアドレッシングに相当します。これによりメモリ(とI/O)の特定のアドレスを一般変数とほとんど区別することなく扱うことができます。
最近のBASICでは標準装備になっていますので多くを述べる必要はないでしょう。GOTO文などの分岐先として,行番号の代わりに用いられます。各サブルーチンの頭にそのルーチンの機能をひと言で表わすような単語をラベルとして記述することでプログラムの読みやすきを向上させるわけです。
内部的には,ラベルが使われると該当する行をテキストの最初から順に探していきます。よってラベルが二重に定義された場合は先に出てきたほうが優先されます。
同じ理由でラベルを使うとプログラムの実行速度は低下します。ですがスピードよりも読みやすきに重点を置く場合には,ラベルの使用は有効でしょう。
また,GOTO文などの分岐先として式の使用を許したために,RENUMコマンドによって行番号を付け換えても分岐先行番号の変更はしないので,ここでもラベルが有用なものとなります。
開発中はラベルを用いるようにし,行番号をきれいに整理し終わった時点でスピードが必要とされる部分をラベルから行番号に直すようにすればよいでしょう。このときSEARCHコマンドを使えば少ない労力ですみます。
変数の退避をともなうGOSUB文といえます。T.T.L.の:=文とほとんど同じですが,局所変数をLOCAL文によって変更できる点が違います。
PROCが実行されると,LOCAL文で指定された6つの変数を変数スタックにプッシュしてからサブルーチンを呼び出します。このとき,カンマで区切った6つまでの式があると,その値を局所変数に与えてからサブルーチンを呼びます。そして,RETPROCにより先にプッシュした6つの変数の値そ復帰させてリターンします。
つまりサブルーチンの中で局所変数のみを使う限り,メインルーチンと変数の重複を気にせずにプログラムが書けるわけです。
PROC文を関数にしたものです。変数の退避を行ってからサブルーチンを呼び出すことに変わりありませんが,関数ですから式の中でのみ用いられ値を持つことになります。サブルーチンでRETFUNCを見つけると,指定された値を持ってリターンします。
変数スタックはユーザーが任意にデータを保存しておくほかにPROC文,FUNC関数の変数退避に用いられ,1回のPROC文およびFUNC関数の実行ごとに12バイトが使われます。また,FUNC関数はこのほかにCPUのスタックを十数〜数十バイト(式の複雑さによる)を使います。
変数スタックとCPUスタックは,5D00H~6300Hまでの範囲に連続して置かれており,VSTACKコマンドによって,その境界を変更することができます。また,変数スタックをLIMITで確保したアドレスなど,まったく他のアドレスに移動させれば,5D00H~6300HのすべてをCPUスタックとして使用できますので,深く再帰するFUNC関数も実行できるようになります。
FOR〜NEXTのほかにREPEAT〜UNTILとWHILE〜WENDがあります。場合によって使い分けてみてください。処理速度の点ではFORループがもっとも速く,REPEAT,WHILEの順になります。
ときに,ループを途中で抜けたい場合があるでしょうが,単にGOTOで分岐してしまうとスタックが積まれたままになってしまうので,分岐先でNEXTまたはUNTILを実行しなければなりません。FORループではよく使うテクニックだと思います。
またブロックIF文からの脱出にも同じ方法が使えます。WHILEループだけは,WENDが見つかった時点で必ずWHILEに戻ってしまいますのでこの方法は使えません。
STOP文の有効/無効を決めるものです。デバッグ時に入れたSTOP文を残したままプログラムを実行できます。
たとえばバンク切り換えをしてG-RAMをアクセスする時に,途中でBREAKしたりすると困ったことになります。そんな場合はG-RAMアクセスルーチンの直前にBROFF文を,直後にBRON文を入れるようにして途中でプログラムが中断しないようにします。
また,FUNC関数ルーチン内でプログラムの実行を中断すると,CONTによる再開がうまくできなくなりますので,前後にこの文を置く必要が出てくるでしょう。
メモリのブロック転送をする命令です。いままでのBASICでは,ブロック転送したい場合ループを組んでやらなければならなかったのですが,これらのステートメントを使えば一発です。メモリ上にVRAMが置かれている機種なら,スクロールなどにも利用できるでしょう。
LDIR文,LDDR文は名前も機能もZ80の命令と同じですのでわかりやすいと思います。メモリのクリアやフィルにも有効なものです。TRANS文は,データと転送先のアドレスにより,LDIRとLDDRを使い分けています。
CODE関数は予約語名を与えると中間コードを返す関数,TABLE関数は逆に中間コードから予約語名を(ポインタとして)返す関数です。
数あるステートメント,関数の中でももっともえたいの知れないものでしょう。実は私も何に使うか考えないで作ったのですがここでヒントを2つ挙げておきましょう。
ひとつはBASICコンパイラを書こうとするときにたぶん使えるでしょう。
もうひとつは,上のこととも重複しますが,BASICのテキストに対してなんらかの処理を行う場合です。たとえばファイルコンパータや,ASCIIセーブなんかが考えられます。このBASICではメモリ上に複数のテキストを置くこともできますから,ほかのアドレスに置かれたテキストに対して処理を行うようなプログラムが作れるのです。
CODE関数を使う上で注意する点として,関数は最初のカッコまでが予約語となっているということです。
(誤) A=CODE(FUNC)
(正) A=CODE(FUNC()
表1 ベンチマークテスト結果(MZ-2000上 単位は秒)
|
Fuzzy BASIC |
WICS
(インタプリタ) |
T.T.L. |
MZ-1Z001 |
5万回素ループ |
15 |
─ |
38 |
30 |
3万回素ループ |
9 |
9 |
22 |
17 |
3万回GOSUB(1) |
32 |
32 |
69 |
57 |
同 (2) |
32 |
32 |
228 |
230 |
3万回加算 |
31 |
35 |
44 |
55 |
3万回減算 |
31 |
35 |
45 |
55 |
3万回乗算 |
38 |
36 |
52 |
63 |
3万回除算 |
42 |
46 |
56 |
72 |
1万回文字表示 |
15 |
21 |
19 |
33 |
FuzzyBASICではステートメントなどの追加ができるようになっています。追加は機械語サブルーチンを作りその先頭アドレスをジャンプテーブルに登録することによって行います。
ステートメントは,USR^A,……,USR^Hの名前で8つまで追加可能です。ジャンプテーブルは5092Hからの2バイトずつが対応します。
関数は,FN^A,……,FN^Hの名前で8つまで追加できます。ジャンプテーブルは511FHからです。またPRINT文用出力関数もPR^AとPR^Bの2つが追加でき,ジャンプテーブルは5156Hから2バイトずつ4バイトです。
ジャンプテーブルに登録する際は,アドレスを下位,上位の順に登録するのを忘れないでください。以下にサブルーチンを作る上で必要と思われることを述べます。
テキストの実行ポインタとしてIXレジスタが使われています。プログラムが実行されるときは,IXレジスタを順にインクリメントしてテキストが読み込まれ,解析されることになります。各ステートメントの機械語サブルーチンが呼び出された時点で,IXレジスタはそのステートメントの中間コードが置かれた直後のアドレスを指しています。
サブルーチン内では汎用レジスタはすべて自由に使えます。IXレジスタは先に述べたようにテキスト実行ポインタとして使われていますから,勝手な使い方はできません。また,IYレジスタはFORループ用のスタックポインタとして使われているので保存する必要があります。
サブルーチンからはRETによって戻り,その時点でIXレジスタはシングルクォーテーション(')かコロン(:)か0DH(行のエンドコード)のあるアドレスを指していなければなりません。
関数はリターン時のHLレジスタが値となりますので,演算結果を入れてリターンするようにします。表2にサブルーチンを組むのに必要と思われるインタプリタ内のエントリーアドレスを示しておきます。インタプリタ内にはほとんど空きがないので,新しく作ったサブルーチンはまったく別にセーブしておくか,次に述べる方法によりインタプリタに組み込みます。まずサブルーチンを6300Hからの本来ならテキストが絡納されるべきアドレスに置くようにします。そして307EH,307FHの2バイト(00H,63Hになっている)をサブルーチンの終わった直後のアドレスの上位,下位を逆転したものに変更します。最後に3000Hから新しいルーチンの最後までをセーブすれば完成です。
3000H |
コールドスタート |
3003H |
ホットスタート |
3006H |
IXレジスタの指すアドレスからの1行の式を評価し,HLに入れて戻る。リターン時,IXレジスタは式の直後のアドレスを指す。 |
3009H |
力ンマで区切られた2つの式(式,式の形)を評価し,順にHL,DEレジスタに入れて戻る。 |
300CH |
カンマで区切られた3つの式を評価し,順にHL,DE,BCレジスタに入れて戻る。 |
300FH |
式の評価のあと閉じ力ッコがなければエラーを発生する。値はHLレジスタに持ってリターンすることは上と同様。 |
3012H |
2つの式の評価と閉じカッコのチェックを続けて行う。 |
3015H |
3つの式の評価と閉じ力ッコのチェックを続けて行う。 |
3018H |
シンタックスエラー(エラー13)を発生する。 |
301BH |
Bad Dataエラー(エラー14)を発生する。 |
301EH |
アキュムレータの値に対応するエラーを発生する。 |
3021H |
IXレジスタの指すアドレスから変数名に対応して,DEレジスアに変数値,HLレジスタにその格納アドレスを持ってリターンする。 |
表3 エラーコード一覧(エラーNo.14まではSWORDと同じ)
15 |
Out of memory |
テキストエリアが不足した |
16 |
Bad NEXT |
対応するFORのないNEXTが使われた |
17 |
Bad RETURN |
対応するGOSUBのないRETURNが使われた |
18 |
Bad UNTIL |
対応するREPEATのないUNTILが使われた |
19 |
Bad WEND |
対応するWHILEのないWENDが使われた |
20 |
Bad ENDIF |
対応するIFのないENDIFが使われた |
21 |
Bad FOR |
FORループのネステイングが16重を越えた |
22 |
Bad GOSUB |
サブルーチンコールのネステイングが127重を越えた |
23 |
Bad REPEAT |
REPEATループのネスティングが16重を越えた |
24 |
Bad WHILE |
WHILEループのネスティングが16重を越えた |
25 |
Bad Block IF |
ブロックIF文のネスティングが16重を越えた |
26 |
Undefined label |
分岐先が見あたらない |
27 |
Stack over flow |
マシンスタックがオーバーフローした |
28 |
Division by 0 |
0による除算が行われた |
29 |
Can't Continue |
CONTコマンドによる実行再開ができない |
30 |
Var stack empty |
変数スタックを掘り過ぎた |
31 |
Var stack over flow |
変数スタックがオーバーフローした |
32 |
Too many variables |
使われた変数の数が127個を越えた |
33 |
Line length over |
1行が79文字を越えた |
34 |
Bad ELSE |
対応するIF文のないELSEが使われた |
36 |
Can't do it |
ダイレクトコマンドとステートメントを混同して使用した。または,未定義命令を実行しようとした |
36 |
Bad RET FUNC |
対応するFUNCのないRETFUNCが使われた |
37 |
Memory protected |
テキストエリアへ機械語ファイルをロードしようとした |
・シングルクォーテーション以下の1行は注釈とみなされる。
・プログラムは注釈行中,文字列中,ラベル中以外のスベースをすべて詰めた形で格納される。例外として,行番号の直後に続くスペースは32文字までに限り,1バイトに庄縮されて詰められずに格納される。
・ひとつの項,もしくは複数の項を2項演算子でつないだもの。
・演算はすべて符号なしの16ビットで行われる。また,オーバーフローのチェックはしない。
・負数は2の補数表現(-1=0-1=FFFFH=65535)。
・定数,変数,メモリ配列,I/O配列,関数,カッコでくられた式,およびこれらに負符号を付けたもの。
・取りうる値は,0~65535。65536以上の場合は65536で割った余りが値となる。
・先頭に$または&Hを付けて表す。取りうる値は$0000〜$FFFF。4桁を越える場合は下位の4桁のみが有効となる。
・先頭に&Bまたは単に&を付けて表す。16桁を超えるときは下位の16桁のみが有効となる。
・ダブルクォーテーションで囲まれた0〜2文字の文字列。左の文字のアスキーコード*256+右の文字のアスキコードの値とする。1文字の場合は上位バイトが0。ヌルストリングの場合は下位バイトも0で結局0が値となる。
注)一般的なBASICのASC関数が2文字(2パイト)に拡張されたものと考えればよい。
・英字で始まり,英数字からなる任意長の文字列を変数名として認める。
・最初の2文字までを識別する。芙小文字の使用も認められるが,大文字との区別はなされない。
・使用できる変数の総数は127個までに制限されている。
・以下に挙げるいくつかの変数は特殊な扱いをする場合がある。
・A,B,……,Zの1文字で表される変数は,2文字(以上)で表されるものよりもいくぶん代入・参照が速い。また1文字変数は値を格納するアドレスが固定されており,機械語ルーチンとの値の受け渡しが容易である。さらに局所変数(LOCAL文,PROC文,FUNC関数参照)となりうるのもl文字変数だけである。
・Z80のレジスタと同名の変数AF,BC,DE,HLの4変数はCALL@文,USR@関数において,機械語サブルーチンとの直接的な値の受け渡しに用いられる。
・変数VSは変数スタックのスタックポインタとして用いられているので,不用意に使われるべきではない。
変数名[式] … 1バイト型
変数名(式) … 2バイト型
・Z80のインデックスアドレッシングに相当し,変数の値をインデックス,式の値をディスプレイスメントとして直接にメモリを操作する。このとき1バイト型の場合は変数の値+式のアドレスがアクセスされ,また,2バイト型においては「変数の値+式*2」のアドレスを下位パイト,「変数の値+式*2+1」のアドレスを上位バイトとしてアクセスされる。
・メモリの代わりにI/O空間をアクセスすること以外はメモリ配列と同様である。
変数名%[式] … 1バイト型
変数名%(式) … 2バイト型
・I/O配列に値を代入することはOUTに相当する。
・2バイト型においてはにI/Oアドレスの小さいほう,大きいほうの順でアクセスされる。
・GOTO文,GOSUB文などの分岐先にラベルを用いることができる。
・ラベルはカギカッコ(「」)またはパックスラッシュ(使えない機種では¥)で囲まれた任意長文字列で,全文字識別する。
・ただし,カギカッコ,バックスラッシュ,カンマを含まないこと。
・ラベルは単に行頭に置かれることによって定義される。
・また,ラベルの後ろにステートメントを置くときはコロンで区切ること。
コマンドやステートメント,関数の書式中の記号・文字には次のような意味がある。なお,コマンドはダイレクト実行のみ可能である。
◆[]の中は任意に省略できる。
◆{}の中の縦に並べて書いてあるものは任意に選択することを示す。
◆……は連続することを意味する。
◆“Str"は文字列を意味する。
◆"filename"は“[デバイス名:]ファイル名[.拡張子J"でデバイス名はS-OS“SWORD"に準拠する。
◆「範囲」は以下のいずれかを示す。
式
,式
式,
式1,式2
式の行番号
先頭行から式の行番号まで
式の行番号から最終行まで
式1の行番号から式2の行番号まで
・テキストファイルをロードする。式が用いられた場合,その値のアドレスより置かれたASCIIコード列をファイル名とする。
・メモリ上のテキストの直後にテキストファイルをロードし,ひとつのテキストとする。行番号は変化しない。
・E-MATEなどでASCIIセーブされたテキストを読み込み,メモリ上のテキストと融合する。
・先頭にシングルクォーテーションの付いている行のみをシングルクォーテーションの直後から出力する。
・シングルクォーテーション付きで,行番号を自動発生する。
・テキスト中より文字列を探し出し,見つけた行をすべて表示する。
・行番号を10行間隔で付け換える。ただし,GOTO文などの分岐先は変更しない。
・変数,変数スタック,ループ文などのネステイングをクリアしたあとプログラムを実行する。式が指定された場合はその行から実行する。ファイル名が指定された場合はテキストをロードしたあと実行に移る。
・STOP文またはSHIFT+BREAKによって実行が中断されていたプログラムの実行を再開する。
・式1から式2-1のアドレスを変数用スタックとする。
式の値が0のとき … エラー発生行のリストを表示
式の値が1のとき … 行番号のみを表示
式の値が0のとき … 予約語を英大文字で出力。
式の値が1のとき … 予約語を芙小文字で出力。
FOR 変数名=式1 TO 式2 STEP 式3
, ,
NEXT [変数名][……]
・式2の値を越えるまで式1に式3を加え,NEXTまでのプログラムを繰り返す。
・式の値が0の間,REPEATとUNTILの間のプログラムを繰り返す(最低一度は実行される)。
・式の値がOでない間WHILEとWENDの間のプログラムを繰り返す(条件によっては一度も実行されない)。WHILEとWENDは必ず行頭に置かれなければならず,また1対1の対応が必要。
・GOSUBに対応するリターン。式(またはラベル)がある場合はGOSUBのネスティングレベルを1段落としたあと,指定の行へ分岐する。
・式のアドレスからの機械語サブルーチンをコールする。
・変数AF,BC,DE,HLの値を同名のレジスタに与えたあと,式のアドレスからの機械語サブルーチンをコールする。さらに,サブルーチンからのリターン時のレジスタの値を再び同名のレジスタ変数へ代入する。
・式1のアドレスからの機械語サブルーチンをコールし,リターン時のHLレジスタを値とする。式2が指定された場合は,その値をHLレジスタにもってサブルーチンをコールする(関数)。
・CALL@文と同様にして機械語サブルーチンをコールし,リターン時のHLレジスタの値を返す(関数)。
ON 式 GOTO〜
ON 式 GOSUB〜
ON 式 RETURN〜
・式の値により分岐先を決める分岐文。この場合,GOSUBを!で代用することはできない。
IF〜THEN/GOTO/GOSUB/RETURN
IF 式 THEN〜[:ELSE]
IF 式 GOTO 式 [:〜][:ELSE〜]
ラベル
IF 式 GOSUB 式 [:〜][:ELSE〜]
ラベル
IF 式 RETURN 式 [:〜][:ELSE〜]
ラベル
・式の値が0でなければ直後のステートメントを,0であればELSE以下のステートメントを実行する。
1)ELSEの直前にコロンが必要。
2)ELSEの前にほかのIF文がある場合(1行中でIF文が2重になっている場合)誤動作する恐れがあるので,必要に応じて(プログラムの見やすさという点でも)次のブロックIF文を使われたい。
3)THEN,ELSEの直後に行番号を置いて分岐させるような形は認められない。
IF 式
[THEN[ステートメント列]]
ステートメント列
[ELSE[ステートメント列]
[ステートメント列]]
ENDIF
・ブロックIF文。IF,THEN,ELSE,ENDIFは必ず行頭に置かれなければならず,またIFとENDIFは1対1の対応をしていなければならない。
・局所変数を指定する。ここでいう局所変数とは,PROC文,FUNC関数の実行時に,変数スタックに値を退避する変数を指す。
例) LOCAL"D"
変数D,E,F,G,H,Iを局所変数とする。
PROC 式 [,式1 [,……,式6]]
# ラベル
・LOCAL文で指定されている変数の値を変数スタックにプッシュし,式1〜式6が続いて記述されている場合はそれらの値を順次局所変数に代入したあと,サブルーチンを呼び出す。つまり部分的な変数の退避をともない,かつ必要に応じてパラメータを与えるGOSUB文である。
・PROCに対応するリターン。先に変数スタックへ退避した値を変数に代入したあとリターンする。
FUNC (式 [,式1[,……,式6]])
ラベル
・LOCAL文で指定されている変数の値を変数スタックにプッシュし,式1〜式6が続いて記述されている場合はそれらの値を順次局所変数に代入したあと,関数ルーチン(サブルーチンに似ているが,RETURNの代わりにRET FUNCで終わる)を呼び出し,RET FUNCで指定された値をとる(関数)。
・FUNC関数に対応するリターン。式の値を関数の値として返す。RET PROC文同様局所変数に使われていた変数の値の復帰をともなう。
注) FOR,REPEAT,WHILE,ブロックIFのネステイングはそれぞれ16重まで。GOSUB,PROC,FUNCのネステイングは合計して127重まで。
INPUT[ "str";]変数名[,“[str";]変数名……]
・キーポードから入力した1行の式の値を順次変数に代入する。1回の入力(CR)がひとつの変数に対応する。
・キーボードから入力した1行の文字列を式のアドレスから格納する。エンドコードとして0"が追加格納される。
式の値が0の時 … 画面のみに出力
式の値が1の時 … 画面とプリンタに出力
式の値が2の時 … プリンタのみに出力
LISTなどもこれに従って出力される。また,AUTOコマンドの実行,エラーの発生,STOP,BREAKなどによって,自動的にモード0になる。
・式1をX座標,式2をY座標とする位置へカーソルを移動する。
・以下の害式に従って出力を行う。特に指定しない限り改行しない。
出力書式
なし … 改行する
式 … 10進左詰め出力
%式 … 10進5桁右詰め出力
#式 … 16進2桁出力
##式 … 16進4桁出力
!式 … 式のアドレスから00HまでをASCII出力
"str" … 文字列をそのまま出力
〈カーソルコントロール文字列〉… 画面制御
1またはD …… 力ーソルを下へ1文字分移動
2またはU …… カーソルを上へ1文字分移動
3またはR …… カーソルを右へ1文字分移動
4またはL …… カーソルを左へ1文字分移動
5またはH …… カーソルを(0,0)へ移動
6またはC …… 画面をクリア
/(スラッシュ)ー改行する
以上の書式はカンマ,または,セミコロンをはさんで複数記述できる。セバレータにカンマを使用した場合は1文字分のスペースが挿入される。
以下の出力関数は,PRINT文中のみで使われ,出力害式となる。カッコ中に複数の式が記述できる出力関数においては,先に述べたのと同様,セバレータとしてカンマとセミコロンの使い分けが可能。
PN (式[……J) … 符号付き16ピット数とみなして10進出力
DECI (式[……]) … 10進5桁右詰め出力
HEX2 (式[……]) … 16進2桁出力
HEX4 (式[……]) … 16進4桁出力
BINL (式[……]) … 2進8桁出力
BIN (式[……]) … 2進16桁出力
MSG (式[……]) … 式のアドレスより0DHの直前までをASCII出力
MSX (式[……]) … 式のアドレスより00Hの直前までをASCII出力
CHR$ (式[……]) … 上位バイト,下位バイトの順にASCII出力
SPC (式) … 式の下位バイト数だけスペースを出力
TAB (式) … 式の下位バイト数だけカーソル右へを移動
STRING (式1,式2) … 式1の下位バイトのキャラクタを式2の下位バイト個出力
LEFT$ (式1,式2)
RIGHT$ (式1,式2) … 式1のアドレスから00Hまでを文字列とみなして,それぞれ左と右から式2の長さをASCII出力
・変数,変数スタック,ループ文などのネスティングをクリアする。
・式の値に対応する時間だけ実行を休止する。単位は約1秒である(4MHz時)。
・指定のアドレスより順次,式の値(1バイト)を書き込む。
・指定のアドレスより順次,式の値(2バイト)を書き込む。
・指定のI/Oポートアドレスより,ポートアドレスをインクリメントしながら,式の値(1バイト)を出力する。
・指定のI/Oポートアドレスより,ポートアドレスをインクリメントしながら,式の値(2バイト)を出力する。
・式2の値を10進数で表した文字例を,式1のアドレスより格納する。
・式2の値を16進数で表した文字列を,式1のアドレスより格納する。
・式2の値を2進数で表した文字列を式1のアドレスより格納する。
注) 上記,4つのステートメントにおいて最後に@を付けた場合は,エンドコード(00H)が追加格納される。
・式のアドレスから00Hが見つかる直前までのメモリを文字列のように見なし,左右反転したあと,再び同アドレスへ格納する。
・ブロック転送する。式1でソースの先頭アドレス,式2でディスティネーションの先頭アドレス,式3でバイト数を指定する。
・式1でソースの最終アドレス,式2でディスティネーシヨンの最終アドレス,式3でバイト数を指定してブロック転送する。
・式1のアドレスから式2のアドレスまでを式3を先頭アドレスとしてブロック転送する。
・式1のアドレスの式2ビットをセットする。式2の値は0〜7に制限する必要はなく,たとえば8が指定された場合であれば,式1+1のアドレスの第0ピットに対して処理が行われる。
・式の下位バイトの回数だけビープ音を鳴らす。式省略時は1回。
TEXT $6300:LlMIT MAX
NEW:CLR:VSTACK $5D00,$6200
PRMODE 0:ERMODE 0:LMODE 0
STON:BRON:LOCAL"I":RANDOMIZE
BLOAD "filename",[ロードアドレス]
BSAVE "filename"開始アドレス,終了アドレス [,実行アドレス]
RENAME “旧filename:新filename"
・式2のレコードナンバーから式3の下位パイトのレコード数だけ式1のアドレスへ読み込む。
・式1のアドレスからの(式3の下位バイト×256)バイトを,式2を先頭レコードとしてディスクに書き込む。
・テキストをロードし,連続して実行する。式が指定された場合はその行より実行する。変数,変数スタックは保存される。
・式1に式2を乗じ65536で割ったものを値とする。
・式の値が0のとき1,それ以外のとき0を値とする。
・0から式の値までの和を値とする(定義域は0〜361)。
・式の値の上位バイトと下位バイトを交換したものを値とする。
・式の値を2進数で表し,すべてのピットを反転したものを値とする。
・式の値を2進数で表し,ピットを左右反転したものを値とする。
・式の値を2進数で表し,左へ1ビット回転したものを値とする。
・式の値を2進数で表し,右へ1ピット回転したものを値とする。
・式の値を2進数で表し,左へ4ピット回転したものを値とする。
・式の値を2進数で表し,右へ4ピット回転したものを値とする。
・式の値を2進数で表したときの1の数(何力所ピットが立っているか)を値とする。
・式lのアドレスから式2の値の下位バイトのASCIIコード(省略すると0)が見つかる直前までのバイト数を値とする。
・式1,式2を先頭アドレスとするメモリを式3バイト分比較し,一致したならば1,不一致ならば0を値とする。
・式で示されるアドレスからのメモリと,文字列を比較し,一致したならば1,不一致ならば0を値とする。
・式1のアドレスから00Hまでの間に,式2のアドレスから式3バイト長の文字列が見つかればその位置(式1のアドレスから数えて何バイト目か)を値とし,見つからなければ0を値とする。
・式のアドレスから00Hまでの問に,指定の文字列が見つかればその位置を値とし,見つからなければ0を値とする。
・座標(式1,式2)の位置に表示されているキャラクタのアスキーコードを値とする。
・式のアドレスと,式+1のアドレスに格納されている値をそれぞれ下位,上位バイトとして返す。
・式のI/Oポートと式+1のI/Oポートから入力した値をそれぞれ下位,上位バイトとして返す。
・リアルタイムキー入力。どのキも押されていないならば0,何かのキが押されていれば,そのASCIIコードを値とする。
・キーが押されるのを待って1文字入力し,そのASCIIコードを値とする。
・変数スタックのいちばん上に積まれている値を返す。
・式のアドレスより中間コードで置かれている1行の式を評価して値とする。
・式の値で示される行番号を持つ行の格納されている先頭アドレスを値とする。
・テキスト最終行のエンドコードを格納しているアドレス+1を値とする。
CODE コマンド
ステートメント
関数
出力関数
論理演算子
・式の値を中間コードとする予約語をフルスペル(ASCIIコード列)で格納している予約語テーブル内のアドレスを返す(エンドコードは00H)。
・式の値が0のとき
式の値が1のとき
式の値が2のとき
式の値が3のとき
式の値が4のとき
GOSUB/PROC/FUNC
FOR~NEXT
REPERT~UNTIL
WHILE~WEND
ブロックIF
表4 命令語省略形一覧 ((c):コマンド (s):ステートメント (f):関数 (p):PRINT文出力関数)
ADR(
AND
APPEND
AUTO
AUTO*
AD
AN.
AP.
A.
A.*
(f)
(f)
(c)
(c)
(e)
BEEP
BIN(
BIN@
BINL(
BIT(
BLOAD
BOOT
BROFF
BRON
BSAVE
BYE
B.
BI.
BINL.
BIT.
BL.
BO.
BR.
BS.
BY.
(s)
(p)
(s)
(p)
(f)
(s)
(s)
(s)
(s)
(s)
(s)
CALL
CALL@
CHAIN
CHARA(
CHECK
CHR$(
CLEAR
CLR
CLS
CODE(
COLD
CONT
CP(
CP$(
CURSOR
CURX
CURY
CA.
CH.
CHAR.
CHE.
CHR.
CLE.
CL.
COD.
COL.
C.
CP.
CP$.
CU.
(s)
(s)
(s)
(f)
(c)
(p)
(s)
(s)
(s)
(f)
(c)
(c)
(f)
(f)
(s)
(f)
(f)
DEC
DECI(
DELETE
DEVICE
DEVI
DEVO
DIR
DSK
DE. or %
DEL.
DEV.
D.
DS.
(s)
(p)
(c)
(s)
(s)
(s)
(s)
(f)
EDIT
ELSE
END
END IF
ERMODE
EX(
E.
EL.
EN.
ER.
EX.
(c)
(s)
(s)
(s)
(c)
(f)
FILES
FLASH
FN^A(
FN^B(
FN^C(
FN^D(
FN^E(
FN^F(
FN^G(
FN^H(
FOR
FRESET
FSET
FUNC(
FI.
FL.
FN.
F.
FR.
FS.
FU.
(s)
(f)
(f)
(f)
(f)
(f)
(f)
(f)
(f)
(f)
(s)
(s)
(s)
(f)
GET
GOSUB
GOTO
GE.
GOS. or !
G.
(f)
(s)
(s)
HEX@
HEX2(
HEX4(
HIGH(
H. or #
HEX4. or ##
HI.
(s)
(p)
(p)
(f)
IF
INC
INKEY
INP(
INPUT
INSTR(
INSTR$(
INK.
I.
INS.
INSTR$.
(s)
(s)
(f)
(f)
(s)
(f)
(f)
LDDR
LDIR
LEFT$(
LEN(
LET
LIMIT
LINADR(
LINPUT
LIST
LIST*
LMODE
LOAD
LOCAL
LOCATE
LOG(
LOW(
LDD.
LD.
LEF.
LE.
------
LIM.
LIN.
LINP.
L.
L.*
LM.
LO.
LOC.
LOG.
LOW.
(s)
(s)
(p)
(f)
(s)
(s)
(f)
(s)
(c)
(c)
(c)
(c)
(s)
(s)
(f)
(f)
MAX
MAX(
MEM
MERGE
MIN(
MIRROR(
MIRROR@
MOD(
MON
MSG(
MSP
MSX(
MULH(
MA.
M.
MI.
MIR.
NO.
MS.
MSX. or !
MU.
(f)
(f)
(s)
(c)
(f)
(f)
(s)
(f)
(s)
(p)
(f)
(p)
(f)
NEST(
NEW
NEXT
NOT(
NOW
NES.
N.
NO.
(f)
(s)
(s)
(f)
(f)
PARITY(
PAUSE
PEEK(
PN(
POKE
POP
PRINT
PRMODE
PROC
PR^A(
PR^B(
PULL
PUSH
PAR.
PA.
PE.
PN.
PO.
P. or ?
PRM.
PRO. or #
PR^.
PU.
PUS.
(f)
(s)
(f)
(p)
(s)
(f)
(s)
(s)
(s)
(p)
(p)
(s)
(s)
RANDOMIZE
RECOVER
RENAME
RENUM
REPEAT
RESET
RET FUNC
RET PROC
RETURN
RIGHT$(
RND
ROTL(
ROTR(
ROTLD(
ROTRD(
RUN
RA.
REC.
RENA.
REN.
REP.
RES.
RETF.
RETP.
RE.
RI.
RN.
RO.
ROTR.
ROTLD.
ROTRD.
R.
(s)
(c)
(s)
(c)
(s)
(s)
(s)
(s)
(s)
(p)
(f)
(f)
(f)
(f)
(f)
(c)
SAVE(
SEARCH(
SET(
SIZE(
SPC((
SQR((
SQU((
STEP(
STOFF(
STON(
STOP(
STRING(
STR(
SUM((
SWAP(
SA.
SE.
SI.
SP.
SQ.
SQU.
S.
STOF.
STO.
STR.
SU.
SW.
(c)
(c)
(s)
(f)
(p)
(f)
(f)
(s)
(s)
(s)
(s)
(p)
(s)
(f)
(s)
TAB(
TABLE(
TEXT
THEN
TO
TOP
TRANS
TXBEGIN
TXEND
TAB.
TA.
TE.
T.
TO.
TR.
TX.
TXE.
(p)
(f)
(c)
(s)
(s)
(f)
(s)
(f)
(f)
UNTIL
USR(
USR@(
USR^A
USR^B
USR^C
USR^D
USR^E
USR^F
USR^G
USR^H
U.
US.
USR@.
USR.
(s)
(f)
(f)
(s)
(s)
(s)
(s)
(s)
(s)
(s)
(s)
VAL(
VEADR
VERSION
VLIST
VSADR
VSTACK
VA.
VE.
VER.
V.
VS.
VST.
(f)
(f)
(f)
(c)
(f)
(c)
WAIT
WDEC
WEND
WHILE
WIDTH
WINC
WINP(
WOUT
WPEEK(
WPOKE
WA.
WD.
WE.
W.
WI.
WIN.
WINP.
WO.
WP.
WPO.
(s)
(s)
(s)
(s)
(s)
(s)
(f)
(s)
(f)
(s)
3000H
57D6H
58A1H
599FH
59DCH
59ECH
5A0CH
5A2CH
5AACH
5BAAH
5CA8H
5D00H
(6200H)
6300H
|
SF-BASICインタプリタ本体
|
変数名エリア (203バイト) |
変数値エリア (254バイト) |
各種ワーク (54バイト) |
ブロックIFスタック (16バイト) |
REPEAT~UNTILスタック (32バイト) |
WHILE~WENDスタック (32バイト) |
FOR~NEXTスタック (128バイト) |
GOSUB,PROC,FUNCスタック(254バイト) |
GOTOなど用行番号←→アドレステーブル (254バイト) |
中間コードへの変換用バッファ(88バイト) |
変数スタック
|
マシンスタック
|
TEXTエリア
|
|
(C)1986 Takashi Takiyama(original)
(C)1997 Junji Okazaki(edited)
(C)2024 Oh!Ishi,Nibbles Lab.(formatted)