2014.9.20

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

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


[第40回]


●SIN関数のプログラム

4日ぶりの更新です。
相変わらずやらなければならないことが目白押しでずっと多忙なのですが、ここ数日はちょいとまた解決できないことがらに出くわしてしまいまして、それでホームページの更新をするゆとりがなかったのです。

いえ。
今回はトラブルではありません。
ただちょっと気になることが出てきてしまいましたのです。

ずっと本題から脱線して書いておりました修理依頼品のMYCPU80についても前回でやっと無事修理完了というところまできましたので、ここらで本題に復帰しなければならないところなのですけれど。
脱線ということもありまして途中説明をはしょりながら書いてきましたところなどがありまして、私自身の備忘録を補完するためにも、この際もう少し詳しく書いておきましょう、と思ってしまったのでありました。

ああ。
もちろん浮動小数点演算のプログラムについても詳しく説明するとよろしいのですけれど。
しかしそれは説明を始めますといつ終るかわからないほど濃い内容でありますから、ちょいと簡単にはいきませんです。
まあ、でも、そのうち時間をみつけまして、ときどき脱線しながら説明できたらいいかなあと思います。

今回ひっかかっておりましたのは、そこではありません。

このところ説明をしてきましたテストプログラムでは三角関数SINの演算プログラムがコアになっておりました。
テストプログラムのリストは[第33回]でお見せしました。
異常動作の原因を追究するために、浮動小数点演算レジスタやCPUレジスタを表示するサブルーチン(FADSP)を途中の要所要所に挿入しておりますが、もとになるプログラムはZB3BASICプログラムに実際に組み込まれているSIN演算ルーチンをほとんどそのまま抜き出して、RAM上で独立して動作するように最低限のアレンジを加えたものです。
もとはZ80用に書かれたものですが、それを8080の命令だけで実行できるように書き改めてあります。

お見せしましたプログラムは実際にSIN()を計算するプログラムそのものです。
ただ基本的な浮動小数点演算のためのサブルーチンはZB3BASICのシステムプログラムとして組み込まれているものをそのままCALLしていますから、このプログラムだけでは実行できませんけれど。
それはともかく、SINを計算するコアなところはそのままですから、このプログラムでSINの計算ができることには間違いはありません。

しかしプログラムリストを見ただけでは、一体何をやっているのか、さっぱりわかりませんでしょう。
そこでそのあたりのところを、ざっと簡単に説明いたしましょう、というつもりで説明のための下準備に入ったのでありますが。

説明するどころか、私自身が納得できなくて、さっそくつかえてしまいました。
定数の根拠がわかりません。
[第33回]のプログラムリストでは定数はプログラムの終わりのところにまとめてあります。
その部分だけを取り出してお見せしましょう。

              ;
8391 60       PI6:DB 60;PI/6=30(degree)
8392 48         DB 48
8393 05         DB 05
8394 43         DB 43
8395 00         DB 00
8396 00         DB 00
              ;;;FPI2
8397 ED       FPI2:DB ED
8398 87         DB 87
8399 64         DB 64
839A 01         DB 01
839B 00         DB 00
              ;;;FPAI
839C ED       FPAI:DB ED
839D 87         DB 87
839E 64         DB 64
839F 02         DB 02
83A0 00         DB 00
              ;;;F2PI
83A1 ED       F2PI:DB ED
83A2 87         DB 87
83A3 64         DB 64
83A4 03         DB 03
83A5 00         DB 00
              ;;;SIT1
83A6 DD       SIT1:DB DD
83A7 6B         DB 6B
83A8 4F         DB 4F
83A9 F4         DB F4
83AA 00         DB 00
              ;;;SIT2
83AB 32       SIT2:DB 32
83AC 93         DB 93
83AD 4C         DB 4C
83AE F9         DB F9
83AF 80         DB 80
              ;;;SIT3
83B0 2C       SIT3:DB 2C
83B1 9A         DB 9A
83B2 51         DB 51
83B3 FD         DB FD
83B4 00         DB 00
              ;;;SIT4
83B5 F0       SIT4:DB F0
83B6 AE         DB AE
83B7 52         DB 52
83B8 00         DB 00
83B9 80         DB 80
              ;;;0.2E-5
83BA DE       FLMT:DB DE
83BB 1B         DB 1B
83BC 43         DB 43
83BD EE         DB EE
83BE 00         DB 00
              ;

ここでひっかかってしまった定数はSIT1〜SIT4です。
どこからこの数値を引っ張り出してきたのか全くわからなくて当惑してしまいました。
数値は浮動小数点数です。
表記のルールは[第37回]で説明しました。

2バイト16ビットの整数のビットの並びと同じで、メモリアドレスの若い方が下位になっています。
説明の都合で後ろからになりますが、
SIT4は符号部が80ですから、この数は負数で、次の指数部は00で、仮数部は 52AEF0です。
SIT3は符号部が00ですから、この数は正数で、次の指数部はFDで、仮数部は 519A2Cです。
SIT2は符号部が80ですから、この数は負数で、次の指数部はF9で、仮数部は 4C9332です。
SIT1は符号部が00ですから、この数は負数で、次の指数部はF4で、仮数部は 4F6BDDです。

このままじゃわかりませんから、十進数に直します。
十進数に直すにはまず仮数部をそのまま十進数に変換します。
Windowsの電卓が利用できますが、毎度のことでこの計算はWindows98のほうが楽にできます。
Windows7の電卓は機能強化されていますけれど、かえって使いにくくなっています。
Windows98では電卓の種類を「関数電卓」にすると、後の計算までそのモードのままでできてしまいます。
Windows7では「関数電卓」では16進数→十進数の変換ができません。
「プログラマ」を選択しなければなりません。
しかしそのモードでは十進数に変換後の値を使って実数演算ができません。
そうするには「M+」でメモリしておいて、モードを「関数電卓」に切り換えて「MR」で呼び出すという面倒なことをしなければなりません。
やっぱりWindows98はなかなか手放せません。

説明に戻ります。
SIT4の52AEF0を十進数に変換すると5418736になります。
16進数の52AEF0の最上位の左に小数点がありますから、5418736/128/256/256が求める数値になります(それに負号がつきます)。
この計算は整数値の54AEF0の小数点位置(最下位の右にある)を、223で割ることで最上位の左に移動するものです。
23=2×2×2です。
つまり8ビット左、8ビット左、7ビット左です。
計算しますと、−5418736/128/256/256=−0.6459636688…になります。
なんじゃあ、この数字は…?

それはちょいと置くことにしまして、とにかく次のSIT3も計算してみますと、
519A2Cを十進数に変換して、5347884を得ます。
5347884/128/256/256=0.6375174522…になります。
SIT4は指数部が00だったのでここまでで計算を終りましたが、SIT3は指数部がFDですから、さらにその計算も加えます。
指数部がFD(つまり−3)ですからそれは仮数部×2−3ということです。
ですから求める数は、5347884/128/256/256/8=0.07968968115…になります。

説明の途中ですが、本日は時間がなくなってしまいました。
続きは次回にいたします。

MYCPU80でCP/Mを![第40回]
2014.9.20upload

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