1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-23 19:28:06 +11:00

parts/z80/sdc: add sdcInitialize

Also, adjust SD card recipe. Straightforward initialization and read!
This commit is contained in:
Virgil Dupras 2019-05-08 16:03:54 -04:00
parent 3d82d7fb30
commit 12ca2bd53e
4 changed files with 108 additions and 71 deletions

View File

@ -131,3 +131,85 @@ sdcCmdR7:
out (SDC_PORT_CSHIGH), a out (SDC_PORT_CSHIGH), a
ret ret
; Initialize a SD card. This should be called at least 1ms after the powering
; up of the card. Sets result code in A. Zero means success, non-zero means
; error.
sdcInitialize:
push hl
push de
push bc
call sdcWakeUp
; Call CMD0 and expect a 0x01 response (card idle)
; This should be called multiple times. We're actually expected to.
; Let's call this for a maximum of 10 times.
ld b, 10
.loop1:
ld a, 0b01000000 ; CMD0
ld hl, 0
ld de, 0
ld c, 0x95
call sdcCmdR1
cp 0x01
jp z, .cmd0ok
djnz .loop1
; Nothing? error
jr .error
.cmd0ok:
; Then comes the CMD8. We send it with a 0x01aa argument and expect
; a 0x01aa argument back, along with a 0x01 R1 response.
ld a, 0b01001000 ; CMD8
ld hl, 0
ld de, 0x01aa
ld c, 0x87
call sdcCmdR7
cp 0x01
jr nz, .error
xor a
cp h ; H is zero
jr nz, .error
cp l ; L is zero
jr nz, .error
ld a, d
cp 0x01
jp nz, .error
ld a, e
cp 0xaa
jr nz, .error
; Now we need to repeatedly run CMD55+CMD41 (0x40000000) until we
; the card goes out of idle mode, that is, when it stops sending us
; 0x01 response and send us 0x00 instead. Any other response means that
; initialization failed.
.loop2:
ld a, 0b01110111 ; CMD55
ld hl, 0
ld de, 0
call sdcCmdR1
cp 0x01
jr nz, .error
ld a, 0b01101001 ; CMD41 (0x40000000)
ld hl, 0x4000
ld de, 0x0000
call sdcCmdR1
cp 0x01
jr z, .loop2
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:
ld a, 0x01
jr .end
.success:
xor a
.end:
pop bc
pop de
pop hl
ret

View File

@ -11,7 +11,7 @@ jr init
; Why not use this unused space between 0x02 and 0x28 for a jump table? ; Why not use this unused space between 0x02 and 0x28 for a jump table?
jp printstr jp printstr
jp printHex jp printHex
jp sdcWakeUp jp sdcInitialize
jp sdcSendRecv jp sdcSendRecv
jp sdcWaitResp jp sdcWaitResp
jp sdcCmd jp sdcCmd
@ -29,6 +29,8 @@ init:
ld sp, hl ld sp, hl
im 1 im 1
call aciaInit call aciaInit
xor a
call blkSel
call shellInit call shellInit
; TODO - block device creation ; TODO - block device creation
@ -43,9 +45,15 @@ ACIA_RAMSTART .equ RAMSTART
.define STDIO_PUTC call aciaPutC .define STDIO_PUTC call aciaPutC
STDIO_RAMSTART .equ ACIA_RAMEND STDIO_RAMSTART .equ ACIA_RAMEND
#include "stdio.asm" #include "stdio.asm"
SHELL_RAMSTART .equ STDIO_RAMEND BLOCKDEV_RAMSTART .equ STDIO_RAMEND
.define SHELL_IO_GETC call aciaGetC BLOCKDEV_COUNT .equ 1
.define SHELL_IO_PUTC call aciaPutC #include "blockdev.asm"
; List of devices
.dw aciaGetC, aciaPutC, 0, 0
SHELL_RAMSTART .equ BLOCKDEV_RAMEND
.define SHELL_IO_GETC call blkGetCW
.define SHELL_IO_PUTC call blkPutC
SHELL_EXTRA_CMD_COUNT .equ 0 SHELL_EXTRA_CMD_COUNT .equ 0
#include "shell.asm" #include "shell.asm"

