SDCCによるクロスビルド
SDCC (Small Device C Compiler)はZ80他の小さいマイコン向けのコンパイラです。
z88dkのほうがお手軽だと思うのであまり説明しません。いちおうファイル類はこちらに置いておきます。
環境構築
Macの場合はHomebrewで導入できます。
brew install sdcc
それ以外の環境ではこちらからバイナリがダウンロードできます。
アセンブラ開発
下記内容のputc.asmを作成します。
.area _HEADER (ABS)
.ORG 0x100
ld a,#'a' ; 文字a
ld d,#0 ; yカーソル座標
ld e,#0 ; xカーソル座標
call #0xbe62 ; IOCSコール
ret
いくつか作法があってよく理解できていませんが、ひとまずこのコードに関連するお作法は下記です。
- 絶対値セクションに置かないと。ORG指定ができない。
- イミディエイトは#で始める。
それ以外のお作法はこちらにすばらしくまとまっています。
下記のようにビルドできます。
sdasz80 -o putc.asm
sdldz80 -i putc
でputc.ihxができます。気持ち悪いことにオブジェクトファイル相当品は*.relでテキストファイルです。
C/インラインアセンブラ開発
SDCCには標準ライブラリがないので、なんらかのアセンブラで作成されたライブラリがないと画面描画もままなりません。
インラインアセンブラは下記のように記載します。
__asm
....
__endasm;
z88dkの場合と同様に、C言語との変数・レジスタのやりとりは関数経由で行います。関数コールの手順は、
- 引数を「後ろから」スタックに積んでいく(z88dkとは向きが違うので注意!)
- リターンアドレスをスタックに積む
- 関数のエントリポイントにジャンプ
となっており、関数に入った直後のスタックは上から下記のようになっています。
アドレス | データ |
---|---|
(SP) | リターンアドレス(L) |
(SP)+1 | リターンアドレス(H) |
(SP)+2 | 引数1 |
(SP)+2+引数1のサイズ | 引数2 |
... | ... |
戻り値はちゃんと調べてません。
標準のCランタイムルーチンの出来があまりよろしくなく、G800シリーズと合わない点があるらしく、 自前のものに差し替えたほうがよいという話がこちらにかかれています。
このため、下記のようなmycrt.sを用意します。
.area _HEADER (ABS)
.globl _main
.ORG 0x100
.area _CODE
call _main
ret
cからの中間ファイルであるasmファイルを消すときにcrtも誤って消してしまうと困るので、拡張をasmではなくsに変えてあります。スタックポインタを保存したり変数エリアの初期化をしたり、ほかにもいろいろやったほうがよいんでしょうが、今回ぐらいのコードならmainを呼び出すだけでOk。
次にメインルーチンとして下記のようなtest.cを用意します。
void putc(char c,char x,char y){
__asm
ld ix,#2
add ix,sp
ld a,0(ix) ; character
ld e,1(ix) ; x cursor
ld d,2(ix) ; y cursor
call #0xbe62 ; call IOCS
__endasm;
}
void main()
{
putc('a',3,3);
}
ビルドは下記のように行なえます。
sdasz80 -o mycrt.s
sdcc -mz80 --code-loc 0x100 --no-std-crt0 -Wlmycrt.rel test.c
これでtest.ihxが出来ます。