前回で、boot対応のモニタができましたので、早速biosを作成して、CP/Mをブートしたい思います。

CP/Mファイルシステムは、「Z80に萌えたい CP/M ディスク容量拡張その2」を参考に、SDCARDに焼きこみます。
(128トラック/64セクタ/4ドライブ)

次にCP/Mシステムですが、CCP+BDOS+BIOSで構成されBIOSは今回製作します。CCP+BDOSは下記手順で別途入手する必要があります。

以前「Z80(TMPZ84C015)に萌えたい。CPM BIOS編1」で 紹介したサイトの「Digital Research Binary Files」「OPERATING SYSTEMS」から  CP/M 2.2 のCP/M2.2 BINARY をダウンロードします。cpm22-b.zipというファイルでダウロードされますので、解凍します。解凍したフォルダーの中から CPM.SYSというファイルを使用します。
このCPM.SYSというファイルにはCCPとBDOSとBIOSが一緒にパッケージされています。このCPM.SYSのメモリサイズエリアは、62K CP/Mで、ロードアドレスは、0xDC00となっています。
作成したモニタではSYS形式のファイルは読み込めないので、一旦hexファイルに変換します。

HEXコンバートを行うソフトですが今旬なPythonを使うことにします。

Pythonで記述されたIntelHexというライブラリーがあり、その中にオブジェクトをHEXコードに変換する実行コマンドが含まれています。

では早速インストールしたいと思います。(今まで通りRaspberryPiのRaspbianでの環境で確認しています。)

ライブラリのインストール
pythonのパッケージ管理コマンドのpipコマンドでインストールします。
$ sudo pip install intelhex

cpm.sysをHEXファイルに変換します。ロードアドレスは。前述のように0xdc00とします。
コマンド名は bin2hex.py オフセットアドレス、入力ファイル、出力ファイルを順に指定します。ここでは出力ファイル名としてcpm.hexとしました。

$ sudo python /usr/local/bin/bin2hex.py --offset=0xdc00 CPM.SYS cpm.hex

モニタのtコマンドで64Kメモリに切り替えてから、lコマンドで先ほどのcpm.hexを読み込みます。0xdc00以降にccp、bdos、biosと書き込まれます。
ただしbiosは、作成したものを上書きします。

BIOSをアセンブルします。(文末にソース・HEXファイルがあります)
ここでは、ファイル名をZ80_SIO_PIO_bios_sk0_64_128_4.asmとしました。

作成されたZ80_SIO_PIO_bios_sk0_64_128_4.ihxをモニタlコマンドで読み込みbiosを上書きします。

今の状況では、メモリ上でCP/Mシステムが構成されていますが、これをSDCARDのトラック0のシステム領域に書き込みします。

これは書き込みソフトZ80_SIO_PIO_cpm_rw(文末にソース・HEXファイルがあります)を使用します。

Z80_SIO_PIO_cpm_rw.ihxを同じくlコマンドで読み込みます。

jコマンドで 0x8000へジャンプします。
>j 8000 y:

:SDHC
read >> r :write >> w CP/M go >> g key in:

SDCARDにシステム(CCP+BDOS)書き込みします。
wキーでwriteを選択し、0000ブロックから000bブロック、アドレスdc00より書き込み指定し、yキーで書き込み実行します。

read/write start block No:0000
read/write block:000b
read/write addr:dc00
Yes: read/write ok!

続いてBIOSを書き込みます。
000bブロックから 0004ブロック、アドレスf200より書き込みしてします。
>j 8000 y:
:SDHC
read >> r :write >> w CP/M go >> g key in:w
read/write start block No:000b
read/write block:0004
read/write addr:f200
Yes: read/write ok!
>

今度は、モニタのbキーでCP/Mシステムをbootします。

>b
CP/M boot ? yes:
:SDHC
CP/M boot ....

:SDHC



62K CP/M VERS 2.2



A>dir


A: ASM      COM : DDT      COM : DISKDEF  LIB : DUMP     COM

A: ED       COM : LOAD     COM : MAC      COM : PIP      COM

A: STAT     COM : SUBMIT   COM : XSUB     COM : Z80      LIB

A>

ちゃんとブートしたみたいです^^

以下 BIOSのソースとHEXファイルです。その後にZ80_SIO_PIO_cpm_rwのソースとHEXファイルを添付しています。

BIOSのソース

;;z80 (Z80+SIO+PIO) 62K cp/m V2.2 BIOS 64sector*128track by Pinecone 2020/11/19

; Z80 cpu
; ram 0000h -- ffffh
; clock 8MHz

; SIO serial communication A-CH
; extemal Clock 614.4KHz(4.9152MHz TC74HC4040 1/8 Frequency division)
; Band Rate:38400  8bits 1Stopbits none Parity (81N)

; assembler
;  program start 0xF200
;  main          0xF200
;
; assemblers  ASxxxx and ASlink V5.10
; file name Z80_SIO_PIO_bios_sk0_64_128_4.asm
; $ asz80 -l -s -o Z80_SIO_PIO_bios_sk0_64_128_4.asm
; $ aslink -i Z80_SIO_PIO_bios_sk0_64_128_4
; $ Z80_SIO_PIO_moni72 l command Hex load jump 0xf200


	.z80

VERS	.equ	22		;Version 2.2

MSIZE	.equ	62		;CP/M memory size 
	
BIAS	.equ	(MSIZE-20)*1024
CCP	.equ	0x3400 + BIAS	;base of cpm console processor
BDOS	.equ	0x806 +	CCP	;basic dos
BIOS	.equ	CCP + 0x1600	;BIOS
IOBYTE	.equ 	0x0003		;intel i/o byte

cpmboot	.equ	CCP

TRACK_OFFSET	.equ	1	;cp/m used tracks number

;; Z80 SIO
SIOAD	.equ	0x84		;SIO A-CH DATA REG
SIOAC	.equ	0x85		;SIO A-CH CONTL REG
SIOBD	.equ	0x86		;SIO B-CH DATA REG
SIOBC	.equ	0x87		;SIO B-CH CONTL REG

; Z80 PIO 
PIOAD 	.equ 	0x88		;PIO-A PORT DATA REG
PIOAC	.equ	0x89		;PIO-A PORT CONTL REG
PIOBD	.equ	0x8a		;PIO-B PORT DATA REG
PIOBC	.equ	0x8b		;PIO-B PORT CONTL REG

;; Z80-PIO-A   SPI OUT-PORT PIO-C D7-D5 

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

;; Z80-PIO-A   SPI OUT-PORT PIO-C D0

DO 		.equ 0 ;0b00000001 D0

BUFF_DEFAULT_ADDR	.equ	0x80	;default buff address
DISKS_MAX		.equ	4	;max disk
DISK_TRACK		.equ	128	;1 disk>> 128 track
DISK_SECTOR		.equ	64	;1 track>> 64 sector

	.area	BIOS(ABS)

	.org	BIOS


