diff --git a/Source/HBIOS/sd.asm b/Source/HBIOS/sd.asm index 171c62ee..5f93cf38 100644 --- a/Source/HBIOS/sd.asm +++ b/Source/HBIOS/sd.asm @@ -79,6 +79,42 @@ ; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA ; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD ; +;------------------------------------------------------------------------------ +; +; *** HACK FOR MISSING PULLUP RESISTORS *** +; +; THERE IS A RECENT TREND FOR SD ADAPTER BOARDS (SUCH AS THOSE USED TO ATTACH AN +; SD CARD TO AN ARDUINO OR RASPBERRY PI) TO OMIT THE PULLUP RESISTORS THAT ARE SUPPOSED +; TO BE ON ALL LINES. DESPITE BEING A CLEAR VIOLATION OF THE SPEC, IT IS SOMETHING THAT +; WE WILL NOW NEED TO LIVE WITH. THE CLK, CS, AND MOSI SIGNALS ARE NOT AN ISSUE SINCE +; WE ARE DRIVING THOSE SIGNALS AS THE HOST. THE PROBLEM IS WITH THE MISO SIGNAL. +; FORTUNATELY, MOST OF THE TIME, THE SD CARD WILL BE DRIVING THE SIGNAL. HOWEVER, +; THERE ARE TWO SCEANRIOS WE NEED TO ACCOMMODATE IN THE CODE: +; +; 1. MISO WILL NOT BE DRIVEN BY THE SD CARD (FLOATING) PRIOR TO RESETING THE +; CARD WITH CMD0. NORMALLY, A COMMAND SEQUENCE INVOLVES WAITING FOR THE +; CARD TO BE "READY" BY READING BYTES FROM THE CARD AND LOOKING FOR $FF. +; WHEN MISO IS FLOATING THIS WILL NOT BE RELIABLE. SINCE THE SPEC INDICATES +; IT IS NOT NECESSARY TO WAIT FOR READY PRIOR TO CMD0, THE CODE HAS BEEN +; MODIFIED TO ISSUE CMD0 WITHOUT WAITING FOR READY. +; +; 2. MISO MAY NOT BE DRIVEN IMMEDIATELY AFTER SENDING A COMMAND (POSSIBLY +; JUST CMD0, BUT NOT SURE). NORMALLY, AFTER SENDING A COMMAND, YOU +; LOOK FOR "FILL" BYTES OF $FF THAT MAY OCCUR PRIOR TO THE RESULT. WHEN MISO +; IS FLOATING IT IS IMPOSSIBLE TO DETERMINE IF THE BYTE RECEIVED IS A FILL +; BYTE OR NOT. BASED ON WHAT I HAVE READ, THERE WILL ALWAYS BE AT LEAST +; ONE FILL BYTE PRIOR TO THE ACTUAL RESULT. ADDITIONALLY, THE SD CARD WILL +; START DRIVING MISO SOMETIME WITHING THAT FIRST FILL BYTE. SO, WE NOW +; JUST DISCARD THE FIRST BYTE RECEIVED AFTER A COMMAND IS SENT WITH THE +; ASSUMPTION THAT IT MUST BE A FILL BYTE AND IS NOT RELIABLE DUE TO FLOATING +; MISO. +; +; THESE CHANGES ARE CONSISTENT WITH THE POPULAR ARDUINO SDFAT LIBRARY, SO THEY ARE +; PROBABLY PRETTY SAFE. HOWEVER, I HAVE BRACKETED THE CHANGES WITH THE EQUATE BELOW. +; IF YOU WANT TO REVERT THESE HACKS, JUST SET THE EQUATE TO FALSE. +; +SD_NOPULLUP .EQU TRUE ; ASSUME NO PULLUP +; #IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION @@ -1119,6 +1155,7 @@ SD_GOIDLE1: LD A,$95 ; CRC FOR GO_IDLE_STATE COMMAND IS $95 LD (SD_CMDCRC),A ; SET CRC CALL SD_EXECCMDND ; EXECUTE COMMAND W/ NO DATA RETURNED + RET NZ ; ABORT ON ERROR LD A,(SD_RC) ; GET CARD RESULT DEC A ; MAP EXPECTED $01 -> $00 @@ -1171,10 +1208,23 @@ SD_EXECCMD: CALL WRITESTR POP AF #ENDIF - +; + CALL SD_SELECT +; +#IF (SD_NOPULLUP) + ; DO NOT WAIT FOR READY PRIOR TO CMD0! THIS HACK IS REQUIRED BY + ; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE + ; COMMENTS AT TOP OF THIS FILE. + LD A,(SD_CMDBUF) + CP SD_CMD_GO_IDLE_STATE + JR Z,SD_EXECCMD0 +#ENDIF +; ; WAIT FOR CARD TO BE READY CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND JP NZ,SD_ERRRDYTO ; HANDLE TIMEOUT ERROR +; +SD_EXECCMD0: ; SEND THE COMMAND LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER LD E,6 ; COMMANDS ARE 6 BYTES @@ -1184,6 +1234,13 @@ SD_EXECCMD1: INC HL ; POINT TO NEXT BYTE DEC E ; DEC LOOP COUNTER JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES +; +#IF (SD_NOPULLUP) + ; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY + ; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE + ; COMMENTS AT TOP OF THIS FILE. + CALL SD_GET ; GET A BYTE AND DISCARD IT +#ENDIF ; ; GET RESULT LD E,0 ; INIT TIMEOUT LOOP COUNTER @@ -1293,10 +1350,9 @@ SD_PUTDATA3: XOR A RET ; -; SELECT CARD AND WAIT FOR IT TO BE READY ($FF) +; WAIT FOR CARD TO BE READY ($FF). MUST ALREADY BE SELECTED. ; SD_WAITRDY: - CALL SD_SELECT ; SELECT CARD LD DE,$FFFF ; LOOP MAX (TIMEOUT) SD_WAITRDY1: CALL SD_GET