「ASM50 ソフトウエアマニュアル」 初版 1996.04.19 JE3HHT "Mako" ASM50はTI社のDSP「TMS320C5x」シリーズの実行コードを生成するマクロアセンブラです。 同社のDSK(DSPスタータキット)のデバッガDSK5Dで読み込み可能な形式および、ブートROM作成のためのインテルヘキサまたはモトローラS形式のファイルを作成することができます。 本書にはASM50に関するすべての情報が記述されています。以下にASM50の主な仕様を示します。 対象CPU DSP TMS320C5x 出力ファイル DSK形式、インテルヘキサ形式、モトローラS形式 アセンブル 絶対アセンブルモードのみ(外部参照は不可) インクルード 7レベルまでのネストが可能 マクロ命令 16レベルまでのネストが可能 条件アセンブル 32レベルまでのネストが可能 ----------------------------------------------------------------------------- 第1章 はじめに ----------------------------------------------------------------------------- 1.1 本書の構成 ~~~~~~~~~~~~~~~~~~ 本書は以下の構成になっています。 第1章 はじめに 用語の解説やプログラム開発方法について解説します。 第2章 ソースファイル ASM50の入力ファイルについて解説します。 第3章 疑似命令 ASM50アセンブラに対する疑似命令について解説します。 第4章 マクロ ASM50アセンブラのマクロ機能について解説します。 第5章 ASM50アセンブラ ASM50アセンブラの実行方法について解説します。 1.2 システムの環境 ~~~~~~~~~~~~~~~~~~~~~~ ASM50アセンブラは以下の環境で動作します。 MS−DOS Version 2.11 以降 ASM50が生成するコードはTI社のTMS320C5xシリーズのDSPで実行することができます。 1.3 提供するファイル ~~~~~~~~~~~~~~~~~~~~~~~~ ASM50パッケージは以下のファイルで構成されます。 ASM50.EXE ASM50アセンブラの本体 ASM50.DOC 本書 BP200.A50 200Hz帯域のCW用BPF LMSBP.A50 LMSアルゴリズムによるCW用ノイズスムーサ LMSAN.A50 LMSアルゴリズムによるオートノッチ 1.4 ドキュメント ~~~~~~~~~~~~~~~~~~~~ ASM50ソフトウエアパッケージのドキュメントは、本書「ASM50ソフトウエアマニュアル」です。 1.5 本書での表記法 ~~~~~~~~~~~~~~~~~~~~~~ 本書の文中では、以下の表記法を使用します。 <> このかっこ内に示す文字は文字コードまたは文字列であることを表します。 また特別に区別する独立した単語を表す場合もあります。 {} このかっこ内のパラメータ(オプション)は省略可能であることを表しま す。 .... このピリオドの前の項目を必要な回数だけ入力することを表します。 () このかっこ内は特別な補足項目を表します。 1.6 用語の解説 ~~~~~~~~~~~~~~~~~~ <1> ソースプログラム 汎用テキストエディターで作成したアセンブルテキストで構成されています。 <2> ソースファイル ソースプログラムが入っているファイルです。ソースファイルはASM50アセンブラの入力ファイルです。ASM50アセンブラのソースファイルの標準的な拡張子は<.A50>です。 <3> インクルードファイル ソースプログラムが入っているファイルです。インクルードファイルはソースファイル内から<INCLUDE>疑似命令によりその位置に挿入されるファイルです。 通常はシンボルに定数を定義したり、まとまったサブルーチンブロックを別のファイルに分離するのに使用します。 <4> オブジェクトコード ソースファイルをASM50アセンブラでアセンブルした結果、DSPで実行することのできる機械コードに変換されます。 <5> オブジェクトファイル オブジェクトファイルはASM50アセンブラの出力ファイルです。ASM50アセンブラが出力するオブジェクトファイルの拡張子は以下の通りです。 16Bit-Boot-ROM インテルヘキサ 上位<.HXH>, 下位<.HXL> 16Bit-Boot-ROM モトローラS 上位<.SXH>, 下位<.SXL> 8Bit-Boot-ROM インテルヘキサ <.HEX> 8Bit-Boot-ROM モトローラS <.S> DSK(DSK5D.EXE用) <.DSK> デフォルトではDSKのデバッガ「DSK5D.EXE」で読み取り可能な形式<.DSK>のファイルを生成します。起動オプションによりインテルヘキサまたはモトローラS形式のファイルを生成します。 この他、DOSで一般的に使用されている用語、「TMS320C5xユーザズガイド」で定義されている用語、デジタル信号処理で一般的に使用されている用語を使用します。 1.7 ASM50プログラム開発 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <1> ASM50プログラム開発の準備 ASM50を使用してDSPのプログラムを作成するには、以下のものが必要です。 1. 汎用エディター ソースファイルを作成する 2. ASM50.EXE ASM50アセンブラ 3. DSPボード DSPによるデジタル信号処理システム <2> プログラム開発の手順 ASM50を使用したDSPプログラム開発の手順を以下に示します。 1. 汎用エディターでソースファイルを作成(修正)する 2. ASM50アセンブラを使用してソースファイルからオブジェクトファイ ルに変換する。 3. DSPボードにオブジェクトファイルを転送する。この時、ROMライタ が必要になるかも知れません。(DSKでは不要) 4. 信号処理結果が目標通りになるように1.〜3.を繰り返す。 DSKを使用する場合はデバッガ「DSK5D.EXE」を利用する事ができます。 ----------------------------------------------------------------------------- 第2章 ASM50ソースファイル ----------------------------------------------------------------------------- 2.1 ソースファイル ~~~~~~~~~~~~~~~~~~~~~~ ASM50が受け付けることのできるソースファイルは、TMS320C5xのニーモニックおよび擬似命令で記述されたステートメントを含む一連の行です。すべてのオペレーションは行で区切られ、1行に1つのオペレーションのみを記述することができます。 1. ソースファイルの名前の拡張子は<.A50>でなければなりません。 2. ソースファイルから入力される各行は、最大255文字の長さまで受け付け ることができます。 3. DSPオペレーションや疑似命令、レジスタ表記は、大文字でも小文字でも 記述することができます。 4. シンボルおよびマクロ名は大文字と小文字が区別されます。 2.2 ステートメント ~~~~~~~~~~~~~~~~~~~~~~ ステートメントの形式は次の通りです。 1. ラベル定義行 ラベル: {コメント} 2. オペレーション行 <スペース> オペレーション {アーギュメント}{コメント} [例] LOOP: ;ラベル定義行 ~~~<1> ~~~~~~~~~~~~<4> B LOOP ;オペレーション行 ~<2> ~~~<3> ~~~~~~~~~~~~~~~~<4> <1>ラベル名, <2>オペレーション, <3>アーギュメント, <4>コメント 2.3 シンボル ~~~~~~~~~~~~~~~~ シンボルは特定の数値を定義した名前です。シンボルは次の3通りの方法で定義することができます。 1. データやコードなどを定義するステートメントにラベルとして定義します。 シンボルの持つ値は、データやコードなどのロケーションアドレスを意味 します。 2. <EQU>疑似命令を使って定義します。シンボルの持つ値は<EQU>疑似命令 で指定した数値または式の値です。 3. <DEFL>疑似命令を使って定義します。シンボルの持つ値は<DEFL>疑似命 令で指定した数値または式の値です。<DEFL>擬似命令を使用すると定義済 みのシンボルの値を変更することができます。 <1> シンボルの規則 シンボルには以下の規則があります。 1. シンボルの長さは任意ですが、その有効桁数は128文字です。 2. シンボルにはコントロールキャラクタと以下に示す文字を除く全ての文字が 使用できます。(ただしシンボル名の最初の文字には使用できないキャラク タもあります) ! " # % & ' ( ) * + , - . / < = > ^ | (文字<$>は名前の最後に1つだけ記述することができます。) 3. 大文字と小文字は区別されます。 4. レジスタ名やASM50で定義されている特別なキーワードと同じ名前を 使用してはなりません。 5. 数字をシンボル名の最初の文字に使用することはできません。 6. 名前の最後の文字が<$>または<?>のとき、そのシンボル(ラベル)はロー カルシンボルになります。 <2> 値シンボル 値シンボルは<EQU>疑似命令、<DEFL>擬似命令で定義する事ができます。値シンボルはその名前がそのまま数値として意味を持ちます。 値シンボルを定義するには、ステートメントの最初のフィールドになければなりません。また値シンボルはシンボルの規則に従う名前です。定義する値シンボルの直後には、コロンを1つ付けても構いません。(特に付けなくても構いません) 値シンボルはステートメントのアーギュメントフィールドの一項目として使うことができます。値シンボルは既知の定数を定義するのに適します。 [ 例 ] ONE EQU 1 上記の例では、<ONE>に値1が定義されます。 ABC EQU 10 ABC DEFL 5 上記の例では、<ABC>に値10が定義された後、値5に変更されます。 <3> ラベル ラベルはデータやコードを定義しているステートメントのラベルフィールドに記述します。ラベルはそのステートメントのロケーションアドレスを持っています。ラベルは別のステートメントでの、アーギュメントフィールドの一項目として使う事のできる参照ポイントとなります。 ラベルは、ステートメントの最初のフィールドになければなりません。またラベルはシンボルの規則に従う名前です。定義するラベルの直後には、コロンを1つ付けても構いません。(特に付けなくても構いません) [ 例 ] FIR: BSS 25 ONES: DW 1 <FIR>は、25ワードの予約領域の先頭アドレスを値として持ちます。 <ONES>は値1が格納されたアドレスを値として持ちます。この場合、ラベル定義だけのステートメントであっても問題となりません。 定義されたラベルは、アーギュメントフィールドの一項目として使用することがで きます。アーギュメントにラベルを記述すると、ラベルを定義しているステートメン トのロケーションアドレスを参照することになります。 [ 例 ] lar ar0,#FIR lacc ONES 上記の例では<AR0>に<FIR>のロケーションアドレスが入り、<ACC>に<ONES> の内容が入ります。 アーギュメントが<#>で始まるイミディエイト命令のオペランドは、8ビットデータおよび16ビットデータでのコードの生成量が異なるため、パス1で既知でなければなりません。パス1で既知でない場合ASM50はエラー(フェーズエラー)を出力します。しかしパス1で後方参照となるような場合は、次の例に示すようにデータの幅を指定することによりエラーになるのを防ぐことが出来ます。 0000'BF080003 lar ar0,#>FIR ; '>'は16ビット幅である事を指定する 0002'B003 lar ar0,# ローカルシンボル 名前の最後の文字が<$>または<?>のときそのシンボルはローカルシンボルになります。アセンブラは通常のラベルを境界として異なる名前をローカルシンボルに割り当てます。 loop$: ; ローカルシンボル1 dmov *- banz loop$ ; ローカルシンボル1を参照 abc: ; ローカルシンボルの境界 loop$: ; ローカルシンボル2 dmov *+ banz loop$ ; ローカルシンボル2を参照 アセンブラはマクロの呼出しの時にもローカルシンボルに異なる名前を割り当てます。マクロ内で定義するラベルがローカルシンボルの場合、そのマクロを何回呼び出してもその名前は重複することはありません。ネストするマクロでは外側のマクロのローカルシンボルと内側のマクロのローカルシンボルは別の名前のシンボルとして扱われます。 ABC macro loop$: dmov *- banz loop$ ABC endm * ZZZ macro loop$: dmov *+ ABC banz loop$ ZZZ endm  反復マクロブロック(.rept〜.endr)内でローカルシンボルを定義すると、そのシンボルには反復されるブロック毎に別の名前が割り当てられます。 .rept 10 loop$: dmov *- banz loop$ .endr 2.4 オペレーション ~~~~~~~~~~~~~~~~~~~~~~ オペレーションの前には少なくとも1つの<スペース>または<TAB>を置かなければなりません。オペレーションには次の3つのいずれかを記述します。 オペコード 疑似命令 マクロ名 オペレーションの項目は次の順番で評価されます。 (1)疑似命令(マクロ登録および条件疑似命令) (2)マクロ名 (3)疑似命令 (4)オペコード DSPニーモニックと同じ名前のマクロを登録することができます。その場合、同じDSPニーモニックの命令は以後アセンブルできなくなります。(マクロ名は大文字と小文字が区別されるので、それを利用してDSPニーモニックをアセンブルすることができます。) 2.5 アーギュメント ~~~~~~~~~~~~~~~~~~~~~~ オペレーションのオペランドや疑似命令のパラメータなどを記述します。 2.6 コメント ~~~~~~~~~~~~~~~~ 1つの行の中の任意の位置にセミコロン<;>を記述して、それ以降をコメントにすることができます。 また行の先頭にアスタリスク<*>を記述して、その行をコメントにすることもできます。 2.7 数値 ~~~~~~~~~~~~ 数値の基数は10進数です。特別な基数指定文字により2進または16進の基数で数値を表現することができます。数値の最初の文字が数字でない場合には、その前に0がなければなりません。 以下の基数指定文字が使用できます。 $・・・・ 16進数の指定 ・・・・H 16進数の指定(先頭の文字は<0>〜<9>) %・・・・ 2進数の指定 ・・・・B 2進数の指定 以下の特別な指定文字も使用できます。 $ カレント行のロケーション 小数点を含むQフォーマットの数値を直接記述できます。Qフォーマットは固定小数点数値を表現する時に使用します。Q指定を行わない場合にはQ15の固定小数点数として扱われます。数値は例えば以下に示すような表記法で記述します。 0.12345 Q15表記 4045 -0.12345 Q15表記 -4045 0.5Q12 Q12表記 2048 1.2345E+3Q18 Q18表記 324 -1.2345E-2Q8 Q8表記 -31603 [ 例 ] mpy #0.123456 ;0.123456をQ15フォーマットで表現した値 dw -0.123456 ;-0.123456をQ15フォーマットで表現した値 2.8 式 ~~~~~~~~~~ 数値およびシンボルは以下の演算子を使用して演算しても構いません。演算の優先順位は演算子に関らず常に左から右です。ただし演算の優先順位は括弧記号で変更することができます。内部の計算は32ビットで行われますが結果は16ビットに変換されます。条件演算子は<.IF>擬似命令の式に記述して使用します。 算術演算子 + 加算 - 減算 * 乗算 / 除算 >> 右論理シフト << 左シフト & AND | OR ^ XOR 条件演算子 == 等しい時 真 != 異なる時 真 >= 大きいか等しい時 真 <= 小さいか等しい時 真 > 大きい時 真 < 小さい時 真 && 条件のAND || 条件のOR [ 例 ] dw 10+20/3 ; 10 = (10+20)/3 dw (10+20)/3 ; 10 = (10+20)/3 dw 10+(20/3) ; 16 = 10+(20/3) lar ar0,#FIR+24 ; ロケーション<FIR>に24が加算された値 lar ar0,#FIR+(24/3) ; ロケーション<FIR>に8が加算された値 2.9 予約シンボル ~~~~~~~~~~~~~~~~~~~~ 予約シンボルとして以下のキーワードが登録されています。 1. _LastAdr_ アセンブルしたコードセグメントの最終ロケーションが格納されます。パス1では未定義です。 2. _FmtHex_ 出力するオブジェクトファイルの形式が以下の数値で定義されます。 0 16ビットブートROMインテルヘキサ 1 16ビットブートROMモトローラS 2 8ビットブートROMインテルヘキサ 3 8ビットブートROMモトローラS 4 DSK形式 3.コンディション TMS320C5xの分岐条件を指定する次のキーワード。 EQ,NEQ,LT,LEQ,GT,GEQ,NC,C,NOV,OV,BIO,NTC,TC,UNC [ 例 ]bcnd foo,bio 4.制御ビット TMS320C5xのステータス・制御レジスタの制御ビットを指定する次のキーワード。 OVM,SXM,HM,TC,C,CNF,INTM,XF [ 例 ]clrc ovm 2.10 セグメント ~~~~~~~~~~~~~~~~~~~~ ASM50は展開するコードおよび確保する領域について、2つのセグメントを持っています。 1.コードセグメント(CSEG) DSPプログラムを記述するセグメントです。DSP内のプログラムメモリの領域です。通常すべてのDSP命令はこのセグメントに記述しなければなりません。係数データなどの数値のテーブルを記述する場合もあります。 このセグメントに展開されたコードは、DSKおよびインテル形式・モトローラS形式のオブジェクトファイルに出力されます。 2.データセグメント(DSEG) DSP内のデータメモリの領域について記述するセグメントです。データセグメントはプログラムテキストとは別の64キロワードアドレスを持ちます。DSP内のRAMは128ワードを境界として第一ページ〜第Nページに区別されます。DSP命令のオペランドが7ビットアドレスしか指定できないような命令では、上位の9ビットは無視されたロケーションアドレスが与えられます。 DSPのカレントデータページ(DPレジスタ)が第何ページになっているかを管理するのはプログラマの責任です。「LDP」命令のイミディエイトオペランドに、データメモリロケーションを指定すると自動的に9ビットのページオペランドに変換されます。<.SETDP>擬似命令を使用すると7ビットアドレスで参照しようとする領域が現在のカレントデータページ内に存在するかを監視することができます。 ROM化可能なインテル形式・モトローラ形式のオブジェクトファイルを生成する場合、このセグメントにDSPの命令や、定数データを配置してはなりません。通常このセグメントはBSS擬似命令による領域確保のみで構成しなければなりません。ただしDSKのデバッガ「DSK5D.EXE」を使用してDSK形式のオブジェクトをDSPボードにロードする場合、このセグメントに初期化済みのデータを定義しても構いません。  TMS320C5xは<PMST>レジスタの<OVLY>ビットの設定によりプログラムメモリとデータメモリのアドレス空間を同一空間上に配置することができます。この場合、コードセグメント(CSEG)とデータセグメント(DSEG)のロケーションがオーバラップするとDSPの実行は予想外のものになります。アセンブラはこのようなセグメントのオーバラップを監視しないので、プログラマは充分注意を払う必要があります。 ----------------------------------------------------------------------------- 第3章 疑似命令 ----------------------------------------------------------------------------- DSPへのオペレーションではなく、ASM50アセンブラに対するオペレーションを疑似命令と呼びます。以下に疑似命令について解説します。 <1> CSEG/.TEXT/.PS [機能] コードセグメントの指定 [文法] CSEG .PS 式 [解説] 現在のカレントポインタ以降のテキストはコードセグメントに関する記述であることを宣言します。ソーステキストの先頭では自動的にコードセグメントの状態になっています。<.PS>命令を使用すると同時に開始ロケーションを指定する事ができます。 <2> DSEG/.DATA/.DS [機能] データセグメントの指定 [文法] DSEG .DS 式 [解説] 現在のカレントポインタ以降のテキストはデータセグメントに関する記述であることを宣言します。<.DS>命令を使用すると同時に開始ロケーションを指定する事ができます。 <3> ORG [機能] ワードデータの定義 [文法] ORG 式 [解説] 現在のカレントポインタのロケーションを式の値で指定するアドレスに変更します。式の値はパス1で既知でなければなりません。 [ 例 ] ORG 100H <4> DPAGE/.DPAGE [機能] データセグメントのページを更新する [文法] DPAGE [解説] 現在のデータセグメントのカレントポインタのロケーションを、次のページの先頭のロケーションに設定します。現在のロケーションが既にページの先頭にある場合はロケーションの変更は行われません。 [ 例 ] .DS 100H ;DADR=100H DPAGE ;ここでは変更されない XnApp .BSS 50 DPAGE ;DADR=180H <5> DEFW/DW/WORD/INT/.WORD/.INT [機能] ワードデータの定義 [文法] DEFW 式{,式{,式....}} [解説] アーギュメントで指定した式の値が、現在のカレントロケーションから1ワードずつセットされます。アーギュメントはカンマ<,>で区切り複数を同時に指定できます。 [ 例 ] DW 8000,4321H,1+2,0.12345 <6> DEFS/DS/BSS/.BSS [機能] 予約領域の確保 [文法] DEFS 式 DEFS Symbol,式 [解説] アーギュメントで指定した式の値のワードサイズの領域を確保します。この疑似命令は通常、状態変数、係数配列、作業領域等の領域を確保するのに使用します。Symbolを指定した場合、確保する予約領域の先頭のロケーションをその名前のシンボルに割り当てます。式の値はパス1で既知でなければなりません。 [ 例 ] DEFS 10 ; 10ワードの予約領域を確保する .BSS ABC,5 ; 5ワードの予約領域を確保し先頭ロケーションを<ABC> ; に定義する <7> .SPACE [機能] 予約領域の確保 [文法] .SPACE 式 [解説] アーギュメントで指定した式の値をビット数としてワードに換算したサイズの領域を確保します。この疑似命令は「DSK5A.EXE」との互換性のための用意したものです。領域の確保には「BSS」擬似命令を使用したほうが便利です。 式の値はパス1で既知でなければなりません。 [ 例 ] .SPACE 16 <8> STRING/.STRING [機能] 文字列の定義 [文法] STRING "strings" [解説] アーギュメントで指定した文字列を現在のカレントロケーションから展開します。16ビットコードのオブジェクト(DSK等)を作成する場合は、データの上位バイトおよび下位バイトのいずれにも同じ文字コードが展開されます。8ビットのブートROMコードを作成する場合は、上位バイト、下位バイトの順に振り分けられます。この擬似命令はROMの中に特定の文字列を埋めこみたい場合に使用します。 [ 例 ] STRING "Leaky LMS Algorithm CW Auto BPF. (C) JE3HHT 1994." <9> MACRO/.MACRO〜ENDM/.ENDM [機能] マクロの登録 [文法] マクロ名 MACRO {ダミー{,ダミー{,....}}} . . {マクロ名} ENDM [解説] MACRO/.MACRO〜ENDM/.ENDMまでの範囲のソースステートメントをマクロ名に登録します。詳細は第4章を参照して下さい。 <10> .REPT〜.ENDR [機能] 反復マクロブロックの定義と展開 [文法] .REPT 式 . . .ENDR [解説] .REPT〜.ENDRまでの範囲のソースステートメントを式の値で指定する回数、繰り返し展開します。式の値はパス1で既知でなければなりません。リピートは特別なマクロとして定義終了と同時に実行が開始されます。詳細は第4章を参照して下さい。 [ 例 ] .REPT 10 LTD *-,AR2 MPY *+,AR1 .ENDR <11> .IFxxx〜.ENDIF [機能] 条件ブロックの定義/変更/終了 [文法] .IFxxx 式 . {.ELSE .} .ENDIF .IFxxx 式 . .ELSEIF 式 . {.ELSE .} .ENDIF [解説] 条件ブロックを開始した場合、式が真の時<.IFxxx>〜<.ENDIF>までの範囲がアセンブルされます。式が偽の時はアセンブルされません。条件ブロックの途中に<.ELSE>を記述して条件を反転することができます。この場合は真は偽になり偽は真になります。そしてその結果によってアセンブルを行うかどうかが決定されます。式の値はパス1で既知でなければなりません。 <.IFxxx>は以下の5種類が記述できます。 .IF 式 式が0以外の時に真 .IFDEF シンボル シンボルが定義されている時真 .IFNDEF シンボル シンボルが定義されていない時真 .IFB 文字列 文字列がヌルの時真 .IFNB 文字列 文字列がヌルでない時真 <.IFDEF>擬似命令では指定するシンボルが後方参照になる場合、パス1では偽、パス2では真になります。この場合アセンブラはフェーズエラーを出力する可能性があります。 <.IFB>および<.IFNB>擬似命令はマクロブロック内でパラメータが指定されているかどうかをテストするのに使用されます。 条件ブロック内に<.ELSEIF>を記述して新しい条件のテストができます。この場合それまでの条件が真の時は無条件に偽になりますが偽の時は式がテストされます。 条件ブロックは最大32レベルまでネストすることができます。条件擬似命令はラベルフィールド(行の先頭)に記述しても構いません。 マクロブロックの中に条件ブロックが存在するとき、条件はマクロを展開する時にテストされます。マクロブロックの外に条件ブロックが存在するとき、先に条件がテストされマクロ定義が行われるかどうかが決まります。 [ 例 ] .IF ABC .IF CDE==3 DMOV *- .ELSE DMOV *+ .ENDIF .ELSE LTD *- .ENDIF <12> INCLUDE/.INCLUDE/.COPY [機能] ソーステキストの挿入 [文法] INCLUDE fname [解説] 指定したファイル名のソースファイルをカレントロケーションに挿入します。この疑似命令は定数定義などのファイルを別ファイルとして記述するのに使用されます。 ファイルのインクルードは最大7レベルまでネストできます。 [ 例 ] INCLUDE MACLIB.INC <13> LIST/.LIST [機能] リスト展開の許可 [文法] LIST [解説] リスト展開を許可します。この疑似命令を実行するとこれ以降のテキストはリストファイルに展開されます。 [ 例 ] LIST <14> NLIST/.NLIST [機能] リスト展開の禁止 [文法] NLIST [解説] リスト展開を禁止します。この疑似命令を実行するとこれ以降のテキストはリストファイルへの展開が禁止されます。 [ 例 ] NLIST <15> EQU/SET/.SET [機能] 値シンボルの定義 [文法] symbol EQU 式 [解説] シンボルに式の値を割り当てます。式の値はパス1で既知でなければなりません。 [ 例 ] ORDER EQU 80 <16> DEFL/= [機能] 値シンボルの定義(再定義を許す) [文法] symbol DEFL 式 [解説] シンボルに式の値を割り当てます。式の値はパス1で既知でなければなりません。この擬似命令を使用した場合、シンボルが既に定義されていてもエラーになりません。 通常この擬似命令は以下のように「.rept〜.endr」の繰り返しブロックと共用で使用します。 [ 例 ] Nx DEFL 1 .rept 10 ltd *- mpy Hn+Nx Nx DEFL Nx+3 .endr <17> .COEF [機能] FIRフィルタの係数を算出し格納します [文法] .COEF TAP,TYP,FS,FC{,FCH},ATT,GAIN,SCALE [解説] 現在のカレントロケーションにパラメータで指定するFIRフィルタの係数を格納します。格納する係数は16ビットの固定小数点に調整された値です。 パラメータは以下の通りです。 TAP フィルタ次数(必ず偶数にすること) TYP LPF,HPF,BPF,BEFのいずれか FS サンプリング周波数(Hz) FC カットオフ周波数(BPF,BEFの場合は低い側)(Hz) FCH BPF,BEFの高い側のカットオフ周波数(Hz) ATT 阻止域の期待する減衰量(DB) GAIN フィルタのゲイン SCALE 格納データの小数点の位置(15=Q15) 少なくともフィルタ次数(TAP)はパス1で既知でなければなりません。算出するフィルタ係数は適切な窓関数によりギブス補正されています。格納する係数データの数は指定するフィルタ次数+1です。 係数データはプログラムから昇順または降順のいずれの方向で参照しても同じ値になります(フィルタの直線位相特性が保証される)。  次数が大きくなるとそれぞれの係数の値は小さくなります。この場合、誤差を減少させる目的で格納データの小数点の位置(SCALE)を調整する必要があります。スケールを大きくすると誤差は減少しますがオーバフローに注意しなければなりません。アセンブラは係数データがオーバフローした場合警告を出力します。  インターポーレータを設計する場合、フィルタのゲインは通常インターポーレータの周波数倍率を指定します。この際フィルタの次数が小さいと係数がオーバフローになる可能性があります。この場合もオーバーフローを防止するためにプログラマは適切なスケーリングを指示しなければなりません。 [ 例 ] .COEF 24,lpf,12500,1600,60,1,15 .COEF 80,bpf,12500,600,800,60,1,16 <18> .ERRMSG [機能] エラーメッセージの出力 [文法] .ERRMSG メッセージ [解説] 指定するメッセージをエラーメッセージとして出力します。通常この擬似命令は条件擬似命令と組み合わせて使用します。この擬似命令が実行されるとアセンブラはエラーをカウントします。 [ 例 ] .if $>500h .errmsg データロケーションがブロックを越えました. .endif <19> .WARMSG [機能] 警告メッセージの出力 [文法] .WARMSG メッセージ [解説] 指定するメッセージを警告メッセージとして出力します。通常この擬似命令は条件擬似命令と組み合わせて使用します。この擬似命令が実行されるとアセンブラは警告をカウントしますがオブジェクトファイルは作成されます。 [ 例 ] .if $>300h .warmsg データロケーションがブロックを越えました. .endif <20> .MSG [機能] メッセージの出力 [文法] .MSG 文字列{,式{,式}} [解説] 指定する文字列をメッセージとして画面に出力します。文字列内に次のキーワードを指定してアーギュメントの式を表示することができます。式の評価はパス2で行われます。 %u 符号なしの10進数 %d 符号ありの10進数 %X 符号なしの16進数 [ 例 ] .msg "Fs = %u[Hz]",Fs <21> .MMREGS [機能] メモリマップレジスタシンボルの登録 [文法] .MMREGS [解説] TMS320C5xで定義されているメモリマップレジスタシンボルを定義します。メモリマップレジスタシンボルは大文字と小文字の区別がされません。また同じ名前のシンボルを<EQU>擬似命令等で定義してもその定義が優先されてエラーとはなりません。 <22> .SAMEP [機能] データセグメントのページをテストする [文法] .SAMEP {式} [解説] 現在のデータセグメントのカレントポインタのロケーションが式で指定するロケーションと同一のページに存在するかをテストします。式が省略された場合は以下の擬似命令が(直前に)アセンブルされた時のロケーションがテストの対象になります。 DSEG(.DS) ORG DPAGE テストした結果が同一ページにならない場合は、アセンブラは警告メッセージを出力します。 この擬似命令は7ビットアドレスしか指定できない命令を使用して一連のデータメモリの集合を参照する場合に、その領域が同一ページになっているかどうかをテストする目的で使用します。 [ 例 ] .DS 100H XnDly .BSS N_DELAY+1 XnApp .BSS N_APP+1 .SAMEP ; ロケーションが 180H 以上の時に警告メッセージ <23> .SETDP [機能] カレントデータページを設定する [文法] .SETDP {式} [解説] 式で指定されるデータメモリアドレスを新規のカレントデータページとして定義します。この擬似命令がアセンブルされると、それ以降アセンブラは7ビットアドレスを生成する前に、そのアドレスがカレントデータページ内に存在するかを監視するようになります(存在しない場合警告メッセージが出力される)。式を指定せずにこの擬似命令を記述すると、それ以降アセンブラは上記の監視を行わなくなります(デフォルトの状態にもどる)。 カレントデータページの更新は<ldp #式>をアセンブルした時にも行われます。 [ 例 ] .setdp XnApp lacc XnApp ldp #0 add dxr sacl XnApp ; ここで警告が出る <24> ENTRY/.ENTRY [機能] DSKエントリポイントの設定 [文法] .ENTRY {式} [解説] 式で指定されるコードセグメントのロケーションをDSKエントリポイントとして設定します。式はパス1で既知でなければなりません。式を省略した場合は現在のカレントロケーションがDSKエントリポイントとなります。この擬似命令をソースファイル内のどこに記述しても構いませんが、一番最後に記述した時のロケーションが有効になります。 DSKエントリポイントはDSK形式のオブジェクトファイルを作成する場合にのみ意味を持ち、デバッグ時のプログラムの開始番地になります。インテルヘキサおよびモトローラS形式のオブジェクトファイルを生成する場合、この擬似命令は意味を持ちません。 [ 例 ] .entry Start <25> END/.END [機能] ソーステキストの終了 [文法] END [解説] ソーステキストの終了を宣言します。インクルードファイル内やマクロ内でこの擬似命令が記述されていても無視されます。 ----------------------------------------------------------------------------- 第4章 マクロ ----------------------------------------------------------------------------- ASM50は標準でマクロ機能を備えています。マクロ名はマクロ定義ブロックにつけた名前です。プログラム中の頻繁にコーディングする部分をあらかじめマクロに定義し、プログラム中の任意の場所で何回でも呼び出して展開することができます。また一連の範囲のブロックをくり返し実行することもできます。 マクロのネスト(マクロの中でのマクロの呼び出し)は16レベルまで行うことができます。 4.1 マクロの定義(MACRO/.MACRO〜ENDM/.ENDM) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [機能] マクロブロックを定義します。 [文法] マクロ名 MACRO {ダミー{,ダミー{,....}}} . . {マクロ名} ENDM [解説] <MACRO>〜<ENDM>までのステートメントをマクロとして定義します。 マクロ名は定義するマクロの名前です。シンボルと同じ規則が適用され、128文字までが有効です。シンボル名で定義した名前をマクロ名として使用しても構いません。両者はまったく別のものとして区別されます。一度定義したマクロは同じ名前で再定義することができます。<ENDM>の行にマクロ名を記述しても構いません。このフィールドのシンボル(マクロ名)は無視されます。 マクロを定義したのち、オペレーションフィールドにそのマクロ名を記述して呼び出すことができます。 ダミー(仮パラメータ)はマクロ定義ブロック内で使用しているダミーがマクロ呼び出し時のパラメータに置き換わります。ダミーの文字数に制限はありません。呼び出し時にマクロ定義ブロック内のダミーと同じすべての文字列が置き換えの対象となります。ダミーとダミーの間はカンマ<,>で区切ります。マクロブロック内がアセンブルされるのはそのマクロを呼び出して展開する時です。 定義したステートメントの集合は、マクロ記憶領域と呼ばれる領域に記憶されます。マクロ記憶領域はデフォルトで4096バイトあります。大きなマクロまたは多数のマクロを定義する場合には起動オプション<-M>で領域サイズを広げて下さい。マクロ記憶領域が消費されるのはマクロを定義する時です。定義したマクロを呼び出しても領域を消費することはありません。 [例] マクロ定義 FOO MACRO &X,&Y,&R .REPT &R LTD *+,&X MPY *-,&Y .ENDR ENDM マクロの呼び出し FOO ar1,ar2,2 アセンブル結果 FOO ar1,ar2,2 + .REPT 2 + LTD *+,ar1 + MPY *-,ar2 + .ENDR 0000'72A9 + LTD *+,ar1 0001'549A + MPY *-,ar2 0002'72A9 + LTD *+,ar1 0003'549A + MPY *-,ar2 4.2 マクロの呼び出し ~~~~~~~~~~~~~~~~~~~~~~~~ マクロの呼び出しはそのマクロを定義した後でなければなりません。マクロの呼び出しの形式は次の通りです。 マクロ名 {パラメータ{,パラメータ{,...}}} ○ マクロ名は必ずオペレーションフィールドに記述しなければなりません。 ○ マクロ名はMACRO命令で定義した名前と同じ名前です。 ○ パラメータはMACRO命令のダミーに左から順番に対応しています。 ○ パラメータは1行に収まらなくてはなりません。パラメータとパラメータはカ ンマ<,>で区切ります。 パラメータの数とダミーの数は必ずしも一致する必要はありません。パラメータの数よりもダミーの数が多い場合、余ったダミーはヌルパラメータとみなされます。パラメータの数よりダミーの数が少ない場合、余ったパラメータは無視されます。 以下の例に示すようにマクロの呼び出しはネストすることができます。ネストは最大16レベルまで許されます。 [例] INSIDE1 MACRO &1,&2 ltd *+,&1 mpy *-,&2 ENDM INSIDE2 MACRO &1,&2 dmov *+,&1 dmov *-,&2 ENDM OUTSIDE MACRO &1,&2 INSIDE1 &1,&2 INSIDE2 &1,&2 ENDM マクロの呼び出し OUTSIDE AR0,AR1 アセンブル結果 OUTSIDE AR0,AR1 + INSIDE1 AR0,AR1 0000'72A8 + ltd *+,AR0 0001'5499 + mpy *-,AR1 + INSIDE2 AR0,AR1 0002'77A8 + dmov *+,AR0 0003'7799 + dmov *-,AR1 4.3 ダミーパラメータの置き換え ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ マクロを展開する際にダミーはパラメータに置き換わります。置き換えはマクロ定義ブロック内のすべての文字列が対象となります。ダミーの文字列の置き換えは大文字と小文字が区別されます。ダミーの名前は予想外の置き換えが実行されないように長い名前にするか<&>などの通常使用しない文字を含めるべきです。 [例] ZZZ MACRO MY,YOU MYLOG DEFL YOU STRING "MY Macro" ENDM マクロの呼び出し ZZZ A,50 アセンブル結果 ZZZ A,50 + ALOG DEFL 50 0000'41412020 + STRING "A Macro" 0002'4D4D6161 0004'63637272 0006'6F6F パラメータの先頭にパーセント<%>を付加すると、そのパラメータの値を数字化したものをダミーと置き換えます。 [例] _LABEL MACRO &1,&2 _L&1_&2: ENDM マクロの呼び出し _BASE = 50 _NEST = 100 _LABEL %_BASE,%_NEST _LABEL %_BASE,%_NEST+1 アセンブル結果 _BASE = 50 _NEST = 100 _LABEL %_BASE,%_NEST + _L50_100: + _LABEL %_BASE,%_NEST+1 + _L50_101: 上記の手法はマクロ内で他と一致しないシンボルを生成する場合に使われます。<%>に続く式はパス1で既知でなければなりません。 4.4 反復マクロブロック ~~~~~~~~~~~~~~~~~~~~~~~~~~ [機能] 反復マクロブロックを定義し指定した回数だけ展開します。 [文法] .REPT 式 . . .ENDR [解説] <.REPT>〜<.ENDR>ステートメントの間の反復ブロックを式の回数だけ繰り返し展開ます。式は16ビットの符号なし整数として処理します。式の値は0〜65535でなければなりません。式の結果が0の場合反復ブロックは展開されません。 式の値はパス1の時に既知でなければなりません。例えば後方参照のシンボルを参照している場合はエラーとなります。 <.REPT>〜<.ENDR>までの間の反復ブロックは特別なマクロとして定義されます。そして<.ENDR>疑似命令をデコードした直後にそのマクロを式の回数だけ繰り返します。反復マクロブロックはマクロ記憶領域を消費しますが、展開を終了する時に消費した領域は解放されます。 [例] .REPT 4 DMOV *- .ENDR     アセンブル結果 .REPT 4 DMOV *- .ENDR 0000'7790 + DMOV *- 0001'7790 + DMOV *- 0002'7790 + DMOV *- 0003'7790 + DMOV *- ----------------------------------------------------------------------------- 第5章 ASM50アセンブラ ----------------------------------------------------------------------------- 5.1 ASM50アセンブラ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ASM50アセンブラはソースファイルに作成したソースプログラムをアセンブルし、オブジェクトプログラムが格納されたオブジェクトファイル(DSK形式、インテルヘキサ形式、モトローラS形式)を作成することができます。 5.2 パス ~~~~~~~~~~~~ ASM50アセンブラはパス1とパス2の2段階でソースプログラムをアセンブルします。パス1ではプログラム中のステートメントの評価を行いオブジェクトコードの生成量を計算します。またプログラム中のシンボルやラベルに値(ロケーションアドレス)を割り当て、シンボルテーブルを作成します。 パス2ではパス1で生成したシンボルテーブルを参照して、オブジェクトコード中のシンボルや式の参照部分にシンボルの値を代入します。 パス1とパス2で定義するシンボルの値が異なる場合、ASM50はフェーズエラーを出力します。 5.3 ASM50アセンブラの実行 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ASM50アセンブラはMSDOSのコマンドで実行します。この時ソースファイルの名前やアセンブラに対する指示をコマンドオプションで指定します。 MSDOSのコマンド状態から次の書式で起動します。 ASM50 ソース名 {オプション} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ または ASM50 {オプション} ソース名 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ オプションは省略することができます。オプションはソース名の前にあっても後ろにあっても構いませんが、必ずソース名を指示しなければなりません。 ソース名の拡張子は<.A50>を使用して下さい。ソース名の拡張子の指定を省略した場合は強制的に<.A50>を付加して処理を進めます。 [ 例 ] C>ASM50 LMSBP TMS3205X MACRO ASSEMBLER ASM50 Version 2.00 (C) JE3HHT 1996. PASS-1 Symbol table PASS-2 Output object Code Location 080A - 0D26 Data Location 0100 - 0266 31760 Bytes memory(Symbol & Macro) Free. No Fatal error. 5.4 オプション ~~~~~~~~~~~~~~~~~~ 以下にオプションを示します。 -I{8} インテルヘキサを作成します。(デフォルトはDSK) -S{8} モトローラSヘキサを作成します。(デフォルトはDSK) -L リストファイルを作成します。(拡張子は<.LST>です) -Y シンボルファイルを作成します。 -K リストファイルにシンボルテーブルを出力しません。 -Dx{=v} シンボルの定義(-Dabc=124) -Mx マクロ記憶領域のサイズ(デフォルト x=4096) 5.5 エラーメッセージ ~~~~~~~~~~~~~~~~~~~~~~~~ <1> ASM50アセンブラのエラー ソースファイル を指定して下さい. ASM50アセンブラの実行時にソースファイルの指定がなかった。 前途多難なので アセンブル を中止します. 発生したエラーが多すぎて前途が多難と判断した。 オプション '-Z' が処理できません. 指定したオプションに誤りがある。 'TEST.HXL' が作成できません. オブジェクトファイルやリストファイルの書き込みを行うことができない。 メモリ が足りません. メモリ不足で実行できない。 シンボル 記憶領域が一杯です. シンボルテーブルの領域がいっぱいになった。 <2> ソースプログラムのエラー '123ABC' は シンボル/マクロ 名として不適切です. 指定したシンボル(マクロ)名はシンボルの規則に違反している。 パス1 と パス2 の ロケーション が異なります. (1221-1222). フェーズエラー 'ABC' は2重定義です. 指定のシンボルは他の場所でも定義されている。 'TEST.DEF' が見つかりません. 指定のインクルードファイルがオープンできない。 INCLUDE スタック が オーバフロー しました. インクルードのネストが7レベルを越えた。 'VVV' の値は処理できません. 指定のアーギュメントは数値として処理できない。 '%&$' が処理できません. 解読できないアーギュメント 'ABC' が確定しません. 指定のアーギュメントの数値が確定していない。 'ABC' はパス1で確定していません." 指定のシンボルの数値が確定していない。 オペレーション または アーギュメント が処理できません. 意味不明なオペレーションまたはアーギュメント アーギュメント 'ABC' が処理できません." 意味不明なアーギュメント 'VAL' の値が大きすぎます." 指定された数値が大き過ぎる。 アーギュメント 'ABC+DEF' に未解決な シンボル が含まれています." 解決されていないシンボルが含まれている。 これ以上マクロのネストはできません.  マクロのネストが16レベルを越えた。 マクロ記憶領域がいっぱいです. -Mオプションで領域を増やして下さい.  マクロブロックを記憶するための領域がいっぱいになった。起動時の<-M>オプションで領域を増やすと解決する。 ----------------------------------------------------------------------------- 第6章 補足事項 ----------------------------------------------------------------------------- ○ BANZ命令 「BANZ pma」命令はデフォルトで「BANZ pma,*-」のコードを生成します。補助ポインタの更新を行いたくない場合は「BANZ pma,*」のように記述して下さい。「BANZD」命令も同様です。 ○ パイプラインの補正 本アセンブラは、パイプラインの補正(「NOP」命令の挿入)は行いません。メモリマップドアクセスでレジスタを操作する場合はプログラマの責任で補正して下さい。 ○ 旧DSPの命令 本アセンブラが解読するのは320C5xの命令だけです。C1xおよびC2xの命令は使用できません。 ○ ブートROM ブートROMを作成する場合はコードセグメントの一番最初に次の2行を定義して下さい。 dw CodeTop ; 転送先アドレス dw CodeLast-CodeTop-1 ; 転送ワード数 シンボル<CodeTop>と<CodeLast>は割り込みベクトルを含むすべてのプログラムテキストの先頭と最後のロケーションでなければなりません。またDSPプログラムアドレスのFFFFH(通常はROMの最終ロケーション)にブートルーチン選択ワードを記述しなければなりません。 <-I{8}>オプション、<-S{8}>オプションによりヘキサファイルを出力する場合、コードセグメントの開始アドレスに関わらず0番地からのイメージにオブジェクトファイルを作成します。ただしプログラム中のアドレス参照関係はユーザがプログラムしたアドレスロケーションの関係を維持しています。このアドレス変換機能によりブートROMの作成は極めて簡単です。以下に0800H番地からのプログラムを8ビットの32KバイトブートROM(8000H〜FFFFHにマップ)に作成する場合の例を示します。 .ps 0800h-2 RomTop: dw CodeTop ; 転送先アドレス dw CodeLast-CodeTop-1 ; 転送ワード数 CodeTop: ここから割り込みベクトルとプログラムを記述 . . . CodeLast: .ps RomTop+03fffh ; ブートルーチン選択ワード dw 81h ; SRC=8000H, 8ビットブート 上記を<-I8>オプションを付けてアセンブルすると0000H〜7FFFHのインテルヘキサイメージのファイルが作成されます。そのままROMに書き込みDSPアドレス8000H〜FFFFHにそのROMを配置すればブートROMとして動作します。 付属のサンプルプログラムはDSKまたはブートROMのいずれでも動作するように条件擬似命令を使用して作成されています。 ○ サンプルプログラム「BP200.A50」 600Hz〜800HzのCW用のバンドパスフィルタです。100次のFIRフィルタで構成しています。 入出力のサンプリング周波数とアプリケーションのカットオフ周波数が離れているので、デシメータおよびインタポーレータを使用してオーバサンプリングフィルタにしてあります。デシメータおよびインターポーレータの部分はASM50のマクロ機能と「.REPT〜.ENDR」擬似命令を使用した適切な参考例です。 オーバサンプリングを行わない場合はアプリケーションの次数を300次にすると同じ特性のフィルタが得られます。この場合は割込み処理内で「RPT/MACD」ループにより計算する事ができプログラムは大きく簡略化できます。しかし次数が多くなるとそれぞれの係数が非常に小さな値になるために演算誤差が大きくなり誤差ノイズが顕著になります。 ○ サンプルプログラム「LMSBP.A50/LMSAN.A50」 「Leaky LMS Algorithm」によるCW用の適応バンドパスフィルタおよび適応ノッチフィルタです。収束の時間はトランスバーサル(FIR)フィルタの次数、サンプリング周波数およびステップサイズ(μ)によって決定されます。μの値を大きくすると収束が早くなりますが残留誤差が大きくなります。これらの適切な組み合わせを計算で求めるのは難しくカットアンドトライで試行錯誤しなければなりません。サンプルプログラムはこれら組み合わせについて充分なチューニングはされていません。 ----------------------------------------------------------------------------- 最後に ----------------------------------------------------------------------------- 当初はDSKに付属の「DSK5A」を使用していましたが、以下の3点に大きな不満を感じました。 「.bss」擬似命令がない(「.space」では計算がめんどう) アーギュメントに式が使用できない 「.rept〜.endr」が使用できない ASM50は数年前に作成したASM10(320C1x用のアセンブラ)を改造したものです。当時はDSPチップはとても高価で、DSKのような評価ボードはとても手がでる価格ではありませんでした。 しかし最近はDSPチップも高性能になり、また私たちアマチュアが手を出すのに手ごろな価格に下がってきつつあります。アマチュア無線ではDSPを利用するテーマが数多く存在しますので、このアセンブラが少しでも皆さんのお役に立てば大変うれしく思います。 なお本アセンブラおよび付属のサンプルプログラムに関して、その使用および配布に制限はありません。ただし使用した結果について責任は持てませんのであらかじめご了承下さい。 「ASM50 ソフトウエアマニュアル」 初版 1996.04.19 JE3HHT "Mako"