インタプリタ言語 Fuzzy BASIC

瀧山孝
 
 FuzzyBASICはWICSインタプリタからグラフィック処理を除き,T.T.L.の長所を取り入れ,少々の命令を加えたBASICインタプリタといえるものです。その少々の命令には,構造化したプログラムを書くのに必要なもの,逆にZ80の機械語に近いもの,“SWORD"のおかげで付け加えられたファイル処理関係ステートメントなどがあります。さらにステートメントを追加することもできるので,より強力なものにすることも可能です。
 

◆命令の特徴

 以下にわかりにくい点や細かな注意について説明します。おのおのの命令についてはマニュアルを参照してください。
●メモリ配列とI/O配列
 WICSでいう配列とT.T.L.のメモリ変数・I/O変数のあいの子と思えば間違いないでしょう。機械語のインデックスアドレッシングに相当します。これによりメモリ(とI/O)の特定のアドレスを一般変数とほとんど区別することなく扱うことができます。
●ラベル
 最近のBASICでは標準装備になっていますので多くを述べる必要はないでしょう。GOTO文などの分岐先として,行番号の代わりに用いられます。各サブルーチンの頭にそのルーチンの機能をひと言で表わすような単語をラベルとして記述することでプログラムの読みやすきを向上させるわけです。
 内部的には,ラベルが使われると該当する行をテキストの最初から順に探していきます。よってラベルが二重に定義された場合は先に出てきたほうが優先されます。
 同じ理由でラベルを使うとプログラムの実行速度は低下します。ですがスピードよりも読みやすきに重点を置く場合には,ラベルの使用は有効でしょう。
 また,GOTO文などの分岐先として式の使用を許したために,RENUMコマンドによって行番号を付け換えても分岐先行番号の変更はしないので,ここでもラベルが有用なものとなります。
 開発中はラベルを用いるようにし,行番号をきれいに整理し終わった時点でスピードが必要とされる部分をラベルから行番号に直すようにすればよいでしょう。このときSEARCHコマンドを使えば少ない労力ですみます。
●PROC/RETPROC
 変数の退避をともなうGOSUB文といえます。T.T.L.の:=文とほとんど同じですが,局所変数をLOCAL文によって変更できる点が違います。
 PROCが実行されると,LOCAL文で指定された6つの変数を変数スタックにプッシュしてからサブルーチンを呼び出します。このとき,カンマで区切った6つまでの式があると,その値を局所変数に与えてからサブルーチンを呼びます。そして,RETPROCにより先にプッシュした6つの変数の値そ復帰させてリターンします。
 つまりサブルーチンの中で局所変数のみを使う限り,メインルーチンと変数の重複を気にせずにプログラムが書けるわけです。
●FUNC/RETFUNC
 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に戻ってしまいますのでこの方法は使えません。
●STON/STOFF
 STOP文の有効/無効を決めるものです。デバッグ時に入れたSTOP文を残したままプログラムを実行できます。
●BRON/BROFF
 たとえばバンク切り換えをしてG-RAMをアクセスする時に,途中でBREAKしたりすると困ったことになります。そんな場合はG-RAMアクセスルーチンの直前にBROFF文を,直後にBRON文を入れるようにして途中でプログラムが中断しないようにします。
 また,FUNC関数ルーチン内でプログラムの実行を中断すると,CONTによる再開がうまくできなくなりますので,前後にこの文を置く必要が出てくるでしょう。
●LDIR/LDDR/TRANS
 メモリのブロック転送をする命令です。いままでのBASICでは,ブロック転送したい場合ループを組んでやらなければならなかったのですが,これらのステートメントを使えば一発です。メモリ上にVRAMが置かれている機種なら,スクロールなどにも利用できるでしょう。
 LDIR文,LDDR文は名前も機能もZ80の命令と同じですのでわかりやすいと思います。メモリのクリアやフィルにも有効なものです。TRANS文は,データと転送先のアドレスにより,LDIRとLDDRを使い分けています。