;;	jump vector for indiviual routines
;
	jp	boot		;cold start
wboote:	jp	wboot		;warm start
	jp	const		;console status
	jp	conin		;console character in
	jp	conout		;console character out
	jp	list		;list character out
	jp	punch		;punch character out
	jp	reader		;reader character out
	jp	home		;move head to home position
	jp	seldsk		;select disk
	jp	settrk		;set track number
	jp	setsec		;set sector number
	jp	setdma		;set dma address
	jp	read		;read disk
	jp	write		;write disk
	jp	listst		;return list status
	jp	sectran		;sector translate

;;
;;     Original DISKS  128 track 64 sector 4 disk
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	disk Parameter header for disk 00
dpbase:
DPE0:   .dw      XLT0,0x0000     ;TRANSLATE TABLE
        .dw      0x0000,0x0000   ;SCRATCH AREA
        .dw      DIRBUF,DPB0     ;DIR BUFF,PARM BLOCK
        .dw      CSV0,ALV0       ;CHECK, ALLOC VECTORS
DPE1:   .dw      XLT1,0x0000     ;TRANSLATE TABLE
        .dw      0x0000,0x0000   ;SCRATCH AREA
        .dw      DIRBUF,DPB1     ;DIR BUFF,PARM BLOCK
        .dw      CSV1,ALV1       ;CHECK, ALLOC VECTORS
DPE2:   .dw      XLT2,0x0000     ;TRANSLATE TABLE
        .dw      0x0000,0x0000   ;SCRATCH AREA
        .dw      DIRBUF,DPB2     ;DIR BUFF,PARM BLOCK
        .dw      CSV2,ALV2       ;CHECK, ALLOC VECTORS
DPE3:   .dw      XLT3,0x0000     ;TRANSLATE TABLE
        .dw      0x0000,0x0000   ;SCRATCH AREA
        .dw      DIRBUF,DPB3     ;DIR BUFF,PARM BLOCK
        .dw      CSV3,ALV3       ;CHECK, ALLOC VECTORS
;
;	sector translate vector

;       DISKDEF 0,1,64,,2048,508,128,128,1
dpblk:	;disk parameter block, common to all disks
DPB0:               ;DISK PARM BLOCK
        .dw      64              ;SEC PER TRACK
        .db      4               ;BLOCK SHIFT
        .db      15              ;BLOCK MASK
        .db      0               ;EXTNT MASK
        .dw      507             ;DISK SIZE-1
        .dw      127             ;DIRECTORY MAX
        .db      192             ;ALLOC0
        .db      0               ;ALLOC1
        .dw      32              ;CHECK SIZE
        .dw      1               ;OFFSET

XLT0	.equ	 0	         ;NO XLATE TABLE

DPB1    .equ     DPB0    ;.equIVALENT PARAMETERS
XLT1    .equ     XLT0    ;SAME TRANSLATE TABLE
;;      DISKDEF 2,0
DPB2    .equ     DPB0    ;.equIVALENT PARAMETERS
XLT2    .equ     XLT0    ;SAME TRANSLATE TABLE
;;      DISKDEF 3,0
DPB3    .equ     DPB0    ;.equIVALENT PARAMETERS
XLT3    .equ     XLT0    ;SAME TRANSLATE TABLE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;	disk port and commands
lf	.equ	0x0a
cr	.equ	0x0d

signon:				;signon massage ??K cp/m  ?.?	
	.db	cr,lf,lf
	.db	MSIZE/10+"0",MSIZE % 10 +"0"
	.str	"K CP/M VERS "
	.db	VERS/10+"0",".",VERS % 10 +"0"
	.db	cr,lf,0

boot:
	ld	sp,BUFF_DEFAULT_ADDR + 0x80
	call	init_io
	ld	hl,signon
	call	prmsg
	xor	a
	ld	(disk_number),a
	ld	(old_disk_number),a
	ld	a,0x11
	ld	(IOBYTE),a
	jr	gocpm

wboot:	
	ld	sp,BUFF_DEFAULT_ADDR
					;reading system block (CCP+BDS)
	ld	hl,CCP			
	ld	(read512_addr),hl	;system top addr (CCP)
	ld	hl,0x0000		
	ld	(read512_block_no),hl	;system top sector no. (512byte read)
	ld	hl,0x000b			
	ld	(read512_block),hl	;0x1600(ccp+BDOS) /512byte(sector)
	call	read512			;read system block

gocpm:				;set default buff address to 0x80
	ld	bc,BUFF_DEFAULT_ADDR
	call	setdma

	ld	a,0xc3		;jump wboot address set at 0x0000
	ld	(0x0000),a
	ld	hl,wboote
	ld	(0x0001),hl

	ld	(0x0005),a	;jump BDOS address set at 0x0005
	ld	hl,BDOS
	ld	(0x0006),hl

	ld	a,(disk_number)
	ld	c,a
	jp	cpmboot

prmsg:
	ld	a,(hl)
	cp	0x00		;massage end ?
	ret	z
	ld	c,a
	call	conout
	inc	hl
	jr	prmsg

const:	in     	a,(SIOAC)
	bit	0,a
        jr      z,con_busy			;console status
	ld	a,0xff		;READY= 0xff BUSY=0x00 out Areg
	ret
con_busy:
	ld	a,0x00
	ret

reader:				;reader character out
	ld	a,0x1a
	and	0x7f
	ret

getchar:			
conin:				;console character in
	in     	a,(SIOAC)
	bit	0,a
        jr      z,getchar
	in      a,(SIOAD)
	and	0x7f
	ret		


list:				;list character out
	ld	a,c
	ret
			
punch:				;punch character out
	ld	a,c
	ret
conout:				;console character out
	ld	a,c
	call 	putchar
	ret

putchar:
	push	af
putchar01:
	in      a,(SIOAC)
        bit     2,a
        jr      z,putchar01
	pop	af
        out     (SIOAD),a
	ret
home:	
	ld	c,0x00		;track 00
	call	settrk
	ret
listst:				;return list status
	ld	a,0x00
	ret
sectran:			;sector translate
				;logical sector > BC
				;sector translate teble > de
				;return to translate ogical sector > hl
;	ld	b,0
;	ex	de,hl
;	add	hl,bc
;	ld	a,(hl)
;	ld	(sector_number),a
;	ld	l,a

	ld	h,b
	ld	l,c
	ret
setdma:				;set dma address set bc reg
	ld	h,b
	ld	l,c
	ld	(dma_Buff_addr),hl
	ret
seldsk:				;c reg set disk no
	ld	hl,0x0000	;err set hl=0000 return
	ld	a,c
	cp	DISKS_MAX
	jr	nc,disk_max
	ld	(disk_number),a
	ld	(old_disk_number),a
	ld	l,a
	ld	h,0x00
	add	hl,hl
	add	hl,hl
	add	hl,hl
	add	hl,hl
	ld	de,dpbase
	add	hl,de
	ret
