[新連載]復活!TINY BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
すべてはここからはじまりました。
中日電工も。
40年前を振り返りつつ新連載です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第86回]
●RND
TINY BASICの関数は今回説明するRND(X)のほかにはABS(X)のみです。
TINY BASICの説明ではこのほかにSIZEも含めて関数(Function)としていますが、SIZEは関数というよりはシステム変数というほうが適切だと思います。
RND(X)は1〜Xまでの間の乱数を発生させます。
おそらくゲームプログラムへの応用を考えてのことかと思います。
ABS(X)はXの絶対値を計算します。
SIZEはテキストエリアの残りバイト数を示します。
今回はそのうちのまずはRND(X)について説明をします。
下がプログラムリストです。
RNDは乱数を発生させるのにTINY BASIC自身のプログラムROMを利用しています。
面白い発想です。
マシン語コードのプログラムをプログラムとしてではなくて16ビットデータの列として見ると順に出現する数値はランダムに並んでいるのではないか、という発想のようです。
RNDプログラムの説明です。
先頭でCALL PARNを実行します。
PARNは[第64回]のEXPR4プログラムの中にあります。
( )で囲んだ式の値を計算してHLに入れます。
RNDの()の値は1以上の正の数でなければなりません。
しかしRND(X)で得られる乱数は1〜Xの範囲の正の整数なのでX=1では乱数になりません。
せめてX>=2である必要があります。
とにかくそういうことなので、Hの値が負のときはHOW?が表示されます。
HLが0の場合もHOW?が表示されます。
そのあと
0431 PUSH D
0432 PUSH H
で現在のテキスト行の位置アドレスと()内の値とをスタックに保存します。
0433 LHLD RANPNT
でHLにRANPNTの値を読み込みます。
RANPNTにはプログラムROM内のアドレスが乱数を計算するもととなるアドレスとして入っています。
RANPNTにはTINY BASICのスタート時に初期値として0000が入れられます([第25回]参照)。
0436 LXI D,LSTROM
でLSTROM(ROMプログラムの最終アドレス、0769)をDEに入れます。
0439 RST 4
043A JC RA1
043D LXI H,START
0440 RA1:MOV E,M
のところでROMのアドレスをチェックします。
RST 4は[第12回]で説明しました。
HLとDEを比較します。
HL<DEのときはキャリーフラグが立ちます。
そのときはRA1にジャンプします。
HL>=DEのときは、HLには初期値(START、0000)が再セットされます。
RA1:からが乱数の計算です。
0440 RA1:MOV E,M
0441 INX H
0442 MOV D,M
0443 SHLD RANPNT
までのところでは、HLで示すアドレスのメモリの値をEに、HL+1で示すアドレスのメモリの値をDに入れます。
HLの値は+1されます。
そのHLの値を新しいRANPNTの値としてRANPNTに入れます。
このときDEにはROMプログラムの連続する2バイトのマシン語の16進数の値が入ります。
プログラムのマシン語コードなので割りとランダムな値になると考えられます。
0446 POP H
でスタックに保存しておいたRND()の()内の値をHLに入れます。
0447 XCHG
でHLとDEの値を交換します。
0448 PUSH B
は以下の計算でBCレジスタを使うので事前にBCレジスタの値を保存しておくためです(おそらくCレジスタの保存のため)。
0449 CALL DIVIDE
で除算を行ないます。
DIVIDEは[第48回]で説明しました。
HL/DEを計算します。
除算の結果の値(商)はBCに、余りはHLに入れられます。
ここで乱数として使うのは商ではなくて余り(HLの値)です。
この計算によってHLは0からX−1までの値になります。
XはRND(X)のXです。
最後に
044E INX H
でHLの値を+1してリターンします。
最後に+1しているのは結果が0にならないようにするためと最大値がXになるようにするためだと思います。
さて。
コンピュータで乱数を発生させるというのは実はなかなかに難しいことのようです。
本当に偏りのない乱数を発生させるのはとても難しいことらしく、一般には擬似乱数というようです。
そのアルゴリズムにもいろいろあるようでネットで検索すると簡便なものから高度な計算を必要とするものまでいろいろな方法がみつかります。
それではTINY BASICのRNDプログラムは?といいますと、上で説明しましたようになんだかあっけないくらい簡単なプログラムです。
ええっ?
こんなんで本当に乱数になるの?
と疑問に思ってしまいます。
ということで、念のため、次回ではTINY BASICのRND関数を実際に使って、その実力のほどを検証してみることにします。
復活!TINY BASIC[第86回]
2020.9.10upload
前へ
次へ
ホームページトップへ戻る