テクハンwiki

Appendix A.2 Math-Packの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
,{c H},{BGCOLOR:dddddd|BOLD|CENTER}
,{c C},{CENTER}
,{c L},{LEFT}
// %第1版第9第刷
// !!!Appendix A.2 Math-Pack
 Math-Pach とは、MSX−BASIC の数値演算ルーチンの中核をなすもので、これらを機械語から呼び出すことにより、簡単に浮動小数点演算や三角関数ルーチンを利用することができます。
 Math-Pack での実数演算はすべて BCD (Binary Coded Decimal = 2 進化 10 進法) 表現によって行われます。また、実数表現には "単精度" と "倍精度" の 2 種類があり、単精度 (6 桁) は 4 バイト、倍精度 (14 桁) は 8 バイトで表現されます (図 A.1、図 A.2)。
{{div_begin style='text-align:center;'}}
{{svg 図A.1.svg,,size:480x360}}
'''図 A.1 BCD による実数表現のフォーマット'''
{{div_end}}
{{div_begin style='text-align:center;'}}
{{svg 図A.2.svg,,size:450x270}}
'''図 A.2 実数の表現例'''
{{div_end}}
 1 つの実数は、符号部、指数部、仮数部から成り立っています。符号部とはこの仮数の符号を表し、0 ならば正、1 ならば負となります。指数部はバイナリ表現であり、+63 乗〜 -63 乗まで表すことができます (図 A.3)。倍精度実数の有効範囲を図 A.4 に示します。
{{div_begin style='text-align:center;'}}
{{svg 図A.3.svg,,size:600x300}}
'''図 A.3 指数部フォーマット'''
{{div_end}}
{{div_begin style='text-align:center;'}}
{{svg 図A.4.svg}}
'''図 A.4 倍精度実数表現の有効範囲'''
{{div_end}}
 Math-Pack では、演算の対象となるメモリがあらかじめ決められています。このメモリエリアを "DAC (Decmal ACcumlator) (F7F6H)" 、それと演算対象となる数値を格納するエリアを "ARG (F847H)" といいます。たとえば乗算ルーチンの場合、DAC に入っている数と ARG に入っている数の積が計算され、その結果が DAC に入ることになります。
 DAC には、単精度実数、倍精度実数、2 バイト整数を格納することができますが、これらのうちのどれが入っているのかを示すために "VALTYP (F663H)" が使われ、それぞれの場合について 4, 8, 2 の値が入ります。
 単精度実数と倍精度実数は、いずれも DAC の先頭から数値を格納しなければなりません。ただし、2 バイト整数の場合だけは、下位、上位を DAC+2, +3 に格納して下さい。
 Math-Pack は BASIC の内部ルーチンであるため、エラーが起きた場合 (0 除算やオーバーフローなど) はそれに応じたエラールーチンへ自動的に分岐し、その後 BASIC コマンドレベルに戻ります。それを避けたいときは、H.ERRO (FFB1H) を書き換えてください。


●Math-Pack のワークエリア
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H}
,ラベル,アドレス,サイズ,意味
,{c},{L},{C},{C},{L}
,VALTYP,F663H,1,DAC に入っている数値の形式を表す
,DAC,F7F6H,16,BCD 形式の浮動小数点アキュムレータ
,ARG,F847H,16,DAC の演算対象


●Math-Pack  エントリ

