16ビットマイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第60回]
●倍精度RND#関数/32bit Xorshift
前回は単精度の浮動小数点計算プログラムに合わせるため、インターネットを検索してみつけたサイトから16bitのXorshiftを有難くいただいてRND関数として実装しました。
その際引用元のサイトを紹介しようとして、うっかり間違えて別のサイトを紹介してしまいました。
現在は正しいサイトのリンクに訂正済みです。
前回はXorshiftについて、ネットで紹介されているものの多くは32bit版なので、単精度浮動小数点計算プログラムには使えない、ということでネットをサーチして16bit版をみつけて組み込んだのでしたが、よく考えてみましたら、32bit版は倍精度浮動小数点計算プログラムには使えることに気が付きました。
倍精度浮動小数点計算では符号なし正の数は55bitまで扱えます。
それなら余裕で32bitのXorshiftを組み込むことができます。
32bitのXorshiftはWikipediaにも何例かが紹介されていますが、そのうちの最もシンプルなものを使わせていただくことにしました。
ただどうもWikipediaで紹介されているシフト回数(左13、右17、左15)はどうやらミスプリントのような気がします。
試してみたのですが、ちょっと数値に偏りが出るようです。
それで、こちらのサイトで紹介されていたシフト回数(左13、右17、左5)を使わせていただくことにしました。
こちらも英文ですけれど。
Xorshift RNGs for small systems(http://excamera.com/sphinx/article-xorshift.html)
下は同サイトを参考にさせていただいて86BASICに組み込んだ倍精度RND#関数部分のプログラムリストです。
今回のRND#関数も前回の単精度RND関数と同様、使い勝手を考えて0より大きくて1より小さい小数を出力します。
[00165] ;DRND=6D99 [00166] 6D99 50 PUSH AX [00167] 6D9A 53 PUSH BX [00168] 6D9B 51 PUSH CX [00169] 6D9C 52 PUSH DX [00170] 6D9D 56 PUSH SI [00171] 6D9E A1DDF2 MOV AX,[RNDVLX] [00172] 6DA1 0BC0 OR AX,AX [00173] 6DA3 750E JNZ DRND1 <6DB3> [00174] 6DA5 8B16DFF2 MOV DX,[RNDVLY] [00175] 6DA9 0BD2 OR DX,DX [00176] 6DAB 7506 JNZ DRND1 <6DB3> [00177] 6DAD B8A28C MOV AX,8CA2;=2463534242 [00178] 6DB0 BAD692 MOV DX,92D6 [00179] 6DB3 8BD8 DRND1:MOV BX,AX [00180] 6DB5 8BF2 MOV SI,DX [00181] 6DB7 B10D MOV CL,0D;=13 [00182] 6DB9 D1E0 DRND2:SHL AX [00183] 6DBB D1D2 RCL DX [00184] 6DBD E2FA LOOP DRND2 <6DB9> [00185] 6DBF 33C3 XOR AX,BX [00186] 6DC1 33D6 XOR DX,SI [00187] 6DC3 8BD8 MOV BX,AX [00188] 6DC5 8BF2 MOV SI,DX [00189] 6DC7 B111 MOV CL,11;=17 [00190] 6DC9 D1EA DRND3:SHR DX [00191] 6DCB D1D8 RCR AX [00192] 6DCD E2FA LOOP DRND3 <6DC9> [00193] 6DCF 33C3 XOR AX,BX [00194] 6DD1 33D6 XOR DX,SI [00195] 6DD3 8BD8 MOV BX,AX [00196] 6DD5 8BF2 MOV SI,DX [00197] 6DD7 B105 MOV CL,5 [00198] 6DD9 D1E0 DRND4:SHL AX [00199] 6DDB D1D2 RCL DX [00200] 6DDD E2FA LOOP DRND4 <6DD9> [00201] 6DDF 33C3 XOR AX,BX [00202] 6DE1 33D6 XOR DX,SI [00203] 6DE3 0BC0 OR AX,AX [00204] 6DE5 750A JNZ DRND5 <6DF1> [00205] 6DE7 0BD2 OR DX,DX [00206] 6DE9 7506 JNZ DRND5 <6DF1> [00207] 6DEB B8A28C MOV AX,8CA2;=2463534242 [00208] 6DEE BAD692 MOV DX,92D6 [00209] 6DF1 A3DDF2 DRND5:MOV [RNDVLX],AX [00210] 6DF4 8916DFF2 MOV [RNDVLY],DX [00211] 6DF8 D1EA SHR DX [00212] 6DFA D1D8 RCR AX [00213] ; [00214] 6DFC 33DB XOR BX,BX [00215] 6DFE 891EF7F1 MOV [*FAH0],BX [00216] 6E02 881EF9F1 MOV [*FAH2],BL [00217] 6E06 A3FAF1 MOV [*FAH3],AX [00218] 6E09 8916FCF1 MOV [*FAH5],DX [00219] 6E0D 891EFEF1 MOV [*FAH7],BX [00220] ; [00221] 6E11 57 PUSH DI [00222] 6E12 E8C702 CALL FNRZ <70DC> [00223] 6E15 5F POP DI [00224] 6E16 5E POP SI [00225] 6E17 5A POP DX [00226] 6E18 59 POP CX [00227] 6E19 5B POP BX [00228] 6E1A 58 POP AX [00229] 6E1B C3 RET |
そして下はRND#のテストプログラムと、その実行結果のログです。
RND#を呼ぶたびに得られる小数を10倍して、それを整数化することで、0〜9の出現率を集計します。
前回と同様に、最初にテストのために作ったプログラムは100個の数を出力するものでしたが、ちょっと少ないので1000個に変更して実行しました。
1000個の数を出力しますので、長くなりますから途中から後ろは省略しました。
>. 10 DIM SUM(10) 20 FOR I%=0 TO 9 30 SUM(I%)=0 40 NEXT I% 50 FOR N%=0 TO 99 55 J#=RND#*10 60 J%=INT(J#) 65 PRINT J# 70 SUM(J%)=SUM(J%)+1 80 NEXT N% 85 PRINT "*** total ***" 90 FOR I%=0 TO 9 100 PRINT I%,SUM(I%) 110 NEXT I% > 50 FOR N%=0 TO 999 >r. 2.650548508390784 1.019630888476968 5.496233752928674 9.850675333291292 0.3015256021171808D-1 9.794000228866935 3.122008945792913 1.109533817507327 2.921380344778299 6.791556607931852 0.9356176573783159 2.082222597673535 6.927995583973825 6.918896185234189 1.417034310288727 1.495721628889441 9.912803852930665 6.350246015936136 4.80824975296855 9.270115941762924 0.8053133683279157 3.724904297851026 7.156409691087902 4.85046561807394 5.475174710154533 9.352885149419308 7.514114063233137 4.597803764045238 1.567883798852563 6.747597646899521 7.469460684806108 9.491493585519493 2.77332860045135 6.704114167951047 8.185763978399336 3.935285890474916 6.501082014292479 4.957326641306281 8.552479213103652 5.437393900938332 5.753735820762813 1.602707905694842 5.669019613415003 4.787343135103583 8.703863648697734 0.1203180523589253 5.309926080517471 0.2047484600916505 7.767739803530276 1.946398857980967 2.16327540576458 4.669739007949829 9.878313760273159 5.246990034356713 1.25498537439853 1.34437526576221 4.604878509417176 7.117380853742361 |
こちらは最後の集計結果を表示している画面です。
出力される数値も見たところランダムなようですし、0〜9に分けて集計した結果も大体同じぐらいの割合になっているようです。
16ビットマイコンボードの製作[第60回]
2018.7.22upload
前へ
次へ
ホームページトップへ戻る