Z80でアセンブラ短歌

CP/M-80でアセンブラ短歌を詠むために,アセンブラ環境を構築する方法を説明します.

なおここではFreeBSDでの例を主に説明します.UbuntuやCentOSなどの GNU/Linuxディストリビューションでも,同様の手順でできるかと思います. apt-getなどでインストールできるツールを探してそれを利用するのが楽で いいでしょう.

目次

Z80アセンブラ

■ 各種のアセンブラ

まずはZ80向けのコードを出力できるアセンブラが必要です.

クロス開発環境で代表的なものはGNUのbinutilsですが, FreeBSDのportsでは以下のようなものが利用できます.

binutilsは高機能でなんといっても強力なのですが,binutilsだと例えばZ80向けと 他マイコン向けは別にビルドしなければならないため面倒です.またbinutilsは6502 がサポートされてないようで,6502用には別にアセンブラが必要になってしまいます.

ということで,マイコン向けの軽いアセンブラで旧来のマイコン系を幅広くサポート しているようなものを使うのが楽でいいかと思います.

複数アーキに対応しているということを考えると,asl/tpasm/asmx あたりが候補 かなあと思います.試してみたところ,aslが対応CPUが多くオプションも豊富で マニュアルも充実していて(もちろん英語ですが),さらにobjcopyに頼らずに バイナリを生成できるのでいいかなあと思います.

tpasm/asmxは出力フォーマットがsrecなので,バイナリに変換するツールが別途必要に なります(単独でできるのかもしれませんが方法が見あたりませんでした). ただobjcopyで変換可能なため,あまり問題にはならないかなあとも思います (Z80向けのクロスのobjcopyでなく,システムに標準でインストールされている (つまりx86向けの)objcopyで変換可能でした). また単にsrec→binary変換ができればいいだけなので, 他の変換ツールがあればそれでもOKです.

以下では一応,ひととおり使いかたを説明します.

■ サンプルコード

アセンブルのサンプルに,以下のコードを利用します. CP/Mのシステムコールを使って「123」と出力するもので, cpmemuで実行できます.

内部ではあえてジャンプ命令を利用しています.これは絶対アドレスを埋め込む ことで,アドレスが0x100にきちんと配置されているかどうかを見るためです.

上記リストは先頭に以下の行がありますが,アセンブラによっては行頭のTABを 見ていて,TABが無いとエラーになるものがあるので注意が必要です. またORGの有無で動作が変わったり,ORGが無いとエラーになったりする場合も あるので注意が必要.

        ORG     100h

■ binutils

以下の手順でインストールできます.binutils-2.23.1で確認しました.

~>% tar xvzf binutils-2.23.1.tar.gz
~>% cd binutils-2.23.1
~/binutils-2.23.1>% ./configure --prefix=/usr/local/z80 --target=z80-coff --disable-nls --disable-werror
~/binutils-2.23.1>% gmake
~/binutils-2.23.1>% su
# gmake install
ターゲットはいろいろ試してみたのですが,z80-coff でないとビルドエラーに なってしまうようです.

z80.asmは先頭の以下を削らないと,生成されるバイナリの頭に余分なデータが 追加されてしまうので,以下を削除してアセンブルします.

        ORG     100h

以下でヘルプを出力します.

% /usr/local/z80/bin/z80-coff-as -help
以下でアセンブルして実行ファイルを作成し,cpmemuで実行が確認できました.
% /usr/local/z80/bin/z80-coff-as z80.asm -o z80.coff
% /usr/local/z80/bin/z80-coff-ld z80.coff -o z80.com
ちなみに以下でもバイナリ生成できますが,これだとアドレスが0x100に ならないようです.
% /usr/local/z80/bin/z80-coff-as z80.asm -o z80.coff
% /usr/local/z80/bin/z80-coff-objcopy -O binary z80.coff z80.bin
アドレスはデフォルトで0x100になるようですが,必要ならば以下で調整できます.
% /usr/local/z80/bin/z80-coff-ld z80.coff -o z80.com -Ttext 0x100
必要あれば,以下でCPUを明示できます.
% /usr/local/z80/bin/z80-coff-as z80.asm -o z80.coff -z80

■ asl

FreeBSDではports/packagesでインストールできる.

ドキュメントは以下.

