Home

Awesome

Z80 Assembler 'AILZ80ASM'

Build Status

AILZ80ASMは、C#で書かれた.NET 8の環境で動作するZ80アセンブラです。

読み方
免責事項
連絡方法

入手方法

※ 実行形式は、「自己完結型の実行可能ファイル」になっています。.NETの環境を用意する必要はありません。

サポートツール

パフォーマンス

使い方

AILZ80ASM [<オプション>] <オプション指定文字列:ファイル名等> [ <オプション指定文字列:ファイル名等>]

> AILZ80ASM sample.z80

コンソールアプリですので、コンソールより起動してください。

入力ファイル形式

コマンドラインオプション

コマンドライン説明
-i, --input <files>アセンブリ対象のファイルをスペース区切りで指定します。 (オプション名の省略が可能)
-ie, --input-encode <mode>入力ファイルのエンコードを選択します。 [auto, utf-8, shift_jis] デフォルト値:auto
-o, --output <file>出力ファイルを指定します。
-om, --output-mode <mode>出力ファイルのモードを選択します。 [bin, hex, t88, cmt, sym, equ, lst, err, tag] デフォルト値:bin
-oe, --output-encode <mode>出力ファイルのエンコードを選択します。 [auto, utf-8, shift_jis] デフォルト値:auto
-lm, --list-mode <mode>リストの出力形式を選択します。 [simple, middle, full] デフォルト値:full
-lob, --list-omit-binaryリストの出力でバイナリーインクルードを省略出力をします。
-ep, --entry-point <address>エントリーポイントを指定します。
-ts, --tab-size <size>TABのサイズを指定します。 デフォルト値:4
-dw, --disable-warning <codes>Warning、Informationをオフにするコードをスペース区切りで指定します。
-ul, --unused-label未使用ラベルを確認します。
-cd, --change-dir <directory>アセンブル実行時のカレントディレクトリを変更します。終了時に元に戻ります。
-gap, --gap-default <gapByte>アセンブラのギャップのデフォルト値を指定します。 デフォルト値:$FF
-df, --diff-fileアセンブル出力結果のDIFFを取ります。アセンブル結果は出力されません。
-dl, --define-label <labels>ラベルをスペース区切りで指定します。値を設定するときは=で代入します。
-nsa, --no-super-asmスーパーアセンブルモードを無効にします。
-sa, --start-address <address>スタートアドレス(出力)を指定します。ORGで指定したアドレスまで -gap で埋めます
-ips, --include-paths <paths>インクルードするファイルの検索パスを指定します。
-f, --force出力ファイルを上書きします。
-v, --versionバージョンを表示します。
-?, -h, --help <help>ヘルプを表示します。各オプションの詳細ヘルプを表示します。例: -h --input-mode
-??, --readmeReadme.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

■ sample.z80をアセンブル、ラベルを指定する
> AILZ80ASM sample.z80 -bin -ips .\lib1

■ -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形式の読み込みアドレスに利用されるエントリーポイントは、以下の優先順位で利用されます。

  1. コマンドラインオプション (-ep) で指定した値
  2. END で指定した値
  3. アセンブル結果が出力される最初のプログラムアドレス

新バージョン導入の手順

  1. 新バージョンを入手
  2. インストール済みのAILZ80ASMでアセンブルを行う
  3. インストール済みのAILZ80ASMを退避
  4. 新バージョンでAILZ80ASMを置き換える
  5. 新バージョンでコマンドラインオプションに「-df」を付け、差分確認アセンブルを行う
  6. アセンブル結果が一致しているかが表示される
  7. アセンブル結果が一致していたら置き換え可能、一致していなければ置き換え不可なので退避したプログラムを元に戻す

ソースコード書式

ニーモニック

未定義命令 (Undocumented Instructions)

ラベル

ラベルは、ネームスペース、標準ラベル、ローカルラベルで指定します。ネームスペースを指定しない場合には、 'NAME_SPACE_DEFAULT' が割り当てられています。必要に応じて変更をしてください。ラベルは指定した行以降は、下位のラベルを利用するときには上位のラベル名を省略することが出来ます。テンポラリーラベルは、.@に数字で宣言します。匿名ラベルは、.@@で宣言します。

ラベルに使用できる文字と出来ない文字列

大文字と小文字の区別

テンポラリーラベルと匿名ラベルについて

テンポラリーラベルは、.@に数字をつけて宣言します。テンポラリーラベルの制約として、ラベル名が一意である必要があります。例えば、ローカルラベル内では.@1 を一度しか宣言できません。匿名ラベルの場合は、ローカルラベル内に、.@@を複数記述することが出来ます。

ラベルの宣言

