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が出来ます。