●CODE/TABLE
 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から新しいルーチンの最後までをセーブすれば完成です。
 
表2 新命令語追加用インタプリタ内ルーチン
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 テキストエリアへ機械語ファイルをロードしようとした
 

Fuzzy BASICリファレンスマニュアル

〈構文規則〉

プログラム
・文法はほぼ一般的なBASICと同様。
・行番号は1〜65535の範囲。
・ステートメント間のセバレータはコロン。
・シングルクォーテーション以下の1行は注釈とみなされる。
・プログラムは注釈行中,文字列中,ラベル中以外のスベースをすべて詰めた形で格納される。例外として,行番号の直後に続くスペースは32文字までに限り,1バイトに庄縮されて詰められずに格納される。
・LIST出力時には適当にスペースが挿入される。
・予約語は英大文字,小文字ともに入力可能。
・1行はLIST出力時の形で79文字まである。
・ひとつの項,もしくは複数の項を2項演算子でつないだもの。
・演算はすべて符号なしの16ビットで行われる。また,オーバーフローのチェックはしない。
・負数は2の補数表現(-1=0-1=FFFFH=65535)。
・定数,変数,メモリ配列,I/O配列,関数,カッコでくられた式,およびこれらに負符号を付けたもの。
 

〈定数〉

10進定数
・取りうる値は,0~65535。65536以上の場合は65536で割った余りが値となる。
16進定数
・先頭に$または&Hを付けて表す。取りうる値は$0000〜$FFFF。4桁を越える場合は下位の4桁のみが有効となる。
2進定数
・先頭に&Bまたは単に&を付けて表す。16桁を超えるときは下位の16桁のみが有効となる。
文字定数
・ダブルクォーテーションで囲まれた0〜2文字の文字列。左の文字のアスキーコード*256+右の文字のアスキコードの値とする。1文字の場合は上位バイトが0。ヌルストリングの場合は下位バイトも0で結局0が値となる。
注)一般的なBASICのASC関数が2文字(2パイト)に拡張されたものと考えればよい。
 

〈変数〉

・英字で始まり,英数字からなる任意長の文字列を変数名として認める。
・ただし予約語では始まらないこと。
・最初の2文字までを識別する。芙小文字の使用も認められるが,大文字との区別はなされない。
・使用できる変数の総数は127個までに制限されている。
・以下に挙げるいくつかの変数は特殊な扱いをする場合がある。
1文字変数
・A,B,……,Zの1文字で表される変数は,2文字(以上)で表されるものよりもいくぶん代入・参照が速い。また1文字変数は値を格納するアドレスが固定されており,機械語ルーチンとの値の受け渡しが容易である。さらに局所変数(LOCAL文,PROC文,FUNC関数参照)となりうるのもl文字変数だけである。
レジスタ変数
・Z80のレジスタと同名の変数AF,BC,DE,HLの4変数はCALL@文,USR@関数において,機械語サブルーチンとの直接的な値の受け渡しに用いられる。
変数スタックポインタ
・変数VSは変数スタックのスタックポインタとして用いられているので,不用意に使われるべきではない。
 

〈配列〉

メモリ配列
・1バイト型と2バイト型があり,それぞれ
 変数名[式] … 1バイト型
 変数名(式) … 2バイト型
の形で表される。
・Z80のインデックスアドレッシングに相当し,変数の値をインデックス,式の値をディスプレイスメントとして直接にメモリを操作する。このとき1バイト型の場合は変数の値+式のアドレスがアクセスされ,また,2バイト型においては「変数の値+式*2」のアドレスを下位パイト,「変数の値+式*2+1」のアドレスを上位バイトとしてアクセスされる。
・メモリ配列に代入することはPOKEに相当する。
・メモリ配列を参照することはPEEKに相当する。
I/O配列
・メモリの代わりにI/O空間をアクセスすること以外はメモリ配列と同様である。
・1パイト型と2バイト型があり,それぞれ
 変数名%[式] … 1バイト型
 変数名%(式) … 2バイト型
