fl 15 constant _sd_cs 16 constant _sd_di \ connected SD's di 17 constant _sd_clk 18 constant _sd_do \ connected SD's do 1 _sd_cs lshift constant _sd_csm 1 _sd_di lshift constant _sd_dim 1 _sd_clk lshift constant _sd_clkm 1 _sd_do lshift constant _sd_dom : _sd_cs_out _sd_cs pinout ; : _sd_di_out _sd_di pinout ; : _sd_clk_out _sd_clk pinout ; : _sd_do_in _sd_do pinin ; : _sd_cs_out_l _sd_csm _maskoutlo ; : _sd_cs_out_h _sd_csm _maskouthi ; : _sd_di_out_l _sd_dim _maskoutlo ; : _sd_di_out_h _sd_dim _maskouthi ; : _sd_clk_out_l _sd_clkm _maskoutlo ; : _sd_clk_out_h _sd_clkm _maskouthi ; wvariable tmp wvariable tmp1 wvariable time_value 0 c, a c, c c, d c, f c, 14 c, 19 c, 1e c, 23 c, 28 c, 2d c, 32 c, 37 c, 3c c, 46 c, 50 c, wvariable time_unit 1 c, a c, 64 c, 1 c, a c, 64 c, 1 c, a c, wvariable rate_unit 64 c, 1 c, a c, 64 c, wvariable buff_ptr wvariable sd_buf wvariable sdhc wvariable ccs wvariable first_sector wvariable byte/sector wvariable sector/cluster wvariable reserve_sector wvariable num_fat wvariable root_entry variable sector/fat variable total_sector variable rootCluster variable BTB_addr variable FAT_addr variable RDE_addr variable USER_addr : sd_shift_out 8 0 do dup 1 7 i - lshift and 0> if _sd_di_out_h else _sd_di_out_l then _sd_clk_out_l _sd_clk_out_h loop drop ; : sd_shift_in 0 8 0 do _sd_clk_out_l _sd_clk_out_h ina COG@ _sd_dom and 0> if 1+ then 1 lshift loop 1 rshift ; : dummy ff sd_shift_out ; \ dummy 8clock \ inititialization for SD-Card : sd_init _sd_di_out _sd_di_out_h _sd_clk_out _sd_clk_out_h _sd_do_in _sd_cs_out _sd_cs_out_h 0 sdhc W! 0 ccs W! 0 tmp W! dictend W@ 200 - sd_buf W! 4a 0 do \ 74 clock _sd_clk_out_l _sd_clk_out_h loop _sd_cs_out_l 40 sd_shift_out \ CMD0 0 4 0 do dup sd_shift_out loop drop 95 sd_shift_out \ CRC begin sd_shift_in 1 = if 1 else tmp dup W@ 1+ swap W! tmp W@ 100 = if ." error: no card" cr cr exit else 0 then then until dummy 48 sd_shift_out \ CMD8 0 2 0 do dup sd_shift_out loop drop 1 sd_shift_out aa sd_shift_out 87 sd_shift_out \ Response for CMD8 begin sd_shift_in dup 1 = if drop 1 else 5 = if begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until ." SDSC initialize success" cr cr exit then 0 then until cr 2 0 do sd_shift_in drop loop sd_shift_in sd_shift_in aa = if 1 = if 1 else 0 then else drop 0 then if begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 40 sd_shift_out 0 3 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until 7a sd_shift_out \ CMD58 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out begin sd_shift_in 0= until sd_shift_in \ Get CardCapacityStatus of OCR 4 0 do sd_shift_in drop loop dummy 40 and 0= if 0 ccs W! else 1 ccs W! then else begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until then 49 sd_shift_out \ CMD9 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out dummy begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token sd_shift_in f 0 do sd_shift_in drop loop \ data block begin sd_shift_in ff = until \ drop crc dummy 40 and 40 = if 1 sdhc W! ." SDHC initialize success" cr cr else ." SDSC initialize success" cr cr then _sd_cs_out_h ; \ set buff_ptr to top address of sd_buf : clear_buff_ptr sd_buf W@ buff_ptr W! ; \ increment buff_ptr : buff_ptr+1 buff_ptr W@ 1+ buff_ptr W! ; \ get sd's block data to sd-buf's area \ ( address -- ) <-- SDSC \ ( sector -- ) <-- SDHC on ccs=1 \ ( address -- ) <-- SDHC on ccs=0 : block_read 4 0 do dup ff and swap 8 rshift loop drop _sd_cs_out_l 51 sd_shift_out \ CMD17 Single Block read sd_shift_out sd_shift_out sd_shift_out sd_shift_out 1 sd_shift_out \ CRC begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token clear_buff_ptr 200 0 do sd_shift_in buff_ptr W@ C! buff_ptr+1 loop begin sd_shift_in ff = until \ drop crc dummy begin sd_shift_in ff = until \ drop crc dummy _sd_cs_out_h ; : collect_info \ collect sd's information 0 block_read clear_buff_ptr buff_ptr W@ 1c6 + W@ buff_ptr W@ 1c8 + W@ 10 lshift or dup first_sector W! \ 200 * block_read ccs W@ if block_read else 200 * block_read then clear_buff_ptr buff_ptr W@ b + C@ buff_ptr W@ c + C@ 8 lshift or byte/sector W! buff_ptr W@ d + C@ sector/cluster W! buff_ptr W@ e + W@ reserve_sector W! buff_ptr W@ 10 + C@ num_fat W! buff_ptr W@ 11 + C@ buff_ptr W@ 12 + C@ 8 lshift or root_entry W! sdhc W@ if buff_ptr W@ 24 + L@ sector/fat L! else buff_ptr W@ 16 + W@ sector/fat L! then buff_ptr W@ 20 + L@ total_sector L! buff_ptr W@ 2c + L@ rootCluster L! sdhc W@ if first_sector W@ BTB_addr L! first_sector W@ reserve_sector W@ + FAT_addr L! num_fat W@ sector/fat W@ * FAT_addr L@ + RDE_addr L! RDE_addr L@ USER_addr L! ccs W@ 0 = if BTB_addr L@ byte/sector W@ * BTB_addr L! FAT_addr L@ byte/sector W@ * FAT_addr L! RDE_addr L@ byte/sector W@ * RDE_addr L! RDE_addr L@ USER_addr L! then else first_sector W@ byte/sector W@ * BTB_addr L! first_sector W@ reserve_sector W@ + byte/sector W@ * FAT_addr L! num_fat W@ sector/fat W@ * byte/sector W@ * FAT_addr L@ + RDE_addr L! root_entry W@ 20 * RDE_addr L@ + USER_addr L! then ; \ cluster Num --> sector Num : cluster_to_sector 2 - sector/cluster W@ * \ ( (cluster_num - 2) X sector/cluster ) sdhc W@ if ccs W@ if USER_addr L@ + else USER_addr L@ byte/sector W@ u/ + then else USER_addr L@ byte/sector W@ u/ + then ; wvariable dictend_org wvariable load_end wvariable sector_num : sector_read \ ( -- address) copy sector-data sector_num W@ \ ." sector_num" dup . ccs W@ 0= if byte/sector W@ * then block_read clear_buff_ptr sector_num dup W@ 1+ swap W! sd_buf W@ ; : sd_buf_end? sd_buf W@ - 200 = if 1 else 0 then ; \ (next c-addres -- t/f) sd_buf end check t:end f:not end : load_file \ ( cluster_number -- ) cluster_to_sector dup . sector_num W! sector_read 0 swap \ st? begin \ skip from "\" to 0x0d C@++ dup 5c = if drop begin C@++ over sd_buf_end? if 2drop sector_read 0 \ st? else d = then until \ skip from "{" to "}" else dup 7b = if drop begin C@++ over sd_buf_end? if 2drop sector_read 0 \ st? else 7d = then until \ else dup 20 = if emit swap 1+ swap dup sd_buf_end? if drop sector_read then \ st? else dup 20 = if dup emit fl_in W@ C! swap 1+ swap fl_in W@ 1+ fl_in W! dup sd_buf_end? if drop sector_read then begin C@++ 20 = if dup sd_buf_end? if drop sector_read 0 else 0 \ else 20 <> if 1- 1 else 0 then then \ st? else 1- 1 then until else dup 0= if st? ." end" fl_in W@ C! fl_in dup W@ 1+ swap W! 1 load_end W! else dup emit fl_in W@ C! swap 1+ swap fl_in W@ 1+ fl_in W! \ dup fl_top W@ = if _eoom reset dup sd_buf_end? \ count up buff_ptr and check buffer-end if drop sector_read then then then then then load_end W@ if swap dup fl_count W! . ." characters" drop 1 else 0 then \ st? until ; : load_sd 0 load_end W! sd_init collect_info dictend W@ 200 - here W@ - 80 - 0 fl_count W! lockdict fl_lock W@ if freedict cr 0 else -1 fl_lock W! freedict -1 then \ ( u t/f -- ) true if successful so far if \ save the original dictend and initialize variables dictend W@ dup dictend_org W! 200 - dup fl_top W! swap - dup fl_base W! dup fl_in W! 1- dictend W! st? load_file \ load cluster2's file 1 else drop 0 then \ dictend_org W@ dictend W! \ 0 fl_lock W! ; \ fl_sd_buf ( n -- ) emit the keys in the fast buffer : fl_sd_buf fl_lock W@ fl_count W@ 0<> and if fl_base W@ fl_count W@ bounds do i dup C@ emit dictend W! loop dictend_org W@ dictend W! 0 fl_count W! lockdict 0 fl_lock W! freedict then ; \ : fl_sd load_sd if c" fl_sd_buf" tbuf ccopy tbuf ." aaa" c" cr " over cappend cogid over cappendnc c" 0 emitptr W! >con" swap cappend tbuf cogxo then ; \