擬似乱数を実装
2012年7月31日
0から32767までの擬似乱数を発生する関数、RND()を実装した。

はじめ、stdlib.hにあるrand()関数を使用しようとしたが、スタティック変数の初期化部分が現在のSDCCを使用したMZ-80用のプログラミングにあわないため、自分で書くことにした。よく使われる32ビット整数に定数を掛けて定数を足すやり方で実装しようとしたところ、32ビット演算用のCのライブラリの大きさなのだかの理由で、2kbの大きさになってしまった。コードがこんなに大きくては使えない。色々調べた結果、Microchip社のMathユーティリティ(AN544)に載っている方法を採用することになった。該当部分のコードは、以下のとおり。
ビット15, 14, 12, 3のXORを取り、それをビット0に入れるような方法で左シフトする。この変換を1回行っただけだと、発生する乱数が前の乱数の2倍に近いような値に偏るため、15回演算した後に下位15ビット(0-32767)を返すようにしてある。

はじめ、stdlib.hにあるrand()関数を使用しようとしたが、スタティック変数の初期化部分が現在のSDCCを使用したMZ-80用のプログラミングにあわないため、自分で書くことにした。よく使われる32ビット整数に定数を掛けて定数を足すやり方で実装しようとしたところ、32ビット演算用のCのライブラリの大きさなのだかの理由で、2kbの大きさになってしまった。コードがこんなに大きくては使えない。色々調べた結果、Microchip社のMathユーティリティ(AN544)に載っている方法を採用することになった。該当部分のコードは、以下のとおり。
void getRand(){
__asm
LD HL,(#_g_seed)
LD B,#15
loop:
LD A,H
RLA // bit 14 of HL will be in bit 7 of A
XOR H // XOR of bits 15 and 14 of HL will be in bit 7 of A
RLA // XOR of bits 15 and 14 of HL will be in carry bit
RLA // XOR of bits 15 and 14 of HL will be in bit 0 of A
LD D,A // Store XOR value in D register
LD A,H // bit 12 of HL will be in bit 4 of A
RRA // bit 12 of HL will be in bit 3 of A
XOR L // XOR of bits 12 and 3 of HL will be in bit 3 of A
RRA // XOR of bits 12 and 3 of HL will be in bit 2 of A
RRA // XOR of bits 12 and 3 of HL will be in bit 1 of A
RRA // XOR of bits 12 and 3 of HL will be in bit 0 of A
XOR D
AND #0x01
ADD HL,HL
OR L
LD L,A
DJNZ loop
LD (#_g_seed),HL
LD A,H
AND #0x7F
LD D,A
LD E,L
__endasm;
}ビット15, 14, 12, 3のXORを取り、それをビット0に入れるような方法で左シフトする。この変換を1回行っただけだと、発生する乱数が前の乱数の2倍に近いような値に偏るため、15回演算した後に下位15ビット(0-32767)を返すようにしてある。