前回で回路が完成しましたので、以前作成したZ8S180用のSPIでのSDCARDのアクセスソフトについてTNPZ84C015用に修正していきたいと思います。
まずはPIOAの入出力の設定ですが、D7~D5までが出力設定、D4-D0までが入力に設定します。
PIOAD .equ 0x1c ;PIO-A CH DATA REG
PIOAC .equ 0x1d ;PIO-A CH CONTL REG
;OUTPUT-PORT
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;INPUT-PORT
DO .equ 0 ;0b00000001 D0
PIOAの初期化は次のようになります。
pioainit:
ld b,3
ld hl,PIO_init_data
pioainit01:
ld a,(HL)
out (PIOAC),a
inc hl
djnz pioainit01
ret
PIO_init_data:
.db 0b11001111 ;PIOAC:set 0xcf: Mode3 (bit mode)
.db 0b00011111 ;PIOAC:set 0x1f: D4-D0=input D7-D5=output
.db 0b00000000 ;PIOAC:set 0x00: interrupt disables
PIOAを通じて、SDCARDに対して、クロックを送り出すソフトが必要になりますが、ハードと直接制御するプログラムは次のようになります。
loopspii:
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
nop
nop
nop
nop
nop
djnz loopspii
ret
実際のタイミングは次のようになります。
デューティー約5μS(システムクロック20MHz時)となりました。

さらにクロックに同期して、DI端子に対してデータを出力し、かつDO端子からデータを読み書きするプログラムは次のようになります。
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
out (PIOAD),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
in a,(PIOAD)
rrca
rl e
djnz loopspi
xor a
out (PIOAD),a
pop bc
ret
こちらも波形を見るとデューティー50%になっていませんが、読み書きはできるようです。(データとして0x40を出力し、返り値として0xffが帰っています)

SDCARDの初期化としては、80パルスのクロックを出した後に、cmd0(0x40,0x00,0x00,0x00,0x00,0x95)の48bitのデータを出力し、返り値として0x01が帰ってくれば第一段階の初期化は終わりです。
main:
call pioainit
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,80 ;80 clok output
call loopspii
xor a
out (PIOAD),a ;CS="L" DI="L" CLK="L"
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
cp 0x01
jr nz,init_err
ret
init_err:
halt
cmd0: ;;48bit(6byte) Fixed length
.db 0x40 ;;command index
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x00 ;;argument
.db 0x95 ;;CRC
返り値(0x01)のタイミングは次のようなります。

全体的なプログラムは次のようになります。
;; TMPZ84C015 SPI (Parallel port) test (port A)
;;
;;
;; i/o address
;; PIOAD i/o 0x1C(r/w)
;; PIOAC i/o 0x1D(w)
;; PIOBD i/o 0x1E(r/w)
;; PIOBC i/o 0x1F(w)
;;
;;
;; assembler
;; program a000H
;; data a000H
;; assemblers ASxxxx and ASlink V5.10
;; tmpz84c015_spi_sdcard01.asm
;; $ asz80 -l -s -o tmpz84c015_spi_sdcard01.asm
;; $ aslink -i tmpz84c015_spi_sdcard01
;; $ monitor L command loedding ihx files at c(call) command a000
.z80
PIOAD .equ 0x1c ;PIO-A CH DATA REG
PIOAC .equ 0x1d ;PIO-A CH CONTL REG
;OUTPUT-PORT
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;INPUT-PORT
DO .equ 0 ;0b00000001 D0
.area TEST(ABS)
.org 0xa000
main:
call pioainit
xor a
set S_CS,a ;CS="H"
set S_DI,a ;DI="H"
out (PIOAD),a
ld b,80 ;80 clok output
call loopspii
xor a
out (PIOAD),a ;CS="L" DI="L" CLK="L"
cmd0_out:
ld hl,cmd0
call cmd_out
call r1_resp
cp 0x01
jr nz,init_err
ret
init_err:
halt
pioainit:
ld b,3
ld hl,PIO_init_data
pioainit01:
ld a,(HL)
out (PIOAC),a
inc hl
djnz pioainit01
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
r1_resp:
call resp
cp 0xff
jr z,r1_resp
ret
resp:
ld d,0xff
call spi_8bit
ld a,e
ret
loopspii:
res S_CLK,a ;CLK L
out (PIOAD),a
nop
nop
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
nop
nop
nop
nop
nop
djnz loopspii
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
out (PIOAD),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out (PIOAD),a
in a,(PIOAD)
rrca
rl e
djnz loopspi
xor a
out (PIOAD),a
pop bc
ret
PIO_init_data:
.db 0b11001111 ;PIOAC:set 0xcf: Mode3 (bit mode)
.db 0b00011111 ;PIOAC:set 0x1f: D4-D0=input D7-D5=output
.db 0b00000000 ;PIOAC:set 0x00: interrupt disables
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 0x02
.db 0x00
.db 0xff
cmd17:
.db 0x51
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
cmd24:
.db 0x58
.db 0x00
.db 0x00
.db 0x02
.db 0x00
.db 0xff
全体的なタイミングは次のようになります。
