TMPZ84C015上のモニターでSDCCによるc言語でprintfを実行してみました。
以前作成しているモニターではTMPZ84C015のシリアルの初期化を行っているので、まずはprintf文に必要なputchar()を作成してみます。
使用したSDCCは下記のバージョンのものです。
$ sudo apt-get install sdcc
$ sdcc -v
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/TININative/ds400/hc08/s08/stm8 3.8.0 #10562 (Linux)
published under GNU General Public License (GPL)
SDCCでは、main文を呼び出すための初期化と後始末を行うcrt0.sがありますが、今回の仕様になるように変更しました。
変更点は、スタックは設定せず、モニターに任せます。
帰りは、retでモニターに戻ります。
変更したcrt0.sは次の通りです。 mycrt0.asmで保存します。
.module crt0
.globl _main
;; Ordering of segments for the linker.
.area _CODE
.area _DATA
.area _CODE
init::
call _main
ret
.area _DATA
作成したmycrt0.asmをアセンブルします。
$ asz80 -l -s -o mycrt0.asm
cのコンパイルには作成された mycrt0.relを使用します。
次にputcharを作成します。
putcharの本体は、モニターでも使用している一文字出力ルーチンです。
mainルーチンから呼ばれると、まず、引数をスタックにセットし、続いてputcharからの戻りアドレスをスタックに積みます。
putcharのルーチン内は、引数を取り出すために、戻りアドレスを+2したスタック値で引数を取得します。
返り値は、HLをクリアしています。
putchar.asmで保存します。
;; int putchar(uint8_t)
;;
_putchar::
ld hl, #0002
add hl, sp
putchar01:
in a, (0x1b)
bit 2, a
jr z, putchar01
ld a, (hl)
out (0x1a), a
ld hl, #0000
ret
アセンブルします。
$ asz80 -l -s -o putchar.asm
putcharを使用した例題を作成ます。
mainでputchar()を呼び出し、”J”を表示します。
putchar_main.cで保存します。
#include <stdint.h>
extern uint8_t putchar(uint8_t);
int main(void)
{
putchar(0x4a);
return(0);
}
コンパイルします。
先ほど作成したmycrt0.relとputchar.relが必要になります。
$ sdcc -mz80 --out-fmt-ihx --code-loc 0xa000 --no-std-crt0 -o putchar_main.ihx mycrt0.rel putchar_main.c putchar.rel
Conflicting flags in area _CODE
Conflicting flags in area _DATA
Conflicting flags in area _CODE
Conflicting flags in area _DATA
作成されたputchar_main.ihxをモニターで読み込み実行してみました。
>c a000 y:
J
>
putcharが正常に動くようですので、purintfを実行してみます。
下記の例題を用意します。
printf_main.cで保存します。
#include <stdio.h>
int main(void)
{
printf("Hello SDCC Z80 C world\n");
return(0);
}
コンパイルします。
先ほど作成したmycrt0.relとputchar.relが必要になります。
$ sdcc -mz80 --out-fmt-ihx --code-loc 0xa000 --no-std-crt0 -o printf_main.ihx mycrt0.rel printf_main.c putchar.rel
Conflicting flags in area _CODE
Conflicting flags in area _DATA
Conflicting flags in area _CODE
Conflicting flags in area _DATA
作成されたprintf_main.ihxをモニターで読み込み実行してみました。
>c a000 y:
Hello SDCC Z80 C world
>
printf上で算術演算を行ってみます。
この場合には算術演算等の処理のために容量がすごく多くなります。
printf_purasu.cで保存します。
#include <stdio.h>
int main(void)
{
printf("10 + 25=%d\n",10 + 25);
return(0);
}
コンパイルします。
先ほど作成したmycrt0.relとputchar.relが必要になります。
$ sdcc -mz80 --out-fmt-ihx --code-loc 0xa000 --no-std-crt0 -o printf_purasu.ihx mycrt0.rel printf_purasu.c putchar.rel
Conflicting flags in area _CODE
Conflicting flags in area _DATA
Conflicting flags in area _CODE
Conflicting flags in area _DATA
作成されたprintf_purasu.ihxをモニターで読み込み実行してみました 。
>c a000 y:
10 + 25=35
>
SDCCで色々できそうなので、Cプログラムに挑戦していきたいと思います。