|
|
|
@ -333,6 +333,27 @@ SD_DDRVAL .EQU %00001101 ; DATA DIRECTION REGISTER VALUE |
|
|
|
SD_INVCS .EQU FALSE ; INVERT CS |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_Z80R) ; Z80 Retro |
|
|
|
; |
|
|
|
; SPLIT OVER TWO REGISTERS TO DRIVE CLK. THE CS LINE IS ON THE GPIO |
|
|
|
; WHICH IS THE SAME LATCHES THAT CONTROL MMU ON/OFF, SO DON;T GLITCH |
|
|
|
; THEM WHEN UPDATING! |
|
|
|
; |
|
|
|
SD_DEVMAX .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRDEF .EQU %00000001 ; OUTPUT PORT DEFAULT STATE |
|
|
|
SD_OPRMSK .EQU %00000101 ; OUTPUT PORT MASK |
|
|
|
SD_OPRREG .EQU $64 ; CS VIA GPIO |
|
|
|
SD_IOBASE .EQU $68 ; 68/69 FOR OUTPUT |
|
|
|
SD_IOREG .EQU SD_IOBASE ; INPUT REGISTER |
|
|
|
SD_IOCLK .EQU SD_IOBASE+1 ; CLOCK IS OFF A0 |
|
|
|
SD_GPIO .EQU $64 ; MISO IS ON THE GPIO |
|
|
|
SD_CS0 .EQU %00000100 ; SELECT |
|
|
|
SD_DI .EQU %00000001 ; DATA IN (CARD <- CPU) MOSI |
|
|
|
SD_DO .EQU %00000001 ; DATA OUT (CARD -> CPU) MISO |
|
|
|
SD_CINIT .EQU FALSE ; INITIALIZE OUTPUT PORT |
|
|
|
SD_INVCS .EQU FALSE ; INVERT CS |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SD_DEVCNT > SD_DEVMAX) |
|
|
|
.ECHO "*** ERROR: SDCNT EXCEEDS MAXIMUM SUPPORTED BY INTERFACE!!!\n" |
|
|
|
!!! ; FORCE AN ASSEMBLY ERROR |
|
|
|
@ -546,6 +567,15 @@ SD_INIT: |
|
|
|
CALL PRTHEXBYTE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_Z80R) |
|
|
|
PRTS(" MODE=Z80R$") |
|
|
|
PRTS(" IO=0x$") |
|
|
|
LD A,SD_IOBASE |
|
|
|
CALL PRTHEXBYTE |
|
|
|
LD A,SD_OPRDEF |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_USR) |
|
|
|
PRTS(" MODE=USER$") |
|
|
|
PRTS(" IO=0x$") |
|
|
|
@ -1910,7 +1940,7 @@ SD_DESELECT: |
|
|
|
AND ~SD_CS0 |
|
|
|
#ENDIF |
|
|
|
; ADJUST BIT(S) FOR INTERFACES USING INVERTED CS BITS |
|
|
|
#IF ((SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_PIO)) |
|
|
|
#IF ((SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_PIO) | (SDMODE == SDMODE_Z80R)) |
|
|
|
#IF ((SDMODE == SDMODE_SC) & (SD_DEVCNT > 1)) |
|
|
|
XOR SD_CS0 | SD_CS1 |
|
|
|
#ELSE |
|
|
|
@ -1957,9 +1987,48 @@ SD_PUT: |
|
|
|
SET 4,A ; SET TRANSMIT ENABLE |
|
|
|
OUT0 (SD_CNTR),A |
|
|
|
#ELSE |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
|
|
|
|
#IF (SDMODE == SDMODE_Z80R) |
|
|
|
; USE C - THE CALLING CODE FOR COMMAND SEND FAILS TO SAVE HL/DE |
|
|
|
; WHILST THE OTHER PATHS DO ? |
|
|
|
LD C,A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
RL C |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
#ELSE |
|
|
|
|
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
XOR $FF ; DI IS INVERTED ON UART |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
LD C,A ; C=BYTE TO SEND |
|
|
|
LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
@ -1975,6 +2044,7 @@ SD_PUT1: |
|
|
|
DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
OUT (SD_OPRREG),A ; LEAVE WITH CLOCK LOW |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
RET ; DONE |
|
|
|
@ -1997,34 +2067,83 @@ SD_GET: |
|
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS |
|
|
|
LD A,C ; KEEP RESULT |
|
|
|
#ELSE |
|
|
|
#IF (SDMODE == SDMODE_Z80R) |
|
|
|
; MUST PRESERVE HL,DE |
|
|
|
PUSH DE |
|
|
|
LD A,1 |
|
|
|
LD C,SD_GPIO |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
IN B,(C) |
|
|
|
RR B |
|
|
|
RL E |
|
|
|
LD A,E |
|
|
|
POP DE |
|
|
|
#ELSE |
|
|
|
LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
SD_GET1: |
|
|
|
XOR SD_CLK ; TOGGLE 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) | (SDMODE == SDMODE_PIO)) |
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_PIO)) |
|
|
|
RLA ; ROTATE INP:7 INTO CF |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_N8) |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_N8) |
|
|
|
RLA ; ROTATE INP:6 INTO CF |
|
|
|
RLA ; " |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
RLA ; ROTATE INP:5 INTO CF |
|
|
|
RLA ; " |
|
|
|
RLA ; " |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
#ENDIF |
|
|
|
#IF (SDMODE == SDMODE_DSD) |
|
|
|
RRA ; ROTATE INP:0 INTO CF |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
RL C ; ROTATE CF INTO C:0 |
|
|
|
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 |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
XOR $FF ; DO IS INVERTED ON UART |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
|