の形で表される。
・I/O配列に値を代入することはOUTに相当する。
・I/O配列を参照することはINPに相当する。
・2バイト型においてはにI/Oアドレスの小さいほう,大きいほうの順でアクセスされる。
 

〈演算子〉

2項演算子
・加減乗除記号,比較演算子,論理演算子がある。
○加減乗除記号
・それぞれ+,-,*,/である。
○比較演算子
・=,<>,><,<,>,<=,>=
・真のとき1,偽のとき0を値とする。
○論理演算子
・AND,OR,XORの3種がある。
演算の優先順位
・負符号>乗除算>加減算>比較演算>論理演算
 

〈ラベル〉

・GOTO文,GOSUB文などの分岐先にラベルを用いることができる。
・ラベルはカギカッコ(「」)またはパックスラッシュ(使えない機種では¥)で囲まれた任意長文字列で,全文字識別する。
・ただし,カギカッコ,バックスラッシュ,カンマを含まないこと。
・ラベルは単に行頭に置かれることによって定義される。
・また,ラベルの後ろにステートメントを置くときはコロンで区切ること。
 
コマンドやステートメント,関数の書式中の記号・文字には次のような意味がある。なお,コマンドはダイレクト実行のみ可能である。
◆[]の中は任意に省略できる。
◆{}の中の縦に並べて書いてあるものは任意に選択することを示す。
◆……は連続することを意味する。
◆“Str"は文字列を意味する。
◆"filename"は“[デバイス名:]ファイル名[.拡張子J"でデバイス名はS-OS“SWORD"に準拠する。
◆「範囲」は以下のいずれかを示す。
 式
 ,式
 式,
 式1,式2
式の行番号
先頭行から式の行番号まで
式の行番号から最終行まで
式1の行番号から式2の行番号まで
 

〈入出力コマンド〉

LOAD
LOAD “filename"
    式
・テキストファイルをロードする。式が用いられた場合,その値のアドレスより置かれたASCIIコード列をファイル名とする。
SAVE
SAVE “filename"
    式
・テキストファイルをセーブする。
APPEND
APPEND “filename"
     式
・メモリ上のテキストの直後にテキストファイルをロードし,ひとつのテキストとする。行番号は変化しない。
MERGE
MERGE “filename"
    式
・E-MATEなどでASCIIセーブされたテキストを読み込み,メモリ上のテキストと融合する。
 

〈編集コマンド〉

LlST
LlST [範囲]
・テキストをディスプレイ(プリンタ)に出力する。
LlST*
LlST* [範囲]
・先頭にシングルクォーテーションの付いている行のみをシングルクォーテーションの直後から出力する。
AUTO
AUTO [[開始行][,増分]]
・行番号を自動発生する。
AUTO*
AUTO* [[開始行][,増分]]
・シングルクォーテーション付きで,行番号を自動発生する。
TEXT
TEXT 式
・テキストを格納する先頭アドレスを指定する。
NEW
NEW
・テキストを消去する。
RECOVER
RECOVER
・NEWしたテキストを復活する。
DELETE
DELETE 範囲
・テキストの一部を削除する。
EDIT
EDIT 式
・指定行をエディットできるよう表示する。
SEARCH
SEARCH "str"
    ステートメントなど
・テキスト中より文字列を探し出し,見つけた行をすべて表示する。
CHECK
CHECK [範囲]
・テキストの1行ごとのチェックサムを出力する。
RENUM
RENUM [新行番号][,旧行番号]
・行番号を10行間隔で付け換える。ただし,GOTO文などの分岐先は変更しない。
 

〈一般コマンド〉

RUN
RUN 式
  “filename"
・変数,変数スタック,ループ文などのネステイングをクリアしたあとプログラムを実行する。式が指定された場合はその行から実行する。ファイル名が指定された場合はテキストをロードしたあと実行に移る。
CONT
CONT
・STOP文またはSHIFT+BREAKによって実行が中断されていたプログラムの実行を再開する。
VLlST
VLlST
・使われたすべての変数名とその値を出力する。
VSTACK
VSTACK 式1,式2
・式1から式2-1のアドレスを変数用スタックとする。
ERMODE
ERMODE 式
・エラー表示のモードを指定する。
 式の値が0のとき … エラー発生行のリストを表示
 式の値が1のとき … 行番号のみを表示
LMODE
LMODE式
・LIST出力のモードを指定する。
 式の値が0のとき … 予約語を英大文字で出力。
 式の値が1のとき … 予約語を芙小文字で出力。
 

〈構文制御ステートメント〉

FOR〜NEXT
FOR 変数名=式1 TO 式2 STEP 式3
        ,   ,
NEXT [変数名][……]
・式2の値を越えるまで式1に式3を加え,NEXTまでのプログラムを繰り返す。
REPEAT〜UNTIL
REPEAT
UNTIL 式
・式の値が0の間,REPEATとUNTILの間のプログラムを繰り返す(最低一度は実行される)。
WHILE〜WEND
WHILE 式
WEND
・式の値がOでない間WHILEとWENDの間のプログラムを繰り返す(条件によっては一度も実行されない)。WHILEとWENDは必ず行頭に置かれなければならず,また1対1の対応が必要。
GOTO
GOTO 式
   ラベル
・指定行へ分岐する。
GOSUB/!
GUSUB 式
 !  ラベル
・サブルーチンを呼び出す。
RETURN
RETURN 式
    ラベル
・GOSUBに対応するリターン。式(またはラベル)がある場合はGOSUBのネスティングレベルを1段落としたあと,指定の行へ分岐する。
CALL
CALL 式
・式のアドレスからの機械語サブルーチンをコールする。
CALL@
CALL@ 式
・変数AF,BC,DE,HLの値を同名のレジスタに与えたあと,式のアドレスからの機械語サブルーチンをコールする。さらに,サブルーチンからのリターン時のレジスタの値を再び同名のレジスタ変数へ代入する。
USR
USR (式1[,式2])
・式1のアドレスからの機械語サブルーチンをコールし,リターン時のHLレジスタを値とする。式2が指定された場合は,その値をHLレジスタにもってサブルーチンをコールする(関数)。
USR@
USR@ (式)
・CALL@文と同様にして機械語サブルーチンをコールし,リターン時のHLレジスタの値を返す(関数)。
ON〜GOTO/GOSUB/RETURN
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 式
[THEN[ステートメント列]]
ステートメント列
[ELSE[ステートメント列]
[ステートメント列]]
ENDIF
・ブロックIF文。IF,THEN,ELSE,ENDIFは必ず行頭に置かれなければならず,またIFとENDIFは1対1の対応をしていなければならない。
LOCAL
LOCAL "1文字変数名"
・局所変数を指定する。ここでいう局所変数とは,PROC文,FUNC関数の実行時に,変数スタックに値を退避する変数を指す。
指定した変数からの6つが局所変数となる。
例) LOCAL"D"
 変数D,E,F,G,H,Iを局所変数とする。
