mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-26 13:18:06 +11:00
Compare commits
4 Commits
19d94dfb47
...
052c744000
Author | SHA1 | Date | |
---|---|---|---|
|
052c744000 | ||
|
c64a8a2e2b | ||
|
b062a9092a | ||
|
66f65daa08 |
2
blk/018
2
blk/018
@ -5,7 +5,7 @@ unsigned. For convenience, decimal parsing and formatting
|
|||||||
support the "-" prefix, but under the hood, it's all unsigned.
|
support the "-" prefix, but under the hood, it's all unsigned.
|
||||||
|
|
||||||
This leads to some oddities. For example, "-1 0 <" is false.
|
This leads to some oddities. For example, "-1 0 <" is false.
|
||||||
To compare whether something is negative, use the "<0" word
|
To compare whether something is negative, use the "0<" word
|
||||||
which is the equivalent to "0x7fff >".
|
which is the equivalent to "0x7fff >".
|
||||||
|
|
||||||
|
|
||||||
|
2
blk/043
2
blk/043
@ -11,6 +11,6 @@ ABORT" x" -- *I* Compiles a ." followed by a ABORT.
|
|||||||
EXECUTE a -- Execute wordref at addr a
|
EXECUTE a -- Execute wordref at addr a
|
||||||
INTERPRET -- Get a line from stdin, compile it in tmp memory,
|
INTERPRET -- Get a line from stdin, compile it in tmp memory,
|
||||||
then execute the compiled contents.
|
then execute the compiled contents.
|
||||||
|
LEAVE -- In a DO..LOOP, exit at the next LOOP call.
|
||||||
QUIT -- Return to interpreter prompt immediately
|
QUIT -- Return to interpreter prompt immediately
|
||||||
EXIT! -- Exit current INTERPRET loop.
|
EXIT! -- Exit current INTERPRET loop.
|
||||||
|
|
||||||
|
184
drv/sdc.fs
Normal file
184
drv/sdc.fs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
: 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 ;
|
||||||
|
|
||||||
|
( -- 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
|
||||||
|
;
|
||||||
|
|
||||||
|
( -- )
|
||||||
|
( 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 ;
|
||||||
|
|
||||||
|
( 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
|
||||||
|
;
|
||||||
|
|
||||||
|
( 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 ;
|
||||||
|
|
||||||
|
( 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 ( a2 crc h l )
|
||||||
|
ROT ( a2 h l crc )
|
||||||
|
_s+crc ( a2 h crc )
|
||||||
|
_s+crc ( a2 crc )
|
||||||
|
SWAP 256 /MOD ( crc h l )
|
||||||
|
ROT ( h l crc )
|
||||||
|
_s+crc ( h crc )
|
||||||
|
_s+crc ( crc )
|
||||||
|
( send CRC )
|
||||||
|
0x01 OR ( ensure stop bit )
|
||||||
|
_sdcSR DROP
|
||||||
|
( And now we just have to wait for a valid response... )
|
||||||
|
_wait
|
||||||
|
;
|
||||||
|
|
||||||
|
( cmd arg1 arg2 -- r )
|
||||||
|
( Send a command that expects a R1 response, handling CS. )
|
||||||
|
: SDCMDR1 _sel _cmd _desel ;
|
||||||
|
|
||||||
|
( 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
|
||||||
|
_cmd ( r )
|
||||||
|
_idle 256 * ( r h )
|
||||||
|
_idle + ( r arg1 )
|
||||||
|
_idle 256 * ( r arg1 h )
|
||||||
|
_idle + ( r arg1 arg2 )
|
||||||
|
_desel
|
||||||
|
;
|
||||||
|
|
||||||
|
( 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. )
|
||||||
|
: 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
|
||||||
|
|
||||||
|
( 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
|
||||||
|
0b01000000 0 0 ( CMD0 )
|
||||||
|
SDCMDR1
|
||||||
|
DUP 0x01 = IF LEAVE THEN
|
||||||
|
LOOP
|
||||||
|
0x01 = NOT IF 1 EXIT 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 )
|
||||||
|
|
||||||
|
( 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
|
||||||
|
0b01110111 0 0 ( CMD55 )
|
||||||
|
SDCMDR1
|
||||||
|
0x01 = NOT IF 5 EXIT THEN
|
||||||
|
0b01101001 0x4000 0x0000 ( CMD41 )
|
||||||
|
SDCMDR1
|
||||||
|
DUP 0x01 > IF DROP 6 EXIT THEN
|
||||||
|
NOT UNTIL
|
||||||
|
( Out of idle mode! Success! )
|
||||||
|
0
|
||||||
|
;
|
||||||
|
|
||||||
|
( dstaddr blkno -- f )
|
||||||
|
: SDC@
|
||||||
|
_sel
|
||||||
|
0x51 ( CMD17 )
|
||||||
|
0 ROT ( a cmd 0 blkno )
|
||||||
|
_cmd
|
||||||
|
IF _desel 0 EXIT THEN
|
||||||
|
_wait
|
||||||
|
0xfe = NOT IF _desel 0 EXIT THEN
|
||||||
|
0 SWAP ( crc a )
|
||||||
|
512 0 DO ( crc a )
|
||||||
|
DUP ( crc a a )
|
||||||
|
_idle ( crc a a n )
|
||||||
|
DUP ROT ( crc a n n a )
|
||||||
|
C! ( crc a n )
|
||||||
|
ROT SWAP ( a crc n )
|
||||||
|
_crc16 ( a crc )
|
||||||
|
SWAP 1+ ( crc a+1 )
|
||||||
|
LOOP
|
||||||
|
DROP ( crc1 )
|
||||||
|
_idle 256 *
|
||||||
|
_idle + ( crc2 )
|
||||||
|
_wait DROP
|
||||||
|
_desel
|
||||||
|
= ( success if crc1 == crc2 )
|
||||||
|
;
|
Binary file not shown.
@ -122,6 +122,7 @@ void sdc_spi_wr(SDC *sdc, uint8_t val)
|
|||||||
uint8_t cmd = b[0] & 0x3f;
|
uint8_t cmd = b[0] & 0x3f;
|
||||||
uint16_t arg1 = (b[1] << 8) | b[2];
|
uint16_t arg1 = (b[1] << 8) | b[2];
|
||||||
uint16_t arg2 = (b[3] << 8) | b[4];
|
uint16_t arg2 = (b[3] << 8) | b[4];
|
||||||
|
// printf("cmd %02x %04x %04x\n", cmd, arg1, arg2);
|
||||||
if (sdc->initstat == 8) {
|
if (sdc->initstat == 8) {
|
||||||
// At this stage, we're expecting CMD0
|
// At this stage, we're expecting CMD0
|
||||||
if (cmd == 0) {
|
if (cmd == 0) {
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
: >= < NOT ;
|
: >= < NOT ;
|
||||||
: <= > NOT ;
|
: <= > NOT ;
|
||||||
: <0 32767 > ;
|
: 0>= 0< NOT ;
|
||||||
: >=0 <0 NOT ;
|
|
||||||
|
|
||||||
( n1 -- n1 true )
|
( n1 -- n1 true )
|
||||||
: <>{ 1 ;
|
: <>{ 1 ;
|
||||||
|
@ -133,6 +133,8 @@
|
|||||||
COMPILE R> COMPILE DROP COMPILE R> COMPILE DROP
|
COMPILE R> COMPILE DROP COMPILE R> COMPILE DROP
|
||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
|
: LEAVE R> R> DROP I 1- >R >R ;
|
||||||
|
|
||||||
( a1 a2 u -- )
|
( a1 a2 u -- )
|
||||||
: MOVE
|
: MOVE
|
||||||
( u ) 0 DO
|
( u ) 0 DO
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
: . ( n -- )
|
: . ( n -- )
|
||||||
( handle negative )
|
( handle negative )
|
||||||
DUP <0 IF '-' EMIT -1 * THEN
|
DUP 0< IF '-' EMIT -1 * THEN
|
||||||
_
|
_
|
||||||
BEGIN
|
BEGIN
|
||||||
DUP '9' > IF DROP EXIT THEN ( stop indicator, we're done )
|
DUP '9' > IF DROP EXIT THEN ( stop indicator, we're done )
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
: = CMP NOT ;
|
: = CMP NOT ;
|
||||||
: < CMP -1 = ;
|
: < CMP -1 = ;
|
||||||
: > CMP 1 = ;
|
: > CMP 1 = ;
|
||||||
|
: 0< 32767 > ;
|
||||||
|
|
||||||
( r c -- r f )
|
( r c -- r f )
|
||||||
( Parse digit c and accumulate into result r.
|
( Parse digit c and accumulate into result r.
|
||||||
@ -61,7 +62,7 @@
|
|||||||
( parse char )
|
( parse char )
|
||||||
'0' -
|
'0' -
|
||||||
( if bad, return "r -1" )
|
( if bad, return "r -1" )
|
||||||
DUP 0 < IF DROP -1 EXIT THEN ( bad )
|
DUP 0< IF DROP -1 EXIT THEN ( bad )
|
||||||
DUP 9 > IF DROP -1 EXIT THEN ( bad )
|
DUP 9 > IF DROP -1 EXIT THEN ( bad )
|
||||||
( good, add to running result )
|
( good, add to running result )
|
||||||
SWAP 10 * + ( r*10+n )
|
SWAP 10 * + ( r*10+n )
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
;
|
;
|
||||||
|
|
||||||
( returns negative value on error )
|
( returns negative value on error )
|
||||||
: hexdig ( c -- n )
|
: _ ( c -- n )
|
||||||
( '0' is ASCII 48 )
|
( '0' is ASCII 48 )
|
||||||
48 -
|
48 -
|
||||||
DUP 0 < IF EXIT THEN ( bad )
|
DUP 0< IF EXIT THEN ( bad )
|
||||||
DUP 10 < IF EXIT THEN ( good )
|
DUP 10 < IF EXIT THEN ( good )
|
||||||
( 'a' is ASCII 97. 59 = 97 - 48 )
|
( 'a' is ASCII 97. 59 = 97 - 48 )
|
||||||
49 -
|
49 -
|
||||||
DUP 0 < IF EXIT THEN ( bad )
|
DUP 0< IF EXIT THEN ( bad )
|
||||||
DUP 6 < IF 10 + EXIT THEN ( good )
|
DUP 6 < IF 10 + EXIT THEN ( good )
|
||||||
( bad )
|
( bad )
|
||||||
255 -
|
255 -
|
||||||
@ -31,24 +31,23 @@
|
|||||||
2+
|
2+
|
||||||
( validate slen )
|
( validate slen )
|
||||||
DUP SLEN ( a l )
|
DUP SLEN ( a l )
|
||||||
DUP 0 = IF DROP 0 EXIT THEN ( a 0 )
|
DUP NOT IF DROP 0 EXIT THEN ( a 0 )
|
||||||
4 > IF DROP 0 EXIT THEN ( a 0 )
|
4 > IF DROP 0 EXIT THEN ( a 0 )
|
||||||
0 ( a r )
|
0 ( a r )
|
||||||
BEGIN
|
BEGIN
|
||||||
OVER C@
|
SWAP C@+ ( r a+1 c )
|
||||||
DUP 0 = IF DROP SWAP DROP 1 EXIT THEN ( r, 1 )
|
DUP NOT IF 2DROP 1 EXIT THEN ( r, 1 )
|
||||||
hexdig ( a r n )
|
_ ( r a n )
|
||||||
DUP 0 < IF DROP DROP 1 EXIT THEN ( a 0 )
|
DUP 0< IF ROT 2DROP 0 EXIT THEN ( a 0 )
|
||||||
SWAP 16 * + ( a r*16+n )
|
ROT 16 * + ( a r*16+n )
|
||||||
SWAP 1+ SWAP ( a+1 r )
|
|
||||||
AGAIN
|
AGAIN
|
||||||
;
|
;
|
||||||
|
|
||||||
( returns negative value on error )
|
( returns negative value on error )
|
||||||
: bindig ( c -- n )
|
: _ ( c -- n )
|
||||||
( '0' is ASCII 48 )
|
( '0' is ASCII 48 )
|
||||||
48 -
|
48 -
|
||||||
DUP 0 < IF EXIT THEN ( bad )
|
DUP 0< IF EXIT THEN ( bad )
|
||||||
DUP 2 < IF EXIT THEN ( good )
|
DUP 2 < IF EXIT THEN ( good )
|
||||||
( bad )
|
( bad )
|
||||||
255 -
|
255 -
|
||||||
@ -65,12 +64,11 @@
|
|||||||
16 > IF DROP 0 EXIT THEN ( a 0 )
|
16 > IF DROP 0 EXIT THEN ( a 0 )
|
||||||
0 ( a r )
|
0 ( a r )
|
||||||
BEGIN
|
BEGIN
|
||||||
OVER C@
|
SWAP C@+ ( r a+1 c )
|
||||||
DUP 0 = IF DROP SWAP DROP 1 EXIT THEN ( r, 1 )
|
DUP NOT IF 2DROP 1 EXIT THEN ( r 1 )
|
||||||
bindig ( a r n )
|
_ ( r a n )
|
||||||
DUP 0 < IF DROP DROP 1 EXIT THEN ( a 0 )
|
DUP 0< IF ROT 2DROP 0 EXIT THEN ( a 0 )
|
||||||
SWAP 2 * + ( a r*2+n )
|
ROT 2 * + ( a r*2+n )
|
||||||
SWAP 1+ SWAP ( a+1 r )
|
|
||||||
AGAIN
|
AGAIN
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user