追加調査と @AILight さんによる AILZ80ASM の継続的なアップデートのおかげで、ついに Newシティヒーロー(以下NCH)が、フルアセンブルできるようになりました。何をどう変更したのか、最後に履歴を残しておきます。
NCHが動いた

  • プリプロセッサ
tools80 では、そのまま IF ELSE ENDIF と記述してもアセンブルは通るのですが、AILZ80ASM では #IF #ELSE #ENDIF と接頭語として # が必要でした。別のエラーと重なり、このエラーに気がつくのが少し遅れました。


  • includeの適用範囲
tools80 では include した直下のみに、読み込んだファイルの影響を受けます。それに対して、AILZ80ASM は include すると、そのアセンブル対象の全域にその影響が及びます。例えば、ラベル定義のファイルをファイルの末尾に追加すると、tools80 では読み込んだ意味がほぼ無いのに対して、AILZ80ASM では先頭で include したのと同じ影響になります。

感覚的には AILZ80ASM の include は global include という動作になります。これはこれで有り難いのですが、equ で読み込んだ定数定義と、プログラム本体側で定義したラベルが衝突してしまい、アセンブルが出来なくなっていました。そのため、プログラム本体側のラベルをリネームする事で、暫定的に対応しました。

個人的には tools80 の記載した場所の上は影響を受けない方が、ラベル定義の影響範囲を調整できるので好きですが、まあこの辺りは趣味というか好みの問題ですね。また、AILZ80ASM は動作的に pass 4 処理なので、include を全域にせざるを得なかった事情もあるように思います。分けられるなら C# の using と同様に、include と grobal include を分けてもらえると嬉しいかなー


  • org間のGAP値の違い
NCHでは拡張RAM側でのアトリビュート値テーブルの参照で inc l と 8bit演算で操作して高速化できるように、以下のような記述をしていました。

org $8000 - 4 EXTFadeTable: ; 256境界を保証させるデータ db ATRB.BLACK, ATRB.BLUE, ATRB.CYAN, ATRB.WHITE

この EXTFadeTable のデータは $7FFC ~ $7FFF に確実に配置したかったので、ソースの最後にこのような org の指定をしていました。この結果、最後のデータとは 15バイトほどの隙間が出来たのです。この隙間に tools80 では $FF を、AILZ80ASM では $00 という値を書き込んでいたのです。

比較すると…
tools80のダンプ
AILZ80ASMのダンプ
見ての通り殆ど同じですよね…。

このバイナリ部分は、そのままテープに保存するとロード時間が長くなるため、圧縮してテープに記録してメインメモリにロード後、拡張RAMに転送するという手段を採っていました。圧縮で凡そ 80% 程度に縮まります。それほど強烈に縮むわけでは無いですが、それでも 1.7KBほどは小さく出来るので、ロード時間を 26秒も短縮する事が出来るのです。
※ 拡張メモリ無し専用にすれば、このバイナリ部分のロードは不要なので、2分半ほどロード時間を短縮できます。

ところがこの圧縮で、先の隙間が $FF か $00 で1バイトの差が出てしまったのです。この1バイトの差で読み込みが出来なくなり、拡張メモリが有効な環境では落ちてしまっていました。$FF のほうが圧縮できるとか繊細すぎますよね…

@AILight さんに調査結果をご報告したところ、隙間埋めのデフォルトを $FF にして、-gap オプションにて埋めるコードを変更可能にするとの事です。殆どの場合は指定不要なオプションですが、アセンブラの挙動を自分の好みに変えるという意味では有り難いですよね。
Unityの寺子屋 定番スマホゲーム開発入門

【広告】
大槻 有一郎
エムディエヌコーポレーション(MdN)
2017-08-16
※ IT和尚こと@Kumanbowさんの著書です。実際のゲーム作家なので内容は実践的ですね。ちょっと和尚クサイですがwww

  • ほんのちょっとだけサイズ縮小
上記、ファイルサイズ問題対応のため、改めてプログラムコードを見直したところ、なぜか簡単に数バイト縮められたので、対応して修正しました。

■ 修正前

; VTEXT をセミグラの黒色で初期化する ld d, ATRB.BLACK | ATRB.SEMIGRPH; ld hl, ADRS.VTEXT_END ld sp, hl ld hl, 0 ld e, CRTC.DIGITS ld c, CRTC.LINES .clear ld b, ATRB.MAX - 1 .loop1 push de djnz .loop1 ld e, 0 push de ld e, CRTC.DIGITS ld b, CRTC.DIGITS / 2 .loop2 push hl djnz .loop2 dec c jr nz, .clear
■ 修正後

