Z80-COREのプログラミングツールとして、CコンパイラSDCCを紹介します。
SDCCは昔から存在は知っていたのですが、SDCCがサポートするPICのプログラミングでは、Microchipの開発環境とコンパイラを使っていますし、Z80などのプログラミングをやってたのは40年も前のことなので、SDCCを使ったことはありませんでした。(多分)
また、小さなプロセッサ用のCコンパイラにはずっと興味があって、SDCCにはちょこちょこと目が行っていたのですが、生成コードの質が良くないとか、ツールに安定性がないとか、結構批判的な意見が目についたのであえて時間を割く必要もないかなと思っていました。
しかしここにきて、Z80-COREのCコンパイラを確保する現実的な要求が突き付けられたので、使ってみることにしました。
結論から言えば、十分使えるという感じです。十分楽しませてもらっています。
まあ、問題はいくつかありますが、それも含めてのホビーですから。
特徴としては、データ型としてlong(32ビット整数), long long(64ビット整数), float(4バイトIEEE形式)などが使えます。ただし、printf()関数で%fを使ってfloat値を表示できなかったり、scanf()関数がなかったりということで、コンソールとのやり取りをするプログラムを作成するにはいくつか制約があります。
インストール
SDCCのサイトを以下に示します。
- http://sdcc.sourceforge.net/
- プロジェクトサイト
- https://sourceforge.net/projects/sdcc/files/
- ダウンロードサイト
ダウンロードサイトからは、バイナリパッケージをダウンロードできるので、それをダウンロードしてインストールします。私は例のごとく、Windows64用のパッケージを使用します。
インストール先は、下記のディレクトリに書き換えてインストールしました。
- C:\XENESIS\SDCC
コードのコンパイル用に以下のようなバッチファイルsdccz80.batを作成しました。
xcore0.relは、Z80-CORE用に作成したcrt0ファイルです。
PATH=C:\XENESIS\SDCC\bin
sdcc -mz80 --no-std-crt0 --code-loc 0x4020 --data-loc 0 xcore0.rel %1
コンソール入力を単純に画面にエコーバックするプログラムです。
まだ、ライブラリなど整備していないので、Z80-CORE固有の文字入出力は、モニタのサブルチンを呼ぶようにしました。
/*
echomon.c
*/
#define CTRLC 0x03
void (*wexit)() = (void *)0x0083 ;
char (*conin)(void) = (void *)0x0098 ;
char (*conoutlf)(char) = (void *)0x008F ;
void main (void)
{
char c ;
while (1) {
c = conin() ;
if (c == CTRLC)
wexit() ;
conoutlf(c) ;
}
}
コンパイルはバッチファイルを使用して以下の様に実行します。
sdccz80 echomon.c
プログラムがコンパイルされたらechomon.ihxというHEXファイルができるので、Z80-COREにダウンロードします。
ダウンロードできたら、モニタのGコマンドで実行します。入力は、Gもしくは、G4000で実行できます。
プログラムを実行しても何も起きないのでドキッとしますが、キーボードから文字を入力すると画面に表示され、CTRL-Cを入力するモニタに帰ります。
SDCCがどのようなコードを出すか、確認しました。以下にechomon.lstに出力されたコードの一部を示します。
000000 56 _main::
57 ;echomon.c:17: while (1) {
000000 58 00104$:
59 ;echomon.c:18: c = conin() ;
000000 2Ar02r00 [16] 60 ld hl, (_conin)
000003 CDr00r00 [17] 61 call ___sdcc_call_hl
62 ;echomon.c:19: if (c == CTRLC)
000006 4F [ 4] 63 ld c, a
000007 D6 03 [ 7] 64 sub a, #0x03
000009 20 08 [12] 65 jr NZ, 00102$
66 ;echomon.c:20: wexit() ;
00000B C5 [11] 67 push bc
00000C 2Ar00r00 [16] 68 ld hl, (_wexit)
00000F CDr00r00 [17] 69 call ___sdcc_call_hl
000012 C1 [10] 70 pop bc
000013 71 00102$:
72 ;echomon.c:21: conoutlf(c) ;
000013 79 [ 4] 73 ld a, c
000014 2Ar04r00 [16] 74 ld hl, (_conoutlf)
000017 CDr00r00 [17] 75 call ___sdcc_call_hl
76 ;echomon.c:23: }
00001A 18 E4 [12] 77 jr 00104$
78 .area _CODE
79 .area _INITIALIZER
000000 80 __xinit__wexit:
000000 83 FF 81 .dw #0xff83
000002 82 __xinit__conin:
000002 98 FF 83 .dw #0xff98
000004 84 __xinit__conoutlf:
000004 8F FF 85 .dw #0xff8f