PROC/#
PROC  式 [,式1 [,……,式6]]
 #  ラベル
・LOCAL文で指定されている変数の値を変数スタックにプッシュし,式1〜式6が続いて記述されている場合はそれらの値を順次局所変数に代入したあと,サブルーチンを呼び出す。つまり部分的な変数の退避をともない,かつ必要に応じてパラメータを与えるGOSUB文である。
RET PROC
RET PROC 式
     ラベル
・PROCに対応するリターン。先に変数スタックへ退避した値を変数に代入したあとリターンする。
FUNC
FUNC (式 [,式1[,……,式6]])
   ラベル
・LOCAL文で指定されている変数の値を変数スタックにプッシュし,式1〜式6が続いて記述されている場合はそれらの値を順次局所変数に代入したあと,関数ルーチン(サブルーチンに似ているが,RETURNの代わりにRET FUNCで終わる)を呼び出し,RET FUNCで指定された値をとる(関数)。
RET FUNC
RET FUNC 式
・FUNC関数に対応するリターン。式の値を関数の値として返す。RET PROC文同様局所変数に使われていた変数の値の復帰をともなう。
注) FOR,REPEAT,WHILE,ブロックIFのネステイングはそれぞれ16重まで。GOSUB,PROC,FUNCのネステイングは合計して127重まで。
 

