,{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*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 注) レジスタは、いずれも保存されない