|
|
@ -204,6 +204,21 @@ SD_CNTR .EQU Z180_CNTR |
|
|
SD_TRDR .EQU Z180_TRDR |
|
|
SD_TRDR .EQU Z180_TRDR |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) ; MT shift register for RC2014 (ref SDMODE_CSIO) |
|
|
|
|
|
SD_DEVCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
|
|
SD_OPRREG .EQU %00011110 ; Dedicated base address $1C |
|
|
|
|
|
SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE |
|
|
|
|
|
SD_CD0 .EQU %00000001 ; IN/OUT:SD_OPREG:0 = CD0, PMOD pull CD0 low |
|
|
|
|
|
SD_CD1 .EQU %00000010 ; IN:SD_OPREG:1 = CD1, IN=0 Card detect switch |
|
|
|
|
|
SD_CD2 .EQU %00000100 ; IN:SD_OPREG:2 = CD2, IN=0 Card detect switch |
|
|
|
|
|
SD_CS0 .EQU %00001000 ; IN/OUT:SD_OPREG:3 = CS0, PMOD SPI CS |
|
|
|
|
|
SD_CS1 .EQU %00010000 ; IN/OUT:SD_OPREG:4 = CS1, SDCARD1 CS, IN=1 Card present |
|
|
|
|
|
SD_CS2 .EQU %00100000 ; IN/OUT:SD_OPREG:5 = CS2, SDCARD2 CS, IN=1 Card present |
|
|
|
|
|
SD_WRTR .EQU %00011100 ; Write data and transfer |
|
|
|
|
|
SD_RDTR .EQU %00011101 ; Read data and transfer |
|
|
|
|
|
SD_RDNTR .EQU %00011100 ; Read data and NO transfer |
|
|
|
|
|
#ENDIF |
|
|
|
|
|
; |
|
|
; SD CARD COMMANDS |
|
|
; SD CARD COMMANDS |
|
|
; |
|
|
; |
|
|
SD_CMD_GO_IDLE_STATE .EQU $40 + 0 ; $40, CMD0 -> R1 |
|
|
SD_CMD_GO_IDLE_STATE .EQU $40 + 0 ; $40, CMD0 -> R1 |
|
|
@ -235,7 +250,7 @@ SD_TYPESDXC .EQU 4 ; SDXC CARD (V3) |
|
|
SD_STOK .EQU 0 ; OK |
|
|
SD_STOK .EQU 0 ; OK |
|
|
SD_STINVUNIT .EQU -1 ; INVALID UNIT |
|
|
SD_STINVUNIT .EQU -1 ; INVALID UNIT |
|
|
SD_STRDYTO .EQU -2 ; TIMEOUT WAITING FOR CARD TO BE READY |
|
|
SD_STRDYTO .EQU -2 ; TIMEOUT WAITING FOR CARD TO BE READY |
|
|
SD_STINITTO .EQU -3 ; INITIALIZATOIN TIMEOUT |
|
|
|
|
|
|
|
|
SD_STINITTO .EQU -3 ; INITIALIZATION TIMEOUT |
|
|
SD_STCMDTO .EQU -4 ; TIMEOUT WAITING FOR COMMAND RESPONSE |
|
|
SD_STCMDTO .EQU -4 ; TIMEOUT WAITING FOR COMMAND RESPONSE |
|
|
SD_STCMDERR .EQU -5 ; COMMAND ERROR OCCURRED (REF SD_RC) |
|
|
SD_STCMDERR .EQU -5 ; COMMAND ERROR OCCURRED (REF SD_RC) |
|
|
SD_STDATAERR .EQU -6 ; DATA ERROR OCCURRED (REF SD_TOK) |
|
|
SD_STDATAERR .EQU -6 ; DATA ERROR OCCURRED (REF SD_TOK) |
|
|
@ -393,6 +408,13 @@ SD_INIT: |
|
|
OR SD_OPRDEF ; SET OUR BIT DEFAULTS |
|
|
OR SD_OPRDEF ; SET OUR BIT DEFAULTS |
|
|
LD (RTCVAL),A ; SAVE IT |
|
|
LD (RTCVAL),A ; SAVE IT |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
|
|
|
; |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
PRTS(" MODE=MT$") |
|
|
|
|
|
PRTS(" IO=0x$") |
|
|
|
|
|
LD A,SD_OPRREG |
|
|
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
CALL SD_PROBE ; CHECK FOR HARDWARE |
|
|
CALL SD_PROBE ; CHECK FOR HARDWARE |
|
|
JR Z,SD_INIT00 ; CONTINUE IF PRESENT |
|
|
JR Z,SD_INIT00 ; CONTINUE IF PRESENT |
|
|
@ -553,8 +575,48 @@ SD_PROBE: |
|
|
CP $01 ; SHOULD READ BACK AS $01 |
|
|
CP $01 ; SHOULD READ BACK AS $01 |
|
|
RET ; RETURN W/ ZF SET AS NEEDED |
|
|
RET ; RETURN W/ ZF SET AS NEEDED |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
|
|
|
; |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
LD A,SD_OPRDEF |
|
|
|
|
|
OUT (SD_OPRREG),A ; MAKE SURE CONTROL REGISTER IS CLEARED |
|
|
|
|
|
; TEST WITH PMOD NOT CONNECTED |
|
|
|
|
|
IN A,(SD_OPRREG) |
|
|
|
|
|
AND SD_CD0+SD_CS0 ; ISOLATE CD0 AND CS0 |
|
|
|
|
|
CP SD_CD0+SD_CS0 ; BOTH SHOULD BE HIGH |
|
|
|
|
|
JR NZ,SD_PROBE_FAIL ; FAIL IF NOT |
|
|
|
|
|
; TEST CD0 |
|
|
|
|
|
; LD A,SD_CD0 ; D1=DNP CANNOT TEST |
|
|
|
|
|
; OUT (SD_OPRREG),A |
|
|
|
|
|
; IN A,(SD_OPRREG) |
|
|
|
|
|
; AND SD_CD0 |
|
|
|
|
|
; JR NZ,SD_PROBE_FAIL ; FAIL IF NOT PULLED LOW |
|
|
|
|
|
; TEST CS0 |
|
|
|
|
|
; LD A,SD_CS0 ; D2=DNP CANNOT TEST |
|
|
|
|
|
; OUT (SD_OPRREG),A |
|
|
|
|
|
; IN A,(SD_OPRREG) |
|
|
|
|
|
; AND SD_CS0 |
|
|
|
|
|
; JR NZ,SD_PROBE_FAIL ; FAIL IF NOT PULLED LOW |
|
|
|
|
|
; TEST CS1 |
|
|
|
|
|
LD A,SD_CS1 |
|
|
|
|
|
OUT (SD_OPRREG),A |
|
|
|
|
|
IN A,(SD_OPRREG) |
|
|
|
|
|
AND SD_CS1 |
|
|
|
|
|
JR NZ,SD_PROBE_FAIL ; FAIL IF NOT PULLED LOW |
|
|
|
|
|
; TEST CS2 |
|
|
|
|
|
LD A,SD_CS2 |
|
|
|
|
|
OUT (SD_OPRREG),A |
|
|
|
|
|
IN A,(SD_OPRREG) |
|
|
|
|
|
AND SD_CS2 |
|
|
|
|
|
JR NZ,SD_PROBE_FAIL ; FAIL IF NOT PULLED LOW |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
XOR A ; SIGNAL SUCCESS |
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
|
|
; |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
SD_PROBE_FAIL: |
|
|
|
|
|
LD A,SD_OPRDEF |
|
|
|
|
|
OUT (SD_OPRREG),A ; MAKE SURE CONTROL REGISTER IS CLEARED |
|
|
|
|
|
#ENDIF |
|
|
RET ; AND RETURN |
|
|
RET ; AND RETURN |
|
|
; |
|
|
; |
|
|
;============================================================================= |
|
|
;============================================================================= |
|
|
@ -764,6 +826,13 @@ SD_INITCARD: |
|
|
JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO |
|
|
JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO |
|
|
; |
|
|
; |
|
|
; WAKE UP THE CARD, KEEP DIN HI (ASSERTED) AND /CS HI (DEASSERTED) |
|
|
; WAKE UP THE CARD, KEEP DIN HI (ASSERTED) AND /CS HI (DEASSERTED) |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
LD A,$FF |
|
|
|
|
|
LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) |
|
|
|
|
|
SD_INITCARD1: |
|
|
|
|
|
OUT (SD_WRTR),A ; SEND 8 CLOCKS |
|
|
|
|
|
DJNZ SD_INITCARD1 |
|
|
|
|
|
#ELSE |
|
|
LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) |
|
|
LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) |
|
|
SD_INITCARD1: |
|
|
SD_INITCARD1: |
|
|
LD A,$FF ; KEEP DIN HI |
|
|
LD A,$FF ; KEEP DIN HI |
|
|
@ -771,6 +840,7 @@ SD_INITCARD1: |
|
|
CALL SD_PUT ; SEND 8 CLOCKS |
|
|
CALL SD_PUT ; SEND 8 CLOCKS |
|
|
POP BC ; RESTORE LOOP CONTROL |
|
|
POP BC ; RESTORE LOOP CONTROL |
|
|
DJNZ SD_INITCARD1 ; LOOP AS NEEDED |
|
|
DJNZ SD_INITCARD1 ; LOOP AS NEEDED |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
; PUT CARD IN IDLE STATE |
|
|
; PUT CARD IN IDLE STATE |
|
|
CALL SD_GOIDLE ; GO TO IDLE |
|
|
CALL SD_GOIDLE ; GO TO IDLE |
|
|
@ -801,6 +871,9 @@ SD_INITCARD3: |
|
|
CALL VDELAY ; CPU SPEED NORMALIZED DELAY |
|
|
CALL VDELAY ; CPU SPEED NORMALIZED DELAY |
|
|
; SEND APP CMD INTRODUCER |
|
|
; SEND APP CMD INTRODUCER |
|
|
CALL SD_EXECACMD ; SEND APP COMMAND INTRODUCER |
|
|
CALL SD_EXECACMD ; SEND APP COMMAND INTRODUCER |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
CALL NZ,SD_EXECACMD ; retry any fail |
|
|
|
|
|
#ENDIF |
|
|
CP SD_STCMDERR ; COMMAND ERROR? |
|
|
CP SD_STCMDERR ; COMMAND ERROR? |
|
|
JR Z,SD_INITCARD3A ; IF SO, TRY MMC CARD INIT |
|
|
JR Z,SD_INITCARD3A ; IF SO, TRY MMC CARD INIT |
|
|
OR A ; SET FLAGS |
|
|
OR A ; SET FLAGS |
|
|
@ -859,7 +932,11 @@ SD_INITCARD4: |
|
|
CALL SD_EXECCMD ; EXECUTE COMMAND |
|
|
CALL SD_EXECCMD ; EXECUTE COMMAND |
|
|
RET NZ ; ABORT ON ERROR |
|
|
RET NZ ; ABORT ON ERROR |
|
|
; CMD58 WORKED, GET OCR DATA AND SET CARD TYPE |
|
|
; CMD58 WORKED, GET OCR DATA AND SET CARD TYPE |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
IN A,(SD_RDTR) ; BITS 31-24 |
|
|
|
|
|
#ELSE |
|
|
CALL SD_GET ; BITS 31-24 |
|
|
CALL SD_GET ; BITS 31-24 |
|
|
|
|
|
#ENDIF |
|
|
CALL SD_DONE ; FINISH THE TRANSACTION |
|
|
CALL SD_DONE ; FINISH THE TRANSACTION |
|
|
AND $40 ; ISOLATE BIT 30 (CCS) |
|
|
AND $40 ; ISOLATE BIT 30 (CCS) |
|
|
LD C,SD_TYPESDSC ; ASSUME V1 CARD |
|
|
LD C,SD_TYPESDSC ; ASSUME V1 CARD |
|
|
@ -1222,6 +1299,16 @@ SD_EXECCMD: |
|
|
SD_EXECCMD0: |
|
|
SD_EXECCMD0: |
|
|
; SEND THE COMMAND |
|
|
; SEND THE COMMAND |
|
|
LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER |
|
|
LD HL,SD_CMDBUF ; POINT TO COMMAND BUFFER |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
; OUT (SD_WRTR),A ; SEND IT |
|
|
|
|
|
LD C,SD_WRTR |
|
|
|
|
|
OUTI |
|
|
|
|
|
OUTI |
|
|
|
|
|
OUTI |
|
|
|
|
|
OUTI |
|
|
|
|
|
OUTI |
|
|
|
|
|
OUTI |
|
|
|
|
|
#ELSE |
|
|
LD E,6 ; COMMANDS ARE 6 BYTES |
|
|
LD E,6 ; COMMANDS ARE 6 BYTES |
|
|
SD_EXECCMD1: |
|
|
SD_EXECCMD1: |
|
|
LD A,(HL) ; PREPARE TO SEND NEXT BYTE |
|
|
LD A,(HL) ; PREPARE TO SEND NEXT BYTE |
|
|
@ -1229,15 +1316,35 @@ SD_EXECCMD1: |
|
|
INC HL ; POINT TO NEXT BYTE |
|
|
INC HL ; POINT TO NEXT BYTE |
|
|
DEC E ; DEC LOOP COUNTER |
|
|
DEC E ; DEC LOOP COUNTER |
|
|
JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES |
|
|
JR NZ,SD_EXECCMD1 ; LOOP TILL DONE W/ ALL 6 BYTES |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
#IF (SD_NOPULLUP) |
|
|
#IF (SD_NOPULLUP) |
|
|
; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY |
|
|
; THE FIRST FILL BYTE IS DISCARDED! THIS HACK IS REQUIRED BY |
|
|
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE |
|
|
; STUPID SD CARD ADAPTERS THAT NOW OMIT THE MISO PULL-UP. SEE |
|
|
; COMMENTS AT TOP OF THIS FILE. |
|
|
; COMMENTS AT TOP OF THIS FILE. |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
IN A,(SD_RDTR) ; GET A BYTE AND DISCARD IT |
|
|
|
|
|
#ELSE |
|
|
CALL SD_GET ; GET A BYTE AND DISCARD IT |
|
|
CALL SD_GET ; GET A BYTE AND DISCARD IT |
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
; GET RESULT |
|
|
; GET RESULT |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
; 256 loops might not be long enough timeout |
|
|
|
|
|
; when only IN is required to read data |
|
|
|
|
|
; LD DE,$7FFF ; INIT TIMEOUT LOOP COUNTER |
|
|
|
|
|
LD E,0 ; INIT TIMEOUT LOOP COUNTER |
|
|
|
|
|
SD_EXECCMD2: |
|
|
|
|
|
IN A,(SD_RDTR) ; GET A BYTE FROM THE CARD |
|
|
|
|
|
OR A ; SET FLAGS |
|
|
|
|
|
JP P,SD_EXECCMD3 ; IF HIGH BIT IS 0, WE HAVE RESULT |
|
|
|
|
|
; DEC DE |
|
|
|
|
|
; BIT 7,D |
|
|
|
|
|
; JR Z,SD_EXECCMD2 ; KEEP TRYING UNTIL TIMEOUT |
|
|
|
|
|
DEC E ; OTHERWISE DECREMENT LOOP COUNTER |
|
|
|
|
|
JR NZ,SD_EXECCMD2 ; AND LOOP UNTIL TIMEOUT |
|
|
|
|
|
#ELSE |
|
|
LD E,0 ; INIT TIMEOUT LOOP COUNTER |
|
|
LD E,0 ; INIT TIMEOUT LOOP COUNTER |
|
|
SD_EXECCMD2: |
|
|
SD_EXECCMD2: |
|
|
CALL SD_GET ; GET A BYTE FROM THE CARD |
|
|
CALL SD_GET ; GET A BYTE FROM THE CARD |
|
|
@ -1245,6 +1352,7 @@ SD_EXECCMD2: |
|
|
JP P,SD_EXECCMD3 ; IF HIGH BIT IS 0, WE HAVE RESULT |
|
|
JP P,SD_EXECCMD3 ; IF HIGH BIT IS 0, WE HAVE RESULT |
|
|
DEC E ; OTHERWISE DECREMENT LOOP COUNTER |
|
|
DEC E ; OTHERWISE DECREMENT LOOP COUNTER |
|
|
JR NZ,SD_EXECCMD2 ; AND LOOP UNTIL TIMEOUT |
|
|
JR NZ,SD_EXECCMD2 ; AND LOOP UNTIL TIMEOUT |
|
|
|
|
|
#ENDIF |
|
|
JP SD_ERRCMDTO |
|
|
JP SD_ERRCMDTO |
|
|
; |
|
|
; |
|
|
SD_EXECCMD3: |
|
|
SD_EXECCMD3: |
|
|
@ -1266,6 +1374,44 @@ SD_EXECCMD3: |
|
|
; SD_GETDATA |
|
|
; SD_GETDATA |
|
|
; |
|
|
; |
|
|
SD_GETDATA: |
|
|
SD_GETDATA: |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
|
|
|
SD_GETDATA1: |
|
|
|
|
|
IN A,(SD_RDTR) |
|
|
|
|
|
|
|
|
|
|
|
CP $FF ; WANT BYTE != $FF |
|
|
|
|
|
JR NZ,SD_GETDATA2 ; NOT $FF, MOVE ON |
|
|
|
|
|
DEC DE |
|
|
|
|
|
BIT 7,D |
|
|
|
|
|
JR Z,SD_GETDATA1 ; KEEP TRYING UNTIL TIMEOUT |
|
|
|
|
|
SD_GETDATA2: |
|
|
|
|
|
LD (SD_TOK),A ; SAVE TOKEN VALUE |
|
|
|
|
|
#IF (SDTRACE >= 3) |
|
|
|
|
|
PUSH AF |
|
|
|
|
|
CALL SD_PRTTOK |
|
|
|
|
|
POP AF |
|
|
|
|
|
#ENDIF |
|
|
|
|
|
|
|
|
|
|
|
CP $FE ; PACKET START? |
|
|
|
|
|
JR NZ,SD_GETDATA4 ; NOPE, ABORT, A HAS ERROR CODE |
|
|
|
|
|
|
|
|
|
|
|
LD D,B ; SIZE TO DB |
|
|
|
|
|
LD B,C |
|
|
|
|
|
LD C,(SD_RDTR) |
|
|
|
|
|
|
|
|
|
|
|
INC B |
|
|
|
|
|
DEC B |
|
|
|
|
|
JR Z,SD_GETDATA3 |
|
|
|
|
|
INC D |
|
|
|
|
|
SD_GETDATA3: |
|
|
|
|
|
INIR ; GET BLOCK |
|
|
|
|
|
|
|
|
|
|
|
DEC D |
|
|
|
|
|
JR NZ,SD_GETDATA3 ; LOOP FOR ALL BYTES |
|
|
|
|
|
|
|
|
|
|
|
IN A,(SD_RDTR) ; DISCARD CRC BYTE 1 |
|
|
|
|
|
IN A,(SD_RDTR) ; DISCARD CRC BYTE 2 |
|
|
|
|
|
#ELSE |
|
|
PUSH HL ; SAVE DESTINATION ADDRESS |
|
|
PUSH HL ; SAVE DESTINATION ADDRESS |
|
|
PUSH BC ; SAVE LENGTH TO RECEIVE |
|
|
PUSH BC ; SAVE LENGTH TO RECEIVE |
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
@ -1278,11 +1424,11 @@ SD_GETDATA1: |
|
|
JR Z,SD_GETDATA1 ; KEEP TRYING UNTIL TIMEOUT |
|
|
JR Z,SD_GETDATA1 ; KEEP TRYING UNTIL TIMEOUT |
|
|
SD_GETDATA2: |
|
|
SD_GETDATA2: |
|
|
LD (SD_TOK),A ; SAVE TOKEN VALUE |
|
|
LD (SD_TOK),A ; SAVE TOKEN VALUE |
|
|
#IF (SDTRACE >= 3) |
|
|
|
|
|
|
|
|
#IF (SDTRACE >= 3) |
|
|
PUSH AF |
|
|
PUSH AF |
|
|
CALL SD_PRTTOK |
|
|
CALL SD_PRTTOK |
|
|
POP AF |
|
|
POP AF |
|
|
#ENDIF |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
POP DE ; RESTORE LENGTH TO RECEIVE |
|
|
POP DE ; RESTORE LENGTH TO RECEIVE |
|
|
POP HL ; RECOVER DEST ADDRESS |
|
|
POP HL ; RECOVER DEST ADDRESS |
|
|
CP $FE ; PACKET START? |
|
|
CP $FE ; PACKET START? |
|
|
@ -1297,6 +1443,7 @@ SD_GETDATA3: |
|
|
JR NZ,SD_GETDATA3 ; LOOP FOR ALL BYTES |
|
|
JR NZ,SD_GETDATA3 ; LOOP FOR ALL BYTES |
|
|
CALL SD_GET ; DISCARD CRC BYTE 1 |
|
|
CALL SD_GET ; DISCARD CRC BYTE 1 |
|
|
CALL SD_GET ; DISCARD CRC BYTE 2 |
|
|
CALL SD_GET ; DISCARD CRC BYTE 2 |
|
|
|
|
|
#ENDIF |
|
|
XOR A ; RESULT IS ZERO |
|
|
XOR A ; RESULT IS ZERO |
|
|
SD_GETDATA4: |
|
|
SD_GETDATA4: |
|
|
RET |
|
|
RET |
|
|
@ -1304,6 +1451,32 @@ SD_GETDATA4: |
|
|
; SD_PUTDATA |
|
|
; SD_PUTDATA |
|
|
; |
|
|
; |
|
|
SD_PUTDATA: |
|
|
SD_PUTDATA: |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
LD D,B ; length to DB |
|
|
|
|
|
LD B,C |
|
|
|
|
|
LD A,$FE ; PACKET START |
|
|
|
|
|
OUT (SD_WRTR),A ; SEND IT |
|
|
|
|
|
|
|
|
|
|
|
LD C,SD_WRTR |
|
|
|
|
|
|
|
|
|
|
|
INC B ; IF B!=0 |
|
|
|
|
|
DEC B |
|
|
|
|
|
JR Z,SD_PUTDATA1 |
|
|
|
|
|
INC D ; THEN D=D+1 |
|
|
|
|
|
SD_PUTDATA1: |
|
|
|
|
|
OTIR ; SEND B BYTES |
|
|
|
|
|
|
|
|
|
|
|
DEC D |
|
|
|
|
|
JR NZ,SD_PUTDATA1 ; LOOP FOR ALL BYTES |
|
|
|
|
|
|
|
|
|
|
|
LD A,$FF ; DUMMY CRC BYTE |
|
|
|
|
|
OUT (SD_WRTR),A |
|
|
|
|
|
OUT (SD_WRTR),A ; SEND IT TWICE |
|
|
|
|
|
|
|
|
|
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
|
|
|
SD_PUTDATA2: |
|
|
|
|
|
IN A,(SD_RDTR) |
|
|
|
|
|
#ELSE |
|
|
PUSH HL ; SAVE SOURCE ADDRESS |
|
|
PUSH HL ; SAVE SOURCE ADDRESS |
|
|
PUSH BC ; SAVE LENGTH TO SEND |
|
|
PUSH BC ; SAVE LENGTH TO SEND |
|
|
|
|
|
|
|
|
@ -1327,6 +1500,7 @@ SD_PUTDATA1: |
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
LD DE,$7FFF ; LOOP MAX (TIMEOUT) |
|
|
SD_PUTDATA2: |
|
|
SD_PUTDATA2: |
|
|
CALL SD_GET |
|
|
CALL SD_GET |
|
|
|
|
|
#ENDIF |
|
|
CP $FF ; WANT BYTE != $FF |
|
|
CP $FF ; WANT BYTE != $FF |
|
|
JR NZ,SD_PUTDATA3 ; NOT $FF, MOVE ON |
|
|
JR NZ,SD_PUTDATA3 ; NOT $FF, MOVE ON |
|
|
DEC DE |
|
|
DEC DE |
|
|
@ -1334,11 +1508,11 @@ SD_PUTDATA2: |
|
|
JR Z,SD_PUTDATA2 ; KEEP TRYING UNTIL TIMEOUT |
|
|
JR Z,SD_PUTDATA2 ; KEEP TRYING UNTIL TIMEOUT |
|
|
SD_PUTDATA3: |
|
|
SD_PUTDATA3: |
|
|
LD (SD_TOK),A |
|
|
LD (SD_TOK),A |
|
|
#IF (SDTRACE >= 3) |
|
|
|
|
|
|
|
|
#IF (SDTRACE >= 3) |
|
|
PUSH AF |
|
|
PUSH AF |
|
|
CALL SD_PRTTOK |
|
|
CALL SD_PRTTOK |
|
|
POP AF |
|
|
POP AF |
|
|
#ENDIF |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
AND $1F |
|
|
AND $1F |
|
|
CP $05 |
|
|
CP $05 |
|
|
RET NZ |
|
|
RET NZ |
|
|
@ -1350,7 +1524,11 @@ SD_PUTDATA3: |
|
|
SD_WAITRDY: |
|
|
SD_WAITRDY: |
|
|
LD DE,$FFFF ; LOOP MAX (TIMEOUT) |
|
|
LD DE,$FFFF ; LOOP MAX (TIMEOUT) |
|
|
SD_WAITRDY1: |
|
|
SD_WAITRDY1: |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
IN A,(SD_RDTR) |
|
|
|
|
|
#ELSE |
|
|
CALL SD_GET |
|
|
CALL SD_GET |
|
|
|
|
|
#ENDIF |
|
|
INC A ; $FF -> $00 |
|
|
INC A ; $FF -> $00 |
|
|
RET Z ; IF READY, RETURN |
|
|
RET Z ; IF READY, RETURN |
|
|
DEC DE |
|
|
DEC DE |
|
|
@ -1369,12 +1547,16 @@ SD_WAITRDY1: |
|
|
; IRRELEVANT. IT CAN BE ASSERTED OR DE-ASSERTED. |
|
|
; IRRELEVANT. IT CAN BE ASSERTED OR DE-ASSERTED. |
|
|
; |
|
|
; |
|
|
; NOTE THAT I HAVE FOUND AT LEAST ONE MMC CARD THAT FAILS UNLESS THE CS SIGNAL |
|
|
; NOTE THAT I HAVE FOUND AT LEAST ONE MMC CARD THAT FAILS UNLESS THE CS SIGNAL |
|
|
; REMAINS ACTIVE DURING THE 8 CLOCKS, SO THE CLOCKS ARE SENT BEFORE DESLECTING THE CARD. |
|
|
|
|
|
|
|
|
; REMAINS ACTIVE DURING THE 8 CLOCKS, SO THE CLOCKS ARE SENT BEFORE DESELECTING THE CARD. |
|
|
; |
|
|
; |
|
|
SD_DONE: |
|
|
SD_DONE: |
|
|
PUSH AF |
|
|
PUSH AF |
|
|
LD A,$FF |
|
|
LD A,$FF |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
OUT (SD_WRTR),A |
|
|
|
|
|
#ELSE |
|
|
CALL SD_PUT |
|
|
CALL SD_PUT |
|
|
|
|
|
#ENDIF |
|
|
CALL SD_DESELECT |
|
|
CALL SD_DESELECT |
|
|
POP AF |
|
|
POP AF |
|
|
RET |
|
|
RET |
|
|
@ -1483,7 +1665,26 @@ SD_SELECT2: |
|
|
AND ~SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
AND ~SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ELSE |
|
|
#ELSE |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
IN A,(SD_OPRREG) |
|
|
|
|
|
BIT 0,(IY+SD_DEV) ; DEVICE 0 OR 1 |
|
|
|
|
|
JR NZ,SD_SELECT1 |
|
|
|
|
|
AND SD_CS1 ; DEVICE 0 |
|
|
|
|
|
JR SD_SELECT2 |
|
|
|
|
|
SD_SELECT1: |
|
|
|
|
|
AND SD_CS2 ; DEVICE 1 |
|
|
|
|
|
SD_SELECT2: |
|
|
|
|
|
JR NZ,SD_SELECT3 ; NZ if CS input high |
|
|
|
|
|
POP DE ; return address of call to SD_SELECT |
|
|
|
|
|
POP DE ; return address of call to SD_WAITRDY |
|
|
|
|
|
JR SD_NOMEDIA |
|
|
|
|
|
SD_SELECT3: |
|
|
|
|
|
LD D,A |
|
|
|
|
|
LD A,(SD_OPRVAL) |
|
|
|
|
|
OR D |
|
|
|
|
|
#ELSE |
|
|
OR SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
OR SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
LD (SD_OPRVAL),A |
|
|
LD (SD_OPRVAL),A |
|
|
OUT (SD_OPRREG),A |
|
|
OUT (SD_OPRREG),A |
|
|
@ -1501,7 +1702,11 @@ SD_DESELECT: |
|
|
OR SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
OR SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ELSE |
|
|
#ELSE |
|
|
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
|
|
AND ~(SD_CS1 + SD_CS2) ; RESET SD_CS1 and SD_CS2 (CHIP SELECT) |
|
|
|
|
|
#ELSE |
|
|
AND ~SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
AND ~SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
LD (SD_OPRVAL),A |
|
|
LD (SD_OPRVAL),A |
|
|
OUT (SD_OPRREG),A |
|
|
OUT (SD_OPRREG),A |
|
|
@ -1529,18 +1734,20 @@ SD_WAITRX: |
|
|
; |
|
|
; |
|
|
; SEND ONE BYTE |
|
|
; SEND ONE BYTE |
|
|
; |
|
|
; |
|
|
|
|
|
#IF (SDMODE != SDMODE_MT) ; SDMODE_MT uses "OUT (SD_WRTR),A" |
|
|
|
|
|
; |
|
|
SD_PUT: |
|
|
SD_PUT: |
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) |
|
|
|
|
|
|
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) |
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS, RESULT IN C |
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS, RESULT IN C |
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
OUT0 (SD_TRDR),C ; PUT BYTE IN BUFFER |
|
|
OUT0 (SD_TRDR),C ; PUT BYTE IN BUFFER |
|
|
IN0 A,(SD_CNTR) |
|
|
IN0 A,(SD_CNTR) |
|
|
SET 4,A ; SET TRANSMIT ENABLE |
|
|
SET 4,A ; SET TRANSMIT ENABLE |
|
|
OUT0 (SD_CNTR),A |
|
|
OUT0 (SD_CNTR),A |
|
|
#ELSE |
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
|
|
|
|
|
#ELSE |
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
XOR $FF ; DI IS INVERTED ON UART |
|
|
XOR $FF ; DI IS INVERTED ON UART |
|
|
#ENDIF |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
LD C,A ; C=BYTE TO SEND |
|
|
LD C,A ; C=BYTE TO SEND |
|
|
LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) |
|
|
LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
@ -1556,13 +1763,16 @@ SD_PUT1: |
|
|
DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS |
|
|
DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
OUT (SD_OPRREG),A ; LEAVE WITH CLOCK LOW |
|
|
OUT (SD_OPRREG),A ; LEAVE WITH CLOCK LOW |
|
|
#ENDIF |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
RET ; DONE |
|
|
RET ; DONE |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
; RECEIVE ONE BYTE |
|
|
; RECEIVE ONE BYTE |
|
|
; |
|
|
; |
|
|
|
|
|
#IF (SDMODE != SDMODE_MT) ; SDMODE_MT uses "IN A,(SD_RDTR)" |
|
|
|
|
|
; |
|
|
SD_GET: |
|
|
SD_GET: |
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) |
|
|
|
|
|
|
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC)) |
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
IN0 A,(Z180_CNTR) ; GET CSIO STATUS |
|
|
IN0 A,(Z180_CNTR) ; GET CSIO STATUS |
|
|
SET 5,A ; START RECEIVER |
|
|
SET 5,A ; START RECEIVER |
|
|
@ -1571,38 +1781,39 @@ SD_GET: |
|
|
IN0 A,(Z180_TRDR) ; GET RECEIVED BYTE |
|
|
IN0 A,(Z180_TRDR) ; GET RECEIVED BYTE |
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS |
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS |
|
|
LD A,C ; KEEP RESULT |
|
|
LD A,C ; KEEP RESULT |
|
|
#ELSE |
|
|
|
|
|
|
|
|
#ELSE |
|
|
LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) |
|
|
LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
SD_GET1: |
|
|
SD_GET1: |
|
|
XOR SD_CLK ; TOGGLE CLOCK |
|
|
XOR SD_CLK ; TOGGLE CLOCK |
|
|
OUT (SD_OPRREG),A ; UPDATE CLOCK |
|
|
OUT (SD_OPRREG),A ; UPDATE CLOCK |
|
|
IN A,(SD_INPREG) ; READ THE DATA WHILE CLOCK IS ACTIVE |
|
|
IN A,(SD_INPREG) ; READ THE DATA WHILE CLOCK IS ACTIVE |
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_PPI)) |
|
|
|
|
|
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_PPI)) |
|
|
RLA ; ROTATE INP:7 INTO CF |
|
|
RLA ; ROTATE INP:7 INTO CF |
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_N8) |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_N8) |
|
|
RLA ; ROTATE INP:6 INTO CF |
|
|
RLA ; ROTATE INP:6 INTO CF |
|
|
RLA ; " |
|
|
RLA ; " |
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
RLA ; ROTATE INP:5 INTO CF |
|
|
RLA ; ROTATE INP:5 INTO CF |
|
|
RLA ; " |
|
|
RLA ; " |
|
|
RLA ; " |
|
|
RLA ; " |
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
RRA ; ROTATE INP:0 INTO CF |
|
|
RRA ; ROTATE INP:0 INTO CF |
|
|
#ENDIF |
|
|
|
|
|
|
|
|
#ENDIF |
|
|
RL C ; ROTATE CF INTO C:0 |
|
|
RL C ; ROTATE CF INTO C:0 |
|
|
LD A,(SD_OPRVAL) ; BACK TO INITIAL VALUES (TOGGLE CLOCK) |
|
|
LD A,(SD_OPRVAL) ; BACK TO INITIAL VALUES (TOGGLE CLOCK) |
|
|
OUT (SD_OPRREG),A ; DO IT |
|
|
OUT (SD_OPRREG),A ; DO IT |
|
|
DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS |
|
|
DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS |
|
|
LD A,C ; GET BYTE RECEIVED INTO A |
|
|
LD A,C ; GET BYTE RECEIVED INTO A |
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
XOR $FF ; DO IS INVERTED ON UART |
|
|
XOR $FF ; DO IS INVERTED ON UART |
|
|
|
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
|
|
|
RET |
|
|
RET |
|
|
|
|
|
#ENDIF |
|
|
; |
|
|
; |
|
|
;============================================================================= |
|
|
;============================================================================= |
|
|
; ERROR HANDLING AND DIAGNOSTICS |
|
|
; ERROR HANDLING AND DIAGNOSTICS |
|
|
@ -1657,6 +1868,7 @@ SD_ERR2: |
|
|
CALL SD_PRTSTAT |
|
|
CALL SD_PRTSTAT |
|
|
CALL SD_REGDUMP |
|
|
CALL SD_REGDUMP |
|
|
#ENDIF |
|
|
#ENDIF |
|
|
|
|
|
CALL SD_DESELECT ; De-select if there was an error |
|
|
OR A ; SET FLAGS |
|
|
OR A ; SET FLAGS |
|
|
RET |
|
|
RET |
|
|
; |
|
|
; |
|
|
|