〈入出力ステートメント〉

INPUT
INPUT[ "str";]変数名[,“[str";]変数名……]
・キーポードから入力した1行の式の値を順次変数に代入する。1回の入力(CR)がひとつの変数に対応する。
LINPUT
LINPUT 式
・キーボードから入力した1行の文字列を式のアドレスから格納する。エンドコードとして0"が追加格納される。
PRMODE
PRMODE 式
・出力モードを設定する。
式の値が0の時 … 画面のみに出力
式の値が1の時 … 画面とプリンタに出力
式の値が2の時 … プリンタのみに出力
LISTなどもこれに従って出力される。また,AUTOコマンドの実行,エラーの発生,STOP,BREAKなどによって,自動的にモード0になる。
CLS
CLS
・画面をクリアする。
CURSOR/LOCATE
CURSOR 式1,式2
LOCATE
・式1をX座標,式2をY座標とする位置へカーソルを移動する。
WIDTH
WIDTH 式
・画面の桁数を指定する。
PRINT/?
PRINT [出力書式並び]
?
・以下の害式に従って出力を行う。特に指定しない限り改行しない。
出力書式
なし … 改行する
式 … 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文出力関数
以下の出力関数は,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出力
 

〈一般ステートメント〉

LET
[LET]変数名 =式
  メモリ配列
  I/O配列
・左辺の項に右辺の式の値を代入する。
CLR/CLEAR
CLR
CLEAR
・変数,変数スタック,ループ文などのネスティングをクリアする。
STOP
STOP
・実行を中断する。
END
END
・実行を終了する。
STON
STON
・STOP文を有効にする。
STOFF
STOFF
・STOP文を無効にする。
BRON
BRON
・SHIFT+BREAKを有効にする。
BROFF
BROFF
・SHIFT+BREAKを無効にする。
PAUSE
PAUSE
・スペースキーが押されている間,実行を休止。
WAIT
WAIT 式
・式の値に対応する時間だけ実行を休止する。単位は約1秒である(4MHz時)。
INC
INC 変数名 [,変数名……]
・変数の値に1を加える。
DEC
DEC 変数名 [,変数名……]
・変数の値に-1を加える。
WINC
WINC 変数名 [,変数名……]
・変数の値に2を加える。
WDEC
WDEC 変数名 [,変数名……]
・変数の値に-2を加える。
SWAP
SWAP 変数名1,変数名2
・2つの変数の値を交換する。
POKE
POKE アドレス,式 [,式……]
・指定のアドレスより順次,式の値(1バイト)を書き込む。
WPOKE
WPOKE アドレス,式 [,式……]
・指定のアドレスより順次,式の値(2バイト)を書き込む。
OUT
OUT I/Oアドレス,式 [,式……]
・指定のI/Oポートアドレスより,ポートアドレスをインクリメントしながら,式の値(1バイト)を出力する。
WOUT
WOUT I/Oアドレス,式 [,式……]
・指定のI/Oポートアドレスより,ポートアドレスをインクリメントしながら,式の値(2バイト)を出力する。
MEM
MEM 式,“str"[@]
・式のアドレスから文字列を格納する。
STR
STR 式1,式2[@]
・式2の値を10進数で表した文字例を,式1のアドレスより格納する。
HEX@
HEX@ 式1,式2[@]
・式2の値を16進数で表した文字列を,式1のアドレスより格納する。
BIN@
BIN@ 式1,式2[@]
・式2の値を2進数で表した文字列を式1のアドレスより格納する。
注) 上記,4つのステートメントにおいて最後に@を付けた場合は,エンドコード(00H)が追加格納される。
MIRROR@
MIRROR@ 式
・式のアドレスから00Hが見つかる直前までのメモリを文字列のように見なし,左右反転したあと,再び同アドレスへ格納する。
PUSH
PUSH 式[,式……]
・式の値を変数スタックに積む。
PULL
PULL 変数名 [,変数名……]
・変数スタックから取り出した値を変数に代入する。
LDIR
LDIR 式1,式2,式3
・ブロック転送する。式1でソースの先頭アドレス,式2でディスティネーションの先頭アドレス,式3でバイト数を指定する。
LDDR
LDDR 式1,式2,式3
・式1でソースの最終アドレス,式2でディスティネーシヨンの最終アドレス,式3でバイト数を指定してブロック転送する。
TRANS
TRANS 式1,式2,式3
・式1のアドレスから式2のアドレスまでを式3を先頭アドレスとしてブロック転送する。
SET
SET 式1,式2
・式1のアドレスの式2ビットをセットする。式2の値は0〜7に制限する必要はなく,たとえば8が指定された場合であれば,式1+1のアドレスの第0ピットに対して処理が行われる。
RESET
RESET 式1,式2
・式1のアドレスの式2ピットをリセットする。
LIMIT
LIMIT 式
・式のアドレスまでをテキストエリアとする。
BEEP
BEEP [式]
・式の下位バイトの回数だけビープ音を鳴らす。式省略時は1回。
MON
MON
・各機種モニタへ制御を移す。
BYE
BYE
・S-OSのホットスタートヘジャンプする。
BOOT
BOOT
・ブートする。
COLD
COLD
・Fuzzy BASICをコールドスタートする。
注)Fuzzy BASIC初期設定
 TEXT $6300:LlMIT MAX
 NEW:CLR:VSTACK $5D00,$6200
 PRMODE 0:ERMODE 0:LMODE 0
 STON:BRON:LOCAL"I":RANDOMIZE
