From a2d89de5573adc2cba9673ed1bfccb30d6d7792c Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sat, 18 Apr 2020 20:33:51 -0400 Subject: [PATCH] drv/sdc: implement core words in z80 In addition to making the driver significantly faster, it allows us to make SDC port configuration opaque to sdc.fs. --- drv/sdc.fs | 45 ++++++++++++++++------------------------- drv/sdc.z80 | 21 +++++++++++++++++++ recipes/rc2014/Makefile | 1 + recipes/rc2014/conf.fs | 3 +++ 4 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 drv/sdc.z80 diff --git a/drv/sdc.fs b/drv/sdc.fs index c2ce869..b904342 100644 --- a/drv/sdc.fs +++ b/drv/sdc.fs @@ -1,12 +1,3 @@ -: SDC_CSHIGH 6 ; -: SDC_CSLOW 5 ; -: SDC_SPI 4 ; - -: _sdcSR SDC_SPI PC! SDC_SPI PC@ ; - -: _sel 0 SDC_CSLOW PC! ; -: _desel 0 SDC_CSHIGH PC! ; - ( -- n ) : _idle 0xff _sdcSR ; @@ -93,30 +84,31 @@ ( cmd arg1 arg2 -- r ) ( Send a command that expects a R1 response, handling CS. ) -: SDCMDR1 _sel _cmd _desel ; +: SDCMDR1 _sdcSel _cmd _sdcDesel ; ( cmd arg1 arg2 -- r arg1 arg2 ) ( Send a command that expects a R7 response, handling CS. A R7 is a R1 followed by 4 bytes. arg1 contains bytes 0:1, arg2 has 2:3 ) : SDCMDR7 - _sel + _sdcSel _cmd ( r ) _idle 256 * ( r h ) _idle + ( r arg1 ) _idle 256 * ( r arg1 h ) _idle + ( r arg1 arg2 ) - _desel + _sdcDesel ; +: _err _sdcDesel ABORT" SDerr" ; + ( Initialize a SD card. This should be called at least 1ms - after the powering up of the card. r is result. - Zero means success, non-zero means error. ) + after the powering up of the card. ) : SDC$ ( Wake the SD card up. After power up, a SD card has to receive at least 74 dummy clocks with CS and DI high. We send 80. ) - 10 0 DO 0xff SDC_SPI PC! LOOP + 10 0 DO _idle DROP LOOP ( call cmd0 and expect a 0x01 response (card idle) this should be called multiple times. we're actually @@ -128,16 +120,16 @@ SDCMDR1 DUP 0x01 = IF LEAVE THEN LOOP - 0x01 = NOT IF 1 EXIT THEN + 0x01 = NOT IF _err THEN ( Then comes the CMD8. We send it with a 0x01aa argument and expect a 0x01aa argument back, along with a 0x01 R1 response. ) 0b01001000 0 0x1aa ( CMD8 ) SDCMDR7 ( r arg1 arg2 ) - 0x1aa = NOT IF 2 EXIT THEN ( arg2 check ) - 0 = NOT IF 3 EXIT THEN ( arg1 check ) - 0x01 = NOT IF 4 EXIT THEN ( r check ) + 0x1aa = NOT IF _err THEN ( arg2 check ) + 0 = NOT IF _err THEN ( arg1 check ) + 0x01 = NOT IF _err THEN ( r check ) ( Now we need to repeatedly run CMD55+CMD41 (0x40000000) until the card goes out of idle mode, that is, when @@ -147,20 +139,17 @@ BEGIN 0b01110111 0 0 ( CMD55 ) SDCMDR1 - 0x01 = NOT IF 5 EXIT THEN + 0x01 = NOT IF _err THEN 0b01101001 0x4000 0x0000 ( CMD41 ) SDCMDR1 - DUP 0x01 > IF DROP 6 EXIT THEN + DUP 0x01 > IF _err THEN NOT UNTIL ( Out of idle mode! Success! ) - 0 ; -: _err _desel ABORT" SDerr" ; - ( dstaddr blkno -- ) : _sdc@ - _sel + _sdcSel 0x51 ( CMD17 ) 0 ROT ( a cmd 0 blkno ) _cmd @@ -181,7 +170,7 @@ _idle 256 * _idle + ( crc2 ) _wait DROP - _desel + _sdcDesel = NOT IF _err THEN ; @@ -194,7 +183,7 @@ ( srcaddr blkno -- ) : _sdc! - _sel + _sdcSel 0x58 ( CMD24 ) 0 ROT ( a cmd 0 blkno ) _cmd @@ -215,7 +204,7 @@ _sdcSR DROP ( lsb ) _sdcSR DROP _wait DROP - _desel + _sdcDesel ; : SDC! diff --git a/drv/sdc.z80 b/drv/sdc.z80 new file mode 100644 index 0000000..2e48f66 --- /dev/null +++ b/drv/sdc.z80 @@ -0,0 +1,21 @@ +( n -- n ) +( Initiate SPI exchange with the SD card. n is the data to + send. ) +CODE _sdcSR + HL POPqq, + chkPS, + A L LDrr, + SDC_SPI OUTnA, + NOP, NOP, + SDC_SPI INAn, + L A LDrr, + HL PUSHqq, +;CODE + +CODE _sdcSel + SDC_CSLOW OUTnA, +;CODE + +CODE _sdcDesel + SDC_CSHIGH OUTnA, +;CODE diff --git a/recipes/rc2014/Makefile b/recipes/rc2014/Makefile index 64e6696..4b1ed00 100644 --- a/recipes/rc2014/Makefile +++ b/recipes/rc2014/Makefile @@ -10,6 +10,7 @@ BOOTSRCS = conf.fs \ $(FDIR)/boot.fs \ $(FDIR)/z80c.fs \ $(BASEDIR)/drv/acia.z80 \ + $(BASEDIR)/drv/sdc.z80 \ $(FDIR)/icore.fs \ $(EDIR)/xstop.fs diff --git a/recipes/rc2014/conf.fs b/recipes/rc2014/conf.fs index 123526b..5c64cfe 100644 --- a/recipes/rc2014/conf.fs +++ b/recipes/rc2014/conf.fs @@ -2,5 +2,8 @@ 0xf000 CONSTANT RS_ADDR 0x80 CONSTANT ACIA_CTL 0x81 CONSTANT ACIA_IO +4 CONSTANT SDC_SPI +5 CONSTANT SDC_CSLOW +6 CONSTANT SDC_CSHIGH RAMSTART 0x70 + CONSTANT ACIA_MEM