z88dkをインストールした記録

コンピュータ

z88dkはz80ベースのコンピュータ向けのCコンパイラやアセンブラの開発環境です。
こちらをWindows11にインストールした記録になります。

z88dkのダウンのロード

インストール

任意のフォルダに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?

コメント