|
|
|
@ -1,37 +1,27 @@ |
|
|
|
; |
|
|
|
; |
|
|
|
;============================================================================= |
|
|
|
; SD/SDHC/SDXC CARD STORAGE DRIVER |
|
|
|
;============================================================================= |
|
|
|
; |
|
|
|
; - CATER FOR THE VARIOUS SDCARD HARDWARE VERSIONS |
|
|
|
; CSIO IS FOR N8-2312 PRODUCTION BOARDS AND MODIFIED N8-2511 PROTOTYPE BOARDS |
|
|
|
; RTC IS FOR UNMODIFIED N8-2511 BOARDS AND N8VEM/ZETA USING JUHA MINI-BOARDS |
|
|
|
; PPISD IS FOR A PPISD MINI-BOARD CONNECTED TO 26-PIN PPI HEADER |
|
|
|
; - MAKE RTC A PSEUDO-REGISTER FOR NON-CSIO |
|
|
|
; - PERFORM BOOT INITIALIZATION OF RTC SOMEWHERE ELSE??? |
|
|
|
; - PUT RELEVANT RTC BITS TO A KNOWN STATE AT ALL I/O ENTRY POINTS |
|
|
|
; |
|
|
|
; |
|
|
|
;---------------------------------------------------------------------- |
|
|
|
; SD Signal Act JUHA N8 CSIO PPI UART DSD |
|
|
|
; SD Signal Active JUHA N8 CSIO PPI UART DSD |
|
|
|
; ------------ ------- ------- ------- ------- ------- ------- ------- |
|
|
|
; CS (DAT3) LO -> RTC:2 RTC:2 RTC:2 ~PC:4 MCR:3 OPS:2 |
|
|
|
; CLK HI -> RTC:1 RTC:1 N/A PC:1 ~MCR:2 OPS:1 |
|
|
|
; DI (CMD) HI -> RTC:0 RTC:0 N/A PC:0 ~MCR:0 OPS:0 |
|
|
|
; DO (DAT0) HI -> RTC:7 RTC:6 N/A PB:7 ~MSR:5 OPS:0 |
|
|
|
; CS (DAT3) LO -> RTC:2 RTC:2 RTC:2 ~PC:4 MCR:3 OPR:2 |
|
|
|
; CLK HI -> RTC:1 RTC:1 N/A PC:1 ~MCR:2 OPR:1 |
|
|
|
; DI (CMD) HI -> RTC:0 RTC:0 N/A PC:0 ~MCR:0 OPR:0 |
|
|
|
; DO (DAT0) HI -> RTC:7 RTC:6 N/A PB:7 ~MSR:5 OPR:0 |
|
|
|
;---------------------------------------------------------------------- |
|
|
|
; |
|
|
|
; CS = CHIP SELECT (AKA DAT3 FOR NON-SPI MODE) |
|
|
|
; CLK = CLOCK |
|
|
|
; DI = DATA IN (HOST -> CARD, AKA CMD FOR NON-SPI MODE) |
|
|
|
; DO = DATA OUT (CARD -> HOST, AKA: DAT0 FOR NON-SPI MODE) |
|
|
|
; DO = DATA OUT (HOST <- CARD, AKA DAT0 FOR NON-SPI MODE) |
|
|
|
; |
|
|
|
; NOTES: |
|
|
|
; 1) SIGNAL NAMES ARE FROM THE SD CARD SPEC AND ARE NAMED FROM THE |
|
|
|
; PERSPECTIVE OF THE SD CARD: |
|
|
|
; DI = DATA IN: HOST -> CARD = MOSI (MASTER OUT/SLAVE IN) |
|
|
|
; DO = DATA OUT: CARD -> HOST (MASTER IN/SLAVE OUT) |
|
|
|
; DO = DATA OUT: HOST <- CARD = MISO (MASTER IN/SLAVE OUT) |
|
|
|
; |
|
|
|
; 2) THE QUIESCENT STATE OF THE OUTPUT SIGNALS (HOST -> CARD) IS: |
|
|
|
; CS = HI (NOT SELECTED) |
|
|
|
@ -46,11 +36,12 @@ |
|
|
|
; TRANSITION AND PROPAGATED ON HIGH-TO-LOW CLOCK TRANSITION. |
|
|
|
; |
|
|
|
; 4) DI SHOULD BE LEFT HI (ACTIVE) WHENEVER UNUSED (FOR EXAMPLE, WHEN |
|
|
|
; HOST IS RECEIVING DATA (CARD -> HOST)). |
|
|
|
; HOST IS RECEIVING DATA (HOST <- CARD)). |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD |
|
|
|
SD_OPSREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPSDEF .EQU %00000001 ; QUIESCENT STATE??? |
|
|
|
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? |
|
|
|
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC |
|
|
|
SD_CS .EQU %00000100 ; RTC:2 IS SELECT |
|
|
|
SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK |
|
|
|
@ -59,8 +50,9 @@ SD_DO .EQU %10000000 ; RTC:7 IS DATA OUT (CARD -> CPU) |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_N8) ; UNMODIFIED N8-2511 |
|
|
|
SD_OPSREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPSDEF .EQU %00000001 ; QUIESCENT STATE??? |
|
|
|
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE??? |
|
|
|
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC |
|
|
|
SD_CS .EQU %00000100 ; RTC:2 IS SELECT |
|
|
|
SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK |
|
|
|
@ -69,20 +61,22 @@ SD_DO .EQU %01000000 ; RTC:6 IS DATA OUT (CARD -> CPU) |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_CSIO) ; N8-2312 |
|
|
|
SD_OPSREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPSDEF .EQU %00000000 ; QUIESCENT STATE |
|
|
|
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION |
|
|
|
SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE |
|
|
|
SD_CS .EQU %00000100 ; RTC:2 IS SELECT |
|
|
|
SD_CNTR .EQU CPU_CNTR |
|
|
|
SD_TRDR .EQU CPU_TRDR |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_PPI) ; PPISD |
|
|
|
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_PPIBASE .EQU PPIBASE ; BASE IO PORT FOR PPI |
|
|
|
SD_PPIB .EQU PPIBASE + 1 ; PPI PORT B (INPUT: DOUT) |
|
|
|
SD_PPIC .EQU PPIBASE + 2 ; PPI PORT C (OUTPUT: CS, CLK, DIN) |
|
|
|
SD_PPIX .EQU PPIBASE + 3 ; PPI CONTROL PORT |
|
|
|
SD_OPSREG .EQU SD_PPIC ; PPI PORT C IS OPS REG |
|
|
|
SD_OPSDEF .EQU %00110001 ; CS HI, DI HI |
|
|
|
SD_OPRREG .EQU SD_PPIC ; PPI PORT C IS OPR REG |
|
|
|
SD_OPRDEF .EQU %00110001 ; CS HI, DI HI |
|
|
|
SD_INPREG .EQU SD_PPIB ; INPUT REGISTER IS PPI PORT B |
|
|
|
SD_CS .EQU %00010000 ; PPIC:4 IS SELECT |
|
|
|
SD_CLK .EQU %00000010 ; PPIC:1 IS CLOCK |
|
|
|
@ -91,6 +85,7 @@ SD_DO .EQU %10000000 ; PPIB:7 IS DATA OUT (CARD -> CPU) |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_MCR .EQU SIO_MCR ; UART MCR PORT (OUTPUT: CS, CLK, DIN) |
|
|
|
SD_MSR .EQU SIO_MSR ; UART MSR PORT (INPUT: DOUT) |
|
|
|
SD_CS .EQU %00001000 ; UART MCR:3 IS SELECT |
|
|
|
@ -100,10 +95,11 @@ SD_DO .EQU %00100000 ; UART MSR:5 IS DATA OUT (CARD -> CPU) |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_DSD) ; DUAL SD |
|
|
|
SD_OPSREG .EQU $08 ; DEDICATED OPERATIONS REGISTER |
|
|
|
SD_OPSDEF .EQU %00000001 ; QUIESCENT STATE |
|
|
|
SD_INPREG .EQU SD_OPSREG ; INPUT REGISTER IS OPSREG |
|
|
|
SD_SELREG .EQU SD_OPSREG + 1 ; DEDICATED SELECTION REGISTER |
|
|
|
SD_UNITCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRREG .EQU $08 ; DEDICATED OPERATIONS REGISTER |
|
|
|
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE |
|
|
|
SD_INPREG .EQU SD_OPRREG ; INPUT REGISTER IS OPRREG |
|
|
|
SD_SELREG .EQU SD_OPRREG + 1 ; DEDICATED SELECTION REGISTER |
|
|
|
SD_SELDEF .EQU %00000000 ; SELECTION REGISTER DEFAULT |
|
|
|
SD_CS .EQU %00000100 ; RTC:2 IS SELECT |
|
|
|
SD_CLK .EQU %00000010 ; RTC:1 IS CLOCK |
|
|
|
@ -144,6 +140,8 @@ SD_STCMDERR .EQU -5 ; COMMAND ERROR OCCURRED (REF SD_RC) |
|
|
|
SD_STDATAERR .EQU -6 ; DATA ERROR OCCURRED (REF SD_TOK) |
|
|
|
SD_STDATATO .EQU -7 ; DATA TRANSFER TIMEOUT |
|
|
|
SD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET |
|
|
|
SD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR |
|
|
|
SD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
@ -162,6 +160,8 @@ SD_DISPATCH: |
|
|
|
; |
|
|
|
; |
|
|
|
SD_MEDIA: |
|
|
|
CALL SD_SELUNIT |
|
|
|
; |
|
|
|
; INITIALIZE THE SD CARD TO ACCOMMODATE HOT SWAPPING |
|
|
|
CALL SD_INITCARD |
|
|
|
LD A,MID_HD ; ASSUME SUCCESS |
|
|
|
@ -172,20 +172,21 @@ SD_MEDIA: |
|
|
|
; |
|
|
|
SD_INIT: |
|
|
|
PRTS("SD:$") |
|
|
|
PRTS(" UNITS=$") |
|
|
|
LD A,SD_UNITCNT |
|
|
|
CALL PRTHEXBYTE |
|
|
|
#IF (SDMODE == SDMODE_JUHA) |
|
|
|
PRTS(" MODE=JUHA$") |
|
|
|
PRTS(" IO=0x$") |
|
|
|
LD A,SD_OPSREG |
|
|
|
LD A,SD_OPRREG |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_N8) |
|
|
|
PRTS(" MODE=N8$") |
|
|
|
PRTS(" IO=0x$") |
|
|
|
LD A,SD_OPSREG |
|
|
|
LD A,SD_OPRREG |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_CSIO) |
|
|
|
@ -194,7 +195,7 @@ SD_INIT: |
|
|
|
PRTS(" FAST$") |
|
|
|
#ENDIF |
|
|
|
PRTS(" IO=0x$") |
|
|
|
LD A,SD_OPSREG |
|
|
|
LD A,SD_OPRREG |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" CNTR=0x$") |
|
|
|
LD A,SD_CNTR |
|
|
|
@ -202,7 +203,6 @@ SD_INIT: |
|
|
|
PRTS(" TRDR=0x$") |
|
|
|
LD A,SD_TRDR |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_PPI) |
|
|
|
@ -210,7 +210,6 @@ SD_INIT: |
|
|
|
PRTS(" BASEIO=0x$") |
|
|
|
LD A,SD_PPIBASE |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
@ -221,36 +220,50 @@ SD_INIT: |
|
|
|
PRTS(" MSR=0x$") |
|
|
|
LD A,SD_MSR |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
PRTS(" MODE=DSD$") |
|
|
|
PRTS(" OPS=0x$") |
|
|
|
LD A,SD_OPSREG |
|
|
|
PRTS(" OPR=0x$") |
|
|
|
LD A,SD_OPRREG |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" SEL=0x$") |
|
|
|
LD A,SD_SELREG |
|
|
|
CALL PRTHEXBYTE |
|
|
|
PRTS(" UNITS=1$") |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
LD A,SD_STNOTRDY |
|
|
|
LD (SD_STAT),A |
|
|
|
LD HL,SD_STATLST |
|
|
|
LD (SD_STATPTR),HL |
|
|
|
LD (HL),A |
|
|
|
INC HL |
|
|
|
LD (HL),A |
|
|
|
LD A,SD_TYPEUNK |
|
|
|
LD HL,SD_TYPELST |
|
|
|
LD (SD_TYPEPTR),HL |
|
|
|
LD (HL),A |
|
|
|
INC HL |
|
|
|
LD (HL),A |
|
|
|
RET |
|
|
|
; |
|
|
|
SD_STATUS: |
|
|
|
LD A,(SD_STAT) |
|
|
|
CALL SD_SELUNIT |
|
|
|
LD HL,(SD_STATPTR) |
|
|
|
LD A,(HL) |
|
|
|
OR A |
|
|
|
RET |
|
|
|
; |
|
|
|
SD_READ: |
|
|
|
CALL SD_SELUNIT |
|
|
|
CALL SD_RDSEC |
|
|
|
JR SD_PRT |
|
|
|
; |
|
|
|
SD_WRITE: |
|
|
|
CALL SD_WRSEC |
|
|
|
JP SD_PRT |
|
|
|
CALL SD_SELUNIT |
|
|
|
CALL SD_CHKWP |
|
|
|
CALL NZ,SD_WRTPROT |
|
|
|
CALL Z,SD_WRSEC |
|
|
|
JR SD_PRT |
|
|
|
; |
|
|
|
SD_PRT: |
|
|
|
#IF (SDTRACE >= 1) |
|
|
|
@ -267,34 +280,55 @@ SD_PRT: |
|
|
|
; SD HARDWARE INTERFACE ROUTINES |
|
|
|
;============================================================================= |
|
|
|
; |
|
|
|
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT |
|
|
|
; |
|
|
|
SD_SELUNIT: |
|
|
|
LD A,C |
|
|
|
AND 0FH ; ISOLATE THE UNIT NIBBLE |
|
|
|
CP SD_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?) |
|
|
|
CALL NC,PANIC ; PANIC ON INVALID VALUE |
|
|
|
LD (SD_UNIT),A ; SAVE CURRENT UNIT NUM |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
; SELECT REQUESTED UNIT |
|
|
|
OUT (SD_SELREG),A ; ACTUALLY SELECT THE CARD |
|
|
|
#ENDIF |
|
|
|
LD HL,SD_STATLST ; POINT TO START OF STATUS LIST |
|
|
|
LD D,0 ; SETUP DE TO HAVE OFFSET |
|
|
|
LD E,A ; FOR CURRENT UNIT |
|
|
|
ADD HL,DE ; APPLY THE OFFSET |
|
|
|
LD (SD_STATPTR),HL ; SAVE IT |
|
|
|
LD HL,SD_TYPELST ; POINT TO START OF CARD TYPE LIST |
|
|
|
ADD HL,DE ; APPLY THE OFFSET |
|
|
|
LD (SD_TYPEPTR),HL ; SAVE IT |
|
|
|
RET |
|
|
|
; |
|
|
|
; PERFORM HARDWARE SPECIFIC INITIALIZATION |
|
|
|
; |
|
|
|
SD_SETUP: |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_N8)) |
|
|
|
LD A,SD_OPSDEF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD A,SD_OPRDEF |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_CSIO) |
|
|
|
; CSIO SETUP |
|
|
|
; LD A,02 ; 18MHz/20 <= 400kHz |
|
|
|
LD A,06 ; ??? |
|
|
|
; LD A,2 ; 18MHz/20 <= 400kHz |
|
|
|
LD A,6 ; ??? |
|
|
|
OUT0 (SD_CNTR),A |
|
|
|
LD A,SD_OPSDEF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD A,SD_OPRDEF |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_PPI) |
|
|
|
LD A,82H ; PPI PORT A=OUT, B=IN, C=OUT |
|
|
|
OUT (PPIX),A |
|
|
|
;LD A,30H ; PC4,5 /CS HIGH |
|
|
|
LD A,SD_OPSDEF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD A,SD_OPRDEF |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
@ -306,64 +340,52 @@ SD_SETUP: |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
LD A,SD_SELDEF |
|
|
|
OUT (SD_SELREG),A |
|
|
|
LD A,SD_OPSDEF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD A,SD_OPRDEF |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
; |
|
|
|
IN A,(SD_OPRREG) |
|
|
|
BIT 5,A ; CARD DETECT |
|
|
|
JP Z,SD_NOMEDIA ; NO MEDIA DETECTED |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
XOR A |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
;; PULSE CLOCK SIGNAL B TIMES |
|
|
|
;; DO NOT MODIFY ANY SIGNALS BUT CLOCK SIGNAL |
|
|
|
;; LEAVE WITH ALL SIGNALS IN ORIGINAL STATE |
|
|
|
;; |
|
|
|
;SD_SENDCLKS: |
|
|
|
;; |
|
|
|
;#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_DSD)) |
|
|
|
; LD A,(SD_OPSVAL) |
|
|
|
;SD_SENDCLKS1: |
|
|
|
; XOR SD_CLK |
|
|
|
; OUT (SD_OPSREG),A |
|
|
|
; XOR SD_CLK |
|
|
|
; OUT (SD_OPSREG),A |
|
|
|
; DJNZ SD_SENDCLKS1 |
|
|
|
; RET |
|
|
|
;#ENDIF |
|
|
|
;; |
|
|
|
;#IF (SDMODE == SDMODE_CSIO) |
|
|
|
;#ENDIF |
|
|
|
;#IF (SDMODE == SDMODE_PPI) |
|
|
|
;#ENDIF |
|
|
|
;#IF (SDMODE == SDMODE_UART) |
|
|
|
;#ENDIF |
|
|
|
; |
|
|
|
; SELECT CARD |
|
|
|
; |
|
|
|
SD_SELECT: |
|
|
|
LD A,(SD_OPSVAL) |
|
|
|
LD A,(SD_OPRVAL) |
|
|
|
#IF (SDMODE == SDMODE_PPI) |
|
|
|
AND ~SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
|
#ELSE |
|
|
|
OR SD_CS ; SET SD_CS (CHIP SELECT) |
|
|
|
#ENDIF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
RET |
|
|
|
; |
|
|
|
; DESELECT CARD |
|
|
|
; |
|
|
|
SD_DESELECT: |
|
|
|
LD A,(SD_OPSVAL) |
|
|
|
LD A,(SD_OPRVAL) |
|
|
|
#IF (SDMODE == SDMODE_PPI) |
|
|
|
OR SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
|
#ELSE |
|
|
|
AND ~SD_CS ; RESET SD_CS (CHIP SELECT) |
|
|
|
#ENDIF |
|
|
|
LD (SD_OPSVAL),A |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
RET |
|
|
|
; |
|
|
|
; CHECK FOR WRITE PROTECT (NZ = WRITE PROTECTED) |
|
|
|
; |
|
|
|
SD_CHKWP: |
|
|
|
XOR A ; ASSUME NOT WRITE PROTECTED |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
IN A,(SD_OPRREG) |
|
|
|
BIT 4,A |
|
|
|
#ENDIF |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
@ -436,19 +458,19 @@ SD_PUT: |
|
|
|
#ELSE |
|
|
|
LD C,A ; C=BYTE TO SEND |
|
|
|
LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) |
|
|
|
LD A,(SD_OPSVAL) ; LOAD CURRENT OPS VALUE |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
SD_PUT1: |
|
|
|
RRA ; PREPARE TO GET DATA BIT FROM CF |
|
|
|
RL C ; ROTATE NEXT BIT FROM C INTO CF |
|
|
|
RLA ; ROTATE CF INTO A:0, SD_DO is OPS:0 |
|
|
|
;OUT (SD_OPSREG),A ; ASSERT DATA BIT |
|
|
|
RLA ; ROTATE CF INTO A:0, SD_DO is OPR:0 |
|
|
|
OUT (SD_OPRREG),A ; ASSERT DATA BIT |
|
|
|
XOR SD_CLK ; TOGGLE CLOCK |
|
|
|
OUT (SD_OPSREG),A ; UPDATE CLOCK AND ASSERT DATA BIT |
|
|
|
OUT (SD_OPRREG),A ; UPDATE CLOCK AND ASSERT DATA BIT |
|
|
|
XOR SD_CLK ; TOGGLE CLOCK |
|
|
|
OUT (SD_OPSREG),A ; UPDATE CLOCK |
|
|
|
OUT (SD_OPRREG),A ; UPDATE CLOCK |
|
|
|
DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS |
|
|
|
LD A,(SD_OPSVAL) ; LOAD CURRENT OPS VALUE |
|
|
|
OUT (SD_OPSREG),A ; LEAVE WITH CLOCK LOW |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
OUT (SD_OPRREG),A ; LEAVE WITH CLOCK LOW |
|
|
|
#ENDIF |
|
|
|
RET ; let it do the rest |
|
|
|
; |
|
|
|
@ -466,10 +488,10 @@ SD_GET: |
|
|
|
LD A,C ; keep result |
|
|
|
#ELSE |
|
|
|
LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) |
|
|
|
LD A,(SD_OPSVAL) ; LOAD CURRENT OPS VALUE |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
SD_GET1: |
|
|
|
XOR SD_CLK ; TOGGLE CLOCK |
|
|
|
OUT (SD_OPSREG),A ; UPDATE CLOCK |
|
|
|
OUT (SD_OPRREG),A ; UPDATE CLOCK |
|
|
|
IN A,(SD_INPREG) ; READ THE DATA WHILE CLOCK IS ACTIVE |
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_PPI)) |
|
|
|
RLA ; ROTATE INP:7 INTO CF |
|
|
|
@ -482,8 +504,8 @@ SD_GET1: |
|
|
|
RRA ; ROTATE INP:0 INTO CF |
|
|
|
#ENDIF |
|
|
|
RL C ; ROTATE CF INTO C:0 |
|
|
|
LD A,(SD_OPSVAL) ; BACK TO INITIAL VALUES (TOGGLE CLOCK) |
|
|
|
OUT (SD_OPSREG),A ; DO IT |
|
|
|
LD A,(SD_OPRVAL) ; BACK TO INITIAL VALUES (TOGGLE CLOCK) |
|
|
|
OUT (SD_OPRREG),A ; DO IT |
|
|
|
DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS |
|
|
|
LD A,C ; GET BYTE RECEIVED INTO A |
|
|
|
#ENDIF |
|
|
|
@ -499,10 +521,7 @@ SD_WAITRDY: |
|
|
|
CALL SD_SELECT ; SELECT CARD |
|
|
|
LD DE,0 ; LOOP MAX (TIMEOUT) |
|
|
|
SD_WAITRDY1: |
|
|
|
; CALL PC_SPACE ; *DEBUG |
|
|
|
CALL SD_GET |
|
|
|
; CALL PRTHEXBYTE ; *DEBUG* |
|
|
|
; XOR A ; *DEBUG* TO SIMULATE READY TIMEOUT |
|
|
|
INC A ; $FF -> $00 |
|
|
|
RET Z ; IF READY, RETURN |
|
|
|
DEC DE |
|
|
|
@ -637,9 +656,9 @@ SD_EXEC: |
|
|
|
SD_EXEC1: |
|
|
|
#IF (SDMODE == SDMODE_CSIO) |
|
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
|
IN A,(SD_OPSREG) |
|
|
|
IN A,(SD_OPRREG) |
|
|
|
OR SD_CS ; SET CS |
|
|
|
OUT (SD_OPSREG),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
IN A,(SIO_MCR) |
|
|
|
@ -709,6 +728,7 @@ SD_GOIDLE1: ; COMMAND OK, CHECK FOR EXPECTED RESULT |
|
|
|
; |
|
|
|
SD_INITCARD: |
|
|
|
CALL SD_SETUP ; DO HARDWARE SETUP/INIT |
|
|
|
RET NZ |
|
|
|
; |
|
|
|
; WAKE UP THE CARD, KEEP DIN HI (ASSERTED) AND /CS HI (DEASSERTED) |
|
|
|
LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) |
|
|
|
@ -727,8 +747,9 @@ SD_INITCARD000: |
|
|
|
|
|
|
|
SD_INITCARD00: |
|
|
|
LD A,SD_TYPESDSC ; ASSUME SDSC CARD TYPE |
|
|
|
LD (SD_TYPE),A ; SAVE IT |
|
|
|
|
|
|
|
LD HL,(SD_TYPEPTR) ; LOAD THE CARD TYPE ADDRESS |
|
|
|
LD (HL),A ; SAVE IT |
|
|
|
|
|
|
|
; CMD8 IS REQUIRED FOR V2 CARDS. FAILURE HERE IS OK AND |
|
|
|
; JUST MEANS THAT IT IS A V1.X CARD |
|
|
|
LD A,SD_CMD8 |
|
|
|
@ -795,8 +816,9 @@ SD_INITCARD2: |
|
|
|
CALL SD_GET ; BITS 31-24 |
|
|
|
AND $40 ; ISOLATE BIT 30 (CCS) |
|
|
|
JR Z,SD_INITCARD21 ; NOT HC/XC, BYPASS |
|
|
|
LD HL,(SD_TYPEPTR) ; LOAD THE CARD TYPE ADDRESS |
|
|
|
LD A,SD_TYPESDHC ; CARD TYPE = SDHC |
|
|
|
LD (SD_TYPE),A ; SAVE IT |
|
|
|
LD (HL),A ; SAVE IT |
|
|
|
SD_INITCARD21: |
|
|
|
CALL SD_GET ; BITS 23-16, DISCARD |
|
|
|
CALL SD_GET ; BITS 15-8, DISCARD |
|
|
|
@ -816,7 +838,8 @@ SD_INITCARD21: |
|
|
|
CALL NEWLINE |
|
|
|
LD DE,SDSTR_SDTYPE |
|
|
|
CALL WRITESTR |
|
|
|
LD A,(SD_TYPE) |
|
|
|
LD HL,(SD_TYPEPTR) |
|
|
|
LD A,(HL) |
|
|
|
CALL PRTHEXBYTE |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
@ -827,7 +850,8 @@ SD_INITCARD21: |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
XOR A ; A = 0 (STATUS = OK) |
|
|
|
LD (SD_STAT),A ; SAVE IT |
|
|
|
LD HL,(SD_STATPTR) ; LOAD STATUS ADDRESS |
|
|
|
LD (HL),A ; SAVE IT |
|
|
|
RET ; RETURN WITH A=0, AND Z SET |
|
|
|
;; |
|
|
|
;; GET AND PRINT CSD, CID |
|
|
|
@ -862,15 +886,13 @@ SD_INITCARD21: |
|
|
|
; CALL PRTHEXBUF |
|
|
|
; |
|
|
|
; RET |
|
|
|
; |
|
|
|
; READ ONE SECTOR |
|
|
|
; |
|
|
|
|
|
|
|
; |
|
|
|
; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED |
|
|
|
; |
|
|
|
SD_CHKCARD: |
|
|
|
LD A,(SD_STAT) ; GET STATUS |
|
|
|
LD HL,(SD_STATPTR) ; LOAD STATUS ADDRESS |
|
|
|
LD A,(HL) ; GET STATUS |
|
|
|
OR A ; SET FLAGS |
|
|
|
CALL NZ,SD_INITCARD ; INIT CARD IF NOT READY |
|
|
|
RET ; RETURN WITH STATUS IN A |
|
|
|
@ -914,7 +936,8 @@ SD_WRSEC: |
|
|
|
; |
|
|
|
; |
|
|
|
SD_SETADDR: |
|
|
|
LD A,(SD_TYPE) |
|
|
|
LD HL,(SD_TYPEPTR) |
|
|
|
LD A,(HL) |
|
|
|
CP SD_TYPESDSC |
|
|
|
JR Z,SD_SETADDRSDSC |
|
|
|
CP SD_TYPESDHC |
|
|
|
@ -973,16 +996,28 @@ SD_ERRCRC: |
|
|
|
LD A,SD_STCRCERR |
|
|
|
JR SD_CARDERR |
|
|
|
; |
|
|
|
; GENERIC ERROR HANDLER, DE POINTS TO ERROR STRING |
|
|
|
SD_NOMEDIA: |
|
|
|
LD A,SD_STNOMEDIA |
|
|
|
JR SD_CARDERR |
|
|
|
; |
|
|
|
SD_WRTPROT: |
|
|
|
LD A,SD_STWRTPROT |
|
|
|
JR SD_CARDERR |
|
|
|
; |
|
|
|
; GENERIC ERROR HANDLER |
|
|
|
; |
|
|
|
SD_CARDERR: |
|
|
|
LD (SD_STAT),A |
|
|
|
PUSH HL ; IS THIS NEEDED? |
|
|
|
LD HL,(SD_STATPTR) |
|
|
|
LD (HL),A |
|
|
|
POP HL ; IS THIS NEEDED? |
|
|
|
#IF (SDTRACE >= 2) |
|
|
|
PUSH AF |
|
|
|
CALL NEWLINE |
|
|
|
PUSH AF ; IS THIS NEEDED? |
|
|
|
PRTC('<') |
|
|
|
CALL SD_PRTSTAT |
|
|
|
PRTC('>') |
|
|
|
POP AF |
|
|
|
POP AF ; IS THIS NEEDED? |
|
|
|
#ENDIF |
|
|
|
OR A |
|
|
|
RET |
|
|
|
@ -993,12 +1028,22 @@ SD_PRTPREFIX: |
|
|
|
CALL NEWLINE |
|
|
|
LD DE,SDSTR_PREFIX |
|
|
|
CALL WRITESTR |
|
|
|
PUSH AF |
|
|
|
LD A,(SD_UNIT) |
|
|
|
ADD A,'0' |
|
|
|
CALL COUT |
|
|
|
POP AF |
|
|
|
CALL PC_COLON |
|
|
|
RET |
|
|
|
; |
|
|
|
; PRINT STATUS STRING |
|
|
|
; |
|
|
|
SD_PRTSTAT: |
|
|
|
LD A,(SD_STAT) |
|
|
|
PUSH HL ; IS THIS NEEDED? |
|
|
|
LD HL,(SD_STATPTR) |
|
|
|
LD A,(HL) |
|
|
|
POP HL ; IS THIS NEEDED? |
|
|
|
OR A |
|
|
|
LD DE,SDSTR_STOK |
|
|
|
JR Z,SD_PRTSTAT1 |
|
|
|
INC A |
|
|
|
@ -1025,11 +1070,20 @@ SD_PRTSTAT: |
|
|
|
INC A |
|
|
|
LD DE,SDSTR_STCRCERR |
|
|
|
JR Z,SD_PRTSTAT1 |
|
|
|
INC A |
|
|
|
LD DE,SDSTR_STNOMEDIA |
|
|
|
JR Z,SD_PRTSTAT1 |
|
|
|
INC A |
|
|
|
LD DE,SDSTR_STWRTPROT |
|
|
|
JR Z,SD_PRTSTAT1 |
|
|
|
LD DE,SDSTR_STUNK |
|
|
|
; |
|
|
|
SD_PRTSTAT1: |
|
|
|
CALL WRITESTR |
|
|
|
LD A,(SD_STAT) |
|
|
|
PUSH HL ; IS THIS NEEDED? |
|
|
|
LD HL,(SD_STATPTR) |
|
|
|
LD A,(HL) |
|
|
|
POP HL ; IS THIS NEEDED? |
|
|
|
CP SD_STCMDERR |
|
|
|
JR Z,SD_PRTCMDERR |
|
|
|
CP SD_STDATAERR |
|
|
|
@ -1066,10 +1120,8 @@ SD_PRTTRN: |
|
|
|
LD DE,SD_CMDBUF |
|
|
|
LD A,6 |
|
|
|
CALL PRTHEXBUF |
|
|
|
CALL PC_SPACE |
|
|
|
LD DE,SDSTR_ARROW |
|
|
|
CALL WRITESTR |
|
|
|
CALL PC_SPACE |
|
|
|
|
|
|
|
LD DE,SDSTR_RC |
|
|
|
CALL WRITESTR |
|
|
|
@ -1083,6 +1135,7 @@ SD_PRTTRN: |
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
|
|
POP AF |
|
|
|
|
|
|
|
RET |
|
|
|
|
|
|
|
; |
|
|
|
@ -1109,8 +1162,8 @@ SD_DSKY: |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
SDSTR_PREFIX .TEXT "SD:$" |
|
|
|
SDSTR_ARROW .TEXT "-->$" |
|
|
|
SDSTR_PREFIX .TEXT "SD$" |
|
|
|
SDSTR_ARROW .TEXT " -> $" |
|
|
|
SDSTR_RC .TEXT "RC=$" |
|
|
|
SDSTR_TOK .TEXT "TOK=$" |
|
|
|
SDSTR_STOK .TEXT "OK$" |
|
|
|
@ -1124,19 +1177,25 @@ SDSTR_STCMDERR .TEXT "COMMAND ERROR$" |
|
|
|
SDSTR_STDATAERR .TEXT "DATA ERROR$" |
|
|
|
SDSTR_STDATATO .TEXT "DATA TIMEOUT$" |
|
|
|
SDSTR_STCRCERR .TEXT "CRC ERROR$" |
|
|
|
SDSTR_STNOMEDIA .TEXT "NO MEDIA$" |
|
|
|
SDSTR_STWRTPROT .TEXT "WRITE PROTECTED$" |
|
|
|
SDSTR_STUNK .TEXT "UNKNOWN$" |
|
|
|
; |
|
|
|
;================================================================================================== |
|
|
|
; SD DISK DRIVER - DATA |
|
|
|
;================================================================================================== |
|
|
|
; |
|
|
|
SD_STAT .DB 0 |
|
|
|
SD_TYPE .DB 0 |
|
|
|
SD_RC .DB 0 |
|
|
|
SD_TOK .DB 0 |
|
|
|
SD_OPSVAL .DB 0 |
|
|
|
SD_LCNT .DB 0 ; LOOP COUNTER |
|
|
|
SD_CMDBUF .EQU $ |
|
|
|
SD_STATLST .FILL SD_UNITCNT,0 ; LIST OF UNIT STATUSES (2 UNITS) |
|
|
|
SD_STATPTR .DW SD_STATLST ; ADDRESS OF STATUS FOR CURRENT UNIT |
|
|
|
SD_TYPELST .FILL SD_UNITCNT,0 ; LIST OF CARD TYPES (2 UNITS) |
|
|
|
SD_TYPEPTR .Dw SD_TYPELST ; ADDRESS OF CARD TYPE FOR CURRENT UNIT |
|
|
|
SD_UNIT .DB 0 ; CURRENT UNIT NUMBER |
|
|
|
SD_RC .DB 0 ; RETURN CODE FROM CMD |
|
|
|
SD_TOK .DB 0 ; TOKEN FROM DATA XFR |
|
|
|
SD_OPRVAL .DB 0 ; CURRENT OPR REG VALUE |
|
|
|
SD_LCNT .DB 0 ; LOOP COUNTER |
|
|
|
; |
|
|
|
SD_CMDBUF: ; START OF STD CMD BUF |
|
|
|
SD_CMD .DB 0 |
|
|
|
SD_CMDP0 .DB 0 |
|
|
|
SD_CMDP1 .DB 0 |
|
|
|
|