|
|
|
@ -372,10 +372,10 @@ 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 |
|
|
|
SD_INVCS .EQU TRUE ; INVERT CS |
|
|
|
DEVECHO "Z80R" |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
; |
|
|
|
; FOR NOW WE JUST HOOK UP ONE UNIT. THERE ARE EIGHT PORTS FOR DIFFERENT |
|
|
|
; THINGS BUT THIS WILL GET US GOING |
|
|
|
#IF (SDMODE == SDMODE_EPITX) ; Z180 ITX - CSIO, 82C55 for CS |
|
|
|
@ -389,6 +389,39 @@ SD_IOBASE .EQU SD_OPRREG ; IOBASE |
|
|
|
SD_INVCS .EQU FALSE ; INVERT CS |
|
|
|
DEVECHO "EPITX" |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
; S100 FPGA Z80 SPI-BASED SD CARD |
|
|
|
; |
|
|
|
; BASE PORT: $6C |
|
|
|
; BASE + 0: DATA IN/OUT |
|
|
|
; BASE + 1: SPI CLOCK SPEED (0=LOW 4KHZ, 1=HIGH 10MHZ) |
|
|
|
; BASE + 2: SELECT (W), STATUS (R) |
|
|
|
; BASE + 3: START READ (IN OPCODE), START WRITE (OUT OPCODE), ANY VALUE |
|
|
|
; |
|
|
|
; STATUS BITS: |
|
|
|
; 7: BUSY (1=BUSY) |
|
|
|
; 0: PRIMARY DEVICE SELECT STATUS (1=SELECTED) |
|
|
|
; 1: SECONDARY DEVICE SELECT STATUS (1=SELECTED) |
|
|
|
; |
|
|
|
; SELECT BITS (INVERTED!!!): |
|
|
|
; 0: PRIMARY DEVICE, USE VALUE ~$01 |
|
|
|
; 1: SECONDARY DEVICE, USE VALUE ~$02 |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) ; S100 FPGA Z80 |
|
|
|
SD_IOBASE .EQU $6C ; IOBASE |
|
|
|
SD_DATA .EQU SD_IOBASE + 0 ; DATA IN/OUT PORT |
|
|
|
SD_CLKSEL .EQU SD_IOBASE + 1 ; CLOCK SPEED SELECT PORT |
|
|
|
SD_SELSTAT .EQU SD_IOBASE + 2 ; DEVICE SELECT PORT (W) / STATUS (R) |
|
|
|
SD_ACTION .EQU SD_IOBASE + 3 ; INITIATE R/W ACTION VIA IN/OUT |
|
|
|
; |
|
|
|
SD_DEVMAX .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS) |
|
|
|
SD_OPRREG .EQU SD_SELSTAT ; SELECT/STATUS PORT |
|
|
|
SD_OPRDEF .EQU $FF ; QUIESCENT STATE |
|
|
|
SD_CS0 .EQU %00000001 ; PRIMARY DEVICE SELECT BIT |
|
|
|
SD_CS1 .EQU %00000010 ; SECONDARY DEVICE SELECT BIT |
|
|
|
SD_INVCS .EQU TRUE ; INVERT CS |
|
|
|
DEVECHO "FZ80" |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
DEVECHO ", IO=" |
|
|
|
DEVECHO SD_IOBASE |
|
|
|
@ -640,6 +673,13 @@ SD_INIT: |
|
|
|
LD A,SD_TRDR |
|
|
|
CALL PRTHEXBYTE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
PRTS(" MODE=FZ80$") |
|
|
|
PRTS(" IO=0x$") |
|
|
|
LD A,SD_IOBASE |
|
|
|
CALL PRTHEXBYTE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
CALL SD_PROBE ; CHECK FOR HARDWARE |
|
|
|
JR Z,SD_INIT00 ; CONTINUE IF PRESENT |
|
|
|
@ -1083,6 +1123,11 @@ SD_INITCARD: |
|
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_EPITX)) |
|
|
|
CALL SD_CSIO_DEF ; ENSURE CSIO AT DEFAULT SPEED |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
;;; FORCE SLOW SPEED HERE? |
|
|
|
;;; CALL SD_SELECT? |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
; WAKE UP THE CARD, KEEP DIN HI (ASSERTED) AND /CS HI (DEASSERTED) |
|
|
|
LD B,$10 ; MIN 74 CLOCKS REQUIRED, WE USE 128 ($10 * 8) |
|
|
|
@ -1486,8 +1531,10 @@ SD_GOIDLE: |
|
|
|
; |
|
|
|
SD_GOIDLE1: |
|
|
|
; SEEMS TO HELP SOME CARDS? |
|
|
|
;CALL SD_SELECT ; ASSERT CS |
|
|
|
;CALL SD_DONE ; SEND 8 CLOCKS AND DEASSERT CS |
|
|
|
;;; DEBUG |
|
|
|
CALL SD_SELECT ; ASSERT CS |
|
|
|
CALL SD_DONE ; SEND 8 CLOCKS AND DEASSERT CS |
|
|
|
;;; DEBUG |
|
|
|
|
|
|
|
; SMALL DELAY HERE HELPS SOME CARDS |
|
|
|
;;LD DE,300 ; 16US * 300 = ~5MS |
|
|
|
@ -1884,6 +1931,15 @@ SD_SETUP: |
|
|
|
LD (SD_OPRVAL),A |
|
|
|
OUT (SD_OPRREG),A |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
LD A,SD_OPRDEF ; DEFAULT SELECT VALUE |
|
|
|
LD (SD_OPRVAL),A ; PUT IN SHADOW |
|
|
|
OUT (SD_OPRREG),A ; WRITE TO PORT |
|
|
|
XOR A ; LOW SPEED OPERATION |
|
|
|
LD (SD_CLKSEL),A ; DO IT |
|
|
|
CALL SD_DESELECT ; MAKE SURE CARD(S) ARE NOT SELECTED |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
XOR A |
|
|
|
RET |
|
|
|
@ -1931,7 +1987,7 @@ SD_SELECT: |
|
|
|
; CALL SD_WAITTX |
|
|
|
;#ENDIF |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_SC) | SDMODE == SDMODE_MT)) |
|
|
|
#IF ((SDMODE == SDMODE_SC) | (SDMODE == SDMODE_MT) | (SDMODE == SDMODE_FZ80)) |
|
|
|
LD A,(IY+SD_DEV) ; GET CURRENT DEVICE |
|
|
|
OR A ; SET FLAGS |
|
|
|
LD A,(SD_OPRVAL) ; GET CURRENT OPRVAL BACK |
|
|
|
@ -1963,7 +2019,7 @@ SD_SELECT2: |
|
|
|
; ADJUST BIT(S) FOR INTERFACES USING INVERTED CS BITS |
|
|
|
;#IF ((SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_SC)) |
|
|
|
#IF (SD_INVCS) |
|
|
|
#IF ((SDMODE == SDMODE_SC) & (SD_DEVCNT > 1)) |
|
|
|
#IF (((SDMODE == SDMODE_SC) | (SDMODE == SDMODE_FZ80)) & (SD_DEVCNT > 1)) |
|
|
|
XOR SD_CS0 | SD_CS1 |
|
|
|
#ELSE |
|
|
|
XOR SD_CS0 |
|
|
|
@ -1994,20 +2050,25 @@ SD_DESELECT: |
|
|
|
; TRACES. |
|
|
|
CALL DLY32 ; DELAY FOR FINAL BIT |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
CALL SD_WAITBSY |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
LD A,(SD_OPRVAL) |
|
|
|
#IF (((SDMODE == SDMODE_SC) | (SDMODE_MT)) & (SD_DEVCNT > 1)) |
|
|
|
AND ~(SD_CS0 | SD_CS1) |
|
|
|
#ELSE |
|
|
|
#if (SDMODE == SDMODE_EPITX) |
|
|
|
#IF (SDMODE == SDMODE_EPITX) |
|
|
|
OR 7 ; CHAN 7 IS USED FOR DESELECTS |
|
|
|
#ELSE |
|
|
|
AND ~SD_CS0 |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
; ADJUST BIT(S) FOR INTERFACES USING INVERTED CS BITS |
|
|
|
#IF ((SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_PIO) | (SDMODE == SDMODE_Z80R)) |
|
|
|
#IF ((SDMODE == SDMODE_SC) & (SD_DEVCNT > 1)) |
|
|
|
;;;#IF ((SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_PIO) | (SDMODE == SDMODE_Z80R)) |
|
|
|
#IF (SD_INVCS) |
|
|
|
#IF (((SDMODE == SDMODE_SC) | (SDMODE == SDMODE_FZ80)) & (SD_DEVCNT > 1)) |
|
|
|
XOR SD_CS0 | SD_CS1 |
|
|
|
#ELSE |
|
|
|
XOR SD_CS0 |
|
|
|
@ -2037,13 +2098,29 @@ SD_WAITRX: |
|
|
|
; |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
; |
|
|
|
; WAIT WHILE FPGA SPI INTERFACE IS BUSY SENDING OR RECEIVING |
|
|
|
; |
|
|
|
SD_WAITBSY: |
|
|
|
PUSH AF |
|
|
|
CALL PC_PERIOD ; *DEBUG* |
|
|
|
;;;CALL DLY32 |
|
|
|
IN A,(SD_SELSTAT) |
|
|
|
BIT 7,A |
|
|
|
JR NZ,SD_WAITBSY |
|
|
|
;;;CALL DLY32 |
|
|
|
POP AF |
|
|
|
RET |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
; SEND ONE BYTE |
|
|
|
; |
|
|
|
SD_PUT: |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
OUT (SD_WRTR),A |
|
|
|
#ELSE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_EPITX)) |
|
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS, RESULT IN C |
|
|
|
@ -2052,8 +2129,8 @@ SD_PUT: |
|
|
|
IN0 A,(SD_CNTR) |
|
|
|
SET 4,A ; SET TRANSMIT ENABLE |
|
|
|
OUT0 (SD_CNTR),A |
|
|
|
#ELSE |
|
|
|
|
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_Z80R) |
|
|
|
; USE C - THE CALLING CODE FOR COMMAND SEND FAILS TO SAVE HL/DE |
|
|
|
; WHILST THE OTHER PATHS DO ? |
|
|
|
@ -2090,8 +2167,9 @@ SD_PUT: |
|
|
|
RLA |
|
|
|
OUT (SD_IOREG),A |
|
|
|
OUT (SD_IOCLK),A |
|
|
|
#ELSE |
|
|
|
|
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_N8) | (SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_DSD) | (SDMODE == SDMODE_USR) | (SDMODE == SDMODE_PIO)) |
|
|
|
#IF (SDMODE == SDMODE_UART) |
|
|
|
XOR $FF ; DI IS INVERTED ON UART |
|
|
|
#ENDIF |
|
|
|
@ -2111,7 +2189,16 @@ SD_PUT1: |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
OUT (SD_OPRREG),A ; LEAVE WITH CLOCK LOW |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
CALL SD_WAITBSY ; WAIT FOR PENDING ACTIVITY |
|
|
|
OUT (SD_DATA),A ; POST THE VALUE |
|
|
|
OUT (SD_ACTION),A ; INITIATE THE WRITE |
|
|
|
;;;CALL SD_WAITBSY |
|
|
|
|
|
|
|
CALL PC_SPACE ; *DEBUG* |
|
|
|
CALL PC_GT ; *DEBUG* |
|
|
|
CALL PRTHEXBYTE ; *DEBUG* |
|
|
|
#ENDIF |
|
|
|
RET ; DONE |
|
|
|
; |
|
|
|
@ -2122,7 +2209,8 @@ SD_GET: |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_MT) |
|
|
|
IN A,(SD_RDTR) |
|
|
|
#ELSE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_CSIO) | (SDMODE == SDMODE_MK4) | (SDMODE == SDMODE_SC) | (SDMODE == SDMODE_EPITX)) |
|
|
|
CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING |
|
|
|
IN0 A,(SD_CNTR) ; GET CSIO STATUS |
|
|
|
@ -2132,7 +2220,8 @@ SD_GET: |
|
|
|
IN0 A,(SD_TRDR) ; GET RECEIVED BYTE |
|
|
|
CALL MIRROR ; MSB<-->LSB MIRROR BITS |
|
|
|
LD A,C ; KEEP RESULT |
|
|
|
#ELSE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_Z80R) |
|
|
|
; MUST PRESERVE HL,DE |
|
|
|
PUSH DE |
|
|
|
@ -2180,7 +2269,9 @@ SD_GET: |
|
|
|
RL E |
|
|
|
LD A,E |
|
|
|
POP DE |
|
|
|
#ELSE |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF ((SDMODE == SDMODE_JUHA) | (SDMODE == SDMODE_N8) | (SDMODE == SDMODE_PPI) | (SDMODE == SDMODE_UART) | (SDMODE == SDMODE_DSD) | (SDMODE == SDMODE_USR) | (SDMODE == SDMODE_PIO)) |
|
|
|
LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) |
|
|
|
LD A,(SD_OPRVAL) ; LOAD CURRENT OPR VALUE |
|
|
|
SD_GET1: |
|
|
|
@ -2211,7 +2302,16 @@ SD_GET1: |
|
|
|
XOR $FF ; DO IS INVERTED ON UART |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
#ENDIF |
|
|
|
; |
|
|
|
#IF (SDMODE == SDMODE_FZ80) |
|
|
|
CALL SD_WAITBSY ; WAIT FOR PENDING ACTIVITY |
|
|
|
IN A,(SD_ACTION) ; INITIATE READ |
|
|
|
CALL SD_WAITBSY ; WAIT FOR DONE |
|
|
|
IN A,(SD_DATA) ; GET THE VALUE |
|
|
|
;;;CALL SD_WAITBSY |
|
|
|
CALL PC_SPACE ; *DEBUG* |
|
|
|
CALL PC_LT ; *DEBUG* |
|
|
|
CALL PRTHEXBYTE ; *DEBUG* |
|
|
|
#ENDIF |
|
|
|
RET |
|
|
|
; |
|
|
|
|