HOMEへ戻る

[新製品]整数型Z80BASICコンパイラ
SBASIC

[SBASICの特徴]
 SBASICコンパイラはZBK開発セットに付属します。ソフトウェア単体での販売はしません。
 SBASIC.COMはWindowsのDOSプロンプト(DOS窓)上で実行しますが、コンパイル動作はZBK開発セットの接続を必要としません。
 ユーザーが作成したBASICソースプログラム(テキストファイル形式)を読み込んで、Z80マシン語バイナリファイルを生成します。
 生成されるバイナリファイルはZ80マシン語ですがZBKボードのシステムROM内サブルーチンをCALLしているので、ZB10K〜ZB28K以外のZ80ボードでは実行させることができません。
[SBASICはV3BASICのためのマシン語サブルーチン作成が目的]
 SBASICはZBKボードのV3BASICと基本的に同じ文法になっていますが、整数型と文字型しか扱いません。浮動小数点演算は行えません。SBASICの開発のコンセプトは一般的なI/O制御など複雑な計算は必要としない用途に対して、マシン語プログラムに近い高速処理を行わせることにあります。
V3BASICはC言語などと違って文法が極めて容易で、簡単にプログラミングができる反面、浮動小数点演算や関数計算など高度な計算処理機能をもたせたために、単純な整数型の計算処理でもそれなりの時間がかかってしまう欠点があります。それでも一般的なI/O制御はそれほどの速度を必要とするものは少ないので大抵の場合にはBASICインタプリタで十分に制御可能です。どうしてももっと速い処理が必要な場合にはその部分のみマシン語サブルーチンを作って対応することを推奨してきました。
 マシン語でのプログラミングはZBK開発セットに付属しているZ80クロスアセンブラを用いて行うことができますが、実際のプログラミングはBASICとは異なってZ80マシン語についてのかなりの知識、経験を必要とします。一般のユーザーはBASICとは比較にならないハードルの高さを意識せざるを得ませんでした。
 SBASICはこのハードルの高さをBASICのレベルまで下げるものです。
[SBASICは整数型と文字型の処理のみ]
 SBASICはV3BASICのマシン語サブルーチンに代わるものという位置付けから、単純な処理を対象に高速で行うことを開発の主目的にしました。そのため整数型と文字型の処理しか行わず、扱える関数も限られた種類になっています。
●変数名A%〜Z%、A$〜H$
 扱える変数名はV3BASICと共通の固定メモリ領域に割り当てられる、A%〜Z%(整数型2バイト)とA$〜H$(文字型39バイト)のみです。いずれの変数もメインプログラムであるV3BASICに対してローカル変数ではなく、V3BASICと同じ名前、同じメモリ領域に割り当てられます。したがってV3BASICとSBASICとの間でのデータの受け渡しについてユーザーは意識することなく容易に行うことができます。
●配列名@( )
 SBASICはこの他に2バイトの1次整数型配列@( )を使うことができます。@( )もV3BASICと領域を共有することができます。
●メモリアクセス用変数[ ]
 V3BASICにはない特殊な変数として [ ]を使うことができます。1バイトの変数で[ ]の中に変数名、定数や計算式を書くことでその値が示すメモリアドレスをアクセスすることができます。BASICのPOKE、PEEKに相当する機能ですが、マシン語のメモリアクセスに近い感覚で扱うことができます。
●使用できる命令
FOR〜NEXT、GOSUB〜RETURN、GOTO、IF…GOTO、OUT、PRINT、
INC、DEC、IFNZ GOTO、IFZ GOTO(V3BASICには無い命令です)
●使用できる関数
ABS、AND、ASC、CHR$、HEX$、IN、LEFT$、LEN、MID$、OR、RIGHT$、SGN、STR$、VAL、XOR
[使い方]
 (1) プログラムの作成
 ソースプログラムはテキストエディタ(notepad)などを使って作成します。ファイル名はMSDOSのルールにしたがいます(最大8文字の英数字+拡張子.txt)。

[簡単なプログラム例] ファイル名 TEST1.TXT
' TESTPROGRAM
    ORG=$4004
    A%=0:B%=2
*LOOP:PRINT A%,B%
    A%=A%+5:B%=B%+3
    IF A%<50 GOTO *LOOP
    PRINT "END"
    RETURN

●上例からわかるようにSBASICでは行番号はつけません(つけてもエラーにはなりません。コンパイラは行番号を無視します)。
(2) プログラムのコンパイル
 DOSプロンプト(DOS窓)でSBASIC.COMを実行します。

C:¥zbk>SBASIC TEST1.TXT[Enter]
TEST1.BIN ...OK $006C(108)bytes
TEST1.WK ...OK
C:¥zbk>

SBASIC.COMが正常に終了すると、マシン語バイナリファイル(TEST1.BIN)と翻訳情報ファイル(TEST1.WK)が作成されます。
翻訳情報ファイルは通常は参照する必要はありません。マシン語に翻訳されたアドレスの情報が記録されています。
(参考までに)
[作成されたTEST1.WKの内容]
0000 ' TESTPROGRAM
0000    ORG=$4004
4004    A%=0:400A B%=2
4010 *LOOP:4010 PRINT A%,B%
402A    A%=A%+5:4038 B%=B%+3
4046    IF A%<50 GOTO *LOOP
405D    PRINT "END"
406E    RETURN
406F

