私が以前制作した Newシティヒーローは、tools80 というアセンブラを前提にソースが作成されています。今回、このソースを AILZ80ASM でアセンブルが通るように改変してみました。一つ一つ違いについて解説していきます。
- ラベルの解釈 - 大文字と小文字
tools80 ではラベルは記述されたまま登録されます。そのため…
STR: .hiScr db "HiSCORE:" ; ハイスコア文字表示 .hiscr db "0010" ; ハイスコア値表示文字列
このような S が大文字と小文字で違うだけでも、別の単語として扱われてアセンブルが通ります。AILZ80ASM では、ラベルを C コンパイラなどと同じような解釈を行いますので、この二つのラベルは同一と見なされてエラーとなります。
当時は気にしていませんでしたが、今改めて見直すと大変気持ち悪いです。そのため、エラーが相当と思いますが、もしものために大文字小文字の同一視をしないというオプションを用意してはと、作者の @AILight さんに提案はしてあります。
※ 採用されるかどうかは分かりませんが、実装コンセプトからは不採用かなと思っています。
※ 採用されるかどうかは分かりませんが、実装コンセプトからは不採用かなと思っています。
ということで、この気持ち悪いラベル部分は名称変更で対応しました💦
BIOS .NBASIC_VER equ $1850 ; N-BASIC Version番号 .FUNC_COLOR equ $08F7 ; Function Key On/Offとカラーモノクロ指定
ところがこれは AILZ80ASM ではエラー扱いです。一見、何が悪いのか分からなかったかと思いますが、よーく見ると BIOS というラベルに :(コロン)が付いていないのです。AILZ80ASM でも、後ろに DB や EQU といった命令が続く際はコロン無しを許容しています(この仕様は私がリクエストしたものです)。ところがラベルだけの場合はコロンが必須になるのです。
個人的には、このラベルだけの行ではコロンは必須という仕様が好ましいと考えます。だって、そうしないと、もしかしたらゴミ文字列が、そのままラベルとして登録され続けてしまうかもしれないのですから。
ということで、このコロン無しラベルにはコロンを付与して対応しています。
- ローカルラベルの解釈 - コロンの有る無し
tools80 ではこの記述で通ります。
.offsetTable: dw 0 * CRTC.LINE_SIZE, 1 * CRTC.LINE_SIZE, 2 * CRTC.LINE_SIZE
dw 3 * CRTC.LINE_SIZE, 4 * CRTC.LINE_SIZE, 5 * CRTC.LINE_SIZE
ところが、AILZ80ASM では、この記述は許容されません。理由は親となるラベルにはコロンが必要ですがローカルラベルは親にはならないと明確に区別しているためです。そのため、ピリオドから始まるローカルラベルにコロンを付与するとエラー扱いというわけです。
この場合の対応は、単にコロンを削除するだけですね。
- バイナリファイルの読み込み
GameMapArchiveF: ; マップデータ 1-6 binclude "mapdataF.bin" GameMapArchiveB: ; マップデータ 7-10 binclude "mapdataB.bin"
一方、AILZ80ASM では、include はそのままで、後方にバイナリである事を示す ,B オプションを付与します。
GameMapArchiveF: ; マップデータ 1-6 include "mapdataF.bin", b GameMapArchiveB: ; マップデータ 7-10 include "mapdataB.bin", b
単純にアセンブラ仕様の違いなので、ポンッと書き換えて対応完了です。外部ファイル読み込みという同一機能なので INCLUDE そのままという考え方は、私は好きですねー
※ PC88の全てのゲームが網羅されているらしい。本当か!?- 予約語でのマクロ引数
tools80 では、マクロの引数の名前には予約語とか関係無しに好きな文字を使用する事が出来ました。
INKEY MACRO port, bit in a, (port) and bit ENDM
ここですが、bit という単語は、AILZ80ASM 内部の予約語となっていて、マクロが解釈できずにエラーとなります。記事作成時点の最新である v0.0.9.15 ではエラー表示にて予約語である旨が追加され、エラー原因が分かりやすくなりました。直し方は当然 bit を別の言葉に置き換えます。
INKEY MACRO pt, bt in a, (pt) and bt ENDM
今回はマクロ引数は2文字と制限してみました。こちらのほうがなんとなく見やすいですね😁
- マクロでの IF 判定
以下は、16bitデータをHLアドレスから取り出す際のマクロです。
LDHL MACRO adr IF "hl"!="adr" ld hl, adr ENDIF ld a, (hl) inc hl ld h, (hl) ld l, a ENDM
引数が HL だった場合は、HL に値を入れる必要が無いので、その展開をスキップする判定をしています。tools80 だとこんな感じなのですが、AILZ80ASM だと adr の判定は、引数が文字列である事を明記する必要がありました。そのため .@TEXT と指定してやる必要があります。AILZ80ASM だと下記のようになります。
LDHL MACRO adr #IF adr.@TEXT != "hl" ld hl, adr #ENDIF ld a, (hl) inc hl ld h, (hl) ld l, a ENDM
マクロ引数 adr に対して、この指定が文字列である事を示す .@TEXT を付与する事で、正しく判定できるようになります。この仕様の違いはおそらくアセンブラ内部のデータの持ち方の違いであると思われます。ここは素直に .@TEXT を付与する事で解決します。
SoundDrvV2.z80:637 W0001: 1バイトの指定場所に、[ 0xFFFF : 65535 ]が設定されています。1バイトに丸められます。 Common.z80:257 W0001: 1バイトの指定場所に、[ 0xB8F2 : 47346 ]が設定されています。1バイトに丸められます。 Common.z80:368 W0001: 1バイトの指定場所に、[ 0xE51A : 58650 ]が設定されています。1バイトに丸められます。 Common.z80:372 W0001: 1バイトの指定場所に、[ 0x270D : 9997 ]が設定されています。1バイトに丸められます。 Common.z80:507 W0002: 2バイトの指定場所に、[ 0xFFFFCED0 : -12592 ]が設定されています。2バイトに丸められます。 GraphicsDrv.z80:310 W0002: 2バイトの指定場所に、[ 0xFFFFF400 : -3072 ]が設定されています。2バイトに丸められます。 GraphicsDrv.z80:351 W0002: 2バイトの指定場所に、[ 0xFFFFF400 : -3072 ]が設定されています。2バイトに丸められます。 Character.z80:87 W0002: 2バイトの指定場所に、[ 0xFFFFFF88 : -120 ]が設定されています。2バイトに丸められます。 Character.z80:145 W0002: 2バイトの指定場所に、[ 0xFFFFFF88 : -120 ]が設定されています。2バイトに丸められます。 Character.z80:523 W0002: 2バイトの指定場所に、[ 0xFFFFF400 : -3072 ]が設定されています。2バイトに丸められます。
こんな感じなのが数十行出ます。何事かとソースリストを確認すると…
SNDStartHighPrty: ld a, -1 ld (ADRS.SNDCTRL + SOF.PRIORITY), a jr SNDStart.start
そう、Acc に -1 を入れているだけなんですが、AILZ80ASM では 0xFFFF と解釈されてしまい、上位が捨てられたので警告としているのです。気持ちはわかるのですが、実際のプログラミングではここにいちいち 0xFF とか、-1 AND 0xFF とか書くのも馬鹿馬鹿しいので、私はまとめて警告を消してしまいました。そのまとめて警告を消す方法が、オプションファイルです。
AILZ80ASM.exe と全く同じフォルダに AILZ80ASM.json を配置します。そして、この json ファイルに対して、既定のオブションや警告抑止の指定を書いておく事で、その指定や警告抑止は必ず有効になります。私は以下のように指定しました。
{ "default-options": [ "-ts", "8" ], "disable-warnings": [ "W0001", "W0002" ] }
この指定の意味ですが、タブは必ず8文字として、値の丸め警告である W0001と W0002の表示を止めるという内容です。json のパースの関係で、カンマの有る無しで簡単に読み込めなくなりますので注意が必要です。
- tools80とAILZ80ASMの違い - まとめ
■ tools80
- Javaで動作するため動作環境が多い
- アセンブル速度が超高速(NCHが一瞬でバイナリ化されます)
- 大変強力なマクロ
■ AILZ80ASM
アセンブル速度ですが、NCH を tools80 はほぼ一瞬で、AILZ80ASM は数秒を要します。差で言えば10倍以上はありますが、だからといって AILZ80ASM が遅いというわけではありません。逆ですね、tools80 が凄まじく速いんです。ということで、何を優先するかで、採用するアセンブラが決まってくると思います。
- C# 実装で配布環境であれぱそのまま動く
- 様々な出力形式にオプションで対応
- 独自拡張されたマクロ機能が魅力
アセンブル速度ですが、NCH を tools80 はほぼ一瞬で、AILZ80ASM は数秒を要します。差で言えば10倍以上はありますが、だからといって AILZ80ASM が遅いというわけではありません。逆ですね、tools80 が凄まじく速いんです。ということで、何を優先するかで、採用するアセンブラが決まってくると思います。
以上が評価です。実はまだ -equ 指定時のファイル出力に問題があり、最終バイナリの出力は出来ていませんが、この問題もすぐに解消されるであろうと @AILight さんは仰っていました。もう v1.0 のリリースはおそらく近いですね。NCH が動作するようになったら、本当に近いと思います。皆さん、期待して待ちましょう!
※ 2022/05/13 09:00 追記
-equ 対応が完了したようです。早い!追記レポートを近いうちに公開します!
※ 気力と根性と涙の総決算なムック本ですね!※ 2022/05/13 09:00 追記
-equ 対応が完了したようです。早い!追記レポートを近いうちに公開します!
コメント