テクハンwiki

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)。


図 A.1 BCD による実数表現のフォーマット


図 A.2 実数の表現例

 1 つの実数は、符号部、指数部、仮数部から成り立っています。符号部とはこの仮数の符号を表し、0 ならば正、1 ならば負となります。指数部はバイナリ表現であり、+63 乗〜 -63 乗まで表すことができます (図 A.3)。倍精度実数の有効範囲を図 A.4 に示します。


図 A.3 指数部フォーマット


図 A.4 倍精度実数表現の有効範囲

 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 のワークエリア

ラベルアドレスサイズ意味
VALTYPF663H1DAC に入っている数値の形式を表す
DACF7F6H16BCD 形式の浮動小数点アキュムレータ
ARGF847H16DAC の演算対象

●Math-Pack エントリ

基本演算

ラベルアドレス機能
DECSUB268CHDAC ← DAC-ARG
DECADD269AHDAC ← DAC+ARG
DECNRM26FAHDAC を正規化する (*1)
DECROU273CHDAC を四捨五入する
DECMUL27E6HDAC ← DAC*ARG
DECDIV289FHDAC ← DAC/ARG
注) これらは、いずれも DAC, ARG にある数を倍精度実数として扱う
  レジスタはいずれも保存されない
*1 仮数部の不要な 0 を取り去ること (0.00123 → 0.123E-2)


関数 1
ラベルアドレス機能変化するレジスタ
COS2993HDAC ← COS(DAC)すべて
SIN29ACHDAC ← SIN(DAC)すべて
TAN29FBHDAC ← TAN(DAC)すべて
ATN2A14HDAC ← ATN(DAC)すべて
LOG2A72HDAC ← LOG(DAC)すべて
SQR2AFFHDAC ← SQR(DAC)すべて
EXP2B4AHDAC ← EXP(DAC)すべて
RND2BDFHDAC ← RND(DAC)すべて
注) すべて BASIC における同名の関数の処理ルーチンである
  変化するレジスタすべてとは、A,B,C,D,E,H,L の各レジスタを指す


関数 2
ラベルアドレス機能変化するレジスタ
SIGN2E71HA ← DAC の符号A
ABSFN2E82HDAC ← ABS(DAC)すべて
NEG2E8DHDAC ← NEG(DAC)A,H,L
SGN2E97HDAC ← SGN(DAC)A,H,L
注) エントリラベル SIG 以外のルーチンは、すべて BASIC における同名の関数の処理ルーチンである
  変化するレジストリすべてとは、A,B,C,D,E,H,L の各レジスタを指す
  SGN は、結果が 2 バイト整数で表されるので注意


移動
ラベルアドレス機能対象変化するレジスタ
MAF2C4DHARG ← DAC倍精度A,B,D,E,H,L
MAM2C50HARG ← [HL]倍精度A,B,D,E,H,L
MOV8DH2C53H[DE] ← [HL]倍精度A,B,D,E,H,L
MFA2C59HDAC ← ARG倍精度A,B,D,E,H,L
MFM2C5CH[HL] ← DAC倍精度A,B,D,E,H,L
MMF2C67H[HL] ← DAC倍精度A,B,D,E,H,L
MOV8HD2C6AH[HL] ← [DE]倍精度A,B,D,E,H,L
XTF2C6FH[SP] ←→ DAC倍精度A,B,D,E,H,L
PHA2CC7HARG → [SP]倍精度A,B,D,E,H,L
PHF2CCCHDAC → [SP]倍精度A,B,D,E,H,L
PPA2CDCH[SP] → ARG倍精度A,B,D,E,H,L
PPF2CE1H[SP] → DAC倍精度A,B,D,E,H,L
PUSHF2EB1HDAC → [SP]単精度D,E
MOVFM2EBEHDAC ← [HL]単精度B,C,D,E,H,L
MOVFR2EC1HDAC ← (CBED)単精度D,E
MOVRF2ECCH(CBED) ← DAC単精度B,C,D,E,H,L
MOVRMI2ED6H(CBDE) ← [HL]単精度B,C,D,E,H,L
MOVRM2EDFH(BCDE) ← [HL]単精度B,C,D,E,H,L
MOVMF2EE8H[HL] ← DAC単精度B,C,D,E,H,L
MOVE2EEBH[HL] ← [DE]単精度B,C,D,E,H,L
VMOVAM2EEFHARG ← [HL]VALTYPB,C,D,E,H,L
MOVVFM2EF2H[DE] ← [HL]VALTYPB,C,D,E,H,L
VMOVE2EF3H[HL] ← [DE]VALTYPB,C,D,E,H,L
VMOVFA2F05HDAC ← ARGVALTYPB,C,D,E,H,L
VMOVFM2F08HDAC ← [HL]VALTYPB,C,D,E,H,L
VMOVAF2F0DHARG ← DACVALTYPB,C,D,E,H,L
VMOVMF2F10H[HL] ← DACVALTYPB,C,D,E,H,L
注) [HL],[DE] は、それぞれ HL,DE レジスタが指したメモリ上の数値を示す
  ( ) 内の 4 レジスタ名は、左から (符号 + 指数部)、(仮数部 1,2 桁)、(仮数部 3.4 桁) 、(仮数部 5,6 桁) を示す単精度実数である
  移動の対象が VALTYP となっているものは、VALTYP (F663H 番地) に示されている型に応じた移動 (2,4,8 バイト) を行う


