モニタ上でSDCCでコンパイルしたC実行ファイルをデバックするために printf文を実装してみます。

すでに先人の方がすでに解決済みなので、それにならって、プログラムしていきます^^

参考にして頂いたサイトは、「素人の論理設計」様の「SDCC Z80」を参考にさせていただきました。
貴重な情報をありがとうございます。

さて、SDCCのprintfは、内部で、最終的には、putchar.sに制御が移るそうなので、コードがどうなってるか
確認してみたいと思います。

SDCCは姉妹プログでソースからコンパイルしたSDCC 3.6.0 を使用しました
コンパイル方法はこちらを参考にしてね

putchar.sの在りかは、
  /usr/local/share/sdcc/lib/src/z80
にあります。

.area   _CODE
_putchar::
_putchar_rr_s::
ld      hl,#2
add     hl,sp

ld      l,(hl)
ld      a,#1
rst     0x08

ret

_putchar_rr_dbs::
ld      l,e
ld      a,#1
rst     0x08

ret

このコードを参考にモニタに組み込みすることにします。

シリアルのイニシャライズはモニタにまかせて、そのあと 0x0008番地が
コールされたら、モニタの内部サブルーチンを呼ぶことにします。
出力される文字データは、Lレジスターに、Aレジスターが0x01の時に
出力すればいいようです。
Aレジスターが0x00の時は、リセットするようにしました。

実際の0x0008のコール部分のモニタは次のようになりました。

.org    0x0000
jp	init_ram

.org	0x0008
cp	0x01
jr	z,putchar_ch0
jr	0x0000

putchar_ch0:
ld	a,l
call	putchar
ret

.org	0x0080
init_ram:
ld	a,cbar_set	;ram	0x8000 to 0xffff
out0	(CBAR),a
ld	a,ram
out0	(BBR),a
out0	(CBR),a
jp      start

.org    0x0100

start:                          ;cold start
ld      sp,0x0000       ;stack pointer set

では、このモニタ(このページの最後のところでソースを展開します)を使って、C言語でかかれたプログラムをコンパイルして実行してみましょう。
C言語の最初のプログラムといえば「 Hello C World! 」を表示することがお決まりですよねwww
ということで 次のようなCソースを作成しました^^
ファイル名は main.cとしました。

#include	<stdio.h>

main()
{

    printf("Hello C World!! on Z180 \n\r");

    return(0);
}

さて、このCソースをコンパイルするわけですが、パソコン上のOSで実行する場合はOSがこのプログラムを実行するにあたり、お膳立てと後始末を行ってくれますが今回のようなOSがない状態の時は、お膳立てと後始末を行うプログラムが必要になります。
そのプログラムはSDCCでは アセンブラで記述された「crt0.s」となります。
ですが、このcrt0.sをのぞくとスタックポインタを設定したり、今回の実行環境に添わなかったりします。

ということで、今回の実行環境に合うように修正しました。
・ポインタはモニタのポインタをそのまま使用する。
・実行開始アドレスは、コンパイル時に指定する。
などなど

変更したcrt0.sは次の通りです。
新しく my_crt0.sとしました。
Cソースをコンパイルするときにリンクしないといけないので、先に
アセンブルしておきます。
$ asz80 -l -s -o my_crt0.s


.module crt0
.globl  _main

;   .area   _HEADER (ABS)
;   ;; Reset vector
;   .org    0
;   jp  init

;   .org    0x08
;   reti
;   .org    0x10
;   reti
;   .org    0x18
;   reti
;   .org    0x20
;   reti
;   .org    0x28
;   reti
;   .org    0x30
;   reti
;   .org    0x38
;   reti

;   .org    0x100
;init:
;   ;; Set stack pointer directly above top of memory.
;   ld  sp,#0x0000

;; Initialise global variables
;        call    gsinit
;   call    _main
;   jp  _exit

;; Ordering of segments for the linker.
;   .area   _HOME
.area   _CODE
;   .area   _INITIALIZER
.area   _GSINIT
.area   _GSFINAL

.area   _DATA
.area   _DATAFINAL
;   .area   _INITIALIZED
;   .area   _BSEG
;   .area   _BSS
;   .area   _HEAP

.area   _CODE
init::
;   ld  sp,#0x8000
call    gsinit
jp  _main
ret
;__clock::
;   ld  a,#2
;   rst     0x08
;   ret

;_exit::
;   ;; Exit - special code to the emulator
;   ld  a,#0
;   rst     0x08
;1$:
;   halt
;   jr  1$

