AILZ80ASMは、C#で書かれた.NET 8の環境で動作するZ80アセンブラです。
※ 実行形式は、「自己完結型の実行可能ファイル」になっています。.NETの環境を用意する必要はありません。
AILZ80ASM [<オプション>] <オプション指定文字列:ファイル名等> [ <オプション指定文字列:ファイル名等>]
> AILZ80ASM sample.z80
コンソールアプリですので、コンソールより起動してください。
コマンドライン | 説明 |
---|---|
-i, --input |
アセンブリ対象のファイルをスペース区切りで指定します。 (オプション名の省略が可能) |
-ie, --input-encode |
入力ファイルのエンコードを選択します。 [auto, utf-8, shift_jis] デフォルト値:auto |
-o, --output |
出力ファイルを指定します。 |
-om, --output-mode |
出力ファイルのモードを選択します。 [bin, hex, t88, cmt, sym, equ, lst, err, tag] デフォルト値:bin |
-oe, --output-encode |
出力ファイルのエンコードを選択します。 [auto, utf-8, shift_jis] デフォルト値:auto |
-lm, --list-mode |
リストの出力形式を選択します。 [simple, middle, full] デフォルト値:full |
-lob, --list-omit-binary | リストの出力でバイナリーインクルードを省略出力をします。 |
-ep, --entry-point | エントリーポイントを指定します。 |
-ts, --tab-size |
TABのサイズを指定します。 デフォルト値:4 |
-dw, --disable-warning |
Warning、Informationをオフにするコードをスペース区切りで指定します。 |
-ul, --unused-label | 未使用ラベルを確認します。 |
-cd, --change-dir |
アセンブル実行時のカレントディレクトリを変更します。終了時に元に戻ります。 |
-gap, --gap-default |
アセンブラのギャップのデフォルト値を指定します。 デフォルト値:$FF |
-df, --diff-file | アセンブル出力結果のDIFFを取ります。アセンブル結果は出力されません。 |
-dl, --define-label |
ラベルをスペース区切りで指定します。値を設定するときは=で代入します。 |
-nsa, --no-super-asm | スーパーアセンブルモードを無効にします。 |
-sa, --start-address | スタートアドレス(出力)を指定します。ORGで指定したアドレスまで -gap で埋めます |
-f, --force | 出力ファイルを上書きします。 |
-v, --version | バージョンを表示します。 |
-?, -h, --help |
ヘルプを表示します。各オプションの詳細ヘルプを表示します。例: -h --input-mode |
-??, --readme | Readme.mdを表示します。 |
■ sample.z80をアセンブル、出力はBIN形式
> AILZ80ASM sample.z80
■ sample.z80をアセンブル、出力はBIN形式、上書き確認プロンプトを表示しないで上書きをする
> AILZ80ASM sample.z80 -f
■ sample.z80をアセンブル、出力はBIN形式、ログファイルを出力
> AILZ80ASM sample.z80 -bin -err
■ sample.z80をアセンブル、出力はBIN形式、LST形式、SYM形式、ログファイルを出力
> AILZ80ASM sample.z80 -bin -lst -sym -err
■ sample.z80をアセンブル、出力はCMT形式
> AILZ80ASM sample.z80 -cmt
> AILZ80ASM sample.z80 -om cmt
■ sample.z80をアセンブル、出力はBIN形式、CMT形式、リストの出力(形式:シンプル、タブサイズ8)
> AILZ80ASM sample.z80 -bin -cmt -lst -lm simple -ts 8
■ sample.z80をアセンブル、出力はBIN形式、ファイル名は、output.bin
> AILZ80ASM sample.z80 -bin output.bin
> AILZ80ASM -i sample.z80 -o output.bin -om bin
■ sample.z80をアセンブル、出力はBIN形式、指定(W0001,W9001,W9002)のワーニング表示をOFFにする
> AILZ80ASM sample.z80 -bin output.bin -dw W0001 W9001 W9002
■ sample.z80をアセンブル、ラベルを指定する
> AILZ80ASM sample.z80 -bin -dl TEST1=10 TEST2=20 TEST3
■ -omオプションのヘルプを表示
> AILZ80ASM -h -om
コマンドラインからラベルを指定することができます。代入式で指定すると値を設定できます。ラベル単体で記述した場合は#TRUEが設定されます。ネームスペースを指定して出力するには「.」で区切って指定します。
> AILZ80ASM sample.z80 -bin -equ -dl TEST1=10 TEST2=20 TEST3 NSTEST.TEST4=40
file: sample.equ
[NAME_SPACE_DEFAULT]
TEST1 equ 10
TEST2 equ 20
TEST3 equ #TRUE
[NSTEST]
TEST4 equ 40
EXEと同じフォルダに以下の形式で「AILZ80ASM.json」を保存
{
"default-options": [
"-err"
],
"disable-warnings": [
"W0001",
"W9001",
"W9002"
]
}
特定のエラーがアセンブル時に発生した場合、再アセンブルを行ってエラーを解決するためのモードです。このモードを適用する前に、アセンブル解析の結果を確認し、再アセンブルによってエラーが解決できる可能性がある場合に限り、このモードが実行されます。このモードは、以下のエラーに対して有効です。
※ スーパーアセンブルモードを無効にする場合には、コマンドラインオプションに '-nsa' を付けてください
CMT形式の読み込みアドレスに利用されるエントリーポイントは、以下の優先順位で利用されます。
ラベルは、ネームスペース、標準ラベル、ローカルラベルで指定します。ネームスペースを指定しない場合には、 'NAME_SPACE_DEFAULT' が割り当てられています。必要に応じて変更をしてください。ラベルは指定した行以降は、下位のラベルを利用するときには上位のラベル名を省略することが出来ます。テンポラリーラベルは、.@に数字で宣言します。匿名ラベルは、.@@で宣言します。
テンポラリーラベルは、.@に数字をつけて宣言します。テンポラリーラベルの制約として、ラベル名が一意である必要があります。例えば、ローカルラベル内では.@1 を一度しか宣言できません。匿名ラベルの場合は、ローカルラベル内に、.@@を複数記述することが出来ます。
NAME_SPACE_DEFAULT
[NAME_SPACE_DEFAULT] ; ネームスペース指定
LABLE: ; ラベル指定
LABLE: ; ラベル指定
.A ; ローカルラベル
.B ; ローカルラベル
LABLE: ; ラベル指定
.A ; ローカルラベル
.@1 ; テンポラリーラベル
.B ; ローカルラベル
.@1 ; テンポラリーラベル
LABLE: ; ラベル指定
.A ; ローカルラベル
.@@ ; 匿名ラベル
.@@ ; 匿名ラベル
.B ; ローカルラベル
.@@ ; 匿名ラベル
.@@ ; 匿名ラベル
ローカルラベルが存在する場合
org $8000
ld a, 0
addr:
ld a, (addr)
ld hl, addr
.test
ld a, (addr.test)
ld hl, addr.test
ld hl, (addr.test)
org $8000
ld a, 0
addr:
ld a, (addr)
.@1 ; (1) addr..@1
ld hl, addr
.test
ld a,(.@1) ; 参照先 (2) 【注意:(1)は参照されない】
.@1 ; (2) addr.text.@1
ld hl, addr.test
.@2 ; (3) addr.text.@2
ld hl, (addr.test)
; 参照
ld hl, (addr..@1) ; 参照先 (1)
ld hl, (.text.@1) ; 参照先 (2)
ld hl, (.@1) ; 参照先 (2)
ld hl, (.@2) ; 参照先 (3)
; 特殊アクセス
EQT:
.@1 equ %00001100 ; (4) EQT..@1
.@2 equ %00001101 ; (5) EQT..@2
.@3 equ %00001110 ; (6) EQT..@3
;【マジック実装】本来ならEQT.AL.@1 を参照するが、存在しないとき EQT..@1を参照する
.AL equ (.@1 | .@2 | .@3) ; 参照先 (4) | (5) | (6)
DB "テスト" ; SJISで変換、アセンブラのデフォルト値
DB @JIS12:"テスト" ; JIS第一・二水準で変換
DB @SJIS:"テスト" ; SJISで変換
エスケープ シーケンス | 表現 | Unicode エンコーディング |
---|---|---|
\' | 単一引用符「'」 | 0x0027 |
\" | 単一引用符「"」 | 0x0022 |
\\ | 円記号「\」 | 0x005C |
\0 | Null | 0x0000 |
\a | ベル (警告) | 0x0007 |
\b | バックスペース | 0x0008 |
\f | フォーム フィード | 0x000C |
\n | 改行 | 0x000A |
\r | キャリッジ リターン | 0x000D |
\t | 水平タブ | 0x0009 |
\v | 垂直タブ | 0x000B |
名前 | デフォルト | 詳細 |
---|---|---|
@SJIS | * | シフトJIS |
@JIS1 | JIS第1水準 | |
@JIS12 | JIS第1水準・第2水準 |
詳細は、ORG命令の章をご覧ください
値を指定するところに、式を使用することができます。使用できる演算子と優先順位は、下の表のとおりです。 | 優先順位 | 演算子 | コメント |
---|---|---|---|
1 | ( ) | 括弧 | |
2 | low high exists text backward forward near far | 下位8ビット 上位8ビット ラベル存在 ラベル値文字列 後方ラベル 前方ラベル 近いラベル 遠いラベル | |
3 | + - ! ~ | 正記号 負記号 論理NOT ビット反転 | |
4 | * / % | 乗算 除算 剰余 | |
5 | + - | 加算 減算 | |
6 | << >> | 左シフト 右シフト | |
7 | < > <= >= | 算術比較 | |
8 | == != | 算術比較 | |
9 | & | ビットAND | |
10 | ^ | ビットXOR | |
11 | | | ビットOR | |
12 | && | 論理AND | |
13 | || | 論理OR | |
14 | : | 三項演算子 | |
15 | ? | 三項演算子 |
※大文字と小文字は区別しません
下位8ビットを取得します
ld a, low $1234 ; a = $34
上位8ビットを取得します
ld a, high $1234 ; a = $12
ラベルが存在する時には、 #TRUEを返します。ラベルが存在しない時には、#FALSE を返します。
LB1 equ $10
#IF exists LB1
;展開されます
#ENDIF
#IF exists LB2
;展開されません
#ENDIF
ラベルに設定された文字列を取得します。
LDEX a, 1
LDEX b, 1
LDEX MACRO arg1, arg2
#IF text arg1 == "a"
ld a, arg2
#ELSE
ld b, arg2
#ENDIF
ENDM
後方(アドレスが小さい方)のラベルを指定します。
LB:
.Sub1
.@1 ; ここが参照されています
.Sub2
JP backward .@1
.Sub3
.@1
前方(アドレスが大きい方)のラベルを指定します。
LB:
.Sub1
.@1
.Sub2
JP forward .@1
.Sub3
.@1 ; ここが参照されています
プログラムアドレスが近いラベルを参照します。距離が同じ場合には後方(アドレスが小さい方)のラベルが優先されます。
LB:
.Sub1
.@1 ; ここが参照されています
.Sub2
JP near .@1
.Sub3
LD HL, 0
LD DE, HL
.@1
プログラムアドレスが遠いラベルを参照します。距離が同じ場合には後方(アドレスが小さい方)のラベルが優先されます。
LB:
.Sub1
.@1
.Sub2
JP far .@1
.Sub3
LD HL, 0
LD DE, HL
.@1 ; ここが参照されています
式に()を利用することが出来ますが、命令には()が含まれるものがあります。式の全体を()で囲むとアドレス指定になります。
ld a,($1234 + 5) ;アドレス指定
ld a,($1234) + 5 ;値として指定されます。16bit値が指定されているので、ワーニングが表示されます。
本アセンブラの特徴として、アセンブル時のアドレスとアウトプット時のアドレスを別で管理しています。通常モードで利用する場合には、第一引数だけで利用してください。アウトプットアドレスは自動的に制御されます。第二引数を利用した時には、アウトプットアドレスを制御できます。その時にはROM出力モードになり、ラベルに使われるアドレスと出力のアドレスを別々に制御することが出来ます。プログラム・ロケーションカウンターは、アセンブル内で重複可能になります。アウトプット時のアドレスは、アウトプット・ロケーションカウンターと呼び、バイナリデータの出力位置を指定します。出力用のアドレスになりますので、重複することは出来ません。
ORG $1000
LB1000:
LD A, (LB1000)
ORG $1010
LB1010:
LD A, (LB1010)
ORG $2000, $0020
LB2000:
LD A, (LB2000)
出力結果
0000 3A 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00
0010 3A 10 10 00 00 00 00 00 00 00 00 00 00 00 00 00
0020 3A 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00
PORT_A equ $CC
.WRITE equ $01
.READ equ $02
LD A, PORT_A.WRITE
OUT (PORT_A), A
LD A, PORT_A.READ
OUT (PORT_A), A
アセンブラ内で利用する、文字列の変換テーブルをロードします。
ファイル名の内容を読み取り、その場所に展開します
include "Test.inc" ; テキストファイルとして展開されます
include "Test.inc", B ; バイナリーファイルとして展開されます
include "Test.inc", B, $1000 ; バイナリーファイルとして展開されます。読み込み位置は、$1000からになります。
include "Test.inc", B, $1000, 200 ; バイナリーファイルとして展開されます。読み込み位置は、$1000からになります。読み込み長さは200バイトです。
include "Test.inc", B, , 200 ; バイナリーファイルとして展開されます。読み込み位置は、$0000からになります。読み込み長さは200バイトです。
ARG1 equ 2
.Three equ 3
ALLLD
TestArg ARG1, ARG1.Three
INITLD B ; レジスター名を指定
ALLLD MACRO
ld a,1
ld b,2
ld c,3
ld d,4
ld e,5
ld h,6
ld l,7
ENDM
TestArg MACRO a1, a2
ld a, a1
ld b, a2
ENDM
INITLD MACRO REG
LD A, REG
LD REG, 0
ENDM
REPT 3
xor a
ENDM
REPT 8 LAST -1
ld (hl), a
set 5, h
ld (hl), a
add hl, de
ENDM
※ LAST -1で消える行にラベルが設定されている場合にはエラーになります。2行に分ける等の工夫をしてください。
REPT 8 LAST -1
ld (hl), a
set 5, h
or a
jr z, .@1
add hl, de
.@1 add hl, de
ENDM
Color ENUM
RED = 5 ; 5
GREEN ; 6
BLUE :2 ; 7, サイズ2バイト
YELLOW ; 9
ORANGE :2 = 12 ; 12, サイズ2バイト
CYAN ; 14
PURPLE = RED-1 ; 4
ENDM
INIT:
LD A, Color.RED ; 5
LD B, Color.GREEN ; 6
LD C, Color.BLUE ; 7
LD D, Color.YELLOW ; 9
LD E, Color.ORANGE ; 12
LD H, Color.CYAN ; 14
LD L, Color.PURPLE ; 4
式をまとめる事が出来ます
LD A, ABS(-1) ; LD A, 1
LD B, ABS(1) ; LD B, 1
Function ABS(value) => value < 0 ? value * -1 : value
アセンブルの実行を中断します。これ以降のソースコードはアセンブルされません。アセンブル結果は出力されます。
CHECKからENDCで囲まれた範囲のアセンブル結果がアライメント境界を超えるとアセンブルエラー(E6002)になります。
式2に設定した値は、アライメント境界のオフセット値になります。2バイトデータの先頭だけアライメント境界内に入っている事を保証したいときに、2と設定します。
org 0x100
CHECK ALIGN 256
DB 0, 1, 2, 3 ,4
ENDC
org 0x1FF
CHECK ALIGN 256 ; **** E6002 ****
DB 0, 1, 2, 3 ,4
ENDC
条件付きアセンブルを制御します
#if mode == 1
ld a,1
#print "mode == 1の処理がされました"
#elif mode == 2
ld d,4
#else
#error "modeの値が範囲外です。"
#endif
アセンブルの情報をインフォメーション[I0001]として表示します。
TEST1 EQU 1
TEST2 EQU 2
#PRINT "TEST1:{0}, TEST2:{1}", TEST1, TEST2
ソースコードをアセンブルするときに、記述があるファイルを1回だけアセンブルすることを指定します
#pragma once
LABEL equ 00FFH
ラベルの再定義エラーを回避する方法 (#pragma onceの利用を推奨)
#if LABEL.@EXISTS
LABEL equ 00FFH
#endif
#if exists LABEL
LABEL equ 00FFH
#endif
LST形式のファイルの出力を停止します。
on equ #TRUE
off equ #FALSE
ld a, 0
#LIST off
ld b, 1
#LIST on
ld c, 2
ret