' This code is extracted from FSRW 2.6 con SECTORSIZE = 512 SECTORSHIFT = 9 DIRSHIFT = 5 SPI_engine_cog = 0 SPI_command = 1 SPI_block_index = 2 SPI_buffer_address = 3 SD_rootdir = 4 SD_filesystem = 5 SD_clustershift = 6 SD_dataregion = 7 SD_fat1 = 8 SD_sectorsperfat = 9 SD_currdir = 10 ERR_BLOCK_NOT_LONG_ALIGNED = -4 ERR_SPI_ENGINE_NOT_RUNNING = -999 obj sdspi : "safe_spi" dat pdate long 0 lastread long 0 dirty long 0 filesystem long 0 clustershift long 0 clustersize long 0 fat1 long 0 sectorsperfat long 0 dataregion long 0 rootdir long 0 rootdirend long 0 endofchain long 0 totclusters long 0 buf byte 0[512] pri brword(b) ' ' Read a byte-reversed word from a (possibly odd) address. ' return (byte[b]) + ((byte[b][1]) << 8) pri brlong(b) ' ' Read a byte-reversed long from a (possibly odd) address. ' return brword(b) + (brword(b+2) << 16) pri getfstype : r if (brlong(@buf+$36) == constant("F" + ("A" << 8) + ("T" << 16) + ("1" << 24)) and buf[$3a]=="6") return 1 if (brlong(@buf+$52) == constant("F" + ("A" << 8) + ("T" << 16) + ("3" << 24)) and buf[$56]=="2") return 2 ' return r (default return) pub mount_explicit(spi_vars, DO, CLK, DI, CS) : r | start, sectorspercluster, reserved, rootentries, sectors {{ ' Mount a volume. The address passed in is passed along to the block ' layer; see the currently used block layer for documentation. If the ' volume mounts, a 0 is returned, else abort is called. }} if (pdate == 0) pdate := constant(((2009-1980) << 25) + (1 << 21) + (27 << 16) + (7 << 11)) 'unmount sdspi.start_explicit(spi_vars, DO, CLK, DI, CS) lastread := -1 dirty := 0 readblock(spi_vars, 0, @buf) if (getfstype > 0) start := 0 else start := brlong(@buf+$1c6) readblock(spi_vars, start, @buf) filesystem := getfstype if (filesystem == 0) abort(-20) ' not a fat16 or fat32 volume if (brword(@buf+$0b) <> SECTORSIZE) abort(-21) ' bad bytes per sector sectorspercluster := buf[$0d] if (sectorspercluster & (sectorspercluster - 1)) abort(-22) ' bad sectors per cluster clustershift := 0 repeat while (sectorspercluster > 1) clustershift++ sectorspercluster >>= 1 sectorspercluster := 1 << clustershift clustersize := SECTORSIZE << clustershift reserved := brword(@buf+$0e) if (buf[$10] <> 2) abort(-23) ' not two FATs sectors := brword(@buf+$13) if (sectors == 0) sectors := brlong(@buf+$20) fat1 := start + reserved if (filesystem == 2) rootentries := 16 << clustershift sectorsperfat := brlong(@buf+$24) dataregion := (fat1 + 2 * sectorsperfat) - 2 * sectorspercluster rootdir := (dataregion + (brword(@buf+$2c) << clustershift)) << SECTORSHIFT rootdirend := rootdir + (rootentries << DIRSHIFT) endofchain := $ffffff0 else rootentries := brword(@buf+$11) sectorsperfat := brword(@buf+$16) rootdir := (fat1 + 2 * sectorsperfat) << SECTORSHIFT rootdirend := rootdir + (rootentries << DIRSHIFT) dataregion := 1 + ((rootdirend - 1) >> SECTORSHIFT) - 2 * sectorspercluster endofchain := $fff0 if (brword(@buf+$1fe) <> $aa55) abort(-24) ' bad FAT signature totclusters := ((sectors - dataregion + start) >> clustershift) long[spi_vars][SD_rootdir] := rootdir >> SECTORSHIFT long[spi_vars][SD_filesystem] := filesystem long[spi_vars][SD_clustershift] := clustershift long[spi_vars][SD_dataregion] := dataregion long[spi_vars][SD_fat1] := fat1 long[spi_vars][SD_sectorsperfat] := sectorsperfat long[spi_vars][SD_currdir] := rootdir >> SECTORSHIFT PUB readblock(spi_vars, block_index, buffer_address) if long[spi_vars][SPI_engine_cog] == 0 abort ERR_SPI_ENGINE_NOT_RUNNING if (buffer_address & 3) abort ERR_BLOCK_NOT_LONG_ALIGNED long[spi_vars][SPI_block_index] := block_index long[spi_vars][SPI_buffer_address] := buffer_address long[spi_vars][SPI_command] := "r" repeat while long[spi_vars][SPI_command] == "r" if long[spi_vars][SPI_command] < 0 abort SPI_command