2018/07/30(月) [n年前の日記]
#1 [pc][prog] Z80用のバイナリを生成できるCコンパイラ SDCCを試用
Z80用のバイナリも生成できるらしいCコンパイラ、SDCC を試用してみたり。以下を参考に作業。
_SDCC用の環境構築 - 電子ブロック工房
_Z80のC言語クロスコンパイル(SDCC)(1) - Resilient Mind
_SDCCでクロス開発環境をインストールと使い方(Z80用) - Tosikの雑記
_最適化オプション - msx-sdcc @ ウィキ - アットウィキ
_コンパイルオプション - msx-sdcc @ ウィキ - アットウィキ
環境は、Windows10 x64。動作確認には、MZ700WIN + NEW MONITOR を使った。
_MZ-700 Emulator MZ700WIN For Windows9x/Me/NT/2000
_MZ-700/80K/C/1200用互換モニタ MZ-NEW MONITOR
_SDCC用の環境構築 - 電子ブロック工房
_Z80のC言語クロスコンパイル(SDCC)(1) - Resilient Mind
_SDCCでクロス開発環境をインストールと使い方(Z80用) - Tosikの雑記
_最適化オプション - msx-sdcc @ ウィキ - アットウィキ
_コンパイルオプション - msx-sdcc @ ウィキ - アットウィキ
環境は、Windows10 x64。動作確認には、MZ700WIN + NEW MONITOR を使った。
_MZ-700 Emulator MZ700WIN For Windows9x/Me/NT/2000
_MZ-700/80K/C/1200用互換モニタ MZ-NEW MONITOR
◎ インストール。 :
公式サイト経由で、sdcc-3.6.0-x64-setup.exe をダウンロード。
_SDCC - Small Device C Compiler
実行すると、インストーラが起動する。任意のフォルダにインストール。最後に、環境変数PATHに追加するかと尋ねてきたけど、今回は自分で設定した。PATHに、インストール場所\bin を追加しておけばいい。
_SDCC - Small Device C Compiler
実行すると、インストーラが起動する。任意のフォルダにインストール。最後に、環境変数PATHに追加するかと尋ねてきたけど、今回は自分で設定した。PATHに、インストール場所\bin を追加しておけばいい。
◎ crt.asm を記述。 :
MZ-80系で動かすプログラムをコンパイル・リンクしたい場合、標準の crt とやらを使わないほうがいいらしい。以下を参考にして、crt.asm を作成。.asm はアセンブラで書かれたソースファイルなのだろう。たぶん。
_SDCC用の環境構築 - 電子ブロック工房
crt.asm
アセンブルして、crt.o を作成。
crt.o が作成できた。
_SDCC用の環境構築 - 電子ブロック工房
crt.asm
.globl _init .globl _main call _init jp _main「.global じゃなくて .globl」な点に注意。
アセンブルして、crt.o を作成。
sdasz80 -o crt.o crt.asm
crt.o が作成できた。
◎ サンプルソースを書いた。 :
MZ-700上で動作するサンプルを、C言語で書く。
main.c
main() がメイン処理で、init() はロード直後にのみ呼ばれる初期化処理。らしい。
以下によると、MZ-700の場合、
_Programming MZ-700: Display
_Programming MZ-700: Memory
main.c をコンパイル・リンクする。
main.ihx が作成された。中身は以下のような感じ。
_Intel HEX - Wikipedia
main.c
int main(void) { int c; for (c = 0; c <= 255; c++) { int y; unsigned char d = (unsigned char)c; for (y = 0; y < 25; y++) { int x = 20; unsigned char *p = (unsigned char*)(0x0d000 + y * 40 + x); unsigned char *q = (unsigned char*)(0x0d800 + y * 40 + x); while(x < 40) { *p++ = d; // display code *q++ = 0x50; // attrib x++; } d++; } } return 0; } int init(void) { return 0; }
main() がメイン処理で、init() はロード直後にのみ呼ばれる初期化処理。らしい。
以下によると、MZ-700の場合、
- 0xD000番地からディスプレイコードを書き込む領域
- 0xD800番地からアトリビュート情報を書き込む領域
_Programming MZ-700: Display
_Programming MZ-700: Memory
main.c をコンパイル・リンクする。
sdcc main.c -mz80 --code-loc 0x1200 --no-std-crt0 -Wlcrt.o
- Z80用のプログラムを作りたいので、-mz80 を指定。
- プログラムは、0x1200 から配置したいので、--code-loc 0x1200 を指定。
- 標準の crt0 とやらを無効にしたいので、--no-std-crt0 を指定。
- 独自の crt.o をリンクしたいので、-Wlcrt.o を指定。
main.ihx が作成された。中身は以下のような感じ。
:20120000CDB412C30612DDE5DD210000DD3921F8FF39F90100003333C5210000DD36FE00E2 :20122000DD36FF00DD7EFEC600DD77FCDD7EFFCED0DD77FDDD7EFEC600DD77FADD7EFFCE4F :20124000D8DD77FB111400E5DD6EFCDD66FDE5FDE1E1FD19DD7EF8FD7700E5DD6EFADD66E8 :20126000FBE5FDE1E1FD19FD360050137BD6287A173F1FDE8038D0D1D513DD73F8DD36F948 :2012800000DD7EFEC628DD77FEDD7EFFCE00DD77FF237DD6197C173F1FDE803887033EFF5D :1812A000B93E0098E2A912EE80F21612210000DDF9DDE1C9210000C91A :00000001FFIntel HEX 形式なるものらしいけど、何がなんだか分からない…。バイナリファイルの元になるっぽいのは分かるけど…。
_Intel HEX - Wikipedia
◎ mztファイルに変換。 :
先ほど出来上がった main.ihx を、MZ700WIN で読み込めるファイルフォーマット、.mzt に変換する。以下で紹介されてる .vbs をそのまま使わせてもらった。ありがたや。
_SDCC用の環境構築 - 電子ブロック工房
ihx2mzt.vbs というファイル名で保存して、最初のあたりのファイル名等を変更。DOS窓上で ihx2mzt.vbs と打って実行すると、「main.mzt is created.」とダイアログが表示されて .mzt が作られた。
_SDCC用の環境構築 - 電子ブロック工房
ihx2mzt.vbs というファイル名で保存して、最初のあたりのファイル名等を変更。DOS窓上で ihx2mzt.vbs と打って実行すると、「main.mzt is created.」とダイアログが表示されて .mzt が作られた。
◎ 動作確認。 :
MZ700WIN を起動して、Setting → MONITOR Rom → MZ-700{J} / MZ700 NEW-MONITOR を選択。画面に「MZ-700」と表示された。
File → Set Load Tape を選択して、main.mzt を指定。L[Enter]でロード。
画面に何か出た。
ということで、SDCC を使えばMZ-700用(Z80 CPU用)のプログラムをC言語で書くことができる、と分かった。
File → Set Load Tape を選択して、main.mzt を指定。L[Enter]でロード。
画面に何か出た。
ということで、SDCC を使えばMZ-700用(Z80 CPU用)のプログラムをC言語で書くことができる、と分かった。
◎ ちゃんと書くならアセンブラは必須かも。 :
MZ-700の画面描画の仕様によると、Z80の各命令のクロック数を意識しながら書かないと最良のパフォーマンスが出ないようで。
_Programming MZ-700: Display
ちゃんと作るなら、どこかしらをアセンブラで書かないといかんようだなと。
_Programming MZ-700: Display
ちゃんと作るなら、どこかしらをアセンブラで書かないといかんようだなと。
[ ツッコむ ]
以上です。