2014.11.24

前へ
次へ
ホームページトップへ戻る

MYCPU80でCP/Mを!
超巨大基板の8080互換HCMOS・CPUでCP/Mを走らせてしまおうという、なんとも狂気なプロジェクトです!


[第70回]


●倍精度実数演算プログラムの組込み(3)

紅葉も見ごろとなりましたこの連休でしたが、もちろん私はといえば、とてもとても紅葉狩りどころではありませんで、ひたすらMYCPU80にZB3BASICを組み込む作業をしておりました。
前にも書いたことですが、24KBもあるZ80のマシン語プログラムを8080の命令に置き換えるという作業はなかなかに苦しい作業です。
なにしろZ80にあって8080にはない命令がそれこそ山ほどあって、それを8080の命令に置き換えなければいけません。
レジスタだってZ80は8080の倍以上あります。
フラグも複雑です。
Z80の命令を8080の命令に置き換える過程で、ついうっかりフラグの設定を間違えたり、見落としたりしてしまい、そのために1日も2日も異常な動作に悩むことになります。
なかなかにつらい作業です。
しかし徐々にではありますが、やっと努力の成果が見えてきました。
その成果報告です。

まずは、倍精度のSIN関数です。

    10 FOR A#=0 TO 90 STEP 5
    20 PRINT A#,SID(A#)
    30 NEXT A#
    40 PRINT "end"
>r.
 0            0
 5            0.8715574274765816D-1
 10           0.1736481776669303
 15           0.2588190451025207
 20           0.3420201433256687
 25           0.4226182617406994
 30           0.5
 35           0.5735764363510461
 40           0.6427876096865393
 45           0.7071067811865475
 50           0.766044443118978
 55           0.8191520442889917
 60           0.8660254037844386
 65           0.90630778703665
 70           0.9396926207859083
 75           0.9659258262890682
 80           0.984807753012208
 85           0.9961946980917455
 90           1
end

SID()は度を与えます。
プログラムの内部では、それをラジアンに換算して計算しています。
ラジアンを置数とする場合にはSIN()を使います。
()の中に単精度の変数、定数を書くと単精度で計算され、倍精度の変数、定数を書くと倍精度で計算が行なわれます。

こちらはCOS関数です。

    10 FOR A#=0 TO 90 STEP 5
    20 PRINT A#,COD(A#)
    30 NEXT A#
    40 PRINT "end"
>r.
 0            1
 5            0.9961946980917456
 10           0.9848077530122081
 15           0.9659258262890682
 20           0.9396926207859083
 25           0.90630778703665
 30           0.8660254037844386
 35           0.8191520442889918
 40           0.766044443118978
 45           0.7071067811865475
 50           0.6427876096865393
 55           0.5735764363510461
 60           0.5
 65           0.4226182617406995
 70           0.3420201433256688
 75           0.2588190451025208
 80           0.1736481776669304
 85           0.8715574274765818D-1
 90           0
end

COD()は置数が度です。
ラジアンの場合はCOS()を使います。

SID()、COD()とも最下位桁に誤差があります。
なにしろ最良近似式なんて知識がなかったころに書いたプログラムですのでかなり苦しいことをしています。
幸い今は最良近似式の出し方も会得できましたので、そのうち時間が取れるようになりましたら、プログラムを改良したいと思います。

ご覧のようにやっとSIN、COSまで組み込むことができましたがTANはまだだめです。
どこかにバグが残っているようです。

こちらはうまくいきました。
倍精度の平方根関数SQR()です。

    10 FOR A#=0 TO 10
    20 PRINT A#,SQR(A#)
    30 NEXT A#
    40 PRINT "end"
>r.
 0            0
 1            1
 2            1.414213562373095
 3            1.732050807568877
 4            2
 5            2.23606797749979
 6            2.449489742783178
 7            2.64575131106459
 8            2.82842712474619
 9            3
 10           3.162277660168379
end

SID()、COD()と同様、()の中に単精度の変数、定数を書くと単精度で計算され、倍精度の変数、定数を書くと倍精度で計算が行なわれます。

倍精度ともなりますといずれの関数も半端ではありません。
もうこれでもかというくらい複雑な計算をさせています。
ND80ZV(ND80Z3.5)はCPUがZ80でクロック6MHzです。
それでも倍精度の計算は、ちょいと考えているなあ、という感じで実行します。
MYCPU80は8080互換でクロックは2MHzです。
しばし黙り込みます。
そしてやっとのことで、結果を吐き出してくれます。
その間ずらりと並んだLEDがせわしげに点滅します。

ちょいと感激です。

MYCPU80でCP/Mを![第70回]
2014.11.24upload

前へ
次へ
ホームページトップへ戻る