Z80 C 言語クロスコンパイラ z88dk (z88 Development kit) についてまとめています。


目次


公式サイト

z88dk
GitHub - z88dk/z88dk


対応プラットフォーム

z88dk は当初 Cambridge z88 portable を対象としていましたが、
Z80 系の様々なプラットフォームに対応し、
現在は 80 種類を超えるプラットフォームに対応しています。

Platform | GitHub z88dk/z88dk Wiki

日本で主に流通していたプラットフォームでは、次に対応しています。

  • EPSON HC-40
  • EPSON HC-80 / HC-88
  • SONY SMC-70 / SMC-777
  • CASIO FP-1000 / FP-1100
  • SHARP PC-E200 / PC-G800~PC-G850 シリーズ
  • ソード M5
  • MSX
  • 三菱 MULTI8
  • SHARP MZ-80・MZ-700
  • SHARP MZ-2500
  • TOSHIBA パソピア7
  • NEC PC-6001 / PC-6601 シリーズ
  • NEC PC-8801 シリーズ
  • CASIO PV-1000 / PV-2000
  • バンダイ RX-78 GUNDAM
  • SEGA SG-1000 / SC-3000
  • SEGA マスターシステム
  • バンダイ TV-JACKスーパービジョン8000
  • TI 電卓
  • Canon X-07
  • SHARP X1
  • シンクレア ZX81

Wiki(公式ドキュメント)