'''基本演算'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H}
,ラベル,アドレス,機能
,{c},{L},{C},{L}
,DECSUB,268CH,DAC ← DAC-ARG
,DECADD,269AH,DAC ← DAC+ARG
,DECNRM,26FAH,DAC を正規化する (*1)
,DECROU,273CH,DAC を四捨五入する
,DECMUL,27E6H,DAC ← DAC*DAC
,DECDIV,289FH,DAC ← DAC/DAC
,DECMUL,27E6H,DAC ← DAC*ARG
,DECDIV,289FH,DAC ← DAC/ARG
注) これらは、いずれも DAC, ARG にある数を倍精度実数として扱う
  レジスタはいずれも保存されない
*1 仮数部の不要な 0 を取り去ること (0.00123 → 0.123E-2)
{{br}}
'''関数 1'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H}
,ラベル,アドレス,機能,変化するレジスタ
,{c},{L},{C},{L},{C}
,COS,2993H,DAC ← COS(DAC),すべて
,SIN,29ACH,DAC ← SIN(DAC),すべて
,TAN,29FBH,DAC ← TAN(DAC),すべて
,ATN,2A14H,DAC ← ATN(DAC),すべて
,LOG,2A72H,DAC ← LOG(DAC),すべて
,SQR,2AFFH,DAC ← SQR(DAC),すべて
,EXP,2B4AH,DAC ← EXP(DAC),すべて
,RND,2BDFH,DAC ← RND(DAC),すべて
注) すべて BASIC における同名の関数の処理ルーチンである
  変化するレジスタすべてとは、A,B,C,D,E,H,L の各レジスタを指す
{{br}}
'''関数 2'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H}
,ラベル,アドレス,機能,変化するレジスタ
,{c},{L},{C},{L},{C}
,SIGN,2E71H,A ← DAC の符号,A
,ABSFN,2E82H,DAC ← ABS(DAC),すべて
,NEG,2E8DH,DAC ← NEG(DAC),"A,H,L"
,SGN,2E97H,DAC ← SGN(DAC),"A,H,L"
注) エントリラベル SIG 以外のルーチンは、すべて BASIC における同名の関数の処理ルーチンである
  変化するレジストリすべてとは、A,B,C,D,E,H,L の各レジスタを指す
  SGN は、結果が 2 バイト整数で表されるので注意
{{br}}
'''移動'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能,対象,変化するレジスタ
,{c},{L},{C},{L},{C},{C}
,MAF,2C4DH,ARG ← DAC,倍精度,"A,B,D,E,H,L"
,MAM,2C50H,ARG ← [HL],倍精度,"A,B,D,E,H,L"
,MOV8DH,2C53H,[DE] ← [HL],倍精度,"A,B,D,E,H,L"
,MFA,2C59H,DAC ← ARG,倍精度,"A,B,D,E,H,L"
,MFM,2C5CH,[HL] ← DAC,倍精度,"A,B,D,E,H,L"
,MMF,2C67H,[HL] ← DAC,倍精度,"A,B,D,E,H,L"
,MOV8HD,2C6AH,[HL] ← [DE],倍精度,"A,B,D,E,H,L"
,XTF,2C6FH,[SP] ←→ DAC,倍精度,"A,B,D,E,H,L"
,PHA,2CC7H,ARG → [SP],倍精度,"A,B,D,E,H,L"
,PHF,2CCCH,DAC → [SP],倍精度,"A,B,D,E,H,L"
,PPA,2CDCH,[SP] → ARG,倍精度,"A,B,D,E,H,L"
,PPF,2CE1H,[SP] → DAC,倍精度,"A,B,D,E,H,L"
,PUSHF,2EB1H,DAC → [SP],単精度,"D,E"
,MOVFM,2EBEH,DAC ← [HL],単精度,"B,C,D,E,H,L"
,MOVFR,2EC1H,DAC ← (CBED),単精度,"D,E"
,MOVRF,2ECCH,(CBED) ← DAC,単精度,"B,C,D,E,H,L"
,MOVRMI,2ED6H,(CBDE) ← [HL],単精度,"B,C,D,E,H,L"
,MOVRM,2EDFH,(BCDE) ← [HL],単精度,"B,C,D,E,H,L"
,MOVMF,2EE8H,[HL] ← DAC,単精度,"B,C,D,E,H,L"
,MOVE,2EEBH,[HL] ← [DE],単精度,"B,C,D,E,H,L"
,VMOVAM,2EEFH,ARG ← [HL],VALTYP,"B,C,D,E,H,L"
,MOVVFM,2EF2H,[DE] ← [HL],VALTYP,"B,C,D,E,H,L"
,VMOVE,2EF3H,[HL] ← [DE],VALTYP,"B,C,D,E,H,L"
,VMOVFA,2F05H,DAC ← ARG,VALTYP,"B,C,D,E,H,L"
,VMOVFM,2F08H,DAC ← [HL],VALTYP,"B,C,D,E,H,L"
,VMOVAF,2F0DH,ARG ← DAC,VALTYP,"B,C,D,E,H,L"
,VMOVMF,2F10H,[HL] ← DAC,VALTYP,"B,C,D,E,H,L"
注) [HL],[DE] は、それぞれ HL,DE レジスタが指したメモリ上の数値を示す
  ( ) 内の 4 レジスタ名は、左から (符号 + 指数部)、(仮数部 1,2 桁)、(仮数部 3.4 桁) 、(仮数部 5,6 桁) を示す単精度実数である
  移動の対象が VALTYP となっているものは、VALTYP (F663H 番地) に示されている型に応じた移動 (2,4,8 バイト) を行う
{{br}}
'''比較'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H},{H}
,ラベル,アドレス,対象,左辺,右辺,変化するレジスタ
,{c},{L},{C},{L},{C},{C},{C}
,FCOMP,2F21H,単精度実数,CBED,DAC,HL
,ICOMP,2F4DH,2 バイト整数,DE,HL,HL
,XDCOMP,2F5CH,倍精度実数,ARG,DAC,すべて
注) 結果はすべて A レジスタに入る。レジスタの意味は、
     A=1  → 左辺 < 右辺
     A=0  → 左辺 = 右辺
     A=-1 → 左辺 > 右辺
  単精度の比較で、左辺の CBED とは各レジスタに、それぞれ(符号 + 指数部)、(仮数部 1,2 桁)、(仮数部 3.4 桁) 、(仮数部 5,6 桁) が入ることを意味する
{{br}}
'''浮動小数点入出力'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能
,{c},{L},{C},{L},{C},{C}
,FIN,3299H,浮動小数点を表す文字列を、実数表現に変換して DAC に格納する
,{COLS 3}エントリー条件 HL  ← 文字列の先頭アドレス{{br}}          A   ← 文字列の先頭文字{{br}}リターン条件  DAC ← 実数{{br}}          C   ← FFH : 小数点なし、0 : 小数点あり{{br}}          B   ← 小数点以降のケタ数{{br}}          D   ← 総ケタ数{{br}}
{{br}}
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能
,{c},{L},{C},{L},{C},{C}
,FOUT,3425H,DAC に入っている実数表現の数を文字列に変換する (フォーマット指定なし)
,PUFOUT,3426H,DAC に入っている実数表現の数を文字列に変換する (フォーマット指定あり)
,{COLS 3}エントリー条件 A  ← 変換のフォーマット{{br}}          bit7 0 : フォーマット指定なし、 1 : フォーマット指定あり{{br}}          bit6 0 : コンマによる区切りなし、 1 : 3 ごとにコンマで区切る{{br}}          bit5 0 : 意味無し、 1 : 先頭のスペースを "*" でうめる{{br}}          bit4 0 : 意味無し、 1 : 数値の前に "$" を付ける{{br}}          bit3 0 : 意味無し、 1 : 正の数の場合も符号 "+" を付ける{{br}}          bit2 0 : 意味無し、 1 : 数値の後ろに符号を付ける{{br}}          bit1 0 : 未使用{{br}}          bit0 0 : 固定小数点、 1 : 浮動小数点{{br}}          B  ← 小数点を含まない、小数点以前のケタ数{{br}}          C  ← 小数点を含む、小数点以降のケタ数{{br}} リターン条件 HL ← 文字列の先頭アドレス{{br}}
{{br}}
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能
,{c},{L},{C},{L},{C},{C}
,FOUTB,371AH,"DAC+2,3 に入っている 2 バイト整数を 2 進数表現の文字列に変換する"
,FOUTO,371EH,"DAC+2,3 に入っている 2 バイト整数を 8 進数表現の文字列に変換する"
,FOUTH,3722H,"DAC+2,3 に入っている 2 バイト整数を 16 進数表現の文字列に変換する"
,{COLS 3}エントリー条件 DAC+2  ← 2 バイト整数{{br}}          VALTYP ← 2{{br}} リターン条件 HL     ← 文字列の先頭アドレス{{br}}
注) レジスタはいずれも保存されない
  出力ルーチンにおける文字列先頭アドレスは、通常 FBUFFR (F7C5H 番地から) 内となるが、場合により先頭アドレスは前後する
  FOUTB,FOUTO,FOUTH に限らず DAC+2 に入れた整数を扱うときには、VALTYP (F663H) に必ず 2 を入れること
{{br}}
'''型変換'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能
,{c},{L},{C},{L},{C},{C}
,FRCINT,2F8AH,"DAC を 2 バイト整数にする (DAC+2,3)"
,FRCSNG,2FB2H,DAC を単精度実数にする
,FRCDBL,303AH,DAC を倍精度実数にする
,FIXER,30BEH,DAC ← SGN(DAC)*INT(ABS(DAC))
注) 実行後 VALTYP (F663H 番地) には、DAC の型を表す数 (2,4,8) が入る
  レジスタは、いずれも保存されない
{{br}}
'''整数演算'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H}
,ラベル,アドレス,機能,変化するレジスタ
,{c},{L},{C},{L},{C},{C}
,UMULT,314AH,DE ← BC*DE,"A,B,C,D,E"
,ISUB,3167H,HL ← DE-HL,すべて
,IADD,3172H,HL ← DE+HL,すべて
,IMULT,3193H,HL ← DE*HL,すべて
,IDIV,31E6H,HL ← DE/HL,すべて
,IMOD,323AH,HL ← DE mod HL (DE ← DE/HL),すべて
{{br}}
'''べき乗'''
,{t},{CENTER|SIZE:600}}
,{c},{H|SIZE:70},{H|SIZE:70},{H},{H},{H},{H}
,ラベル,アドレス,機能,基数,指数,結果
,{c},{L},{C},{L},{C},{C},{C}
,SNGEXP,37C8H,単精度実数のべき乗を求める,DAC,ARG,DAC
,DBLEXP,37D7H,倍精度実数のべき乗を求める,DAC,ARG,DAC
,INTEXP,383FH,2 バイト整数のべき乗を求める,DE,HL,DAC
注) レジスタは、いずれも保存されない