比較
ラベルアドレス対象左辺右辺変化するレジスタ
FCOMP2F21H単精度実数CBEDDACHL
ICOMP2F4DH2 バイト整数DEHLHL
XDCOMP2F5CH倍精度実数ARGDACすべて
注) 結果はすべて A レジスタに入る。レジスタの意味は、
     A=1 → 左辺 < 右辺
     A=0 → 左辺 = 右辺
     A=-1 → 左辺 > 右辺
  単精度の比較で、左辺の CBED とは各レジスタに、それぞれ(符号 + 指数部)、(仮数部 1,2 桁)、(仮数部 3.4 桁) 、(仮数部 5,6 桁) が入ることを意味する


浮動小数点入出力
ラベルアドレス機能
FIN3299H浮動小数点を表す文字列を、実数表現に変換して DAC に格納する
エントリー条件 HL ← 文字列の先頭アドレス
          A ← 文字列の先頭文字
リターン条件  DAC ← 実数
          C ← FFH : 小数点なし、0 : 小数点あり
          B ← 小数点以降のケタ数
          D ← 総ケタ数


ラベルアドレス機能
FOUT3425HDAC に入っている実数表現の数を文字列に変換する (フォーマット指定なし)
PUFOUT3426HDAC に入っている実数表現の数を文字列に変換する (フォーマット指定あり)
エントリー条件 A ← 変換のフォーマット
          bit7 0 : フォーマット指定なし、 1 : フォーマット指定あり
          bit6 0 : コンマによる区切りなし、 1 : 3 ごとにコンマで区切る
          bit5 0 : 意味無し、 1 : 先頭のスペースを "*" でうめる
          bit4 0 : 意味無し、 1 : 数値の前に "$" を付ける
          bit3 0 : 意味無し、 1 : 正の数の場合も符号 "+" を付ける
          bit2 0 : 意味無し、 1 : 数値の後ろに符号を付ける
          bit1 0 : 未使用
          bit0 0 : 固定小数点、 1 : 浮動小数点
          B ← 小数点を含まない、小数点以前のケタ数
          C ← 小数点を含む、小数点以降のケタ数
 リターン条件 HL ← 文字列の先頭アドレス


ラベルアドレス機能
FOUTB371AHDAC+2,3 に入っている 2 バイト整数を 2 進数表現の文字列に変換する
FOUTO371EHDAC+2,3 に入っている 2 バイト整数を 8 進数表現の文字列に変換する
FOUTH3722HDAC+2,3 に入っている 2 バイト整数を 16 進数表現の文字列に変換する
エントリー条件 DAC+2 ← 2 バイト整数
          VALTYP ← 2
 リターン条件 HL ← 文字列の先頭アドレス
注) レジスタはいずれも保存されない
  出力ルーチンにおける文字列先頭アドレスは、通常 FBUFFR (F7C5H 番地から) 内となるが、場合により先頭アドレスは前後する
  FOUTB,FOUTO,FOUTH に限らず DAC+2 に入れた整数を扱うときには、VALTYP (F663H) に必ず 2 を入れること


型変換
ラベルアドレス機能
FRCINT2F8AHDAC を 2 バイト整数にする (DAC+2,3)
FRCSNG2FB2HDAC を単精度実数にする
FRCDBL303AHDAC を倍精度実数にする
FIXER30BEHDAC ← SGN(DAC)*INT(ABS(DAC))
注) 実行後 VALTYP (F663H 番地) には、DAC の型を表す数 (2,4,8) が入る
  レジスタは、いずれも保存されない


整数演算
ラベルアドレス機能変化するレジスタ
UMULT314AHDE ← BC*DEA,B,C,D,E
ISUB3167HHL ← DE-HLすべて
IADD3172HHL ← DE+HLすべて
IMULT3193HHL ← DE*HLすべて
IDIV31E6HHL ← DE/HLすべて
IMOD323AHHL ← DE mod HL (DE ← DE/HL)すべて


べき乗
ラベルアドレス機能基数指数結果
SNGEXP37C8H単精度実数のべき乗を求めるDACARGDAC
DBLEXP37D7H倍精度実数のべき乗を求めるDACARGDAC
INTEXP383FH2 バイト整数のべき乗を求めるDEHLDAC
注) レジスタは、いずれも保存されない