前回に引き続き、ディスク容量拡張を行っていきます。今回はBIOSの変更です。
BIOSの変更を行う前に、拡張したディスク容量の詳細を再度確認してみます。
ディスク数 4 ドライブ(A/B/C/D)
トラック数 128 トラック
セクタ数 64 セクタ
セクタバイト数 128 バイト
ファイル最小単位 2048バイト
システムトラック 0トラック
スキュー なし
では、BIOSの最初の方から確認していきます。
セクタ(ブロック)の計算に必要な、ディスク数、トラック数、セクタ数の定義を更新します。
DISKS_MAX .equ 4 ;max disk
DISK_TRACK .equ 128 ;1 disk>> 128 track
DISK_SECTOR .equ 64 ;1 track>> 64 sector
前回の 「その1」で作成したディスクパラメータを更新します。
;;
;; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
拡張したディスクでは、スキューを使用しないので、sectran:のルーチンでは、ロジカルセクタNo.(BCレジスタ)をそのまま HLレジスタに渡してリターンします。
sectran: ;sector translate
;logical sector > BC
;sector translate teble > de
;return to translate logical 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
与えられたディスクNo.、トラックNo.、セクタNo.からSDCARDのセクタ(ブロックNo.)を計算するルーチンを更新します。
更新前はループで掛け算を行っていましたが、トラック、セクタとも2のn乗としたため、シフトの算術演算で処理できるようになりました。
1ディスクは トラック×セクタで 128*64=8192で16進に直すと 0x2000になります。したがってHLレジスタの上位桁Hレジの0x20にドライブ数をかければいいことになります。逆に言うと、ドライブ数をHレジスタにセットし、0x20倍すればいいことになります。0x20は2進では0b00100000なので、左シフトで6回シフトすればいいのですが、ここでは 0ビットを7ビットに移動させて 3ビット右シフトのrrca命令で、実現しました。ちょっとだけ命令数が少なくなりました。
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
次にトラックも同様にシフト命令で実現します。
トラックは64なので 2進では0x0100000となります。与えられたとトラック数を0x01000000倍すればいいことになります。ここではDEレジスタの上位Dにトラック数を設定し、Dレジスタを右シフトし、キャリーフラグに入れたのち、このキャリーフラグをEレジスタの7ビット目に右シフトします。これを2回繰り返すことで、64倍にしています。
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
セクターはスキューがないため、0から始まるので、セクターの減算はしていません。
read_sector:
ld a,(sector_number)
; dec a
ld e,a
ld d,0x00
add hl,de
最後に、ディスクのスクラッチRAMエリアを更新します。
; 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
アセンブルして、システムをRAM上で立ち上げてみました
>j f200 y: :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>stat *.*
Recs Bytes Ext Acc
64 8k 1 R/W A:ASM.COM
38 6k 1 R/W A:DDT.COM
49 8k 1 R/W A:DISKDEF.LIB
4 2k 1 R/W A:DUMP.COM
52 8k 1 R/W A:ED.COM
14 2k 1 R/W A:LOAD.COM
92 12k 1 R/W A:MAC.COM
58 8k 1 R/W A:PIP.COM
41 6k 1 R/W A:STAT.COM
10 2k 1 R/W A:SUBMIT.COM
6 2k 1 R/W A:XSUB.COM
77 10k 1 R/W A:Z80.LIB
Bytes Remaining On A: 938k
A>b:
B>dir
NO FILE
B>a:stat
A: R/W, Space: 938k
B: R/W, Space: 1012k
B>
1ディスク容量は約1M(1012K)となりました^^
以下に新たなディスク容量に更新したBIOSを展開しました。
;;z80 (TMPZ84C015) 62K cp/m V2.2 BIOS 64sector*128track by Pinecone 2020/05/24
; TMPZ84C015 cpu
; ram 0000h -- ffffh
; External clock 20MHz
; TMPZ84C015 serial communication (CH-B)
; 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 bios304sk0_64_128_3.asm
; $ asz80 -l -s -o bios304sk0_64_128_3.asm
; $ aslink -i bios304sk0_64_128_3
; $ tmpz84_moni71 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
;; TMPZ84C015 serial port SIO-B CH
SIOBD .equ 0x1A ;SIO-B CH DATA REG
SIOBC .equ 0x1B ;SIO-B CH CONTL REG
;; TMPZ84C015 pio port PIO-A CH
PIOAD .equ 0x1c ;PIO-A CH DATA REG
PIOAC .equ 0x1d ;PIO-A CH CONTL REG
;; TMPZ84C015 pio SPI OUT-PORT PIO-A CH
S_DI .equ 7 ;0b10000000 D7
S_CS .equ 6 ;0b01000000 D6
S_CLK .equ 5 ;0b00100000 D5
;; TMPZ84C015 pio SPI INPUT-PORT PIO-A CH
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,(SIOBC)
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,(SIOBC)
bit 0,a
jr z,getchar
in a,(SIOBD)
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,(SIOBC)
bit 2,a
jr z,putchar01
pop af
out (SIOBD),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: ;tmpz84c015 serial siob ch/pio-a ch/spi-init
call siobinit
call pioainit
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 ;write Error countermeasure 2020/06/11
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
siobinit:
ld b,12
ld hl,SIO_init_data
sioainit01:
ld a,(HL)
out (SIOBC),a
inc hl
djnz sioainit01
ret
pioainit:
ld b,3
ld hl,PIO_init_data
pioainit01:
ld a,(HL)
out (PIOAC),a
inc hl
djnz pioainit01
ret
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_data:
.db 0x00,0b00110000 ;WR0=WR0:set ,WR0: err reset
.db 0x01,0b00000000 ;WR0=WR1:set ,WR1: all int reset
.db 0x02,0b00000000 ;WR0=WR2:set ,WR2: CH-B int set
.db 0x03,0b11000001 ;WR0=WR3:set ,WR3: RxBit=8bit Rx=ready
.db 0x04,0b01000100 ;WR0=WR4:set ,WR4: clck=exIN*1 stop=1bit parity=non
.db 0x05,0b11101010 ;WR0=WR5:set ,WR5: char=8bit hardware flow=non Tx=ready
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
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