z88dkはz80ベースのコンピュータ向けのCコンパイラやアセンブラの開発環境です。
こちらをWindows11にインストールした記録になります。
z88dkのダウンのロード
Nightly Buildのリンク先からz88dk-win32-latest.zipをダウンロード
インストール
任意のフォルダにz88dk-win32-latest.zipファイルを展開
今回はc:\z88dkに展開
環境変数の設定
設定⇒システム⇒バージョン情報⇒システム詳細設定⇒環境変数
ユーザーの環境変数
変数:Z88DK_HOME
値:C:\z88dk
変数:ZCCCFG
値:C:\z88dk\lib\config
環境変数:Path
値:%Z88DK_HOME%\bin(←Pathに追加)
動作確認
アセンブラ:sample002.asm
; BIOS
CHPUT:equ $00A2
ORG $4000
HEADER:
DEFB 'A', 'B', $10, $40, $00, $00, $00, $00
DEFB $00, $00, $00, $00, $00, $00, $00, $00
START:
LD A, $41
CALL CHPUT
LOOP:
JR LOOP
ROM形式のファイル作成
z80asm -b sample002.asm
Directory: F:\msx\sample002
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2024/08/18 18:45 205 sample002.asm
-a--- 2024/08/18 18:47 23 sample002.bin
-a--- 2024/08/18 18:47 288 sample002.o
sample002.binが出来上がる。
WebMSXで実行
WebMSXのページにウェブブラウザでアクセスする。
カートリッジ1のアイコン⇒Load ROM Imageでsample002.binを選択する。
画面にAの文字が出力されます。
感想
プログラミング学習状況的にZ88DKを使える日はほど遠いのですが、いつか使えるようになる日が来ることを祈って導入してみました。
C言語でMSX-DOSで動くCOMファイルをコンパイル
#include<stdio.h>
// Windows
// cl hello.c
// MSX-DOS
// zcc +msx -subtype=msxdos -create-app -o hello.com hello.c -lmsxbios
void main() {
printf("Hello, World!");
}
zcc +msx -subtype=msxdos -create-app -o hello.com hello.c -lmsxbios
Add Boot Diskを選択しResetする。
Aドライブの+FILESにHELLO.COMをドラックアンドドロップ
仮想フロッピーディスクにHELLO.COMがコピーされるので実行することが出来る。
C言語でROMイメージをコンパイルする。
インラインアセンブラでBIOSコールするサンプルソースコード
ファイル名:Hello2.c
#include<stdio.h>
// MSX-ROM
// zcc +msx -subtype=rom -create-app Hello2.c -o hello2.rom
void my_chput(char* cp)
{
#asm
LD IX, 2
ADD IX, SP
LD L, (IX)
INC IX
LD H, (IX)
LOOP:
LD A,(HL)
CP 0x0
JP Z,FIN
CALL 0x00A2; CHPUT
INC HL
JP LOOP
FIN:
ret
#endasm
}
void main() {
my_chput("HELLO WORLD");
printf(".");
}
試したところインラインアセンブラに引数を渡す場合、引数のアドレスがSPにセットされているようなので、まずIXに2をセットしその後SPを加算することで引数char* cpのアドレスを求めています。
HLレジスタにchar* cpのアドレスをセットし、Aレジスタへ1文字づつ取り出し、CHPUTで画面へ出力、取り出した値が0になるまで繰り返しています。ちなみにC言語の文字列の末尾は0がセットされていることが確認できました。
最後のprintf(".");はmy_chput()から戻って来ていることの確認用で、インラインアセンブラが暴走していないことの確認と、my_chput()では改行が発生していないことが確認できました。
コンパイル
zcc +msx -subtype=rom -create-app Hello2.c -o hello2.rom
実行
コンパイルで出来上がったromファイルをMSXWebの「Cartridge1」へエクスプローラーからドラックランドドロップ
リセットがかかる
実行される。
C言語のソースコードからasmファイルを生成してみる
コマンド
zcc +msx -subtype=rom -create-app Hello2.c -a
Hello2.c.asmというファイルが生成される。
生成されたHello2.c.asmの内容
~省略~
; Function my_chput flags 0x00000200 __smallc
; void my_chput(char * cp)
; parameter 'char * cp' at sp+2 size(2)
C_LINE 7,"Hello2.c::my_chput::0::0"
._my_chput
LD IX, 2
ADD IX, SP
LD L, (IX)
INC IX
LD H, (IX)
LOOP:
LD A,(HL)
CP 0x0
JP Z,FIN
CALL 0x00A2; CHPUT
INC HL
JP LOOP
FIN:
ret
ret
C_LINE 25,"Hello2.c::my_chput::0::1"
; Function main flags 0x00000000 __stdc
; void main()
C_LINE 25,"Hello2.c::main::0::2"
._main
ld hl,i_1+0
push hl
call _my_chput
pop bc
ld hl,i_1+12
push hl
ld a,1
call printf
pop bc
ret
SECTION bss_compiler
SECTION code_compiler
; --- Start of Optimiser additions ---
SECTION rodata_compiler
.i_1
defm "HELLO WORLD"
defb 0
defm "."
defb 0
; --- Start of Static Variables ---
~省略~
インラインアセンブラのコードは結構そのままといった感じで、C言語のコードで関数の呼び出し部分で引数となるポインタ(アドレス)をpushしているので、なんとなく分かりそうな気がしますがスタックポインタ(SP)の動きがどのような振る舞いなのか理解していないので、SPの中身がどのように動くのか見てみたい感じがします。
また、printfがどのようなコードになっているか見れるかと期待したのですが、ライブラリの呼び出し部分が見えるだけでした。
C言語で書いたコードがアセンブリ言語になることでCPUのどのような処理として解釈されるのか見えるので中々楽しいです。
int型の宣言と代入
ソースコード
#include<stdio.h>
// MSX-ROM
// zcc +msx -subtype=rom -create-app Hello3.c -o hello3.rom
// zcc +msx -a hello3.c
void main()
{
int i = 9;
}
生成されたアセンブラ
; void main()
C_LINE 8,"hello3.c::main::0::1"
._main
ld hl,9 ;const
ret
hlは16bitレジスタなのでint方は16bit?
コメント