% man asl
% ls /usr/local/share/doc/asl
以下でアセンブルして実行ファイルを作成し,cpmemuで実行が確認できました.
% asl -cpu z80 z80.asm -o z80.p
% p2bin -r \$-\$ z80.p z80.com
アセンブルするときに-Lオプションをつけることで,ニーモニックと機械語コードの 対応を出力することができます.

■ tpasm

ドキュメントは以下.

% tpasm -h
% ls /usr/local/share/doc/tpasm
以下にアセンブラのサンプルあり.
% ls /usr/local/share/examples/tpasm
以下でアセンブルして実行ファイルを作成し,cpmemuで実行が確認できました.
% tpasm -P z80 z80.asm -o srec z80.srec
% objcopy -I srec -O binary z80.srec z80.com
objcopyは本来ならZ80向けにビルドしたもの(z80-coff-objcopy)を使うべきですが, 通常のobjcopyでも問題ないようでした.

アセンブル時に -l z80.lst を付加することで,アセンブラ・リストを出力する ことができます.

対応アーキテクチャ名と対応出力フォーマット名は,以下で出力できます.

% tpasm --show_procs
% tpasm --show_types

■ asmx

ドキュメントは以下.

% asmx-z80
% ls /usr/local/share/doc/asmx
以下でアセンブルして実行ファイルを作成し,cpmemuで実行が確認できました.
% asmx-z80 -o z80.srec z80.asm
% objcopy -I srec -O binary z80.srec z80.com
objcopyはtpasmと同様,通常のobjcopyでも問題ないようでした.

アセンブル時に -l z80.lst を付加することで,アセンブラ・リストを出力する ことができます.(出力ファイル名の指定の前にオプション指定すること)

■ z80-asm

ドキュメントは以下.

% man z80-asm
% ls /usr/local/share/doc/z80-asm
以下でアセンブルできるが出力ファイル形式が不明.よくわからない.
% z80-asm z80.asm z80.bin

■ z80asm

ドキュメントは以下.

% z80asm -h
% man z80asm
以下にアセンブラのサンプルあり.
% ls /usr/local/share/examples/z80asm
以下でアセンブルして実行ファイルを作成し,cpmemuで実行が確認できました.
% z80asm z80.asm -o z80.com

逆アセンブル

■ coff形式の逆アセンブル

パッと見たところ,asl/tpasm/asmxには逆アセンブラの機能は無さそうです. なのでbinutilsのビルドで作成された,Z80向けobjdumpを利用するのが楽です.

まず,binutilsを利用してアセンブルしている場合は,以下のようにして逆アセンブル できます.

% /usr/local/z80/bin/z80-coff-as z80.asm -o z80.coff
% /usr/local/z80/bin/z80-coff-objdump -d z80.coff
なおobjcopy/objdumpは,以下で対応フォーマットを出力できます.
% /usr/local/z80/bin/z80-coff-objcopy -i
% /usr/local/z80/bin/z80-coff-objdump -i

■ srec形式の逆アセンブル

srecは以下で逆アセンブルできました.

% /usr/local/z80/bin/z80-coff-objdump -m z80-any -D z80.srec
ついでに,srecファイルについては以下で逆アセンブルできそうな気がするが, 実際にやってみるとダメでした.
% /usr/local/z80/bin/z80-coff-objcopy -I srec -O coff-z80 z80.srec z80.coff
% /usr/local/z80/bin/z80-coff-objdump -d z80.coff

CP/Mシミュレータ

■ cpmemu

FreeBSDのportsでは,cpmemuというエミュレータが使えます. CP/Mエミュレータは他には見あたりませんでした.

ソースコードをパッと見たところ,システムコール・エミュレーションをしていて, ライセンスグレーなROMバイナリなどを使っていることはなさそうです. ライセンスはクリーンと考えてよさそうです.

試してみたところ,以下のファイルを実行することができるみたいです.

まずは実行ファイルを上記のようなフォーマットで作成します. これは上で説明した「z80.com」が相当します.

で,z80.com が存在するディレクトリで以下を実行し,cpmemuを起動します.

% ls
z80.asm z80.com
% cpmemu

A0>
dirコマンドを実行すると,cpmemuを起動したカレントディレクトリの内容を 出力できます.(ホスト側のファイルシステム上のファイルを認識しています)
A0>dir
A: Z80     .COM : Z80     .ASM
A0>
*.comファイルは,実行することができます.
A0>Z80
123
A0>
Ctrl-@ → q で終了します.
メールは kozos(アットマーク)kozos.jp まで