View File

@ -1,9 +1,9 @@
JUMP_PRINTSTR .equ 0x03 JUMP_PRINTSTR .equ 0x02
JUMP_PRINTHEX .equ 0x06 JUMP_PRINTHEX .equ 0x05
JUMP_SDCWAKEUP .equ 0x09 JUMP_SDCINITALIZE .equ 0x08
JUMP_SDCSENDRECV .equ 0x0c JUMP_SDCSENDRECV .equ 0x0b
JUMP_SDCWAITRESP .equ 0x0f JUMP_SDCWAITRESP .equ 0x0e
JUMP_SDCCMD .equ 0x12 JUMP_SDCCMD .equ 0x11
JUMP_SDCCMDR1 .equ 0x15 JUMP_SDCCMDR1 .equ 0x14
JUMP_SDCCMDR7 .equ 0x18 JUMP_SDCCMDR7 .equ 0x17

View File

@ -1,62 +1,9 @@
#include "jumptable.inc" #include "jumptable.inc"
.org 0x9000 .org 0x9000
call JUMP_SDCWAKEUP call JUMP_SDCINITALIZE
or a
; We expect a 0x01 R1 response
ld hl, sCmd
call JUMP_PRINTSTR
ld a, 0b01000000 ; CMD0
ld hl, 0
ld de, 0
ld c, 0x95
call JUMP_SDCCMDR1
cp 0x01
jp nz, .error jp nz, .error
ld hl, sOk
call JUMP_PRINTSTR
; We expect a 0x01 R1 response followed by 0x0001aa R7 response
ld hl, sCmd
call JUMP_PRINTSTR
ld a, 0b01001000 ; CMD8
ld hl, 0
ld de, 0x01aa
ld c, 0x87
call JUMP_SDCCMDR7
ld a, d
cp 0x01
jp nz, .error
ld a, e
cp 0xaa
jr nz, .error
ld hl, sOk
call JUMP_PRINTSTR
; Now we need to repeatedly run CMD55+CMD41 (0x40000000) until we
; the card goes out of idle mode, that is, when it stops sending us
; 0x01 response and send us 0x00 instead. Any other response means that
; initialization failed.
ld hl, sCmd
call JUMP_PRINTSTR
.loop1:
ld a, 0b01110111 ; CMD55
ld hl, 0
ld de, 0
call JUMP_SDCCMDR1
cp 0x01
jr nz, .error
ld a, 0b01101001 ; CMD41 (0x40000000)
ld hl, 0x4000
ld de, 0x0000
call JUMP_SDCCMDR1
cp 0x01
jr z, .loop1
cp 0
jr nz, .error
; Success! out of idle mode!
ld hl, sOk
call JUMP_PRINTSTR
; Alright, normally we should configure block size and all, but this is ; 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 ; too exciting and we'll play it dirty: we'll read just enough bytes
@ -78,17 +25,17 @@
call JUMP_PRINTSTR call JUMP_PRINTSTR
; Command sent, no error, now let's wait for our data response. ; Command sent, no error, now let's wait for our data response.
ld b, 20 ld b, 20
.loop3: .loop1:
call JUMP_SDCWAITRESP call JUMP_SDCWAITRESP
; 0xfe is the expected data token for CMD17 ; 0xfe is the expected data token for CMD17
cp 0xfe cp 0xfe
jr z, .loop3end jr z, .loop1end
cp 0xff cp 0xff
jr nz, .error jr nz, .error
djnz .loop3 djnz .loop1
jr .error jr .error
.loop3end: .loop1end:
ld hl, sGettingData ld hl, sGettingData
call JUMP_PRINTSTR call JUMP_PRINTSTR
; Data packets follow immediately ; Data packets follow immediately