(3) プログラムの実行
 SBASICコンパイラによって作成されたバイナリファイルTEST1.BINはZBKシステムを起動させて、/LDコマンドで$4004番地にロードしたあと、USR($4004)命令によって実行することができます。下にTEST1.BINのロード、USR($4004)のダイレクト命令による実行結果を示します。

DEBUG TOOL FOR KL5C8012
(C)Copyright CHUNICHIDENKO 2000,2001,2004,2005 Rev.1.4
02
t/0202
)Z
>/LD TEST1.BIN,4004
TEST1.BINのロード
006CBYTES LOAD
>USR($4004)
TEST1.BINの実行
0 2
5 5
10 8
15 11
20 14
25 17
30 20
35 23
40 26
45 29
END


AここではUSR($4004)をダイレクト実行していますが、一般的には次のようにBASICプログラムとして実行させます(マシン語サブルーチンのメモリエリアを確保するためにBASICプログラム作成前にNEWコマンドの実行が必要です。

>NEW,4100
>10 USR($4004)
>RUN

[SBASICの実行速度]
 ZBK−V3BASIC(インタプリタ)とSBASICとでどのくらい実行速度が違うのかテストプログラムで比較してみました。
 最初にZBKボード上でV3BASICのテストプログラムを実行し、次に同じZBKボード上でSBASICでコンパイルしたプログラムを実行し両者の実行時間を比較しました。
[比較その1]
(A)ZBK−V3BASIC

10 TIME$="00:00:00"
20 FOR A%=0 TO 10000
30 FOR B%=0 TO 100
40 NEXT B%
50 NEXT A%
60 PRINT TIME$
>RUN
00:01:15

 100万回のループの実行時間は75秒です。1回の実行時間は75μ秒です。8ビットCPU上でのBASICインタプリタとしては結構速いと思いませんか?
(B)SBASIC
ソースプログラムリスト(sbtest14.txt)

'SBASIC TEST14
      ORG=$4004
      FOR  A%=0 TO 10000
      FOR B%=0 TO 100
      NEXT
      NEXT

●SBASICではNEXTに変数名は不要です。
コンパイル後のバイナリファイルをZBKボードにロードして実行します。
>/LD SBTEST14.BIN,4004
003BBYTES LOAD
>NEW,4100
10 TIME$="00:00:00"
20 USR($4004)
30 PRINT TIME$

>RUN
00:00:18

 100万回のループの実行時間は18秒です。1回の実行時間は18μ秒です。
[比較その2]
(A)ZBK−V3BASIC

10 TIME$="00:00:00"
20 A%=10000
30 B%=100
40 B%=B%-1
50 IF B%>0 GOTO 40
60 A%=A%-1
70 IF A%>0 GOTO 30
80 PRINT TIME$
>RUN
00:07:35

 100万回の減算+比較+ジャンプの実行時間は455秒です。1回の実行時間は455μ秒です。上と同じ処理ですがこちらは減算やIFに時間がかかります。FOR〜NEXTの方が圧倒的に速いようです。
(B)SBASIC
ソースプログラムリスト(sbtest15.txt)

'SBASIC TEST15
     ORG=$4004
     A%=10000
*LOOP1:B%=100
*LOOP2:B%=B%-1
     IF B%>0 GOTO *LOOP2
     A%=A%-1
     IF A%>0 GOTO *LOOP1

コンパイル後のバイナリファイルをZBKボードにロードして実行します。
>/LD SBTEST15.BIN,4004
005BBYTES LOAD
>NEW,4100
10 TIME$="00:00:00"
20 USR($4004)
30 PRINT TIME$

>RUN
00:00:18

 100万回の減算+比較+ジャンプの実行時間はFOR〜NEXTと同じ18秒です。1回の実行時間は18μ秒です。インタプリタに比較して圧倒的に速くなっています。
(C)SBASICプログラム例2
 SBASICでは減算+比較+ジャンプの処理をより高速で行うための命令(DEC、INC、IFNZ、IFZ)が用意されています。上の例のように変数の値を−1して0になるまで繰り返す処理に最適です。
ソースプログラムリスト(sbtest16.txt)

'SBASIC TEST16
     ORG=$4004
     A%=10000
*LOOP1:B%=100
*LOOP2:DEC B% IFNZ GOTO *LOOP2
     DEC A% IFNZ GOTO *LOOP1

コンパイル後のバイナリファイルをZBKボードにロードして実行します。
>/LD SBTEST16.BIN,4004
0025BYTES LOAD
>NEW,4100
10 TIME$="00:00:00"
20 USR($4004)
30 PRINT TIME$

>RUN
00:00:03

 100万回の減算+比較+ジャンプの実行時間は3秒です。1回の実行時間は3μ秒です。
[参考までに。N88BASIC(PC9821Xe10)との比較]
 コンパイラはともかくとして、ZBK−V3BASICインタプリタは遅すぎるではないか、と思われたあなた。CPUが8ビット、クロック10MHzというスペックを忘れてはいけません。
 参考までにN88BASICでも同じプログラムを実行してみました。マシンはPC9821Xe10(CPUはi486、クロック100MHz)です。
 比較その1のFOR〜NEXT100万回は12秒、比較その2の減算+比較+ジャンプ100万回は48秒でした。

HOMEへ戻る