; VTEXT をセミグラの黒色で初期化する ld d, ATRB.BLACK | ATRB.SEMIGRPH; ld sp, ADRS.VTEXT_END ld hl, 0 ld e, CRTC.DIGITS ld c, CRTC.LINES .clear ld b, ATRB.MAX - 1 .loop1 push de djnz .loop1 ld e, l push de ld e, CRTC.DIGITS ld b, CRTC.DIGITS / 2 .loop2 push hl djnz .loop2 dec c jr nz, .clear
どこが変わっているか分かりますよね?なんでこんな無駄な記述をしていたのか💦これで無事、またメモリに収まってロードできるようになりました。あのローダー、ロゴアニメも連動しているので、サイズが大きくなるといろいろと困るのです…。


  • ラベル定義ファイル出力
tools80 でのアセンブルでは、シンボル定義ファイルを取り出す方法が無かったので、アセンブル後に生成されていた .log.asz ファイルから、自作プログラムにてラベル定義部分だけを Symbol.inc として切り出していました。それが MakeSymbol というツールです。何かのお役に立つかもなので、ソースコード付きで公開しておきます。tools80 のアセンブルリストファイル専用です。

MakeSymbol.zip
2022/05/15 16:00

プログラム公開するまでも無いぐらい簡単なツールです。####  SYMBOL TABLE  #### という文字列が現れるまで読み込みをスキップして、それ以降の行だけを別ファイルに出力し直すという、数十行のプログラムです。エラー処理すらありませんが、まあ参考になれば💦

そして、AILZ80ASM では -equ オプションを付与すると、.equ というファイルが生成されて、そこに EQU でラベル定義されたファイルが出力されます、このツールは不要というわけですね。


  • NCHをアセンブルするバッチファイル
AILZ80ASM でアセンブルするバッチは最終的には以下のようになりました。
※ 環境変数設定部分は簡略化しています。

■ メイン

@echo off SET DEVPATH="\Develop" SET SRCPATH="\Src" SET ASM="AILZ80ASM.exe" cd %SRCPATH% if exist *.err del *.err if exist *.lst del *.lst if exist *.sym del *.sym if exist *.equ del *.equ if exist GameMain.bin del GameMain.bin echo --------------------------------------- echo メインプログラムのアセンブル %ASM% %SRCPATH%\GameMain.z80 -lst -bin -equ if %ERRORLEVEL% neq 0 ( start %EDIT% GameMain.err cd %SRCPATH% exit /b 1 ) cd %SRCPATH% move GameMain.equ loader\Symbol.inc %DEVPATH%\bin2cmt\bin2cmt\bin\Release\bin2cmt.exe %SRCPATH%\GameMain.bin -L$8000 -S%SRCPATH%\__serial.txt copy GameMain.cmt %DEVPATH%\j80\_rec move GameMain.cmt %DEVPATH%\j80mk2\_rec call %SRCPATH%\loader\_Loader_Assemble.bat cd %SRCPATH%

■ ローダー

@echo off SET DEVPATH="\Develop" SET SRCPATH="\Src\loader" SET ARCHIVE="exomizer.exe" SET ASM="AILZ80ASM.exe" cd %SRCPATH% if exist *.err del *.err if exist *.lst del *.lst if exist *.sym del *.sym if exist Expand.bin del Expand.bin echo --------------------------------------- echo 拡張RAMプログラムのアセンブル %ASM% %SRCPATH%\Expand.z80 -bin -lst if %errorlevel% neq 0 ( start %EDIT% Expand.err cd %SRCPATH% exit /b 1 ) cd %SRCPATH% copy Expand.bin Expand_org.bin %ARCHIVE% raw -P7 -oExpand.bin Expand_org.bin echo --------------------------------------- echo ローダープログラムのアセンブル call %ASM% %SRCPATH%\Loader.z80 -cmt -lst copy %SRCPATH%\Loader.cmt %DEVPATH%\j80\_rec move %SRCPATH%\Loader.cmt %DEVPATH%\j80mk2\_rec rem ---------------------------------------- rem 結合 call %DEVPATH%\j80\_rec\_connect.bat call %DEVPATH%\j80mk2\_rec\_connect.bat cd %SRCPATH%
これで Z80としては大規模プロジェクトにあたる NCH でも実用的なバイナリ出力が出来ました。作者の @AILight さんによると、私の放置プログラム夢の島 Finalでもアセンブルできたそうなので、これでいよいよ AILZ80ASM も v1.0 リリースが近いなったと思います!
UnityではじめるC# 基礎編 改訂版

【広告】
リブロワークス
エムディエヌコーポレーション(MdN)
2020-12-01
※これも所謂「和尚本」の類いです。ある程度プログラミングの基礎があった方が読みやすいと思います。