To use this file copy and paste this:    // #URL-lib "http://pin1.org/forthlib/flb/SD-Card/fat-3.flb"   into BV Terminal 3 or here to download.

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // FAT formmatted SD card access // ========== P A R T 3 ====================================== // This section is for reading existing files on the card // it also has the beginnings of operastions with the FAT that // is also necessary for writing. This file introduces logical // sectors, sectors within files rather then physical sectors on // the card. // This shares many words with fat-1-a and fat-2 so it should // have the same SID number // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY: // Mar 2008 * found extra ; in f.open - removed

// REQUIRES: // #URL-Inc "http://pin1.org/forthlib/flb/General/soft1.flb" sid=99 // #URL-lib "http://pin1.org/forthlib/flb/General/pinsel.flb" sid=100 // #URL-lib "http://pin1.org/forthlib/flb/General/SPI.flb" sid=101 // #URL-lib "http://pin1.org/forthlib/flb/SD-Card/MMC.flb" sid=102 // #URL-lib "http://pin1.org/forthlib/flb/SD-Card/fat-1.flb" // #URL-lib "http://pin1.org/forthlib/flb/SD-Card/fat-2.flb"


Full Contents of File

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// FAT formmatted SD card access
// ========== P A R T 3 ======================================
// This section is for reading existing files on the card
// it also has the beginnings of operastions with the FAT that
// is also necessary for writing. This file introduces logical
// sectors, sectors within files rather then physical sectors on
// the card.
// This shares many words with fat-1-a and fat-2 so it should
// have the same SID number
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

// HISTORY:
// Mar 2008 * found extra ; in f.open - removed

// REQUIRES:
// #URL-Inc "http://pin1.org/forthlib/flb/General/soft1.flb" sid=99
// #URL-lib "http://pin1.org/forthlib/flb/General/pinsel.flb" sid=100
// #URL-lib "http://pin1.org/forthlib/flb/General/SPI.flb" sid=101
// #URL-lib "http://pin1.org/forthlib/flb/SD-Card/MMC.flb" sid=102
// #URL-lib "http://pin1.org/forthlib/flb/SD-Card/fat-1.flb"
// #URL-lib "http://pin1.org/forthlib/flb/SD-Card/fat-2.flb"

// ========== FAT - Read ==========================
// this gets an address and sector where the adress was found
// so that the cluster can either be fetchd or stored to, eing word16
// this can be considered the cluster variable
: fatClust  ( clust -- address )
        2*            // calc cluster #
        BytesSec  d  @  u/mod // [offset fat]
        FatTable1  d  @  +      // load correct sector ** only if not current
        dup  d-sec  <>  if  Dsec@  else  drop  then
        Dbuff  +            // offset into table
;
// fat cluster fetch, given a cluster number this will fetch its
// value, the table starts at 0, 0 fatClust@ will fect the value
// of the first cluster. Note in a chain the value fetched will be the
// next cluster
: fatClust@ ( clust# -- val )
        fatClust
        word16  // fetch
;

// a Logical sector is the sector into that file, translates
// a logical sector to a physical sector using the FAT table
// file must be open with File handle fillled
// returns -1 if trying to read beyond available sectors
// logical sector to physical sector
: Ls2Phys ( lSec -- PhySec|-1 )          
    SectClust  d  @  u/mod // get jump and offset
    dirAdd  start-clust@  swap
// 12 dir# @ swap
    ?dup  // for will iterate even if 0
    if
        for 
            fatClust@      // iterate Jump times
            dup  &fff7  >  if  drop  drop  -1  unloop  escape  then      // end of file
        next
    then   
    SectClust  d  @  *      // convert back to sectors
    +                          // add offset into sector
    fileSpace  d  @    +  // add filespace offset
;       

// opens a file and sets up the file handle structure, does not read any
// data in at this stage but simply sets up the buffer and file variables
// Opens file on CURRENT device
// File handle is also loaded with the directory entry so that it does
// not need to be read again and only needs writing on close.
: r-open ( string, handle -- [error] )
    =>  f#          // file buffer
    dir-search    // serch dir of that device
    if
        dup  en#  f  !          // save entry number
        dir-entry  dirEntry  f  32  move    // copy dir entry
        d-sec  dirSec  f  !    // for later writing, on close
        -1  isOpen  f  !        // indicate opened
        d#  device  f  !      // associate device with file
        0    EOF  f  !          // not eof
        0  error
    else
        20  error
        0  IsOpen  f  !
    then
;               

// calculates actual file size as calculated ffrom the fat table.
// : fileSize ( --- sectors )
// IsOpen f @ 0 > if 110 error then
// TotalSec d @
// for
// i Ls2Phys 0 < if leave then
// next
// ii
// ;


// random read - reads a file at a given logical sector, this is a sector
// within that particular file regardless of where it is on the card
// it uses Ls2Phys to calculate its actual position
// return -1 if trying to read past end of clutser
// **** can be improoved by looking at file size ****
: r-random  ( handle LogicalSec --- [buff]0|-1)
    swap  =>  f#
    Ls2Phys      // convert
    dup  0  <  if  drop  -1  else  sec@  0  then
;   

// --------------- Public interfaces from this module ------------------
// note on file operations -1 is eof so this is opposite to what is norm
: <0>f.open ( string handle -- -1|0)
    dup  0  devices  between
    if 
        r-open  error#  0=    // -1 okay
    else
        drop  drop
        ."  Handle  value  wrong  "
    then
;           
: <0>f.rrandom ( handle sector -- 0|-1)     // -1 on past end of file
    r-random  ;
: <0>f.fileSize ( handle -- sectors )     // file size
    =>  f#  dirAdd  filesize@  bytessec  d  @  /
;
: <0>f.size ( handle -- bytes )   =>  f#  dirAdd  fileSize@  ;  // size
: <0>f.fb ( handle -- file-buffer )   =>  f#  fatb  ;  // file buffer