disk_max:			
	ld	a,(old_disk_number)
	ld	(disk_number),a
	ld	hl,0x0000	;err set hl=0000 return
	ret	


settrk:				;set track address given by c
	ld	hl,track_number
	ld	(hl),c
	ret
setsec:				;set sector numbar given by c
	ld	hl,sector_number
	ld	(hl),c
	ret

init_io:			;serial sio a-ch/pio-a ch/spi-init
	call 	sio_init
	call	pio_init
	call    init_spi
	ret

init_spi:
        push    af
        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
        pop     af
        xor     a
        out     (PIOAD),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
	call	set_cs
        ret
SD_ver2:
        ld      hl,sd_ver2_msg
        jr      init_msg

        ret

init_err:
        ld      hl,spi_init_err_msg
        call    msgout
        ld	a,0x0d
        call	putchar
        jp      boot


cmd0_out: 
        ld      hl,cmd0
        call    cmd_out
        call    r1_resp
        ret
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
        ld      a,0x01
        ret

cmd55_out:
        call    dummy_data
        ld      hl,cmd55
        call    cmd_out
        call    r1_resp
        ret

acmd41_out:
        call    dummy_data
        ld      hl,acmd41               ;sd-card Initialize
        call    cmd_out
        call    r1_resp
        cp      0x00
        ret     z
        call    cmd55_out
        jr      acmd41_out

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,r7
        ld      b,4
cmd58_r_d_loop:
        inc     hl
        djnz    cmd58_r_d_loop
        ld      a,0x0d
        call    putchar
        pop     af
        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
        out    (PIOAD),a
        nop
        nop
        nop
        nop
        nop
        nop
	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
	set	S_DI,a		;DI  H
        out    (PIOAD),a
        pop     bc
        ret

get_sector:

;	ld	a,"["
;	call	putchar
;	ld	a,(disk_number)
;	call	hex_a_disp
;	ld	a,","
;	ld	a,(track_number)
;	call	hex_a_disp
;	ld	a,","	
;	ld	a,(sector_number)
;	call	hex_a_disp
;	ld	a,"="	
;	call	putchar


	ld	hl,0x0000
;	ld	de,DISK_TRACK * DISK_SECTOR	;1 disk sector >> DISK_TRACK * DISK_SECTOR
;	ld	a,(disk_number)
;	cp	0x00
;	jr	z,read_track
;	ld	b,a	
;read_disk01:
;	add	hl,de	
;	djnz	read_disk01

					;disk_number * 0x2000(DISK_TRACK * DISK_SECTOR)
	ld	a,(disk_number)
	rrca
	rrca
	rrca
	and	a,0xe0
	ld	h,a
		
read_track:
;	ld	de,DISK_SECTOR		;1 track sector >> DISK_SECTOR
;	ld	a,(track_number)
;	cp	0x00
;	jr	z,read_sector
;	ld	b,a	
;read_track01:
;	add	hl,de	
;	djnz	read_track01	
;
	ld	e,0x00
	ld	a,(track_number)	;track_number * 64		
	ld	d,a
	srl	d
	rr	e
	srl	d
	rr	e
	add	hl,de
read_sector:
	ld	a,(sector_number)
;	dec	a
	ld	e,a
	ld	d,0x00
	add 	hl,de

;	ld	a,h
;	call	hex_a_disp
;	ld	a,l
;	call	hex_a_disp
;	ld	a,"]"
;	call	putchar
	ret

read:				;read next disk record(assuming disk/trk/sec/dma set)
;	ld	a,"R"
;	call	putchar

	call	get_sector		;read block   HL reg

			
        ld      a,(r7)
        bit     6,a
        jp      z,read_SD_ver2
        ld      a,h                    	;SDHC
        ld      (cmd18+03),a
        ld      a,l
        ld      (cmd18+04),a
        jr      spi_read2
read_SD_ver2:
        ld      a,h                    	;Ver2
        ld      (cmd18+02),a
        ld      a,l
        ld      (cmd18+03),a


	ld	hl,(dma_Buff_addr)
spi_read2:

        
        call    dummy_data              ;dummy data(0xff) out
        ld      hl,cmd18
        call    cmd_out                 ;cmd17 Issue
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jr      nz,cmd18_err
cmd18_st:
        ld      d,0xff
        call    spi_8bit


        call    r1_resp                 ;read data start response?
        cp      0xfe                    ;data start byte 0xfe?
        jr nz,  cmd18_st

        ld      b,0x80                  ;read data size 128byte
        ld	hl,(dma_Buff_addr)      ;read data buff address

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

;;	dummy read 128byte 2st 3st 4st

        ld      b,0x80			;read data size 128byte
cmd18_r2st:
        call    resp
        djnz    cmd18_r2st
        ld      b,0x80
cmd18_r3st:
        call    resp
        djnz    cmd18_r3st

        ld      b,0x80
cmd18_r4st:
        call    resp
        djnz    cmd18_r4st

        call    resp                    ;crc Skipping read
        call    resp                    ;crc Skipping read
        ld      d,0xff                  ;dummy data 0xff
        call    spi_8bit


       	ld      hl,cmd12		;stop cmd
        call    cmd_out                 ;cmd12 Issue
	ld	d,0xff
	call	spi_8bit
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jr      nz,cmd18_err

cmd18_wch3:
	call	resp
	cp	0x00
	jr	z,cmd18_wch3

        call	set_cs		          ;CS="H"


;	ld	a,"R"
;	call	putchar
;	ld	a,"o"
;	call	putchar
;	ld	a,"k"
;	call	putchar
;	ld	a,0x0d
;	call	putchar

        xor        a
        ret

cmd18_err:
	call	set_cs		          ;CS="H"
	ld	a,0x01
	ret

read512:
					;read 1sector 512byte
        ld	hl,(read512_block_no)   ;read bolck_no
					
        ld      a,(r7)
        bit     6,a
        jp      z,read512_SD_ver2
        ld      a,h                    	;SDHC
        ld      (cmd18+03),a
        ld      a,l
        ld      (cmd18+04),a
        jr      spi_read512_2
read512_SD_ver2:
        ld      a,h                    	;Ver2
        ld      (cmd18+02),a
        ld      a,l
        ld      (cmd18+03),a

spi_read512_2:
        call    dummy_data              ;dummy data(0xff) out
        ld      hl,cmd18
        call    cmd_out                 ;cmd17 Issue
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jr      nz,cmd18_512_err

sector_read_loop:
cmd18_512_st:
 
        call    r1_resp                 ;read data start response?
        cp      0xfe                    ;data start byte 0xfe?
        jr nz,  cmd18_512_st

 
        ld	hl,(read512_addr)       ;read data buff address
       	ld      b,0x00                  ;read data size 256byte