KEY0
KEY0 "str"
・キー入力パッファに文字列をセットする。
RANDOMIZE
RANDOMIZE
・乱数系列を初期化する。
 

〈ファイル処理ステートメント〉

DIR/FILES
DIR ["デバイス名"]
FILES
・ディレクトりを取る。
DEVICE
DEVICE “デバイス名"
・デフォルトデバイスを指定する。
BLOAD
BLOAD "filename",[ロードアドレス]
・機械語プログラムをロードする。
BSAVE
BSAVE "filename"開始アドレス,終了アドレス [,実行アドレス]
・機械語プログラムをセーブする。
KILL
KILL “filename"
・指定のファイルを消去する。
RENAME
RENAME “旧filename:新filename"
・ファイル名を変更する。
FSET
FSET "filename"
・ライトプロテクトをかける。
FRESET
FRESET "filename"
・ライトプロテクトを外す。
DEVI
DEVI ["デバイス名"],式1,式2,式3
・式2のレコードナンバーから式3の下位パイトのレコード数だけ式1のアドレスへ読み込む。
DEVO
DEVO ["デバイス名"],式1,式2,式3
・式1のアドレスからの(式3の下位バイト×256)バイトを,式2を先頭レコードとしてディスクに書き込む。
CHAIN
CHAIN "filename"[,式]
・テキストをロードし,連続して実行する。式が指定された場合はその行より実行する。変数,変数スタックは保存される。
〈数値関数〉
MOD
MOD(式1,式2)
・式1を式2で割った余りを値とする。
MULH
MULH(式1,式2)
・式1に式2を乗じ65536で割ったものを値とする。
ZERO
ZERO(式)
・式の値が0のとき1,それ以外のとき0を値とする。
SQU
SQU(式)
・式の値の2乗を値とする(定義域は0〜255)。
SOR
SQR(式)
・式の値の2乗根を値とする(値は切り捨て)。
SUM
SUM(式)
・0から式の値までの和を値とする(定義域は0〜361)。
LOG
LOG(式)
・式の値の常用対数を値とする。
MAX
MAX(式[,式……])
・与えられた式の中での最大値を値とする。
MIN
MIN(式[,式……])
・与えられた式の中での最小値を値とする。
RND
RND(式)
・0から式-1までの乱数を値とする。
〈特殊数値関数〉
HIGH
HIGH(式)
・式の値の上位バイトを値とする。
LOW
LOW(式)
・式の値の下位バイトを値とする。
EX
EX(式)
・式の値の上位バイトと下位バイトを交換したものを値とする。
NOT
NOT(式)
・式の値を2進数で表し,すべてのピットを反転したものを値とする。
MIRROR
MIRROR(式)
・式の値を2進数で表し,ピットを左右反転したものを値とする。
ROTL
ROTL(式)
・式の値を2進数で表し,左へ1ビット回転したものを値とする。
ROTR
ROTR(式)
・式の値を2進数で表し,右へ1ピット回転したものを値とする。
ROTLD
ROTLD(式)
・式の値を2進数で表し,左へ4ピット回転したものを値とする。
ROTRD
ROTRD(式)
・式の値を2進数で表し,右へ4ピット回転したものを値とする。
PARITY
PARITY(式)
・式の値を2進数で表したときの1の数(何力所ピットが立っているか)を値とする。
 

