sdc: implement CRC7 computation on cmds

For now, this achieves nothing else than wasting cycles, but this is the
first step in enabling CRC verifications (CMD59).

I think that this is where my random problems with assembling large
kernels from SDC come from: bad data that isn't detected. If that
happens when PGM loads programs in memory, then anything can happen.

`sdct`, when ran often enough, will error out or corrupt away (go
crazy)...
This commit is contained in:
Virgil Dupras 2019-06-18 14:45:55 -04:00
parent 6516ff7212
commit 34db493496
1 changed files with 34 additions and 15 deletions

View File

@ -142,37 +142,62 @@ sdcWaitReady:
; L: Arg 2 ; L: Arg 2
; D: Arg 3 ; D: Arg 3
; E: Arg 4 (LSB) ; E: Arg 4 (LSB)
; C: CRC
; ;
; Returns R1 response in A. ; Returns R1 response in A.
; ;
; This does *not* handle CS. You have to select/deselect the card outside this ; This does *not* handle CS. You have to select/deselect the card outside this
; routine. ; routine.
sdcCmd: sdcCmd:
push bc
; Wait until ready to receive commands ; Wait until ready to receive commands
push af push af
call sdcWaitResp call sdcWaitResp
pop af pop af
ld c, 0 ; init CRC
call .crc7
call sdcSendRecv call sdcSendRecv
; Arguments ; Arguments
ld a, h ld a, h
call .crc7
call sdcSendRecv call sdcSendRecv
ld a, l ld a, l
call .crc7
call sdcSendRecv call sdcSendRecv
ld a, d ld a, d
call .crc7
call sdcSendRecv call sdcSendRecv
ld a, e ld a, e
call .crc7
call sdcSendRecv call sdcSendRecv
; send CRC ; send CRC
ld a, c ld a, c
; Most of the time, we don't care about C, but in all cases, we want or 0x01 ; ensure stop bit is set
; the last bit to be high. It's the stop bit.
or 0x01
call sdcSendRecv call sdcSendRecv
; And now we just have to wait for a valid response... ; And now we just have to wait for a valid response...
jp sdcWaitResp ; return call sdcWaitResp
pop bc
ret
; push A into C and compute CRC7 with 0x09 polynomial
; Note that the result is "left aligned", that is, that 8th bit to the "right"
; is insignificant (will be stop bit).
.crc7:
push af
xor c
ld b, 8
.loop:
sla a
jr nc, .noCRC
; msb was set, apply polynomial
xor 0x12 ; 0x09 << 1. We apply CRC on high 7 bits
.noCRC:
djnz .loop
ld c, a
pop af
ret
; Send a command that expects a R1 response, handling CS. ; Send a command that expects a R1 response, handling CS.
sdcCmdR1: sdcCmdR1:
@ -191,17 +216,13 @@ sdcCmdR7:
; We have our R1 response in A. Let's try reading the next 4 bytes in ; We have our R1 response in A. Let's try reading the next 4 bytes in
; case we have a R3. ; case we have a R3.
push af push af
ld a, 0xff call sdcIdle
call sdcSendRecv
ld h, a ld h, a
ld a, 0xff call sdcIdle
call sdcSendRecv
ld l, a ld l, a
ld a, 0xff call sdcIdle
call sdcSendRecv
ld d, a ld d, a
ld a, 0xff call sdcIdle
call sdcSendRecv
ld e, a ld e, a
pop af pop af
@ -225,7 +246,6 @@ sdcInitialize:
ld a, 0b01000000 ; CMD0 ld a, 0b01000000 ; CMD0
ld hl, 0 ld hl, 0
ld de, 0 ld de, 0
ld c, 0x95
call sdcCmdR1 call sdcCmdR1
cp 0x01 cp 0x01
jp z, .cmd0ok jp z, .cmd0ok
@ -239,7 +259,6 @@ sdcInitialize:
ld a, 0b01001000 ; CMD8 ld a, 0b01001000 ; CMD8
ld hl, 0 ld hl, 0
ld de, 0x01aa ld de, 0x01aa
ld c, 0x87
call sdcCmdR7 call sdcCmdR7
cp 0x01 cp 0x01
jr nz, .error jr nz, .error