cmd18_512_r:
        call    resp                    ;read data
        ld      (hl),a
        inc     hl
        djnz    cmd18_512_r

        ld      b,0x00			;2st 256byte write
cmd18_512_r2st:
        call    resp
        ld      (hl),a                  ;read data
        inc     hl
        djnz    cmd18_512_r2st

        ld      (read512_addr),hl

        call    resp                    ;crc Skipping read
        call    resp                    ;crc Skipping read

	ld	hl,(read512_block)
	dec	hl
	ld	(read512_block),hl
	ld	a,h			;HL = 0?
	or	l
	jr	nz,sector_read_loop

        ld      d,0xff                  ;dummy data 0xff(cs low)
        call    spi_8bit

       	ld      hl,cmd12		;stop cmd
        call    cmd_out                 ;cmd12 Issue
	ld	d,0xff
	call	spi_8bit
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jr      nz,cmd18_512_err

cmd18_512_wch3:
	call	resp
	cp	0x00
	jr	z,cmd18_512_wch3

        call	set_cs		        ;CS="H"
        xor    	a
        ret

cmd18_512_err:
	call	set_cs		         ;CS="H"
	ld	a,0x01
	ret


write:
;	ld	a,"W"
;	call	putchar
 
	call	get_sector
 
spi_write1:
        ld      a,(r7)
        bit     6,a
        jp      z,write_SD_ver2
        ld      a,h                   ;SDHC
        ld      (cmd25+03),a
        ld      a,l
        ld      (cmd25+04),a
        jr      spi_write2
write_SD_ver2:                        ;Ver2
        ld      a,h
        ld      (cmd25+02),a
        ld      a,l
        ld      (cmd25+03),a    


spi_write2:
;        call    dummy_data
        ld      hl,cmd25
        call    cmd_out
        call    r1_resp
        cp      0x00
        jp      nz,cmd25_err

        ld      d,0xff
        call    spi_8bit
 
	ld      d,0xfc				;cmd25 data token
        call    spi_8bit

	ld	hl,(dma_Buff_addr)
        ld      b,0x80
cmd25_w:
        ld      d,(hl)
        inc     hl
        call    spi_8bit
        djnz    cmd25_w

;	2st dummy write(0xe5)
 
        ld      b,0x80
cmd25_w2st:
        ld      d,0xe5
        call    spi_8bit
        djnz    cmd25_w2st

;	3st dummy write(0xe5)  
        ld      b,0x80
cmd25_w3st:
        ld      d,0xe5
        call    spi_8bit
        djnz    cmd25_w3st

;	4st dummy write(0xe5)  
        ld      b,0x80
cmd25_w4st:
        ld      d,0xe5
        call    spi_8bit
        djnz    cmd25_w4st

        ld      d,0xff
        call    spi_8bit    ;crc
        ld      d,0xff
        call    spi_8bit    ;crc

        call    r1_resp
        and     0x0f
        cp      0x05
        jr      nz,cmd25_err2
cmd25_wch:
        call    resp
        cp      0x00
        jr      z,cmd25_wch

	ld	d,0xfd			;cmd25 stop token
	call	spi_8bit 	
	ld	d,0xff
	call	spi_8bit
cmd25_wch3:
	call	resp
	cp	0x00
	jr	z,cmd25_wch3

	call	set_cs			;set CS
	call	dummy_data

;	ld	a,"W"
;	call	putchar
;	ld	a,"o"
;	call	putchar
;	ld	a,"k"
;	call	putchar
;	ld	a,0x0d
;	call	putchar

        xor     a
        ret

cmd25_err:
cmd25_err2:
	call	set_cs			;set cs
	ld	a,0x01
	ret

set_cs:
	xor	a
	set     S_CS,a          ;CS="H"
	set	S_DI,a		;DI="H"
	out    (PIOAD),a
        ret

dummy_data:
        xor     a
        set     S_CS,a          ;CS="H"
        set     S_DI,a          ;DI="H"
        out    (PIOAD),a
        ld      b,8            ;1clok output
        call    loopspii
        xor     a
	set     S_CS,a          ;CS="H"	
	set	S_DI,a		;DI="H"
        out    (PIOAD),a
        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

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


hl_disp:
	push	hl
        ld      a,(HL)          ;dump addres data (HL)
        inc     HL
        call    hex_a_disp
        ld      a,(HL)          ;dump addres data (HL) 
        call    hex_a_disp
	pop	hl
        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

hex_ascii:                      ;Areg(HEX) >> Areg(ascii code)  
        and     a,0x0f
        cp      0x0a
        jr      c,ascii0_9
        add     0x37
        ret
ascii0_9:
        add     0x30
        ret
;
sio_init:
	ld	b,0x0b
	ld	c,SIOBC
	ld	hl,SIO_INIT_TB_B
	otir
	ld	b,0x09
	ld	c,SIOAC
	ld	hl,SIO_INIT_TB_A
	otir	
	ret

pio_init:
	;; PIO-A PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOAC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOAC),a
	ld	a,0b00001111	;portA 7-4 output 3-0 input
	out	(PIOAC),a
	ld	a,0b00000111	;int disple
	out	(PIOAC),a
	ld	a,0b11111111	;mask bit
	out	(PIOAC),a

	;; PIO-B PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOBC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOBC),a
	ld	a,0b11111111	;portB 7-0 input
	out	(PIOBC),a
	ld	a,0b00000111	;int disple
	out	(PIOBC),a
	ld	a,0b11111111	;mask bit
	out	(PIOBC),a
	ret	
;

SIO_INIT_TB_A:
	.db	0x18		;ch RESET
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
SIO_INIT_TB_B:
	.db	0x18		;ch RESET
	.db	0x02		;WR2 set
	.db	0x00		;int tabel 0x00
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
;
	
sdhc_msg:
        .str    ":SDHC"
        .db     0x0d
        .db     0x00    
sd_ver2_msg:
        .str    ":SD Ver2"
        .db     0x0d
        .db     0x00
spi_init_err_msg:
        .str    "Spi Init Err"
        .db     0x0d
        .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  
cmd8:
        .db     0x48
        .db     0x00
        .db     0x00
        .db     0x01
        .db     0xaa
        .db     0x87
cmd55:
        .db     0x77
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
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

cmd16:
        .db     0x50
        .db     0x00
        .db     0x00
        .db     0x02
        .db     0x00
        .db     0xff

cmd18:
        .db     0x52
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
cmd12:
        .db     0x4c
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff

cmd25:
        .db     0x59
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff

r7:
        .ds     4 


