I/O誌のBASIC COMPILER/BMを動かしてみる

BASICMASTER

I/O 1981年6月号pp105-112に、L1 BASICのコンパイラ(BASIC COMPILER/BM)が掲載されている。

大昔、学生だったころはGAMEかKUMAJIRIコンパイラばかり使っていて、L1 BASICコンパイラを使った記憶がほとんどない。

幸い、昔と違って生成AIを使えばダンプリスト入力は簡単にできる。geminiを使ったら ほぼノーエラーで入力できた。しかし…



deBUG多数なので注意

BASIC COMPILER/BM関連の記事は以下の5冊に掲載されている。6月号がコンパイラの本体(ダンプリスト)とサンプルプログラム(L1 BASIC)。

7月号は記事中のミスと注意書きの追加。

10月号は注意書きとダンプが載っているが、このダンプは別のプログラムのものが誤って掲載されているように思われる。このダンプは使ってはいけない。

11月号にようやく正しいダンプが載ったが、まだ足りない。翌1982年の1月号にさらに抜け分の掲載記事(2バイト)があり、ここまで追加してようやく動くようになった。

結局、最初に掲載されてから動作するようになるまで半年以上かかっている。不遇なコンパイラである。

  • I/O 1981年6月号pp.105-111
  • I/O 1981年7月号p.257
  • I/O 1981年10月号p.272
  • I/O 1981年11月号p.283
  • I/O 1982年1月号p.271

私自身は、I/O誌1980年8月号に掲載されたKUMAJIRI をベーシックマスターに移植して使っていた。ASCII 1981年5月号にはGAME68コンパイラも掲載され、そちらの移植作業も行なっていたので、L1 BASIC COMPILERまでは手が回らなかったのだろう。

実行してみる

エミュレーターで動かしてみた。サンプルの素数プログラム。

コンパイラに内蔵の L1 BASICインタプリタで実行すると bm2では1007秒。j68だと1059秒。タイマー関連はj68の方が正確なので、以下j68で測定。

コンパイル後はj68が108秒。10倍速くなる。GAME-MBインタプリタでは340秒、コンパイルすると85秒である。

L1インタプリタとGAMEインタプリタでは3倍の差があるが、コンパイルすると2割しか変わらない。ちなみに拙作のGAME-CCだと36秒。

L1 BASICは遅い

L1 BASICをコンパイルすると10倍速くなるのだけど、これはL1インタプリタが遅いせいでもある。

日立のL1 BASICインタプリタは、ダブルインタプリタになっていて、BASICインタプリタ自身が中間言語インタプリタ上で動いている。

元はテキサス版Tiny BASICのようで、中間言語部分は8080用のTexas Tiny BASICのコードとそっくりである。

興味がある方はBASIC COMPILER/BMの$6000から格納されているインタプリタを読んでみると良い。
$6594(ROM版は$D594)に中間言語のインタプリタ部分がある。

詳細は下記ページを参照のこと。


BASIC COMPILER/BMの出力コード

コンパイラを動かすのに32KBの領域が必要だが、コンパイラ自身が$6000-$7FFFを使うので、ワークエリアは20KBほど。

とにかくメモリを食わないようにコンパイラを作らないといけないので、最適化はおろかASTを作ることもできない。
アセンブルコードを吐くこともできないので、ジャンプ先の処理もなにもかも自前でやる必要がある。

数値や変数を読んではサブルーチンコール、演算子を読んではサブルーチンコールせざるを得ない。

素数プログラムの 40 B=B+2 は下記のようなコードに落ちる。

演算用のスタックが 〜$008Fにあって、AccBが8bit長の仮想スタックポインタになっている。まるで6502である。

変数や数値をいちいち仮想スタック経由で操作するのは遅いので、pushに該当する操作は直接STXしている。加算や代入処理はサブルーチン経由である。


Z07CA   CLRB                             ;
        LDX     #M0502                   ; Bのアドレス
        STX     M008E                    ;
        DECB                             ;
        LDX     M0502                    ; Bの内容を$8Cに入れて
        STX     M008C                    ;
        DECB                             ;
        LDX     #M0002                   ; 2を$8Aに入れて
        STX     M008A                    ;
        DECB                             ;
        JSR     Z7A66                    ; $8C = $8C + $8A
        JSR     Z7B69                    ; $8E = $8C

GAME-MBコンパイラだと、素直にAccABで処理する。ここだけ見ると大差だが、素数プログラムは剰余演算の比重が高いので、全体ではそれほど差がつかない。


        LDAB    $77
        LDAA    $76
        ADDB    #$02
        ADCA    #$00
        STAB    $77
        STAA    $76

拙作GAME-CCは、IXを使った方が速い場合はそちらを使う。サイズも小さくなる。


        LDX     _B
        INX
        INX
        STX     _B

出た時期が悪かった

L2 BASICのコンパイラは実数演算が必要になるし、どうしても大きく・遅くなる。割り切ってL1 BASIC用にしたのは悪くない判断だと思う。

GAMEやKUMAJIRIが実用になっていたのだから、L1 BASICでも十分なはず。

問題は提供された時期で、ちゃんと動くようになった1981年末には、既にGAMEやKUMAJIRIコンパイラが実用的に使われていたので、L1 BASICを使うメリットが無くなっていた。

せめて初出時に抜けなしで掲載されていれば、もう少しは使われたように思われる。

掲載誌

  • I/O 1981年6月号pp.105-111
  • I/O 1981年7月号p.257
  • I/O 1981年10月号p.272
  • I/O 1981年11月号p.283
  • I/O 1982年1月号p.271


おまけ

ダンプリストをモトローラS形式に変換する perl スクリプト。

コメント

タイトルとURLをコピーしました