doc drawn up: 2006-01-15 .. 2012-11-25
BASIC 略記
はじめに
最近ゲームプログラミングに挑戦してみて、QBASIC という Microsoft 製の BASIC を使う機会がありました(参照:『勇者ハニワ』)。太古の昔に、Sharp 製 X-68000 用の X-BASIC や、NEC 製 PC-9801 用の N88-BASIC を使った経験があるのですが、その時は単なる数値計算のためにしか使わなかったので、FORTRAN 77 との違いをあまり感じませんでした。今回、BASIC を使ったのは、ゲームという、入出力制御を主眼とするものなので、その時の使い方とは全く異っています。
もっと昔の子供の時分、自分がプログラミング能力とは無縁だった時代には、電波通信社の『ベーシックマガジン』(通称ベーマガ)に掲載されている投稿プログラムを通じてお馴染みの BASIC だったはずなんですが、「高度なプログラムはどうせ BASIC では不可能なんだろう」という先入観があって、ほとんど興味が湧きませんでした。しかし実際の所、それがほとんど思い違いだったと言えます。当時、マシン語やアセンブリ言語がもてはやされていた理由は「当時の PC の低い性能では BASIC だと速度面での十分なパフォーマンスが得られない」というのが本当のところでしょう。
今さらながら BASIC に触れてみて、その存在価値を再発見した思いです。特にゲームプログラミングを学習するには、BASIC ほど最適な言語環境はないのではないかと思います。GUI-OS の時代になって(かつてあったような DOS 環境の)BASIC が存続していないのが残念に思えます。QBASIC のように、出力(画像)と入力(キーボード)が標準命令として用意されていて、しかも都度実行型であるという言語体系は、入門者にとっては大変重要だと思うのです。
本当に簡単なメモ
- FORTRAN の影響を一番強く受けているので、全体としては FORTRAN のクセに近いものを持っている。例えば、配列変数を使う場合最初に配列の次元と大きさを DIM 文で宣言しておく、等。
- 複数命令文という記述方式がある。本来、一行に一つの命令文が基本だが、「:」(コロン)で区切ることによって、一行に複数の命令文を押し込めることができる。これは、ブロック指向ではない行指向の命令文(例えば IF … THEN ~)を使う場合に便利だから、らしい。
C や Perl の「;」(セミコロン)に似ているが、C/Perl の「;」は BASIC の「:」と違ってむしろ必須だし、また C/Perl は基本的にブロック指向なので必ずしも複数命令文形式にする必要性はない。
- QBASIC という方言固有の話なのかもしれないが、なぜか、真偽値が「真 = -1」、「偽 = 0」である(これは本来、二進数で「真 = 11111111」、「偽 = 00000000」なのであり、それを十進表記したら -1 と 0 になっているだけだと考えれば納得がいく)。
そこで、
col = col + (col < sa) * s0 + (col >= sa) * s7
このような式の場合、col < sa の場合は、
col = col + (-1) * s0 + (0) * s7 = col - s0
を意味し、col >= sa の場合は、
col = col + (0) * s0 + (-1) * s7 = col - s7
を意味することになる。もちろん、ちゃんと IF 文を使って、場合分けして記述しても同じ結果を得ることができる。省略した記述方法に過ぎない。
- 変数の種類は、変数名の末尾に「$」や「%」のような記号を付けることによって区別する。
- 「!」(実数。デフォルトなので省略可)
- 「#」(倍精度の実数)
- 「%」(整数)
- 「&」(倍精度の整数)
- 「$」(文字列)
この規則は、Perl の変数名に関する規則に似ている(Perl は変数名の頭に記号を付ける)。Perl の方が新しい言語なので、恐らく Perl が BASIC から借りてきたアイデアなのだろう。記号が付いていると一目で変数だとわかり、Perl っぽくて見やすいので、僕は「!」も含めてわざと使うようにしている。
- 明らかに QBASIC(というよりDOS)に固有の話だが、画像(VRAM)の書換のタイミングを取るための定番のテクニックが存在する。それは I/O ポート 3DA 番地の第 3 ビット(最下位ビットから 4 桁目)をチェックするものである。画像が書換中の場合は、このビットが 0 になっており、書換が済んでいれば 1 になっている。他のビットに関しては無関係。すなわち、
????0???
の時は書換中で、
????1???
の時は書換済なので、
00001000
と論理積(AND)を計算すれば、
0 と AND されたビットは ? が 1 だろうが 0 だろうが結局は 0 となり、1 と AND されたビットは 1 であれば 1、0 であれば 0 となるので、結局第 3 ビットが 1 の場合は論理積の結果が 00001000(= 8)となり、0 の場合は論理積の結果が 00000000(= 0)となることから、条件判定を使って状態を調べることができる。
vsync:
vs! = INP(&H3DA)
IF (vs! AND &H8) = 0 THEN GOTO vsync
このようにすれば、画像の書換が終わるまで次の処理に移ることがなく、画像のチラツキを抑えることができる。
参考
©2006-2012 Masanori HATA
<Programming>