;	scratch ram area for bdos use
;begdat	equ	$	 	;beginning of data area
DIRBUF: .ds      128     ;DIRECTORY ACCESS BUFFER
ALV0:   .ds      64
CSV0:   .ds      32
ALV1:   .ds      64
CSV1:   .ds      32
ALV2:   .ds      64
CSV2:   .ds      32
ALV3:   .ds      64
CSV3:   .ds      32

dma_Buff_addr:	.dw	BUFF_DEFAULT_ADDR	;dma buff address
sector_number:	.db	0x01			;sector number			
track_number:	.db	TRACK_OFFSET		;track number
disk_number:	.db	0x00			;disk number
old_disk_number:	.dw	0x00		;old disk number
read512_addr:	.dw	0xdc00			;system top addr(512byte read)
read512_block_no: .dw	0x0000			;system top sector no. (512byte read)
read512_block:	.dw	0x000b			;0x1600(ccp+BDOS) /512byte(sector)
	.end

BIOSのHEXファイル

:20F20000C399F2C3B3F2C3F7F2C308F3C317F3C313F3C315F3C303F3C327F3C339F3C35DC8
:20F22000F3C362F3C333F3C3A6F4C3B8F5C32DF3C330F300000000000000005FF773F21F6A
:20F24000F8DFF700000000000000005FF773F27FF83FF800000000000000005FF773F2DFDD
:20F26000F89FF800000000000000005FF773F23FF9FFF84000040F00FB017F00C000200067
:20F2800001000D0A0A36324B2043502F4D205645525320322E320D0A00310001CD67F321C7
:20F2A00082F2CDECF2AF3263F93264F93E1132030018183180002100DC2266F9210000223D
:20F2C00068F9210B00226AF9CD32F5018000CD33F33EC33200002103F222010032050021F0
:20F2E00006E42206003A63F94FC300DC7EFE00C84FCD17F32318F5DB85CB4728033EFFC93B
:20F300003E00C93E1AE67FC9DB85CB4728FADB84E67FC979C979C979CD1CF3C9F5DB85CB7D
:20F320005728FAF1D384C90E00CD5DF3C93E00C96069C96069225FF9C921000079FE0430DE
:20F34000123263F93264F96F2600292929291133F219C93A64F93263F9210000C92162F9A2
:20F3600071C92161F971C9CDB6F6CDC9F6CD71F3C9F5AFCBF7CBFFD3880650CD69F6F1AFF2
:20F38000D388CDCAF3FE01C2BCF3CDD4F3FE01C2BCF3CDF2F3FE01C2BCF3CDFFF3CD13F45F
:20F3A0003A5BF7CB7FCABCF3CB77280A2106F7CD81F6CD4DF6C9210DF718F4C92117F7CD59
:20F3C00081F63E0DCD1CF3C399F22125F7CD4AF4CD3BF4C9CD55F6212BF7CD4AF4CD3BF4D2
:20F3E000FE01C00604215BF7CD43F4772310F93E01C9CD55F62131F7CD4AF4CD3BF4C9CD24
:20F4000055F62137F7CD4AF4CD3BF4FE00C8CDF2F318ECCD55F6213DF7CD4AF4CD3BF4F566
:20F420000604215BF7CD43F4772310F9215BF706042310FD3E0DCD1CF3F1C9CD43F4FEFF19
:20F4400028F9C916FFCD58F47BC9E5C5060656CD58F42310F9C1E1C9C50E000608AFCB0237
:20F460001FCBAFD388000000000000000000000000CBEFD388DB880FCB1310E1AFCBFFD3F6
:20F4800088C1C92100003A63F90F0F0FE6E0671E003A62F957CB3ACB1BCB3ACB1B193A61B5
:20F4A000F95F160019C9CD83F43A5BF7CB77CABBF47C324CF77D324DF7180B7C324BF77DFD
:20F4C000324CF72A5FF9CD55F62149F7CD4AF4CD3BF4FE00205616FFCD58F4CD3BF4FEFE1B
:20F4E00020F406802A5FF9CD43F4772310F90680CD43F410FB0680CD43F410FB0680CD4389
:20F50000F410FBCD43F4CD43F416FFCD58F4214FF7CD4AF416FFCD58F4CD3BF4FE00200CF0
:20F52000CD43F4FE0028F9CD4DF6AFC9CD4DF63E01C92A68F93A5BF7CB77CA47F57C324CAF
:20F54000F77D324DF718087C324BF77D324CF7CD55F62149F7CD4AF4CD3BF4FE002053CD01
:20F560003BF4FEFE20F92A66F90600CD43F4772310F90600CD43F4772310F92266F9CD43D3
:20F58000F4CD43F42A6AF92B226AF97CB520D016FFCD58F4214FF7CD4AF416FFCD58F4CD7A
:20F5A0003BF4FE00200CCD43F4FE0028F9CD4DF6AFC9CD4DF63E01C9CD83F43A5BF7CB771D
:20F5C000CACDF57C3258F77D3259F718087C3257F77D3258F72155F7CD4AF4CD3BF4FE0017
:20F5E000C247F616FFCD58F416FCCD58F42A5FF906805623CD58F410F9068016E5CD58F476
:20F6000010F9068016E5CD58F410F9068016E5CD58F410F916FFCD58F416FFCD58F4CD3B37
:20F62000F4E60FFE052020CD43F4FE0028F916FDCD58F416FFCD58F4CD43F4FE0028F9CD31
:20F640004DF6CD55F6AFC9CD4DF63E01C9AFCBF7CBFFD388C9AFCBF7CBFFD3880608CD6986
:20F66000F6AFCBF7CBFFD388C9CBAFD3880000000000000000CBEFD388000000000010E952
:20F68000C97EFE00C8CD1CF32318F6E57E23CD97F67ECD97F6E1C9F50F0F0F0FCDAAF6CD83
:20F6A0001CF3F1CDAAF6CD1CF3C9E60FFE0A3803C637C9C630C9060B0E8721FBF6EDB3061D
:20F6C000090E8521F2F6EDB3C93E00D3893ECFD3893E0FD3893E07D3893EFFD3893E00D325
:20F6E0008B3ECFD38B3EFFD38B3E07D38B3EFFD38BC918144403C10568110018020014444E
:20F7000003C1056811003A534448430D003A534420566572320D0053706920496E697420E1
:20F720004572720D0040000000009548000001AA877700000000FF6940FF8000FF7A00002D
:1BF740000000FF5000000200FF5200000000FF4C00000000FF5900000000FF6A
:0DF95F008000010100000000DC00000B0032
:00000001FF

Z80_SIO_PIO_cpm_rwのソース

;z80 (Z80+SIO+PIO) cp/m V2.2 system read/write by Pinecone 2020/11/19

; Z80 cpu
; ram 0000h -- ffffh
; clock 8MHz

; SIO serial communication A-CH
; extemal Clock 614.4KHz(4.9152MHz TC74HC4040 1/8 Frequency division)
; Band Rate:38400  8bits 1Stopbits none Parity (81N)
 
