AASMマクロの作り方

AASMで各種CPUに対応させる時のマクロの作り方を紹介します。
非常に簡単な解説ですので、不明な点はメールして頂いても構いません。


「前処理

以下の内容はH8-3048用からの抜粋です。

;多くのアセンブラ同様セミコロン(;)以降はコメントになります。
;
;H8-3048マクロ定義 for AASM Ver.3.51
;
;マクロを作成した人の著作権表示を行います。無くても構いません。
.copyright = "H8-3048 Macro for AASM Release0.1 Copyright (C) 2000 T.Sagae"

;CPUによって数字をメモリーに格納する順序が異なります。
;byte_order=0 1234H -> 1234H で格納します。(little endian)
;byte_order=1 1234H -> 3412H で格納します。(big endian)
;H8はlittle endian、Z80や8086はbig endianです。
byte_order = 0

;式を計算した時に、最外縁の括弧を取るか取らないかを指定します。
;calc_order=0 ”(値)”の計算結果を”(値)”として扱います。
;calc_order=1 ”(値)”の計算結果を”値”として扱います。
;これによりZ80等で”LD A,(値)”が”LD A,値”に解釈されないようにします。
;同様な命令が使われていない場合は1にしておきます。
calc_order = 1

;"-L"でリストを出力する時のバイトオーダー指定を行います。
;list_order=0 1234H -> 1234H で出力します。(little endian)
;list_order=1 1234H -> 3412H で出力します。(big endian)
;DD,DWで出力している時のみ有効です。(PIC,AVR等で1にしています)
list_order = 0

;アドレスの処理単位を指定します。
;word_adrs=0 1バイト単位でアドレスを処理します。(Z80,H8等)
;word_adrs=1 1ワード(2バイト)単位でアドレスを処理します。(PIC,AVR等)
word_adrs = 0

;@マークを文字列の一部として扱うかどうかを指定します。
;symbol_order=0 @xxxxを1つの文字列として扱います。
;symbol_order=1 @とxxxxを別に扱います。(H8)
symbol_order = 1

以上の内容はどんなマクロを作る場合でもなるべく入れておきましょう。


「ここから本題

ADD.B #5,R0H」の場合はどのようなマクロにするか説明します。

まず数値の部分を注目すると「ADD.B #5,R0H」は「ADD.B #数値,R0H」になります。
「macro」定義での数値部分は「NUMBER」に置き換えられますのでマクロ定義はこうなります。

macro ADD.B #NUMBER,R0H

次にマクロの中味はデータシートを参照してこうなります。

db 0x80,#0

どうして「#0」がでてきたのでしょう?
AASMではマクロ定義文の先頭から順に、数値(NUMBER)やconst定義された要素が出現すると内部変数に順次格納して行きます。(「#0」から開始)
よって「#0」にはマクロのNUMBER部分が出力されます。

それでは「ADD.B #5,R1H」の場合はどうでしょうか?
こうなります。

macro ADD.B #NUMBER,R1H
db 0x80+1,#0
endm

これでも何ら問題ありませんが量が多いと大変です。定義量を減らしましょう。
データシートをよく見るとレジスタ番号に合わせて「+1」の部分が変化しているのが判ります。
こんな時は一致する文字列を検索して数値に変換してくれる「const」命令を使います。
「const」に使用する名前はレジスタ名等とダブりにくい名前を付けて下さい。

const _Rb_ = R0H,R1H,R2H,R3H,R4H,R5H,R6H,R7H,R0L,R1L,R2L,R3L,R4L,R5L,R6L,R7L

マクロ定義の中に「_Rb_」を記述しておくと一致した時の番号が得られます。(ゼロから順番)
得られた番号も「#0」等の内部変数に入ります。すると今まで説明したマクロはこうなります。

macro ADD.B #NUMBER,_Rb_
db 0x80+#1,#0
endm

これで8ビットレジスタ16個分の定義ができました。
後は書き方の違いで、以下のようにもできます。

macro ADD.B #NUMBER,_Rb_
dw 0x8000+(#1<<8)+#0
endm

マクロ作成の基本は以上の通りです。
後は実際のAASM添付マクロを参照する事で理解できるはずです。
更に完成度を高めたい方はぜひ数値やアドレス範囲チェックを追加して下さい。
チェックが無いと、作ったプログラムが悪いのかマクロが悪いのか判らなくなります。
(と言いながら面倒なので良く手抜きする部分です)


「最後に

;本題でマクロの基本的な作り方がわかったら以下のように作るだけです。
const _BCC_ = BRA,BRN,BHI,BLS,BCC,BCS,BNE,BEQ,BVC,BVS,BPL,BMI,BGE,BLT,BGT,BLE
const _ER_ = ER0,ER1,ER2,ER3,ER4,ER5,ER6,ER7
const _R_ = R0,R1,R2,R3,R4,R5,R6,R7,E0,E1,E2,E3,E4,E5,E6,E7
const _Rb_ = R0H,R1H,R2H,R3H,R4H,R5H,R6H,R7H,R0L,R1L,R2L,R3L,R4L,R5L,R6L,R7L

;純正アセンブラ専用命令がAASMでスキップされるようにします。
; [.CPU 300HA]は[.CPU][300H][A]に分解されるので下記のマクロになる
macro .CPU NUMBER A
msg "" ; ダミーの処理を入れる
endm

;純正アセンブラの擬似命令をAASMの擬似命令に置き換えます。
.def .equ = equ
.def .data.b = db
.def .data.w = dw
.def .sdata = db
.def .include = include

macro .ORG NUMBER
$ = #0
endm

macro .RES.B NUMBER
$ = $ + #0
endm

macro .ALIGN NUMBER
$ = (($+(#0-1))/#0)*#0
endm

macro ADD.B #NUMBER,_Rb_
db 0x80+#1,#0
endm

;続く...