[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
\0Null0x0000
\aベル (警告)0x0007
\bバックスペース0x0008
\fフォーム フィード0x000C
\n改行0x000A
\rキャリッジ リターン0x000D
\t水平タブ0x0009
\v垂直タブ0x000B

内蔵CHARMAP一覧

名前デフォルト詳細
@SJIS*シフトJIS
@JIS1JIS第1水準
@JIS12JIS第1水準・第2水準

ロケーションカウンタ

詳細は、ORG命令の章をご覧ください

値を指定するところに、式を使用することができます。使用できる演算子と優先順位は、下の表のとおりです。

優先順位演算子コメント
1( )括弧
2low 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?三項演算子
※大文字と小文字は区別しません

low 演算子

下位8ビットを取得します

	ld a, low $1234 ; a = $34

high 演算子

上位8ビットを取得します

	ld a, high $1234 ; a = $12

exists 演算子

ラベルが存在する時には、 #TRUEを返します。ラベルが存在しない時には、#FALSE を返します。

LB1	equ $10

	#IF exists LB1
		;展開されます
	#ENDIF
	
	#IF exists LB2
		;展開されません
	#ENDIF

text 演算子

ラベルに設定された文字列を取得します。

	LDEX a, 1
	LDEX b, 1

LDEX MACRO arg1, arg2
	#IF text arg1 == "a"
		ld a, arg2
	#ELSE
		ld b, arg2
	#ENDIF

	ENDM

backward 演算子

後方(アドレスが小さい方)のラベルを指定します。

LB:
.Sub1
.@1				; ここが参照されています
.Sub2
	JP backward .@1
.Sub3
.@1

forward 演算子

前方(アドレスが大きい方)のラベルを指定します。

LB:
.Sub1
.@1
.Sub2
	JP forward .@1
.Sub3
.@1				; ここが参照されています

near 演算子

プログラムアドレスが近いラベルを参照します。距離が同じ場合には後方(アドレスが小さい方)のラベルが優先されます。

LB:
.Sub1
.@1				; ここが参照されています
.Sub2
	JP near .@1
.Sub3
	LD HL, 0
	LD DE, HL
.@1

far 演算子

プログラムアドレスが遠いラベルを参照します。距離が同じ場合には後方(アドレスが小さい方)のラベルが優先されます。

LB:
.Sub1
.@1
.Sub2
	JP far .@1
.Sub3
	LD HL, 0
	LD DE, HL
.@1				; ここが参照されています

アドレス指定について

式に()を利用することが出来ますが、命令には()が含まれるものがあります。式の全体を()で囲むとアドレス指定になります。

	ld a,($1234 + 5)	;アドレス指定
	ld a,($1234) + 5	;値として指定されます。16bit値が指定されているので、ワーニングが表示されます。

コメント

アドレス・制御命令

ORG <式>, [<式2>], [<式3>]

本アセンブラの特徴として、アセンブル時のアドレスとアウトプット時のアドレスを別で管理しています。通常モードで利用する場合には、第一引数だけで利用してください。アウトプットアドレスは自動的に制御されます。第二引数を利用した時には、アウトプットアドレスを制御できます。その時には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

ALIGN <式>, [<式2>]

DS <式>, [<式2>]

制御命令

<ラベル> EQU <式>

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

CHARMAP <CHARMAP名>, <ファイル名>

アセンブラ内で利用する、文字列の変換テーブルをロードします。

INCLUDE <ファイル名>, [<ファイルタイプ>], [<開始位置>], [<長さ>]

ファイル名の内容を読み取り、その場所に展開します

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バイトです。

DB <式>, [<式>]

DB [<変数名>=<ループ開始値>..<ループ終了値>:<式>]

DW <式>, [<式>]

DW [<変数名>=<ループ開始値>..<ループ終了値>:<式>]

DBFIL <式>, [<式2>]

DWFIL <式>, [<式2>]

マクロ

<マクロ名> MACRO [<引数1>, <引数2>] ~ ENDM

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 <式1> [LAST <式2>] ~ 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

<名前> ENUM ~ <ラベル名> : <長さ> = <値> ~ 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

FUNCTION <名前>([<引数1>, <引数2>]) => <式>

式をまとめる事が出来ます

	LD A, ABS(-1)	; LD A, 1
	LD B, ABS(1)	; LD B, 1

Function ABS(value) => value < 0 ? value * -1 : value

END [<式1>]

アセンブルの実行を中断します。これ以降のソースコードはアセンブルされません。アセンブル結果は出力されます。

コード・チェック

CHECK ALIGN <式1>[, <式2>] ~ ENDC

CHECKからENDCで囲まれた範囲のアセンブル結果がアライメント境界を超えるとアセンブルエラー(E6002)になります。

	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
#PRINT <引数1> [<引数2>]

アセンブルの情報をインフォメーション[I0001]として表示します。

TEST1	EQU 1
TEST2	EQU 2

	#PRINT "TEST1:{0}, TEST2:{1}", TEST1, TEST2

PRAGMA (プラグマ)

PRAGMA ONCE

ソースコードをアセンブルするときに、記述があるファイルを1回だけアセンブルすることを指定します

#pragma once

LABEL	equ 00FFH

ラベルの再定義エラーを回避する方法 (#pragma onceの利用を推奨)

#if LABEL.@EXISTS
LABEL	equ 00FFH
#endif
#if exists LABEL
LABEL	equ 00FFH
#endif
#LIST <引数1>

LST形式のファイルの出力を停止します。

on  equ #TRUE
off equ #FALSE

    ld  a, 0

    #LIST off

    ld  b, 1

    #LIST on

    ld  c, 2
    
    ret

表記の揺れ対応

エラー

仕様の裏話

謝辞

Z80資料