.area   _GSINIT
gsinit::
;   ld  bc, #l__INITIALIZER
;   ld  a, b
;   or  a, c
;   jr  Z, gsinit_next
;   ld  de, #s__INITIALIZED
;   ld  hl, #s__INITIALIZER
;   ldir
;gsinit_next:

.area   _GSFINAL
ret

.area   _DATA
_datastart::

.area   _DATAFINAL
_dataend::

出来上がった my_crt0.relは コンパイル時にリンクします。

やっとwww コンパイル準備ができましたので、先ほどのCソースをコンパイルします。
実行開始アドレスを 0xa000として指定しています。

$sdcc -mz80 --code-loc 0xa000 --no-std-crt0 my_crt0.rel main.c
Conflicting flags in area _CODE
Conflicting flags in area _DATA
Conflicting flags in area _GSINIT
Conflicting flags in area _GSFINAL

コンパイルが終了するとHexファイルが生成されます。
出来上がった main.ihx を モニタのlコマンドで転送します。

モニタ上でcコマンドで 0xa000をコールします。

>c a000 Yes:
Hello C World!! on Z180

ちゃんと 表示されたみたいですwww

以下 SDCCのprinntf対応のモニタソースです。
いつもながら 非常に長いです^^;

; Z180 monitor ver0.73(spi) on UV-EPROM or printf by Pinecone 2018/9/7
;
; Z8S180 cpu
; rom 0000h -- 7fffh
; ram 8000h -- ffffh(MMU setting)
; External clock 16MHz

; Z8S180 serial communication (Ch0)
; extemal Clock
;
; spi Interface (sd-card)
; i/o address
;    INPUT-PORT    0x84(r) 74HC541
;    OUTPUT-PORT   0x84(w) 74HC574

