Copy sdc driver to blkfs
This commit is contained in:
parent
a19376df6c
commit
8fbbf5209a
2
blk/001
2
blk/001
@ -4,7 +4,7 @@ MASTER INDEX
|
|||||||
70 Implementation notes 100 Block editor
|
70 Implementation notes 100 Block editor
|
||||||
200 Z80 assembler 260 Cross compilation
|
200 Z80 assembler 260 Cross compilation
|
||||||
280 Z80 boot code 350 ACIA driver
|
280 Z80 boot code 350 ACIA driver
|
||||||
|
370 SD Card driver
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4
blk/370
Normal file
4
blk/370
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
SD Card driver
|
||||||
|
|
||||||
|
Load the z80 part with "372 LOAD", the Forth part with
|
||||||
|
"374 LOAD".
|
@ -1,7 +1,6 @@
|
|||||||
( n -- n )
|
|
||||||
( Initiate SPI exchange with the SD card. n is the data to
|
( Initiate SPI exchange with the SD card. n is the data to
|
||||||
send. )
|
send. )
|
||||||
CODE _sdcSR
|
CODE _sdcSR ( n -- n )
|
||||||
HL POPqq,
|
HL POPqq,
|
||||||
chkPS,
|
chkPS,
|
||||||
A L LDrr,
|
A L LDrr,
|
||||||
@ -12,10 +11,4 @@ CODE _sdcSR
|
|||||||
HL PUSHqq,
|
HL PUSHqq,
|
||||||
;CODE
|
;CODE
|
||||||
|
|
||||||
CODE _sdcSel
|
373 LOAD
|
||||||
SDC_CSLOW OUTnA,
|
|
||||||
;CODE
|
|
||||||
|
|
||||||
CODE _sdcDesel
|
|
||||||
SDC_CSHIGH OUTnA,
|
|
||||||
;CODE
|
|
9
blk/373
Normal file
9
blk/373
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CODE _sdcSel
|
||||||
|
SDC_CSLOW OUTnA,
|
||||||
|
;CODE
|
||||||
|
|
||||||
|
CODE _sdcDesel
|
||||||
|
SDC_CSHIGH OUTnA,
|
||||||
|
;CODE
|
||||||
|
|
||||||
|
|
16
blk/374
Normal file
16
blk/374
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( -- n )
|
||||||
|
: _idle 0xff _sdcSR ;
|
||||||
|
|
||||||
|
( -- n )
|
||||||
|
( _sdcSR 0xff until the response is something else than 0xff
|
||||||
|
for a maximum of 20 times. Returns 0xff if no response. )
|
||||||
|
: _wait
|
||||||
|
0 ( cnt )
|
||||||
|
BEGIN
|
||||||
|
_idle
|
||||||
|
DUP 0xff = IF DROP ELSE SWAP DROP EXIT THEN
|
||||||
|
1+
|
||||||
|
DUP 20 = UNTIL
|
||||||
|
DROP 0xff
|
||||||
|
;
|
||||||
|
375 386 LOADR
|
10
blk/375
Normal file
10
blk/375
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
( -- )
|
||||||
|
( The opposite of sdcWaitResp: we wait until response is 0xff.
|
||||||
|
After a successful read or write operation, the card will be
|
||||||
|
busy for a while. We need to give it time before interacting
|
||||||
|
with it again. Technically, we could continue processing on
|
||||||
|
our side while the card it busy, and maybe we will one day,
|
||||||
|
but at the moment, I'm having random write errors if I don't
|
||||||
|
do this right after a write, so I prefer to stay cautious
|
||||||
|
for now. )
|
||||||
|
: _ready BEGIN _idle 0xff = UNTIL ;
|
16
blk/376
Normal file
16
blk/376
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( c n -- c )
|
||||||
|
( Computes n into crc c with polynomial 0x09
|
||||||
|
Note that the result is "left aligned", that is, that 8th
|
||||||
|
bit to the "right" is insignificant (will be stop bit). )
|
||||||
|
: _crc7
|
||||||
|
XOR ( c )
|
||||||
|
8 0 DO
|
||||||
|
2 * ( <<1 )
|
||||||
|
DUP 255 > IF
|
||||||
|
( MSB was set, apply polynomial )
|
||||||
|
0xff AND
|
||||||
|
0x12 XOR ( 0x09 << 1, we apply CRC on high bits )
|
||||||
|
THEN
|
||||||
|
LOOP
|
||||||
|
;
|
||||||
|
|
16
blk/377
Normal file
16
blk/377
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( c n -- c )
|
||||||
|
( Computes n into crc c with polynomial 0x1021 )
|
||||||
|
: _crc16
|
||||||
|
SWAP DUP 256 / ( n c c>>8 )
|
||||||
|
ROT XOR ( c x )
|
||||||
|
DUP 16 / XOR ( c x^x>>4 )
|
||||||
|
SWAP 256 * ( x c<<8 )
|
||||||
|
OVER 4096 * XOR ( x c^x<<12 )
|
||||||
|
OVER 32 * XOR ( x c^x<<5 )
|
||||||
|
XOR ( c )
|
||||||
|
;
|
||||||
|
|
||||||
|
( send-and-crc7 )
|
||||||
|
( n c -- c )
|
||||||
|
: _s+crc SWAP DUP _sdcSR DROP _crc7 ;
|
||||||
|
|
16
blk/378
Normal file
16
blk/378
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( cmd arg1 arg2 -- resp )
|
||||||
|
( Sends a command to the SD card, along with arguments and
|
||||||
|
specified CRC fields. (CRC is only needed in initial commands
|
||||||
|
though). This does *not* handle CS. You have to
|
||||||
|
select/deselect the card outside this routine. )
|
||||||
|
: _cmd
|
||||||
|
_wait DROP ROT ( a1 a2 cmd )
|
||||||
|
0 _s+crc ( a1 a2 crc )
|
||||||
|
ROT 256 /MOD ROT ( a2 h l crc )
|
||||||
|
_s+crc _s+crc ( a2 crc )
|
||||||
|
SWAP 256 /MOD ROT ( h l crc )
|
||||||
|
_s+crc _s+crc ( crc )
|
||||||
|
0x01 OR ( ensure stop bit )
|
||||||
|
_sdcSR DROP ( send CRC )
|
||||||
|
_wait ( wait for a valid response... )
|
||||||
|
;
|
16
blk/379
Normal file
16
blk/379
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
( cmd arg1 arg2 -- r )
|
||||||
|
( Send a command that expects a R1 response, handling CS. )
|
||||||
|
: 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
|
||||||
|
_sdcSel
|
||||||
|
_cmd ( r )
|
||||||
|
_idle 256 * _idle + ( r arg1 )
|
||||||
|
_idle 256 * _idle + ( r arg1 arg2 )
|
||||||
|
_sdcDesel
|
||||||
|
;
|
||||||
|
|
16
blk/380
Normal file
16
blk/380
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
: _err _sdcDesel ABORT" SDerr" ;
|
||||||
|
|
||||||
|
( Initialize a SD card. This should be called at least 1ms
|
||||||
|
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 _idle DROP LOOP
|
||||||
|
( call cmd0 and expect a 0x01 response (card idle)
|
||||||
|
this should be called multiple times. we're actually
|
||||||
|
expected to. let's call this for a maximum of 10 times. )
|
||||||
|
0 ( dummy )
|
||||||
|
10 0 DO ( r )
|
||||||
|
DROP 0x40 0 0 SDCMDR1 ( CMD0 )
|
||||||
|
DUP 0x01 = IF LEAVE THEN
|
||||||
|
LOOP 0x01 = NOT IF _err THEN ( cont. )
|
10
blk/381
Normal file
10
blk/381
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
( Then comes the CMD8. We send it with a 0x01aa argument and
|
||||||
|
expect a 0x01aa argument back, along with a 0x01 R1
|
||||||
|
response. )
|
||||||
|
0x48 0 0x1aa ( CMD8 )
|
||||||
|
SDCMDR7 ( r arg1 arg2 )
|
||||||
|
0x1aa = NOT IF _err THEN ( arg2 check )
|
||||||
|
0 = NOT IF _err THEN ( arg1 check )
|
||||||
|
0x01 = NOT IF _err THEN ( r check )
|
||||||
|
|
||||||
|
( cont. )
|
13
blk/382
Normal file
13
blk/382
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
( Now we need to repeatedly run CMD55+CMD41 (0x40000000)
|
||||||
|
until the card goes out of idle mode, that is, when it stops
|
||||||
|
sending us 0x01 response and send us 0x00 instead. Any other
|
||||||
|
response means that initialization failed. )
|
||||||
|
BEGIN
|
||||||
|
0x77 0 0 SDCMDR1 ( CMD55 )
|
||||||
|
0x01 = NOT IF _err THEN
|
||||||
|
0x69 0x4000 0x0000 SDCMDR1 ( CMD41 )
|
||||||
|
DUP 0x01 > IF _err THEN
|
||||||
|
NOT UNTIL
|
||||||
|
( Out of idle mode! Success! )
|
||||||
|
;
|
||||||
|
|
15
blk/383
Normal file
15
blk/383
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
: _sdc@ ( dstaddr blkno -- )
|
||||||
|
_sdcSel 0x51 ( CMD17 ) 0 ROT ( a cmd 0 blkno ) _cmd
|
||||||
|
IF _err THEN
|
||||||
|
_wait 0xfe = NOT IF _err THEN
|
||||||
|
0 SWAP ( crc a )
|
||||||
|
512 0 DO ( crc a )
|
||||||
|
DUP _idle ( crc a a n )
|
||||||
|
DUP ROT C! ( crc a n )
|
||||||
|
ROT SWAP _crc16 ( a crc )
|
||||||
|
SWAP 1+ ( crc a+1 )
|
||||||
|
LOOP
|
||||||
|
DROP ( crc1 )
|
||||||
|
_idle 256 * _idle + ( crc2 )
|
||||||
|
_wait DROP _sdcDesel
|
||||||
|
= NOT IF _err THEN ;
|
7
blk/384
Normal file
7
blk/384
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
: SDC@
|
||||||
|
2 * DUP BLK( SWAP ( b a b )
|
||||||
|
_sdc@
|
||||||
|
1+ BLK( 512 + SWAP
|
||||||
|
_sdc@
|
||||||
|
;
|
||||||
|
|
16
blk/385
Normal file
16
blk/385
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
: _sdc! ( srcaddr blkno -- )
|
||||||
|
_sdcSel 0x58 ( CMD24 ) 0 ROT ( a cmd 0 blkno ) _cmd
|
||||||
|
IF _err THEN
|
||||||
|
_idle DROP 0xfe _sdcSR DROP
|
||||||
|
0 SWAP ( crc a )
|
||||||
|
512 0 DO ( crc a )
|
||||||
|
C@+ ( crc a+1 n )
|
||||||
|
ROT OVER ( a n crc n )
|
||||||
|
_crc16 ( a n crc )
|
||||||
|
SWAP ( a crc n )
|
||||||
|
_sdcSR DROP ( a crc )
|
||||||
|
SWAP ( crc a )
|
||||||
|
LOOP
|
||||||
|
DROP ( crc ) 256 /MOD ( lsb msb )
|
||||||
|
_sdcSR DROP _sdcSR DROP
|
||||||
|
_wait DROP _sdcDesel ;
|
7
blk/386
Normal file
7
blk/386
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
: SDC!
|
||||||
|
2 * DUP BLK( SWAP ( b a b )
|
||||||
|
_sdc!
|
||||||
|
1+ BLK( 512 + SWAP
|
||||||
|
_sdc!
|
||||||
|
;
|
||||||
|
|
@ -7,7 +7,6 @@ EMUL = $(BASEDIR)/emul/hw/rc2014/classic
|
|||||||
BOOTSRCS = conf.fs \
|
BOOTSRCS = conf.fs \
|
||||||
$(EDIR)/xcomp.fs \
|
$(EDIR)/xcomp.fs \
|
||||||
drvz80.fs \
|
drvz80.fs \
|
||||||
$(BASEDIR)/drv/sdc.z80 \
|
|
||||||
$(FDIR)/icore.fs \
|
$(FDIR)/icore.fs \
|
||||||
$(EDIR)/stop.fs
|
$(EDIR)/stop.fs
|
||||||
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
352 LOAD ( acia.z80 )
|
352 LOAD ( acia.z80 )
|
||||||
|
372 LOAD ( sdc.z80 )
|
||||||
|
Loading…
Reference in New Issue
Block a user