; assembler
;  program start 0x8000
;  main          0x8000
;
; assemblers  ASxxxx and ASlink V5.10
; file name Z80_SIO_PIO_cpm_rw.asm
; $ asz80 -l -s -o Z80_SIO_PIO_cpm_rw.asm
; $ aslink -i Z80_SIO_PIO_cpm_rw
; $ Z80_SIO_PIO_moni71 l command Hex load jump 0x8000

	.z80

;; Z80 SIO
SIOAD	.equ	0x84		;SIO A-CH DATA REG
SIOAC	.equ	0x85		;SIO A-CH CONTL REG
SIOBD	.equ	0x86		;SIO B-CH DATA REG
SIOBC	.equ	0x87		;SIO B-CH CONTL REG

; Z80 PIO 
PIOAD 	.equ 	0x88		;PIO-A PORT DATA REG
PIOAC	.equ	0x89		;PIO-A PORT CONTL REG
PIOBD	.equ	0x8a		;PIO-B PORT DATA REG
PIOBC	.equ	0x8b		;PIO-B PORT CONTL REG

;; Z80-PIO-A   SPI OUT-PORT PIO-C D7-D5 

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

;; Z80-PIO-A   SPI OUT-PORT PIO-C D0

DO 		.equ 0 ;0b00000001 D0

	.area	FORMAT(ABS)

	.org	0x8000


; spi read, write. boot
;
;
start:
	call	sio_init
	call	pio_init
	call	init_spi
	ld	hl,rwg_msg
	call	msgout
	call	getchar
	call	putchar
	cp	"r"
	jr	z,read
	cp	"w"
	jr	z,write
	cp	"b"
	jr	z,cpm_boot
	ret
read:
	call	cr
	call	spi_read
	ret
write:
	call	cr
	call	spi_write
	ret

cpm_boot:
	ld	hl,0x0000		;CP/M system block 0x0000 start 
	ld	(rw_block_no),hl
	ld	hl,0x000b		;ccp+bdos >0x0b
	ld	(rw_block),hl
	ld	hl,0xdc00		;62K cp/m ccp top addr >> 0xdc00
	ld	(rw_addr),hl
	call	spi_read_go

	ld	hl,0x000b		;CP/M bios block 0x000b start 
	ld	(rw_block_no),hl
	ld	hl,0x0004		;bios >0x04 
	ld	(rw_block),hl
	ld	hl,0xf200		;62K cp/m bios top addr >> 0xf200
	ld	(rw_addr),hl
	call	spi_read_go

	ld	hl,cpm_boot_msg
	call	msgout

	jp	0xf200
	


init_spi:
        push    af
        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
        pop     af
        xor     a
        out     (PIOAD),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
	call	set_cs
        ret
SD_ver2:
        ld      hl,sd_ver2_msg
        jr      init_msg

init_err:
        ld      hl,spi_init_err_msg
        call    msgout
        ld	a,0x0d
        call	putchar
        jp      0x0000

set_cs:
	xor	a
	set     S_CS,a          ;CS="H"
	set	S_DI,a		;DI="H"
	out    (PIOAD),a
        ret

cmd0_out: 
        ld      hl,cmd0
        call    cmd_out
        call    r1_resp
        ret
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
        ld      a,0x01
        ret

cmd55_out:
        call    dummy_data
        ld      hl,cmd55
        call    cmd_out
        call    r1_resp
        ret

acmd41_out:
        call    dummy_data
        ld      hl,acmd41               ;sd-card Initialize
        call    cmd_out
        call    r1_resp
        cp      0x00
        ret     z
        call    cmd55_out
        jr      acmd41_out

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,r7
        ld      b,4
cmd58_r_d_loop:
        inc     hl
        djnz    cmd58_r_d_loop
        ld      a,0x0d
        call    putchar
        pop     af
        ret

cr:
        ld	a,0x0d
	call	putchar
	ret


spi_read:
	call	data_in
	cp	0x00
	ret	z
        ld      hl,yes_msg
        call    msgout
        call    getchar
	cp	"y"
	ret	nz
	call	spi_read_go
	call	cr
	ret

spi_write:
	call	data_in
	cp	0x00
	ret	z
	ld      hl,yes_msg
        call    msgout
        call    getchar
	cp	"y"
	ret	nz
	call	spi_write_go
	ret
	

data_in:
	call	cr
        ld      hl,rw_sblock_no_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,spi_data_in01
	call	cr 
        xor     a
        ret
spi_data_in01:					;read/write block no
	call	cr 
	ld	(rw_block_no),hl
	ld      hl,rw_block_msg
        call    msgout
        call    input_hl
        cp      0x00
        jr      z,spi_data_in02
        call    cr
        xor     a
        ret

spi_data_in02:
	call	cr
	ld	(rw_block),hl			;read/write block 
        ld      hl,rw_addr_msg
        call    msgout
        call    input_hl
	cp      0x00
        jr	z,spi_data_in03
        call    cr
	xor     a
        ret

spi_data_in03:
	call	cr
	ld	(rw_addr),hl			;read/write addr
	ld	a,0xff
	ret

spi_write_go:

	ld	hl,(rw_block_no)
 
        ld      a,(r7)
        bit     6,a
        jp      z,write_SD_ver2
        ld      a,h                   ;SDHC
        ld      (cmd25+03),a
        ld      a,l
        ld      (cmd25+04),a
        jr      spi_write4
write_SD_ver2:                        ;Ver2
        ld      a,h
        ld      (cmd25+02),a
        ld      a,l
        ld      (cmd25+03),a    


spi_write4: 

        call    dummy_data
        ld      hl,cmd25
        call    cmd_out
        call    r1_resp
        cp      0x00
        jp      nz,cmd25_err

        ld	d,0xff
	call	spi_8bit

sector_write_loop:
	ld	hl,(rw_addr)
	ld      d,0xfc				;cmd25 data token
        call    spi_8bit

;;	spi write 256byte 1st blok

        ld      b,0x00
cmd25_w:					;1st 256byte write
	ld	d,(hl)
	inc	hl
        call    spi_8bit			; D reg >> write data
        djnz    cmd25_w

;	2st write 256byte 1st blok
 
        ld      b,0x00
cmd25_w2st:					;2st 256byte write
	ld	d,(hl)
	inc	hl
        call    spi_8bit		 	; D reg >> write data
        djnz    cmd25_w2st

	ld	(rw_addr),hl

        ld      d,0xff
        call    spi_8bit    ;crc
        ld      d,0xff
        call    spi_8bit    ;crc

        call    r1_resp
        and     0x0f
        cp      0x05
        jr      nz,cmd25_err2

