MSX-BASIC

今更 MSX-BASIC を触る人がどれくらいいるだろう? とは思いますが、これはその昔、管理人がハマった言語です。 近年(2022年現在)では MSX3 が公式に登場する?という話も聞こえてきていますが、全然違う言語をサポートしそう。 MSX-BASIC は「MSXパソコン(Wikipedia)」に標準搭載されている BASIC言語(実質的OS)ですが、これが当時としてはよく考えられたものでした。 なお、下記は超基本的な事と謎な事しか書いてません。

- Index -

整数型の宣言
乱数の初期化
謎のTips! RND(-TIME) で高速化!?
初期ルーチンを後ろのほうにして高速化!?



整数型の宣言 どの言語でもそうですが、変数には文字型(String)と数値型があります。
数値型は更に実数型(Double)と整数型(Integer)があります。 そこで、数値型変数をどちらにするのか宣言が必要になってきます。 整数型に宣言するには、下記のようにします。

DEFINT A

これは、A という変数を整数型にするという意味です。 この変数に対して下記コードを実行してみます。

A=1.2

結果、変数 A には 1 が入ります。 先に整数型に宣言していたので、小数点以下は切り捨てられるのです。

整数型にすることのメリットとしては…

1. 変数に割り当てられるメモリを節約できる
2. 実行速度が速くなる(これがいちばんの理由ですね)

MSX-BASIC の場合、宣言無しの数値型変数は実数型(倍精度)として扱われます。 小数点以下を含む数値を扱えますが、その分処理速度は遅くなってしまいます。 これは体感できるくらいの違いがあるため重要です。 特にゲームを作る場合はほとんどは整数計算で問題ありませんし、できるだけ整数で済むようにコーディングすることが望ましいです。 そのような理由から、全ての数値型変数を整数型に宣言することがあります。

DEFINT A-Z

これを実行すると、全ての数値型変数を整数型に宣言したことになります。 ゲームなどでは初期ルーチンで必ずといっていいほど入っている処理です。

乱数の初期化
10 DEFINT A
20 A=RND(1)*100
30 PRINT A

上記は 0〜99 の乱数を表示するものです。
しかし、このままでは乱数のはずなのに RUN で実行するたびに数に変化がありません。 これは乱数の初期化を行っていないためです。 他の言語では RANDOMIZE と書いたりすることがありますが、MSX-BASIC の場合は下記のようにします。

A=RND(-TIME)

A という変数は何でも構いません。
これで乱数の初期化(初期値のかき回し)になります。 じつは TIME 関数を利用しているのですね。 TIME 関数は 1/60秒で自動的にカウントアップされるので、毎回初期値が変化するという仕組みです。

結果、下記のようなコードになります。

10 DEFINT A
20 A=RND(-TIME):A=RND(1)*100
30 PRINT A

実行してみると、ちゃんと乱数が得られます。

RND(-TIME) で高速化!? ※これはかなり怪しい情報ですが、うちの経験上は本当だったので一応載せてます。

10 DEFINT A-Z:I=RND(-TIME)

なぜか分からないのですが、これを初期ルーチンで実行しておくと、その変数が高速になるっぽいです。

10 DEFINT A-Z:I=RND(-TIME):X=RND(-TIME):Y=RND(-TIME):S=RND(-TIME)

このように、特に高速にしたい(使用頻度の高い)変数ほど先に書くと体感できるほどの違いが出ることがあります。 I という変数名は習慣的に汎用やループ用に使うことが多いため最初にしておきます。 ゲームを作っている際に気づいたことだったのですが、体感的に倍速程度の違いが感じられることさえあります。 理由はいまだに分かりません。オカルトチックですが、実機では明らかに差が現れていました。

たぶん、これについて書いているサイトは無いと思われます。長年の謎です。
想像ですが、メモリ配置が関係している可能性はあるような予感はしています。
それならば I=1 でも同じ効果があるのではないか?と書きつつ思いましたが、いま直ぐには実機で試せる環境がないので検証していません。

初期ルーチンを後ろのほうにして高速化!?
10 GOSUB 5000
20 …ここから以下メインルーチン

(中略)

以下初期ルーチン
5000 CLEAR 200:DEFINT A-Z:I=RND(-TIME)
5010 …以下初期ルーチン続き(スプライトの定義など、最初に1回実行する処理)

(中略)

5090 RETURN

当時の様々なコードを見ると、初期ルーチンを後ろに記述して GOSUB〜RETURN を使用している例が多いです。 私もこうしていました。じつは上のほうに書かれたコードほど実行速度が速いらしいのです。 上の方(メモリアドレスが若い)ほど RAM へのアクセスが速いとか何とか…当時聞いたのですが、本当なのかベンチとったわけではないです。処理速度を稼ぐのに色々工夫したものです。