〈メモリ操作用関数〉

LEN
LEN(式1[,式2])
・式lのアドレスから式2の値の下位バイトのASCIIコード(省略すると0)が見つかる直前までのバイト数を値とする。
CP
CP(式1,式2,式3)
・式1,式2を先頭アドレスとするメモリを式3バイト分比較し,一致したならば1,不一致ならば0を値とする。
CP$
CP$(式,“str")
・式で示されるアドレスからのメモリと,文字列を比較し,一致したならば1,不一致ならば0を値とする。
INSTR
INSTR(式1,式2,式3)
・式1のアドレスから00Hまでの間に,式2のアドレスから式3バイト長の文字列が見つかればその位置(式1のアドレスから数えて何バイト目か)を値とし,見つからなければ0を値とする。
INSTR$
INSTR$(式,“str")
・式のアドレスから00Hまでの問に,指定の文字列が見つかればその位置を値とし,見つからなければ0を値とする。
CHARA
CHARA(式1,式2)
・座標(式1,式2)の位置に表示されているキャラクタのアスキーコードを値とする。
PEEK
PEEK(式)
・式のアドレスに格納されている値を返す。
WPEEK
WPEEK(式)
・式のアドレスと,式+1のアドレスに格納されている値をそれぞれ下位,上位バイトとして返す。
BIT
BIT(式1,式2)
・式1のアドレスの式2ピットを値とする。
INP
INP(式)
・式のI/Oポートから入力した値を返す。
WINP
WINP(式)
・式のI/Oポートと式+1のI/Oポートから入力した値をそれぞれ下位,上位バイトとして返す。
 

〈システム関数〉

GET
GET
・リアルタイムキー入力。どのキも押されていないならば0,何かのキが押されていれば,そのASCIIコードを値とする。
INKEY
INKEY
・キーが押されるのを待って1文字入力し,そのASCIIコードを値とする。
FLASH
FLASH
・カーソルを点滅させて1文字入力する。
CURX
CURX
・カーソルのX座標を値とする。
CURY
CURY
・カーソルのY座標を値とする。
TOP
TOP
・変数スタックのいちばん上に積まれている値を返す。
POP
POP
・変数スタックからポップした値を返す。
ADR
ADR(変数名)
・変数の値が格納されているアドレスを値とする。
VAL
VAL(式)
・式のアドレスより中間コードで置かれている1行の式を評価して値とする。
DSK
DSK
・デフォルトデバイス名を値とする。
NOW
NOW
・現在実行中の行番号を値とする。
LINADR
LlNADR(式)
・式の値で示される行番号を持つ行の格納されている先頭アドレスを値とする。
SIZE
SIZE
・テキストエリアの残りバイト数を値とする。
MAX
MAX
・フリーエリア上限のアドレスを値とする。
VERSION
VERSION
・S-OSのバージョンを値とする。
TXBEGIN
TXBEGIN
・テキストを格納している先頭アドレスを値とする。
TXEND
TXEND
・テキスト最終行のエンドコードを格納しているアドレス+1を値とする。
VSADR
VSADR
・変数スタックの先頭アドレスを値とする。
VEADR
VEADR
・変数スタックの最終アドレスを値とする。
MSP
MSP
・現在のマシンスタックポインタの値を返す。
CODE
CODE コマンド
   ステートメント
   関数
   出力関数
   論理演算子
・中間コードを値とする。
TABLE
TABLE(式)
・式の値を中間コードとする予約語をフルスペル(ASCIIコード列)で格納している予約語テーブル内のアドレスを返す(エンドコードは00H)。
NEST
NEST(式)
・式の値が0のとき
 式の値が1のとき
 式の値が2のとき
 式の値が3のとき
 式の値が4のとき
GOSUB/PROC/FUNC
FOR~NEXT
REPERT~UNTIL
WHILE~WEND
ブロックIF
のネステイングレベルを値とする。
 
表4 命令語省略形一覧 ((c):コマンド (s):ステートメント (f):関数 (p):PRINT文出力関数)
[A]
ADR(
AND
APPEND
AUTO
AUTO*
AD
AN.
AP.
A.
A.*
(f)
(f)
(c)
(c)
(e)
 
[B]
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)
 
[C]
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)
 
[D]
DEC
DECI(
DELETE
DEVICE
DEVI
DEVO
DIR
DSK

DE. or %
DEL.
DEV.


D.
DS.
(s)
(p)
(c)
(s)
(s)
(s)
(s)
(f)
 
[E]
EDIT
ELSE
END
END IF
ERMODE
EX(
E.
EL.

EN.
ER.
EX.
(c)
(s)
(s)
(s)
(c)
(f)
 
[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)
 
[G]
GET
GOSUB
GOTO
GE.
GOS. or !
G.
(f)
(s)
(s)
 
[H]
HEX@
HEX2(
HEX4(
HIGH(

H. or #
HEX4. or ##
HI.
(s)
(p)
(p)
(f)
 
[I]
IF
INC
INKEY
INP(
INPUT
INSTR(
INSTR$(


INK.

I.
INS.
INSTR$.
(s)
(s)
(f)
(f)
(s)
(f)
(f)
 
[K]
KEY0
KILL
K.
KI.
(s)
(s)
 
[L]
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)
 
[M]
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)
 
[N]
NEST(
NEW
NEXT
NOT(
NOW
NES.

N.
NO.
(f)
(s)
(s)
(f)
(f)
 
[O]
ON(
OR(
OUT(


O.
(s)
(f)
(s)
 
[P]
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)
 
[R]
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)
 
[S]
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)
 
[T]
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)
 
[U]
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)
 
[V]
VAL(
VEADR
VERSION
VLIST
VSADR
VSTACK
VA.
VE.
VER.
V.
VS.
VST.
(f)
(f)
(f)
(c)
(f)
(c)
 
[W]
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)
 
[X]
XOR
X.
(f)
 
[Z]
ZERO
Z.
(f)
 
図 メモリマップ
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)