cmd25_wch:
        call    resp
        cp      0x00
        jr      z,cmd25_wch

	ld	d,0xff
	call	spi_8bit

	ld	hl,(rw_block)
	dec	hl

	ld	(rw_block),hl
	ld	a,h			;HL = 0?
	or	l
	jr	nz,sector_write_loop
	

	ld	d,0xfd			;cmd25 stop token
	call	spi_8bit 	
	ld	d,0xff
	call	spi_8bit
cmd25_wch2:
	call	resp
	cp	0x00
	jr	z,cmd25_wch2

	call	dummy_data
	call	set_cs			;set CS
	ld	hl,rw_ok_msg
	call	msgout
	call	cr
	xor	a
	ret

cmd25_err: 
cmd25_err2:
	ld	hl,cmd25_err_msg
	call    msgout
	call	set_cs			;set CS
	ld	a,0x01
	ret




spi_read_go:
	ld	hl,(rw_block_no)
 
        ld      a,(r7)
        bit     6,a
        jp      z,read_SD_ver2
        ld      a,h                   ;SDHC
        ld      (cmd18+03),a
        ld      a,l
        ld      (cmd18+04),a
        jr      spi_read01
read_SD_ver2:                        ;Ver2
        ld      a,h
        ld      (cmd18+02),a
        ld      a,l
        ld      (cmd18+03),a    


spi_read01: 

        call    dummy_data
        ld      hl,cmd18
        call    cmd_out
        call    r1_resp
        cp      0x00
        jp      nz,cmd18_err

sector_read_loop:
cmd18_st:
        call    r1_resp                 ;read data start response?
        cp      0xfe                    ;data start byte 0xfe?
        jr nz,  cmd18_st

	ld	hl,(rw_addr)

        ld      b,0x00
cmd18_r:
	call	resp				;read data
	ld	(hl),a
	inc	hl
        djnz    cmd18_r

;	2st dummy read
 
        ld      b,0x00
cmd18_r2st:					;2st 256byte write
	call	resp
	ld	(hl),a
	inc	hl
        djnz    cmd18_r2st

	ld	(rw_addr),hl

        call    resp                    ;crc Skipping read
        call    resp                    ;crc Skipping read

	ld	hl,(rw_block)
	dec	hl
	ld	(rw_block),hl
	ld	a,h			;HL = 0?
	or	l
	jr	nz,sector_read_loop

        ld      d,0xff                  ;dummy data 0xff(cs low)
        call    spi_8bit


       	ld      hl,cmd12		;stop cmd
        call    cmd_out                 ;cmd12 Issue
	ld	d,0xff
	call	spi_8bit
        call    r1_resp
        cp      0x00                    ;response is 0x00 read mode OK?
        jr      nz,cmd18_err

cmd18_wch:
	call	resp
	cp	0x00
	jr	z,cmd18_wch

	call	set_cs

	xor	a
	ret


;; 1 sector write 


cmd18_err: 
cmd18_err2:
	ld	hl,cmd25_err_msg
	call    msgout
	call	set_cs
	ld	a,0x01
	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

cmd0_msg:
        .str    "CMD0:"
        .db     0x00

dummy_data:
        xor     a
        set     S_CS,a          ;CS="H"
        set     S_DI,a          ;DI="H"
        out    (PIOAD),a
        ld      b,8            ;1clok output
        call    loopspii
        xor     a
	set     S_CS,a          ;CS="H"	
	set	S_DI,a		;DI="H"
        out    (PIOAD),a
        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
	set	S_DI,a		;DI  H
        out    (PIOAD),a
        pop     bc
        ret
msgout:
        ld      a,(hl)          ;(HL)reg is output disp at 0x00
        cp      0x00
        ret     z
        call    putchar
        inc     hl
        jr      msgout

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

hex_ascii:                      ;Areg(HEX) >> Areg(ascii code)  
        and     a,0x0f
        cp      0x0a
        jr      c,ascii0_9
        add     0x37
        ret
ascii0_9:
        add     0x30
        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

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

getchar:			
	in     	a,(SIOAC)
	bit	0,a
        jr      z,getchar
	in      a,(SIOAD)
	ret		

putchar:
	push	af
putchar01:
	in      a,(SIOAC)
        bit     2,a
        jr      z,putchar01
	pop	af
        out     (SIOAD),a
	ret


sio_init:
	ld	b,0x0b
	ld	c,SIOBC
	ld	hl,SIO_INIT_TB_B
	otir
	ld	b,0x09
	ld	c,SIOAC
	ld	hl,SIO_INIT_TB_A
	otir	
	ret

pio_init:
	;; PIO-A PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOAC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOAC),a
	ld	a,0b00001111	;portA 7-4 output 3-0 input
	out	(PIOAC),a
	ld	a,0b00000111	;int disple
	out	(PIOAC),a
	ld	a,0b11111111	;mask bit
	out	(PIOAC),a

	;; PIO-B PORT INIT
	ld	a,0x00		;int bector set
	out	(PIOBC),a
	ld	a,0b11001111	;mode 3 set(bit control)
	out	(PIOBC),a
	ld	a,0b11111111	;portB 7-0 input
	out	(PIOBC),a
	ld	a,0b00000111	;int disple
	out	(PIOBC),a
	ld	a,0b11111111	;mask bit
	out	(PIOBC),a
	ret	
;

SIO_INIT_TB_A:
	.db	0x18		;ch RESET
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
SIO_INIT_TB_B:
	.db	0x18		;ch RESET
	.db	0x02		;WR2 set
	.db	0x00		;int tabel 0x00
	.db	0x14		;WR4 set ,int reset
	.db	0b01000100	;x16 8bitchar 1stopbit nonparity
	.db	0x03		;WR3 set
	.db	0b11000001	;rx 8bit char ,RxEnable
	.db	0x05		;WR5 set
	.db	0b01101000	;tx 8bit char ,TxEnable ,DTR=0 ,RTS=0
	.db	0x11		;WR1 set ,int reset
	.db	0b00000000	;non int
;

sdhc_msg:
        .str    ":SDHC"
        .db     0x0d
        .db     0x00    
sd_ver2_msg:
        .str    ":SD Ver2"
        .db     0x0d
        .db     0x00
spi_init_err_msg:
        .str    "Spi Init Err"
        .db     0x0d
        .db     0x00  
cmd17_err_msg:
        .str    "cmd17 Err"
        .db     0x0d
        .db     0x00  
cmd24_err_msg:
        .str    "cmd24 Err"
        .db     0x0d
        .db     0x00  
cmd25_err_msg:
        .str    "cmd25 Err"
        .db     0x0d
        .db     0x00  
rw_sblock_no_msg:
        .str    " read/write start block No:"
        .db     0x00

rw_block_msg:
        .str    " read/write block:"
        .db     0x00
rw_addr_msg:
        .str    " read/write addr:"
        .db     0x00
yes_msg:
        .str    " Yes:"
        .db     0x00
rw_ok_msg:
        .str    " read/write ok!"
        .db     0x00