; assembler
;  program start 0000H
;  main          0100H
;
; assemblers  ASxxxx and ASlink V5.10
; file name moni_rom_cc.asm
; $ asz80 -l -s -o moni_rom_cc.asm
; $ aslink -i moni_rom_cc
; $ UV-EPROM writer (TL866(2)PLUS moni_cc_rom.ihx
;

.z180

.area TEST(ABS)

;; dely timing set in 100uS
D100U  .equ    6

;;spi i/o port setting
INPUTP  .equ    0x84            ;;74HC541
OUTPUTP .equ    0x84            ;;74HC574

;OUTPUT-PORT
S_DI    .equ    7               ;0b10000000  D7
S_CS    .equ    6               ;0b01000000  D6
S_CLK   .equ    5               ;0b00100000  D5

;INPUT-PORT
DO      .equ    7               ;0b10000000  D7

TDR0    .equ    0x06    ;ch0 serial
RDR0    .equ    0x08
STAT0   .equ    0x04
CNTLA0  .equ    0x00
CNTLB0  .equ    0x02

;TDR1   .equ    0x07    ;ch1 serial
;RDR1   .equ    0x09
;STAT1  .equ    0x04
;CNTLA1 .equ    0x01
;CNTLB1 .equ    0x03

CBR     .equ    0x38    ;i/o setting reg
BBR     .equ    0x39
CBAR    .equ    0x3a

CMR     .equ    0x1e
CCR     .equ    0x1f
DCNTL   .equ    0x32

ram     .equ    0x20    ;ram address 0x20000
cbar_set        .equ    0x88    ;moni move temprary CBAR setting address 0x8000
temp_addr       .equ    0x8000  ;moni move temprary address

.org    0x0000
jp      init_ram

.org    0x0008
cp      0x01
jr      z,putchar_ch0
jr      0x0000

putchar_ch0:
ld      a,l
call    putchar
ret

.org    0x0080
init_ram:
ld      a,cbar_set      ;ram    0x8000 to 0xffff
out0    (CBAR),a
ld      a,ram
out0    (BBR),a
out0    (CBR),a
jp      start

.org    0x0100

start:                          ;cold start
ld      sp,0x0000       ;stack pointer set
call    com_init        ;serial channel initialize
call    cr
ld      hl,msg_op       ;opening message display
call    msgout
call    cpu_msg1
call    cpu_msg2
call    moni_area
prompt: ld      a,">"           ;main  routine
call    putchar         ;prompt display
call    getchar
call    putchar
cp      "?"             ;help ?
call    z,help
cp      "d"             ;memory disply?
call    z,dump
cp      "m"             ;memory rewrite ?
call    z,memory
cp      "l"             ;hex file load?
call    z,loadhex
cp      "j"             ;address jump?
call    z,jump
cp      "i"             ;i/o register rewite
call    z,ioreg
cp      "c"
call    z,calling       ;address call
cp      "t"
call    z,trance        ;moni 64Kmemory trance
cp      "a"
call    z,spi_card      ;read/write spi sd-card

cp      0x0d
jr      z,prompt
cp      0x00
jr      z,prompt
call    cr
jr      prompt

help:   call        cr
ld      hl,msg_op     ;help ?
call    msgout
ld      hl,help_msg
call    msgout
ret
cr:
ld      a,0x0d
call    putchar
ret
crret_t:
call    cr
ret
trance:
call    call_yes_msg
call    getchar
cp      "y"
jr      nz,crret_t
call    cr
ld      a,cbar_set              ;ram    0x8000 to 0xffff
out0    (CBAR),a
ld      a,ram
out0    (BBR),a
out0    (CBR),a

ld      hl,0x0000       ;moni   copy at temp_addr
ld      de,temp_addr
ld      bc,prog_end
ldir

ld      hl,move_prog+temp_addr
jp      (hl)            ;temprary address jump
;
move_prog:
xor     a               ;ram 0x0000 to 0x7fff setting
out0    (CBAR),a
ld      hl,temp_addr    ;moni moveing at ram 0x0000 to prog_end
ld      de,0x0000
ld      bc,prog_end
ldir
ld      hl,go_moni
jp      (hl)            ;ram monitor jump
;
go_moni:
ld      sp,0x8000
in0     a,(CMR)         ;XTAL*2
set     7,a
out0    (CMR),a
in0     a,(CCR)         ;XTAL/1
set     7,a
out0    (CCR),a

in0     a,(DCNTL)
res     7,a             ;MWI1=0
res     6,a             ;MWI0=0  Memory wait state =0
res     5,a             ;IWI1=0
res     4,a             ;IWI0=0 I/O wait state =1
out0    (DCNTL),a
nop
nop
jp      start

cpu_msg1:
ld      hl,cpu_msg_bbr  ;BBR reg disply
call    msgout
in0     a,(BBR)
call    hex_a_disp
ld      hl,cpu_msg_cbr  ;CBR reg disply
call    msgout
in0     a,(CBR)
call    hex_a_disp
ld      hl,cpu_msg_cbar ;CBAR reg disply
call    msgout
in0     a,(CBAR)
call    hex_a_disp
call    cr
ret
cpu_msg2:
ld      hl,cpu_msg_clock        ;clock divide
call    msgout
in0     a,(CCR)
rlca
jr      c,clock1
ld      a,"2"
jr      cpum1
clock1: ld      a,"1"
cpum1:
call    putchar
ld      hl,cpu_msg_speed        ;*2 Clock Multiplier
call    msgout
in0     a,(CMR)
rlca
jr      c,speed1
ld      a,"1"
jr      cpum2
speed1: ld      a,"2"
cpum2:
call    putchar
ld      hl,cpu_msg_wait_m       ;Memory Wait State
call    msgout
in0     a,(DCNTL)
rlca
rlca
and     0x03
add     a,0x30
call    putchar
ld      hl,cpu_msg_wait_io       ;i/o Wait State
call    msgout
in0     a,(DCNTL)
rlca
rlca
rlca
rlca
and     0x03
add     a,0x31
call    putchar
call    cr
ret
moni_area:
ld      hl,moni_area_msg        ;monitor area
call    msgout
ld      hl,start
ld      a,h
call    hex_a_disp
ld      a,l
call    hex_a_disp
ld      a,"-"
call    putchar
ld      hl,prog_end
ld      a,h
call    hex_a_disp
ld      a,l
call    hex_a_disp
call    cr
ret

jump:                           ;address jump?
ld      a," "
call    putchar
call    input_hl        ;dump address input
cp      0x00
jr      nz,crret
call    call_yes_msg
call    getchar
cp      "y"
jr      nz,crret
call    cr
jp      (HL)
crret:
call    cr
ret

calling:                         ;address call?
ld      a," "
call    putchar
call    input_hl         ;call address input
cp      0x00
jr      nz,crret
call    call_yes_msg
call    getchar
cp      "y"
jr      nz,crret
call    cr
ld      de,callret
push    de
jp      (HL)
callret:
ret

call_yes_msg:
push    hl
ld      hl,yes_msg
call    msgout
pop     hl
ret

loadhex:
call    loadhexline     ;load 1line Hex file
cp      0xff            ;hex file read err
jr      z,loadhexerr
cp      0x01            ;hex file end?
jr      nz,loadhex
call    cr
ld      hl,ok_msg
call    msgout
ret

loadhexerr:
call    cr          ;hex file read skipret
ld      hl,err_msg
call    msgout
ret

loadhexline:
ld      a,0x0d
call    putchar
ld      d,0x00          ;checksum count clr
call    getchar         ;record mark is ":"
cp      ":"
jr      nz,loadhexlineerr
call    input_l         ;data size 1byte
ld      b,l             ;checksum = checksum + data size
ld      a,d
add     b
ld      d,a
call    input_hl        ;offset address 2byte
push    hl
pop     ix              ;offset address HLreg >> IXreg
ld      a,d             ;checksum = checksum + address Low
add     l
add     h               ;checksum = checksum + address Hi
ld      d,a
call    input_l         ;record type
ld      a,l
cp      0x00            ;data record
jr      nz,checkrecord

;; *** data record job ****
data_hex:
call    input_l         ;read hex 1byte in Lreg(hex)
ld      (ix),l          ;offset address < hex data
        inc     ix              ;offset address +1
        ld      a,l
        add     d               ;cheksum Dreg = Dreg + Lreg
        ld      d,a
        djnz    data_hex        ;Breg(data size) == 0?
        call    input_l         ;chechsum OK?
        ld      a,d
        add     l
        cp      0x00
        jr      nz,loadhexlineerr
        call    getchar
        cp      0x0a            ;load 1line hex LF?
        jr      nz,loadhexlineerr
        ld      a,0x00
        ret

checkrecord:                    ;end record ?
        cp      0x01
        jr      nz,loadhexlineerr
        call    input_l
        ld      a,l
        cp      0xff
        jr      nz,loadhexlineerr
        ld      a,0x01
        ret

loadhexlineerr:
        ld      a,0xff          ;read record err (no support)
        ret     

dump:                           ;memory dump
        ld      a," "
        call    putchar
        call    input_hl        ;dump address input
        cp      0x00
        jr      z,dump1
        push    iy              ;memory dump address set
        pop     hl
dump1:
        call    dump_hl         ;memory dump
        push    hl              ;memory address IY set
        pop     iy
        ret

memory:                         ;memory change
        ld      a," "           ;space
        call    putchar         
        call    input_hl        ;change memory address 
        cp      0x00
        jr      z,memory1       ;no address hex code 
        ld      a,0x0d
        call    putchar
        ret
memory1:
        ld      a," "           ;current memory display
        call    putchar
        ld      a,(HL)
        call    hex_a_disp
        ld      a," "
        call    putchar
        push    hl
        call    input_l         ;new memory conntents input
        cp      0x00
        jr      z,memory2
        pop     hl
        xor     a
        ret
memory2:
        ld      c,l             ;memory contents update
        pop     hl
        ld      (hl),c
        ld      a,0x0d
        call    putchar
        ret

ioreg:                         ;ioreg change
        ld      a," "           ;space
        call    putchar
        call    input_l        ;change i/o register
        cp      0x00
        jr      z,ioreg1       ;no address hex code
        ld      a,0x0d
        call    putchar
        ret
ioreg1:
        ld      a," "           ;current memory display
        call    putchar
        ld      b,0x00
        ld      c,l
        in      a,(c)
        call    hex_a_disp
        ld      a," "
        call    putchar
        call    input_l         ;new memory conntents input
        cp      0x00
        jr      z,ioreg2
        xor     a
        ret
ioreg2:
        ld      a,l             ;memory contents update
        out     (c),a
        ld      a,0x0d
        call    putchar
        ret

spi_card:
        call    getchar
        cp      "i"
        call    z,spi_init
        cp      "r"
        call    z,spi_read
        cp      "w"
        call    z,spi_write
        ret

spi_read:
        ld      hl,read_block_no_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,spi_read1
        call    cr
        xor   a
        ret
spi_read1:
        ld      a,(r7)
        bit     6,a
        jp      z,read_SD_ver2
        ld      a,h                    ;SDHC
        ld      (cmd17+03),a
        ld      a,l
        ld      (cmd17+04),a
        jr      spi_read2
read_SD_ver2:
        ld      a,h                    ;Ver2
        ld      (cmd17+02),a
        ld      a,l
        ld      (cmd17+03),a
spi_read2:
        ld      hl,save_addr_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,cmd17_out
        call    cr
        xor     a
        ret

cmd17_out:
        call    call_yes_msg
        call    getchar
        cp      "y"
        jp      nz,spi_ret

        push    hl
        call    dummy_data              ;dummy data(0xff) out
        ld      hl,cmd17
        call    cmd_out                 ;cmd17 Issue
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jp      nz,init_err
cmd17_st:
        call    r1_resp                 ;read data start response?
        cp      0xfe                    ;data start byte 0xfe?
        jr nz,  cmd17_st
        ld      b,0x00                  ;read data size 256byte
        pop        hl           ;read data buff address
cmd17_r:
        call    resp                    ;read data
        ld      (hl),a
        inc     hl
        djnz    cmd17_r

        ld      b,0x00

cmd17_r2:
        call    resp
        ld      (hl),a                  ;read data
        inc     hl
        djnz    cmd17_r2

        call    resp                    ;crc Skipping read
        call    resp                    ;crc Skipping read
        ld      d,0xff                  ;dummy data 0xff(cs low)
        call    spi_8bit

                ;memory dump address

        ld      bc,0x0200
        sbc     hl,bc
                                ;memory dump 512b
        ld      a,0x0d
        call    putchar

        call    hl_disp256              ;256bye dump 
        call    putchar
        call    hl_disp256              ;256bye dump
        call    putchar
        xor        a
        ret

hl_disp256:
        push    bc
        ld      b,0x00                  ;dump data size 256bye
        push    hl
        ld      hl,dump_msg             ;dump address msg output
        call    msgout
        pop     hl
        ld      a,h                     ;dump address HLreg
        call    hex_a_disp              ;dump address output
        ld      a,l
        call    hex_a_disp
        ld      a," "
        call    putchar
        call    putchar
hl_disp256_loop:
        ld      a,(HL)                  ;dump addres data (HL)
        inc     HL
        call    hex_a_disp
        ld      a,b
        cp      0x01                    ;end dump size?
        jr      z,hl_disp256_loop1
        ld      a,b
        and     0x0f
        cp      0x01                    ;0x?0-0x?f is 0x01(1line disp end?)
        jr      z,hl_disp256_cr
        ld      a," "                   ;space Insert
        call    putchar
        jr      hl_disp256_loop1
hl_disp256_cr:
        ld      a,0x0d
        call    putchar
        ld      a,h                     ;dump address HLreg
        call    hex_a_disp              ;dump address output
        ld      a,l
        call    hex_a_disp
        ld      a," "
        call    putchar
        call    putchar
hl_disp256_loop1:

        djnz    hl_disp256_loop

        ld      a,0x0d
        call    putchar
        pop     bc
        ret

spi_write:

        ld      hl,write_block_no_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,spi_write1
        call    cr
        xor     a
        ret
spi_write1:
        ld      a,(r7)
        bit     6,a
        jp      z,write_SD_ver2
        ld      a,h                   ;SDHC
        ld      (cmd24+03),a
        ld      a,l
        ld      (cmd24+04),a
        jr      spi_write2
write_SD_ver2:                        ;Ver2
        ld      a,h
        ld      (cmd24+02),a
        ld      a,l
        ld      (cmd24+03),a    

spi_write2:
        ld      hl,write_addr_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,cmd24_out
        call    cr
        xor     a
        ret

cmd24_out:       
        call    call_yes_msg
        call    getchar
        cp      "y"
        jp      nz,spi_ret
        push    hl
        call    dummy_data
        ld      hl,cmd24
        call    cmd_out
        call    r1_resp
        cp      0x00
        jp      nz,init_err
        ld      d,0xfe
        call    spi_8bit
        pop     hl
        ld      b,0x00
cmd24_w:
        ld      d,(hl)
        inc     hl
        call    spi_8bit
        djnz    cmd24_w

        ld      b,0x00
cmd24_w2:
        ld      d,(hl)
        inc     hl  
        call    spi_8bit
        djnz    cmd24_w2
        ld      d,0xff
        call    spi_8bit    ;crc
        call    spi_8bit    ;crc
        call    r1_resp
        and     0x0f
        cp      0x05
        jp      nz,init_err
cmd24_wch:
        call    r1_resp
        cp      0x00
        jr      z,cmd24_wch
        call    dummy_data

        ld      bc,0x0200
        sbc     hl,bc

                                ;memory dump 512b
        ld      a,0x0d
        call    putchar

        call    hl_disp256              ;256bye dump 
        call    putchar
        call    hl_disp256              ;256bye dump
        call    putchar
        xor     a
        ret

spi_init:
        ld      hl,spi_init_msg
        call    msgout
        call    call_yes_msg
        call    getchar
        cp      "y"
        jp      nz,spi_ret
        call    cr
        call    spi_card_init
        ld      hl,ok_msg
        call    msgout
        ret

spi_card_init:
        xor     a
        set     S_CS,a          ;CS="H" 
        set     S_DI,a          ;DI="H"
        out0    (OUTPUTP),a
        ld      b,80            ;80 clok output
        call    loopspii

        xor     a
        out     (OUTPUTP),a     ;CS="L" DI="L" CLK="L"

        call    cmd0_out
        cp      0x01
        jp      nz,init_err
        call    cmd8_out
        cp      0x01
        jp      nz,init_err
        call    cmd55_out
        cp      0x01
        jp      nz,init_err
        call    acmd41_out
        call    cmd58_out
        ld      a,(r7)
        bit     7,a
        jp      z,init_err
        bit     6,a
        jr      z,SD_ver2
        ld      hl,sdhc_msg
init_msg:
        call    msgout
        ret
SD_ver2:
        ld      hl,sd_ver2_msg
        jr      init_msg

cmd0_out: 
        ld      hl,cmd0
        call    cmd_out
        call    r1_resp
        push    af
        ld      hl,cmd0_msg
        call    msgout
        pop     af
        push    af
        call    hex_a_disp
        ld      a,0x0d
        call    putchar
        pop     af
        ret
cmd0_msg:
        .str    "CMD0:"
        .db     0x00

cmd8_out:
        call    dummy_data
        ld      hl,cmd8
        call    cmd_out
        call    r1_resp
        cp      0x01
        ret     nz
        ld      b,4
        ld      hl,r7
cmd8_r:
        call    resp
        ld      (hl),a
        inc     hl
        djnz    cmd8_r
cmd8_r_d:
        ld      hl,cmd8_msg
        call    msgout
        ld      a,0x01
        call    hex_a_disp
        ld      hl,r7
        ld      b,4
cmd8_r_d_loop:
        ld      a,(hl)
        call    hex_a_disp
        inc     hl      
        djnz    cmd8_r_d_loop           
        ld      a,0x0d
        call    putchar
        ld      a,0x01
        ret
cmd8_msg:
        .str    "CMD8:"
        .db     0x00

cmd55_out:
        call    dummy_data
        ld      hl,cmd55
        call    cmd_out
        call    r1_resp
        push    af
        ld      hl,cmd55_msg
        call    msgout
        pop     af
        push    af
        call    hex_a_disp
        ld      a,0x0d
        call    putchar
        pop     af
        ret
cmd55_msg:
        .str    "CMD55:"
        .db     0x00

acmd41_out:
        call    dummy_data
        ld      hl,acmd41               ;sd-card Initialize
        call    cmd_out
        call    r1_resp
        cp      0x00
        push    af
        ld      hl,acmd41_msg
        call    msgout
        pop     af
        push    af
        call    hex_a_disp
        ld      a,0x0d
        call    putchar
        pop     af
        ret     z
        call    cmd55_out
        jr      acmd41_out
acmd41_msg:
        .str    "ACMD41:"
        .db     0x00

spi_ret:
        call    cr
        ret

init_err:
        ld      hl,spi_init_err_msg
        call    msgout
        call    cr
        jp      start

cmd58_out:
        call    dummy_data
        ld      hl,cmd58
        call    cmd_out
        call    r1_resp
        push    af
        ld      b,4
        ld      hl,r7
cmd58_r:
        call    resp
        ld      (hl),a
        inc     hl
        djnz    cmd58_r
cmd58_r_d:
        ld      hl,cmd58_msg
        call    msgout
        pop     af
        push    af
        call    hex_a_disp
        ld      hl,r7
        ld      b,4
cmd58_r_d_loop:
        ld      a,(hl)
        call    hex_a_disp
        inc     hl
        djnz    cmd58_r_d_loop
        ld      a,0x0d
        call    putchar
        pop     af
        ret
cmd58_msg:
        .str    "CMD58:"
        .db     0x00

dummy_data:
        xor     a
        set     S_CS,a          ;CS="H"
        set     S_DI,a          ;DI="H"
        out0    (OUTPUTP),a
        ld      b,8            ;1clok output
        call    loopspii
        xor     a
        out0    (OUTPUTP),a
        ret

loopspii:
        res     S_CLK,a         ;CLK    L
        out0    (OUTPUTP),a
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop

        set     S_CLK,a         ;CLK    H
        out0    (OUTPUTP),a
        nop
        nop
        nop
        nop
        nop
        djnz    loopspii
        ret
r1_resp:
        call    resp
        cp      0xff
        jr      z,r1_resp
        ret

resp:
        ld      d,0xff  
        call    spi_8bit
        ld      a,e
        ret

cmd_out:                        ;command out
        push    hl
        push    bc
        ld      b,0x06          ;command line word count
cmd_out1:
        ld      d,(hl)          ;command line area
        call    spi_8bit
        inc     hl
        djnz    cmd_out1
        pop     bc
        pop     hl
        ret

spi_8bit:                       ;outdata Dreg,inputdata Ereg
        push    bc
        ld      c,0x00
        ld      b,0x08        
loopspi:
        xor     a
        rlc     d
        rra
        res     S_CLK,a         ;CLK    L
        out0    (OUTPUTP),a
        nop
        nop
        nop
        nop
        nop
        nop
        set     S_CLK,a         ;CLK    H
        out0    (OUTPUTP),a
        in0     a,(INPUTP)
        rlca
        rl      e
        djnz    loopspi
        xor     a
        out0    (OUTPUTP),a
        pop     bc
        ret

delym:
        push    bc
delyml: call    dely1m
        djnz    delyml
        pop     bc
        ret

dely1m:                                 ;; 1mS dely
        push    bc
        call    dely500u
        call    dely500u
        pop     bc
        ret

dely500u:                               ;; 500uS dely
        push    bc
        ld      b,5
dd5:    call dely100u
        djnz    dd5
        pop     bc
        ret

dely100u:                               ;; 100uS dely
        push    bc
        ld      b,D100U
l100u:  djnz    l100u
        pop     bc
        ret

input_l:                        ;input Lreg hex (1byte)
        push    bc
        ld      b,0x02
        jr      input_loop

input_hl:                       ;input HLreg hex (2byte)
        push    bc
        ld      b,0x04
input_loop:
        ld      hl,0x0000       ;HL reg cler
        jr      input_hl2
shift_hl:
        add     hl,hl           ;HL reg shift left 4bit
        add     hl,hl
        add     hl,hl
        add     hl,hl
input_hl2:
        call    getchar         ;input ascii hex 1char
        call    putchar
        call    ascii_hex       ;ascii hex 1char >> Areg
cp      0xff
jr      z,input_hl_err
and     0x0f            ;Areg low order 4bit >> Lreg
or      l
ld      l,a
djnz    shift_hl
input_hl_end:
pop     bc
xor     a               ;OK >> Areg 0x00
ret
input_hl_err:
ld      a,0xff          ;NG >> Areg 0xff
pop     bc
ret

dump_hl:                        ;memory dump 1line(+0 -- +f)
ld      a,0x0d
call    putchar
push    hl
ld      hl,dump_msg     ;dump address msg output
call    msgout
pop     hl

ld      a,h             ;dump address HLreg
call    hex_a_disp      ;dump address output
ld      a,l
call    hex_a_disp
ld      a," "
call    putchar
call    putchar
ld      b,0x10          ;address --> address +0f
hl_disp:
ld      a,(HL)          ;dump addres data (HL)
inc     HL
call    hex_a_disp
ld      a," "
call    putchar
djnz    hl_disp

ld      a,0x0d
call    putchar
ret

hex_a_disp:                     ;Areg(HEX) >> putchar(areg)
push    af
rrca                    ;7-4bit Right shift
rrca
rrca
rrca
call    hex_ascii       ;3-0bit Hex >> Hex ascii(0-F)
call    putchar         ;7-4bit putchar
pop     af
call    hex_ascii       ;3-0bit Hex >> Hex ascii(0-F)
call    putchar         ;3-0bit putchar
ret

ascii_hex:
sub     0x30
jr      c,err_hex
cp      0x0A            ;0-9
jr      c,hex_1_9
sub     0x11
cp      0x06            ;A-F
jr      c,hex_A_F
sub     0x20
cp      0x06            ;a-f
jr      nc,err_hex
hex_A_F:
add     0x0a
hex_1_9:
ret
err_hex:ld      a,0xff
ret

hex_ascii:                      ;Areg(HEX) >> Areg(ascii code)
and     a,0x0f
cp      0x0a
jr      c,ascii0_9
add     0x37
ret
ascii0_9:
add     0x30
ret

msgout:
ld      a,(hl)          ;(HL)reg is output disp at 0x00
cp      0x00
ret     z
call    putchar
inc     hl
jr      msgout

getchar:in0     a,(STAT0)       ;ch0 serial input
rlca
jr      nc,getchar
in0     a,(RDR0)
;       call    putchar1        ;ch0 serial monitor >> ch1 output
ret

putchar:push    af              ;ch0 seriai output
com_out:in0     a,(STAT0)
bit     1,a
jr      z,com_out
pop     af
out0    (TDR0),a
ret

;getchar1:in0     a,(STAT1)
;        rlca
;        jr      nc,getchar1
;        in0     a,(RDR1)
;        ret
;putchar1:push    af
;com_out1:in0     a,(STAT1)
;        bit     1,a
;        jr      z,com_out1
;        pop     af
;        out0    (TDR1),a
;        ret
com_init:
push    af
ld      a,0x64
out0    (CNTLA0),a
ld      a,0x07
out0    (CNTLB0),a
;        ld      a,0x64
;        out0    (CNTLA1),a
;        ld      a,0x07
;        out0    (CNTLB1),a
pop     af
ret
;
msg_op: .str    "Z180 monitor ver0.73(spi) on UV-EPROM or printf by Pinecone 2018/9/7"
.db     0x0d
.db     0x00
help_msg:
.db     0x0d
.str    "Help menu"
.db     0x0d

.db     0x0d
.str    "?  Help"
.db     0x0d
.str    "d  memory dump"
.db     0x0d
.str    "m  memory change   address old new"
.db     0x0d
.str    "l  hex file load"
.db     0x0d
.str    "j  jump"
.db     0x0d
.str    "i  i/o register    i/o-address old new"
.db     0x0d
.str    "c  call"
.db     0x0d
.str    "t  ram area trance monitor jump"
.db     0x0d
.str  "ai spi(sd-card) Initialization"
.db   0x0d
.str  "ar spi(sd-card) read  (512byte/block)  0x0000-0xffff set"
.db   0x0d
.str  "aw spi(sd-card) write (512byte/block)  0x0000-0xffff set"
.db   0x0d
.db   0x00
dump_msg:
.str    "addr  +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F"
.db     0x0d
.db     0x00
yes_msg:
.str    " Yes:"
.db     0x00
cpu_msg_cbr:
.str    "CBR:"
.db     0x00
cpu_msg_bbr:
.str    " BBR:"
.db     0x00
cpu_msg_cbar:
.str    " CBAR:"
.db     0x00
cpu_msg_clock:
.str    " clock:1/"
.db     0x00
cpu_msg_speed:
.str    " speed:*"
.db     0x00
cpu_msg_wait_m:
.str    " wait memory:"
.db     0x00
cpu_msg_wait_io:
.str    " wait i/o:"
.db     0x00
moni_area_msg:
.str    " monitor area:"
.db     0x00
ok_msg:
.str    "OK"
.db     0x0d
.db     0x00
err_msg:
.str    "ERR"
.db     0x0d
.db     0x00
read_block_no_msg:
.str    " read block No:"
.db     0x00
write_block_no_msg:
.str    " write block No:"
.db     0x00
save_addr_msg:
.str    " save addr:"
.db     0x00
write_addr_msg:
.str    " write addr:"
.db     0x00
spi_init_err_msg:
.str    "Spi Init Err"
.db     0x0d
.db     0x00
sdhc_msg:
.str    ":SDHC"
.db     0x0d
.db     0x00
sd_ver2_msg:
.str    ":SD Ver2"
.db     0x0d
.db     0x00
spi_init_msg:
.str    " spi(sd-card) Initialize :"
.db     0x00

cmd0:                           ;;48bit(6byte) Fixed length
.db     0x40            ;;command index
.db     0x00            ;;argument
.db     0x00            ;;argument
.db     0x00            ;;argument
.db     0x00            ;;argument
.db     0x95            ;;CRC
;cmd1:
;       .db     0x41            ;;command init
;       .db     0x00
;       .db     0x00
;       .db     0x00
;       .db     0x00
;       .db     0xf9            ;;CRC
cmd8:
.db     0x48
.db     0x00
.db     0x00
.db     0x01
.db     0xaa
.db     0x87
acmd41:
.db     0x69
.db     0x40
.db     0xff
.db     0x80
.db     0x00
.db     0xff
cmd58:
.db     0x7a
.db     0x00
.db     0x00
.db     0x00
.db     0x00
.db     0xff

cmd55:
.db     0x77
.db     0x00
.db     0x00
.db     0x00
.db     0x00
.db     0xff

cmd16:
.db     0x50
.db     0x00
.db     0x00
.db     0x00
.db     0x00
.db     0xff
cmd17:
.db     0x51
.db     0x00
.db     0x00
.db     0x00
.db     0x00
.db     0xff

cmd24:
.db     0x58
.db     0x00
.db     0x00
.db     0x00
.db     0x00
.db     0xff

r7:      .ds    4

prog_end:
.end
monitor, Z80, Z8S180の関連記事
  • Z80(TMPZ84C015)に萌えたい。64KRAM化ソフト編その2(モニタ)
  • Z80(TMPZ84C015)に萌えたい。SPI対応モニタ
  • Z80(TMPZ84C015)に萌えたい。モニタの移植
  • Z80(Z8S180)に萌えたい SDCC printf文
  • Z80(Z8S180)に萌えたい モニタROM化
  • Z80に萌えたい 拡張SRAM用モニタ
おすすめの記事
Z8S180
内蔵タイマーの確認を行ってみました。 内蔵タイマーは2チャンネルありますが、ここでは1チャンネルだけでLED 点滅(といっても 20mSの速...
Z80
前回のI/Oポートに SPI接続できるSDカードを接続したいと思います。 SDカード自体が3.3V動作なので、電圧変換が必要になります。 変...