include "inc/cmdsys.plh"
include "inc/spiport.plh"

//
// FAT I/O object
//
predef cwd(pathname), chdir(path), mkdir(path), rmdir(path), rename(newpath), remove, exists(path)
predef openFirst(filename), openNext(filename), open(path, mode)
predef close, read(buf, len), write(buf, len), sync, rewind, seek, seekOfs, pos
predef size, truncate, isDir, isFile
//
// SD card FAT filesystem interface
//
export byte[] sdFAT
word[] = @cwd, @chdir, @mkdir, @rmdir, @rename, @remove, @exists, @openFirst, @openNext, @open
word[] = @close, @read, @write, @sync, @rewind, @seek, @seekOfs, @pos
word[] = @size, @truncate, @isDir, @isFile
//
// Directory related functions
//
def cwd(pathname)
    byte namelen

    namelen = 0
    spiSend(15) // CWD
    namelen = spiRecv
    if namelen
        spiReadBuf(pathname+1, namelen)
    fin
    ^pathname = namelen
    return namelen
end

def chdir(path)
    spiWriteBuf(path + 1, ^path)
    spiSend(16) // CHGDIR
    return spiRecv
end

def mkdir(path)
    return 0
end

def rmdir(path)
    return 0
end

def rename(newpath)
    return 0
end

def remove
    return 0
end

def exists(path)
    return 0
end

def openDir(cmd, filename)
    byte namelen

    namelen = 0
    spiSend(cmd)
    namelen = spiRecv
    if namelen == $FF
        namelen = 0
    fin
    if namelen
        spiReadBuf(filename+1, namelen)
    fin
    ^filename = namelen
    return namelen
end
def openFirst(filename) // return filename in buffer
    return openDir(22, filename) // OPENFIRST
end

def openNext(filename) // return filename i buffer
    return openDir(23, filename) // OPENNEXT
end

//
// File related functions
//
def open(path, mode)
    spiWriteBuf(path + 1, ^path) // send filename
    spiSend(21) // OPEN
    spiSend(mode)
    return spiRecv // status
end

def close
    return spiSend(24) // CLOSE
end

def read(buf, len)
    if len > 512
        len = 512
    fin
    spiSend(25) // READ
    spiSend(len >> 8); spiSend(len)
    len = (spiRecv << 8) | spiRecv
    if len > 0
        spiReadBuf(buf, len)
    fin
    return len
end

def write(buf, len)
    if len > 512
        len = 512
    fin
    spiWriteBuf(buf, len)
    spiSend(26) // WRITE
    spiSend(len >> 8); spiSend(len)
    len = (spiRecv << 8) | spiRecv
    return len
end

def sync
    return 0
end

def rewind
    return 0
end

def seek
    return 0
end

def seekOfs
    return 0
end

def pos
    return 0
end

def size
    return 0
end

def truncate
    return 0
end

def isDir
    spiSend(35) // ISDIR
    return spiRecv
end

def isFile
    return 0
end

//
// Init SD card FAT filesystem
//
spiSend(14) // SDINIT
return spiReady <> 0 // Is Arduino READY?
done