rwg_msg:
        .str    " read >> r :write >> w  CP/M boot >> b key in:"
        .db     0x00
cpm_boot_msg:
	.db	0x0d
        .str    " CP/M system boot !"
	.db	0x0d
        .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  
cmd8:
        .db     0x48
        .db     0x00
        .db     0x00
        .db     0x01
        .db     0xaa
        .db     0x87
cmd55:
        .db     0x77
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
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

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
cmd18:
        .db     0x52
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
cmd12:
        .db     0x4c
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
cmd23:
        .db     0x57
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
cmd24:
        .db     0x58
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
cmd25:
        .db     0x59
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0x00
        .db     0xff
r7:
        .ds     4 
rw_block_no:
	.ds	2
rw_block:
	.ds	2
rw_addr:
	.ds	2	

	.end

Z80_SIO_PIO_cpm_rwのHEXファイル

:20800000CDE283CDF583CD638021C984CD6083CDCE83CDD783FE722809FE77280CFE622804
:208020000FC9CD3481CD3A81C9CD3481CD5381C9210000225A85210B00225C852100DC2239
:208040005E85CD5F82210B00225A85210400225C852100F2225E85CD5F8221F884CD608327
:20806000C300F2F5AFCBF7CBFFD3880650CD2383F1AFD388CDC380FE01C2AD80CDCD80FEE6
:2080800001C2AD80CDEB80FE01C2AD80CDF880CD0C813A5685CB7FCAAD80CB77280A21320E
:2080A00084CD6083CDBB80C921398418F4214384CD60833E0DCDD783C30000AFCBF7CBFFC9
:2080C000D388C9210E85CDEC82CDFA82C9CD0F83211485CDEC82CDFA82FE01C0060421569E
:2080E00085CD0283772310F93E01C9CD0F83211A85CDEC82CDFA82C9CD0F83212085CDECB4
:2081000082CDFA82FE00C8CDEB8018ECCD0F83212685CDEC82CDFA82F50604215685CD0219
:2081200083772310F921568506042310FD3E0DCDD783F1C93E0DCDD783C9CD6981FE00C8FF
:2081400021B384CD6083CDCE83FE79C0CD5F82CD3481C9CD6981FE00C821B384CD6083CD77
:20816000CE83FE79C0CDB781C9CD3481217284CD6083CD8E83FE002805CD3481AFC9CD345C
:2081800081225A85218E84CD6083CD8E83FE002805CD3481AFC9CD3481225C8521A184CDDF
:2081A0006083CD8E83FE002805CD3481AFC9CD3481225E853EFFC92A5A853A5685CB77CA22
:2081C000CC817C3253857D32548518087C3252857D325385CD0F83215085CDEC82CDFA823F
:2081E000FE00C2538216FFCD3B832A5E8516FCCD3B8306005623CD3B8310F906005623CD41
:208200003B8310F9225E8516FFCD3B8316FFCD3B83CDFA82E60FFE052039CD0283FE002840
:20822000F916FFCD3B832A5C852B225C857CB520B916FDCD3B8316FFCD3B83CD0283FE00D4
:2082400028F9CD0F83CDBB8021B984CD6083CD3481AFC9216784CD6083CDBB803E01C92A98
:208260005A853A5685CB77CA74827C323B857D323C8518087C323A857D323B85CD0F8321AE
:208280003885CDEC82CDFA82FE00C2E082CDFA82FEFE20F92A5E850600CD0283772310F915
:2082A0000600CD0283772310F9225E85CD0283CD02832A5C852B225C857CB520D016FFCDDE
:2082C0003B83213E85CDEC8216FFCD3B83CDFA82FE00200CCD0283FE0028F9CDBB80AFC9BD
:2082E000216784CD6083CDBB803E01C9E5C5060656CD3B832310F9C1E1C9CD0283FEFF280D
:20830000F9C916FFCD3B837BC9434D44303A00AFCBF7CBFFD3880608CD2383AFCBF7CBFF27
:20832000D388C9CBAFD3880000000000000000CBEFD388000000000010E9C9C50E0006088C
:20834000AFCB021FCBAFD388000000000000CBEFD388DB880FCB1310E7AFCBFFD388C1C9F3
:208360007EFE00C8CDD7832318F6F50F0F0F0FCD7D83CDD783F1CD7D83CDD783C9E60FFE9B
:208380000A3803C637C9C630C9C506021803C50604210000180429292929CDCE83CDD78336
:2083A000CDB483FEFF2809E60FB56F10E9C1AFC93EFFC1C9D6303813FE0A380ED611FE06EF
:2083C0003806D620FE063003C60AC93EFFC9DB85CB4728FADB84C9F5DB85CB5728FAF1D37A
:2083E00084C9060B0E87212784EDB306090E85211E84EDB3C93E00D3893ECFD3893E0FD32D
:20840000893E07D3893EFFD3893E00D38B3ECFD38B3EFFD38B3E07D38B3EFFD38BC91814C4
:208420004403C105681100180200144403C1056811003A534448430D003A5344205665727B
:20844000320D0053706920496E6974204572720D00636D643137204572720D00636D64324F
:2084600034204572720D00636D643235204572720D0020726561642F777269746520737464
:2084800061727420626C6F636B204E6F3A0020726561642F777269746520626C6F636B3AD8
:2084A0000020726561642F777269746520616464723A00205965733A0020726561642F77C4
:2084C00072697465206F6B21002072656164203E3E2072203A7772697465203E3E2077200B
:2084E0002043502F4D20626F6F74203E3E2062206B657920696E3A000D2043502F4D2073F2
:20850000797374656D20626F6F7420210D0040000000009548000001AA877700000000FF42
:208520006940FF8000FF7A00000000FF5000000200FF5100000200FF5200000000FF4C005B
:16854000000000FF5700000000FF5800000000FF5900000000FF21
:00000001FF
コメントを残す

BIOS, CP/M, Z80, Z80+SIO+PIO, Z80-PIO, Z80-SIOの関連記事
  • Z80(KL5C80B12C)に萌えたい。5-BIOS完成
  • Z80(Z80+SIO+PIO)に萌えたい。7-BIOS完成
  • Z80(Z80+8251+8255)に萌えたい。9-BIOS完成
  • Z80に萌えたい CP/M ディスク書き込み改善
  • Z80(Z8S180)に萌えたい。Z8S180でも容量拡張BIOS
  • Z80に萌えたい CP/M ディスクアクセス改善
おすすめの記事
monitor
TMPZ84C015を使用したAKI-80ボードに以前作成したZ8S180用モニタを移植してみました。 移植したZ8S180用モニタは、メモ...
Z8S180
今回実際にi2c通信(出力のみ^^;)できるようにしたいと思います。 接続するのは、キャラクター表示の液晶に接続してみました ソフト的には、...