z88dk 関連の Wiki(公式ドキュメント9は 2 ヶ所存在します。

Wiki | GitHub z88dk/z88dk
Wiki | z88dk.org

GitHub Wiki へ移行されているのですが、一部記載がないものもあります。
逆に新たに追記されている情報は GitHub の Wiki にしかありません。


Nightly Build

最新版よりも新機能やプラットフォームの対応などが含まれているため、
Nightly Build を使用するのも良いとされています。

Nightly Build | z88dk

日本時間昼 12:30 前後でビルドされたファイルが公開されています。
(ビルドに失敗して公開されていない場合もあります)


conio.h MS-DOS 互換ライブラリ

include <conio.h>

プラットフォームによっては動作しない関数があります。

Classic conio | GitHub z88dk/z88dk Wiki

コンソール入力

  • int kbhit(void)
    キーが押された場合は 0 以外、押されていない場合は 0 を返します。
    キーバッファに影響を与えません。
  • int getch(void)
    標準入力から 1 文字読み込みます。
    特殊キーもコードを得る事ができます。
  • int getche(void)
    getch に同じです。
  • void cgets(char *dest)
    コンソールから文字列を読み取ります。配列 s へ入れます。
    s[0] に入力最大文字数を入れておきます。
    s[1] に入力された文字数、s[2] 以降に文字列が入ります。
  • int cscanf(unsigned char *fmt,…)
    scanf に同じです。

コンソール出力

  • void putch(char c)
    fputc_cons に同じです。
  • void cputs(const char *message)
    コンソールに文字列 message を出力します。
  • int cprintf(const char *fmt,…)
    書式文字列 fmt に従ってコンソールに出力します。
    z88dk では printk に同じです。
  • void gotoxy(unsigned int x, unsigned int y)
    カーソル位置を横座標 x 縦座標 y へ移動します。
  • void settextcolor(int c)
    文字色を設定します。
  • void textcolor(int c)
    文字色を設定します。
  • void textbackground(int c)
    背景色を設定します。
  • textattr
    文字色・背景色を指定設定します。上位 4 ビットが背景色、下位 4 ビットが文字色です。
  • clrscr(void)
    画面をクリアします。fputc_cons(12) を実行します。
  • clreol
    カーソルから行末までをクリアします。printf(“ESC[K”) を実行します。

graphics.h モノクログラフィック

include <graphics.h>

z88dk にはプラットファーム共通のモノクログラフィックライブラリ graphics.h があります。

Classic Monochrome Graphics | GitHub z88dk/z88dk Wiki

このライブラリを使用する事で、
プラットフォームに依存しないグラフィックの線画が可能です。

プラットフォームによってはテキスト画面にキャラクターを出力する
仮想グラフィックを用いる場合があります。
そのため、モノクログラフィックで使用できる幅は
プラットフォームで大きく差があります。

graphics.h の関数

  • void plot(int x, int y)
    点を描きます。
  • void unplot(int x, int y)
    点で消します。
  • void xorplot(int x, int y)
    点で反転します。
  • int point(int x, int y)
    特定座標に線画されているかを得ます。
  • int getmaxx()
    横の最大座標を得ます。
  • int getmaxy()
    縦の最大座標を得ます。
  • void draw(int x1, int y1, int x2, int y2)
    線を描きます。
  • void xordraw(int x1, int y1, int x2, int y2)
    線で反転します。
  • void undraw(int x1, int y1, int x2, int y2)
    線で消します。
  • void drawto(int px, int py)
    最後に描いた座標を開始点として座標まで線を描きます。
  • void xordrawto(int px, int py)
    最後に描いた座標を開始点として座標まで線で反転します。
  • void undrawto(int px, int py)
    最後に描いた座標を開始点として座標まで線で消します。
  • void drawr(int px, int py)
    最後に描いた座標からの相対座標で線を描きます。
  • void xordrawr(int px, int py)
    最後に描いた座標からの相対座標で線を反転します。
  • void undrawr(int px, int py)
    最後に描いた座標からの相対座標で線を消します。
  • void drawb(int tlx, int tly, int width, int height)
    四角枠で描きます。開始座標と大きさになっている事に注意して下さい。
  • void undrawb(int tlx, int tly, int width, int height)
    四角枠で消します。
  • void xorborder(int tlx, int tly, int width, int height)
    四角枠で反転します。
  • void circle(int x, int y, int radius, int skip)
    円枠を描きます。
  • void uncircle(int x, int y, int radius, int skip)
    円枠で消します。
  • void clg(void)
    グラフィックモードの初期化を行い、画面をクリアします。\

4x4 ドット単位の点で線画します。座標は 4 分の 1 となります。

  • void c_plot(int x, int y)
    座標に 4x4 ドットの点を線画します。
  • void c_unplot(int x, int y)
    座標に 4x4 ドットの点で消去します。
  • void c_xorplot(int x, int y)
    座標に 4x4 ドットの点で反転します。
  • int c_point(int x, int y)
    座標の 4x4 点状態を返します。

games.h モノクロスプライト

include <games.h>

z88dk にはプラットファーム共通のモノクロスプライトがあります。

Classic Monochrome Graphics Sprite functions | GitHub z88dk/z88dk Wiki

char sprite[] = { 8, 8,
  0x0e /* ....###. */,
  0x1d /* ...###.# */,
  0x1f /* ...##### */,
  0x1f /* ...##### */,
  0x0e /* ....###. */,
  0x08 /* ....#... */,
  0x10 /* ...#.... */,
  0xe0 /* ###..... */
};
char sprite[] = { 5, 5,
  0x70 /* .###.... */,
  0xe8 /* ###.#... */,
  0xf8 /* #####... */,
  0xf8 /* #####... */,
  0x70 /* .###.... */
};

通常使用する関数は putsprite のみです。

  • putsprite(int ortype, int x, int y, void *sprite)
    スプライトを表示します。sprite がデータです。
    ortype は SPR_OR・SPR_XOR・SPR_AND で
    すでに線画されている状態とスプライトデータの OR・XOR・AND になります。

stdio.h 標準入出力

include <stdio.h>

C 言語ではよく使われる関数です。
z88dk では Z80 系プラットフォーム向けにいくつか関数が追加されています。

stdio | GitHub z88dk/z88dk Wiki

ファイル関連

  • FILE *fopen(char *name, unsigned char *mode)
    読み書きモード mode でファイル名 name を開きます。
    mode は w:書き込み r:読み込み s:ファイル末尾から追記 を指定できます。
    a はプラットフォームによって使用できない場合があります。
    また、プラットフォームによっては name が切り捨てられたり、
    null を返します。
  • FILE *freopen(char *name, unsigned char *mode, FILE *fp)
    読み書きモード mode でファイル名 name を開き、ファイルポインタ fp へ関連付けます。
    エラーの場合は fp または NULL を返します。
  • int fflush(FILE *fp)
    メモリ上の情報をファイルへ反映します。
    z88dk ではスタプとして存在します。(単に BIOS コールを実行しているだけ)
  • int fclose(FILE *fp)
    ファイルポインタ fp を閉じます。
  • extern int remove(char *name)
    ファイル name を削除します。プラットフォームによっては動作しない場合があります。
  • int rename(char *s, char *d)
    ファイル名 s を d へ変更します。プラットフォームによっては動作しない場合があります。

キャラクター入出力関連

  • int fgetc(FILE *fp)
    fp から次の 1 文字を得ます。ファイルの終わりまたはエラーの場合は EOF を返します。
  • char *fgets(unsigned char *s, int n, FILE *fp)
    fp から配列 s へ 1 行最大 n-1 文字読み込みます。
    通常は s を返します。ファイルの終わりまたはエラーは NULL を返します。
  • int fputc(int c, FILE *fp)
    fp へ文字 c を書き込みます。正常時は文字 c、エラーの場合は EOF を返します。
  • int fputs(unsigned char *s, FILE *fp)
    配列 s の内容を fp へ書き込みます。正常時は 0 以上、エラーは EOF を返します。
  • int puts(unsigned char *s)
    文字列 s +改行を出力します。
  • int ungetc(int c, FILE *fp)
    文字 c をファイルポインタ fp へ戻します。
    次に文字を読み込んだ時、c の文字を得る事ができます。

ダイレクト入出力関連

  • int fread(void *ptr, int size, int num, FILE *fp)
    fp から size のオブジェクト最大 num 個を ptr に読み込みます。
    読み込んだオブジェクト数を返します。
  • int fwrite(void *ptr, int size, int num, FILE *fp)
    配列 ptr から pf へ size のオブジェクト num 個文書き込みます。
    書き込んだオブジェクト数を返します。

ファイル位置関連

  • int fseek(FILE *fp, fpos_t offset, int whence)
    fp の位置を whence から offset の位置に設定・変更します。
    whence は SEEK_SET: ファイルのはじめ、
    SEEK_CUR: 現在位置、 SEEK_END: ファイルの終わり です。
  • fpos_t ftell(FILE *fp)
    ファイル fp の位置を得ます。
  • int fgetpos(FILE *fp, fpos_t *pos)
    fp の解析状態またはファイル位置を pos に返します。
  • int feof(FILE *fp)
    fp が終了しているかを確認します。

書式付き入出力関連

  • int printf(char *,…)
    書式文字列に従って標準出力へ出力します。
  • int fprintf(FILE *,char *,…)
    書式文字列に従ってストリームへ出力します。
  • int sprintf(char *,char *,…)
    書式文字列に従って配列に書き込みます。
  • int vsprintf(char *str,unsigned char *fmt,void *ap)
    可変長引数リストのデータを書式文字列 fmt に従って配列 str に書き込みます。
  • int scanf(unsigned char *fmt,…)
    標準入力から書式文字列に従ってデータを読み込みます。
  • int fscanf(FILE *,unsigned char *fmt,…)
    ストリームから書式文字列に従ってデータを読み込みます。
  • int sscanf(char *,unsigned char *fmt,…)
    指定した文字列から書式文字列に従ってデータを取得します。
  • int vfscanf(FILE *, unsigned char *fmt, void *ap)
    ストリーム から可変長引数リストを用いてデータを読み込みます。
  • int vsscanf(char *str, unsigned char *fmt, void *ap)
    指定した文字列から可変長引数リストを用いてデータを取得します。

コンソール関連

  • int fgetc_cons()
    コンソールから 1 文字得ます。
  • int fputc_cons(char c)
    コンソールに文字 c を出力します。
  • int fgets_cons(char *s, int n)
    コンソールから配列 s へ 1 行最大 n-1 文字読み込みます。
  • void puts_cons(unsigned char *s)
    文字列 s +改行をコンソールへ出力します。
  • void printk(char *fmt,…)
    書式文字列 fmt に従ってコンソールに出力します。\
  • int getk()
    コンソールから 1 文字得ます。

標準に含まれていない関数

  • printn(int number, int radix,FILE *file)
    ストリーム file へ文字 radix を number 文字出力します。
  • int ltoa_any(long in,unsigned char *str, int sz, unsigned int radix, int signflag)
  • FILE *fdopen(int fildes, unsigned char *mode)
  • long fdtell(int fd)
  • int fdgetpos(int fd, fpos_t *posn)
  • void closeall()
    開いているストリームをすべて閉じます。
  • void fabandon(FILE *)

stdlib.h 標準ライブラリ

include <stdlib.h>

C 標準で定義されているユーティリティ関数の一部です。
一部関数は z80 系プラットフォームに適するよう変更され、いくつかの機能が追加されています。
float・double から文字列への変換は対応されていません。

stdlib | GitHub z88dk/z88dk Wiki

標準

  • int atoi(char *s)
    s を整数 int 型へ変換します。
  • int itoa(int n, char *s, unsigned char radix)
    整数値 n を NULL で終わる文字列に変換し配列 s へ収納します。
    n が 0 より小さい場合は文字列の頭に - が付きます。
    NULL を含まない s へ書き込まれた文字数を返します。
  • int utoa(unsigned int n, char *s, unsigned char radix)
    itoa に同じですが、符号なしで返されます。
  • long atol(char *s)
    s を long 型へ返します。
  • int ltoa(long n, char *s, unsigned char radix)
    long 型 n である事以外は itoa に同じです。\
  • int ultoa(unsigned long n, char *s, unsigned char radix)
    ltoa に同じですが、符号なしで返されます。
  • long strtol(char *s, char **endp, int base)
  • unsigned long strtoul(char *s, char **endp, int base)
  • int rand(void)
    0~RAND_MAX の疑似乱数を返します。RAND_MAX は最低 32767 です。
  • void srand(unsigned int seed)
    疑似乱数の元値 seed を設定します。
  • void *calloc(int nobj, int size)
    size で配列 nobj を領域に割り当て、そのポインターを返します。
    エラーの場合は 0 を返します。
  • void *malloc(int size)
    size 分の領域割り当て、ポインターを返します。
  • void *realloc(void *p, int size)
    割り当てられた領域 p を size へ変更します。
  • void free(void *p)
    領域 p を解放します。
  • void abort(void)
    exit(15) に同じです。
  • void exit(int status)
    プログラムを正常に終了させます。
  • int atexit(void (*fcn)(void))
    正常終了時に呼び出される関数 fcn を登録します。
  • void sleep(int)
    ウェイトを入れます。単位は秒です。
  • void csleep(int)
    ウェイトを入れます。単位はセンチ秒です。
  • void delay(int)
    ウェイトを入れます。単位はミリ秒です。
  • void t_delay(int)
    CPU T_STATE 分待ちます。(最低 141 T)
  • int getopt(int nargc, char **nargv, const char *ostr)
  • void l_bsearch(void *key, void *base, unsigned int n, char (*cmp)(void *keyval, void *datum))
    base[0]~base[n-1] から key をバイナリ検索します。
  • void l_qsort(void *base, size_t n, char (*cmp)(void *keyval, void *datum))
    base[0]~base[n-1] から key を昇順に並べ替えます。
  • int abs(int n)
    n の絶対値を返します。
  • long labs(long n)
    lang 型 n の絶対値を返します。

標準に含まれていない関数

  • unsigned char inp(unsigned int port)
    16 ビット I/O ポートから読み取り、返します。
  • void outp(unsigned int port, unsigned char byte)
    16 ビット I/O ポートに byte を書き込みます。
  • int sleep(int seconds)
    int csleep(int centiseconds)
    int delay(int milliseconds)
    ウェイト。他のコンパイラ同等の実装になっています。
  • unsigned long extract_bits(unsigned char *data, unsigned int start, unsigned int size)
    data から start より size 分のビット数を long 型に変換します。
  • void t_delay(unsigned int tstates)
    Z80 のサイクル数 tstates 分待ちます。
  • void *swapendian(void *addr)
    addr の上位バイトと下位バイトを交換し、返します。
  • void bpoke(void *addr, unsigned char byte)
    addr に byte を書き込みます。
  • void wpoke(void *addr, unsigned int word)
    addr に word を書き込みます。
  • unsigned char bpeek(void *addr)
    addr の値を読み込み、返します。
  • unsigned int wpeek(void *addr)
    addr から 2 バイトの値を読み込み、返します。値はリトルエンティアンになります。
  • unsigned int isqrt(unsigned int n)
    n の平方根を返します。n は 16384 未満です。

Z88 専用

  • int system(char *s)
    CLI コマンドを実行します。

MSX

MSX 関連の情報は MSX JAPAN▉ に専用ページを設けています。

🎈 クロス開発 z88dk | MSX JAPAN▉

ライブラリ

z88dk の MSX 関連ライブラリ対応は MSX1 向けです。
MSX2 以降はあまり対応されていません。
一方 MSX-DOS 関連は MSX-DOS1・2 に対応しています。

Nightly Build 使用時の注意

2019年8月現在 Nightly Build で
MSX 独自のライブラリの一部関数で問題が発生しています。
他のプラットフォームでも使用できるようにするため、
BIOS コールを用いず直接 VDP を初期化し、
初期状態とは異なる番地で初期化しようとするので、
その影響を受けているように思われます。


PC-6001 / PC-6601

🎈 z88dk で PC-6001・PC-6601 シリーズ向けに作る。 | ふうせん🎈 FU-SEN

モノクログラフィックのスクリーンモード

デフォルトはテキスト画面を用いた 64×48 になります。
これは関数の追加により、スクリーンモードの設定が可能です。

int mode = 1;
console_ioctl(IOCTL_GENCON_SET_MODE, &mode);
  • mode = 0 : テキスト画面 64×48
  • mode = 1 : 256×192・2 色画面
  • mode = 2 : 128×192・4 色画面

PC-E200 / G800~G850

PC-E200・G800~G850 シリーズ向けの情報は POKE COM でまとめてあります。

🎈 クロス開発 z88dk | POKE COM

BIOS コールや I/O レベルでは
座標と出力文字またはグラフィックパターンの同時指定をするため、
まともに使用すル場合は独自にライブラリを生成する必要があります。
z88dk ではプラットフォーム共通のモノクログラフィック・モノクロスプライトを
PC-E200・G800~G850 で対応させてあります。
もちろん標準 C ライブラリでテキストの出力も可能です。
そのため z88dk 内蔵のライブラリで容易に操作できるようになっています。