mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-25 16:48:06 +11:00
parts/z80/sdc: add sdcSetBlkSize and sdcReadBlk
This commit is contained in:
parent
12ca2bd53e
commit
54d0286486
@ -20,6 +20,18 @@
|
||||
; SDC_PORT_CSLOW: Port number to make CS low
|
||||
; SDC_PORT_SPI: Port number to send/receive SPI data
|
||||
|
||||
; *** Consts ***
|
||||
.equ SDC_BLKSIZE 512
|
||||
|
||||
; *** Variables ***
|
||||
; Index of the sector currently contained in SDC_BUF
|
||||
.equ SDC_SECTOR SDC_RAMSTART
|
||||
; Whenever we read a sector, we read a whole block at once and we store it
|
||||
; in memory. That's where it goes.
|
||||
.equ SDC_BUF SDC_SECTOR+1
|
||||
.equ SDC_RAMEND SDC_BUF+SDC_BLKSIZE
|
||||
|
||||
; *** Code ***
|
||||
; Wake the SD card up. After power up, a SD card has to receive at least 74
|
||||
; dummy clocks with CS and DI high. We send 80.
|
||||
sdcWakeUp:
|
||||
@ -199,7 +211,6 @@ sdcInitialize:
|
||||
or a ; cp 0
|
||||
jr nz, .error
|
||||
; Success! out of idle mode!
|
||||
; At this point, you are ready to read and write data.
|
||||
jr .success
|
||||
|
||||
.error:
|
||||
@ -213,3 +224,74 @@ sdcInitialize:
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; Send a command to set block size to SDC_BLKSIZE to the SD card.
|
||||
; Returns zero in A if a success, non-zero otherwise
|
||||
sdcSetBlkSize:
|
||||
push hl
|
||||
push de
|
||||
|
||||
ld a, 0b01010000 ; CMD16
|
||||
ld hl, 0
|
||||
ld de, SDC_BLKSIZE
|
||||
call sdcCmdR1
|
||||
; Since we're out of idle mode, we expect a 0 response
|
||||
; We need no further processing: A is already the correct value.
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; Read block index specified in A and place the contents in (SDC_BUF).
|
||||
; Doesn't check CRC.
|
||||
; Returns 0 in A if success, non-zero if error.
|
||||
; Returns SDC_BUF in HL
|
||||
sdcReadBlk:
|
||||
push bc
|
||||
|
||||
out (SDC_PORT_CSLOW), a
|
||||
ld hl, 0 ; read single block at addr A
|
||||
ld d, 0
|
||||
ld e, a
|
||||
ld a, 0b01010001 ; CMD17
|
||||
call sdcCmd
|
||||
or a ; cp 0
|
||||
jr nz, .error
|
||||
|
||||
; Command sent, no error, now let's wait for our data response.
|
||||
ld b, 20
|
||||
.loop1:
|
||||
call sdcWaitResp
|
||||
; 0xfe is the expected data token for CMD17
|
||||
cp 0xfe
|
||||
jr z, .loop1end
|
||||
cp 0xff
|
||||
jr nz, .error
|
||||
djnz .loop1
|
||||
jr .error ; timeout. error out
|
||||
.loop1end:
|
||||
; We received our data token!
|
||||
; Data packets follow immediately, we have 512 of them to read
|
||||
ld bc, SDC_BLKSIZE
|
||||
ld hl, SDC_BUF
|
||||
.loop2:
|
||||
call sdcWaitResp
|
||||
ld (hl), a
|
||||
cpi ; a trick to inc HL and dec BC at the same time.
|
||||
; P/V indicates whether BC reached 0
|
||||
jp pe, .loop2 ; BC is not zero, loop
|
||||
; Read our 2 CRC bytes
|
||||
call sdcWaitResp
|
||||
call sdcWaitResp
|
||||
; success!
|
||||
xor a
|
||||
jr .end
|
||||
.error:
|
||||
; try to preserve error code
|
||||
or a ; cp 0
|
||||
jr nz, .end ; already non-zero
|
||||
inc a ; zero, adjust
|
||||
.end:
|
||||
out (SDC_PORT_CSHIGH), a
|
||||
ld hl, SDC_BUF
|
||||
pop bc
|
||||
ret
|
||||
|
@ -17,6 +17,8 @@ jr init
|
||||
jp sdcCmd
|
||||
jp sdcCmdR1
|
||||
jp sdcCmdR7
|
||||
jp sdcReadBlk
|
||||
jp sdcSetBlkSize
|
||||
|
||||
; interrupt hook
|
||||
.fill 0x38-$
|
||||
@ -57,6 +59,7 @@ SHELL_RAMSTART .equ BLOCKDEV_RAMEND
|
||||
SHELL_EXTRA_CMD_COUNT .equ 0
|
||||
#include "shell.asm"
|
||||
|
||||
.equ SDC_RAMSTART SHELL_RAMEND
|
||||
.equ SDC_PORT_CSHIGH 6
|
||||
.equ SDC_PORT_CSLOW 5
|
||||
.equ SDC_PORT_SPI 4
|
||||
|
@ -6,4 +6,6 @@ JUMP_SDCWAITRESP .equ 0x0e
|
||||
JUMP_SDCCMD .equ 0x11
|
||||
JUMP_SDCCMDR1 .equ 0x14
|
||||
JUMP_SDCCMDR7 .equ 0x17
|
||||
JUMP_SDCREAD .equ 0x1a
|
||||
JUMP_SDCSETBLKSIZE .equ 0x1d
|
||||
|
||||
|
@ -5,51 +5,30 @@
|
||||
or a
|
||||
jp nz, .error
|
||||
|
||||
; Alright, normally we should configure block size and all, but this is
|
||||
; too exciting and we'll play it dirty: we'll read just enough bytes
|
||||
; to fetch our "Hello World!" and print it and we'll leave the SD card
|
||||
; hanging. Yeah, I know, not very polite.
|
||||
|
||||
|
||||
out (5), a
|
||||
ld hl, sCmd
|
||||
ld hl, sOk
|
||||
call JUMP_PRINTSTR
|
||||
ld a, 0b01010001 ; CMD17
|
||||
ld hl, 0 ; read single block at addr 0
|
||||
ld de, 0
|
||||
call JUMP_SDCCMD
|
||||
cp 0
|
||||
jr nz, .error
|
||||
|
||||
ld hl, sCmd
|
||||
call JUMP_PRINTSTR
|
||||
; Command sent, no error, now let's wait for our data response.
|
||||
ld b, 20
|
||||
.loop1:
|
||||
call JUMP_SDCWAITRESP
|
||||
; 0xfe is the expected data token for CMD17
|
||||
cp 0xfe
|
||||
jr z, .loop1end
|
||||
cp 0xff
|
||||
jr nz, .error
|
||||
djnz .loop1
|
||||
jr .error
|
||||
call JUMP_SDCSETBLKSIZE
|
||||
or a
|
||||
jp nz, .error
|
||||
|
||||
.loop1end:
|
||||
ld hl, sGettingData
|
||||
ld hl, sOk
|
||||
call JUMP_PRINTSTR
|
||||
; Data packets follow immediately
|
||||
ld b, 12 ; size of "Hello World!"
|
||||
ld hl, sDest ; sDest has null chars, we'll be alright
|
||||
; printing it.
|
||||
.loop2:
|
||||
call JUMP_SDCWAITRESP
|
||||
ld (hl), a
|
||||
inc hl
|
||||
djnz .loop2
|
||||
out (6), a
|
||||
ld hl, sDest
|
||||
|
||||
; read sector 0
|
||||
xor a
|
||||
call JUMP_SDCREAD
|
||||
or a
|
||||
jp nz, .error
|
||||
|
||||
push hl
|
||||
ld hl, sOk
|
||||
call JUMP_PRINTSTR
|
||||
pop hl
|
||||
; SDC buffer address is in HL
|
||||
; YOLO! print it!
|
||||
call JUMP_PRINTSTR
|
||||
|
||||
ret
|
||||
.error:
|
||||
call JUMP_PRINTHEX
|
||||
@ -57,14 +36,7 @@
|
||||
call JUMP_PRINTSTR
|
||||
ret
|
||||
|
||||
sCmd:
|
||||
.db "CMD", 0xa, 0xd, 0
|
||||
sGettingData:
|
||||
.db "Data", 0xa, 0xd, 0
|
||||
sOk:
|
||||
.db "Ok", 0xa, 0xd, 0
|
||||
sErr:
|
||||
.db "Err", 0xa, 0xd, 0
|
||||
|
||||
sDest:
|
||||
.fill 0x10
|
||||
|
Loading…
Reference in New Issue
Block a user