\ FILES.TXT     Information on Files and their interface in ZF.

 9. The File System and Handles

          The file system interface in ZF uses Handles to talk to
        DOS, that is only number representing the File ID is passed
        to DOS from Forth. To make the interface a simple and clean
        as possible, you the Forth programmer need never deal with
        the details of how this works, you only need know that
        handles are created with the word HANDLE, handles are arrays
        within which special file information is stored, and when a
        handles name is executed, it returns an address which is the
        address that is passed to the handle file control words. Word
        definitions and usage follow;

        Handle Words in ZF

                .FILES          ( --- )

          Print to the screen a list of the files currently open.

                .LOADED         ( --- )

          Print a list of the files that have been loaded, This list
        is used to locate the source file for a particular word that
        has been compiled.

                ">$             ( char_addr count --- counted_string )

          Drops the count, and decrements char_addr by one, to
        convert to a counted string.

                $>HANDLE        ( a1 handle --- )

          Move the COUNTED STRING a1 into the filename field of
        handle.

                $>EXT           ( a1 handle --- )

          Move the counted string a1 into the extension field of
        handle, the extension string should not contain a decimal
        point, and should be exactly (3) three characters long.

                $HOPEN          ( a1 --- return_code )

          Close the current file if one is open, move the counted
        string from address a1 to the current handle on the handle
        stack. Return the result code from DOS as return_code.

                !HCB            ( handle | text --- )

          Picks up text from the input stream with word, and places
        the name into the handle.



                ?DEF.EXT        ( --- handle )

          Conditionally applies the extension specified in the array
        DEFEXT to the filename in handle. DEFEXT is a counted string,
        three characters long plus the count.

                CHARREAD        ( --- c1 )

          Reads a character from the currently open file specified by
        SHNDL @, before using this word, you will need to initialize
        the sequential input buffer to empty, to force a refill from
        the currently selected file, by saying; INLEN OFF This will
        force a disk read on the next call to CHARREAD, assuring you
        get data from the file you selected.

                CLOSE           ( --- )

          Close the currently open file on SHNDL @, moves down one
        level on the handle stack, so another file may be open after
        performing this operation, but normally you will be able to
        operate on the handle in SHNDL, as an empty handle after
        performing CLOSE.

                CLR-HCB         ( handle --- )

          Clears the handle, to nulls, and resets the handle
        identifier field to -1 to indicate no file is open.

                CURPOINTER      ( handle --- Double_current )

          Returns the current 32-bit double pointer into the file
        specified by handle.

                DEFEXT          ( --- a1 )

          Returns the address of the default file extension that will
        be applied to any file to be opened, if no extension is
        specified in the filename when the HOPEN occurs. The address
        a1 is the address of a 4 byte array containing a count byte,
        and three extension bytes following. In no case should a
        string longer than 3 characters plus count be placed in
        DEFEXT.

                ENDFILE         ( handle --- double_end )

          Return the double_end number which represents the length of
        the file specified by handle. The file must already be open.








                EXHREAD         ( a1 n1 handle segment --- n2 )

          Read from file handle into the buffer specified by segment
        and address a1 for a length of bytes n1, return n2 the length
        of bytes actually read. The file must already be open. Useful
        for reading from a file into memory other than Forth's code
        segment. A read from a file is limited to 65535 bytes.

                EXHWRITE        ( a1 n1 handle segment --- n2 )

          Write from segment and address a1 for a length of n1 bytes
        to file handle, return n2 the length of bytes actually
        written. the file must already be open. Useful for writing
        from memory other than Forth code segment to a file. A write
        to a file is limited to 65535 bytes.

                FILE>TIB        ( a1 --- )

          Move the counted string filename from address a1 to the
        Terminal Input Buffer (TIB), available for use by !HCB.

                FLOAD           ( filename --- )

          Open and load the file specified by filename.

                HANDLE          ( <hndlname> --- )

          Create a handle with name <hndlname>. When <hndlname> is
        later executed, it returns the address of the handle array
        created.

                HANDLE>EXT      ( handle --- a1 )

          Steps from the handle address to the address of the file
        extension in the handle, if an extension exists, else it
        steps to the null following the filename. The address a1 will
        be the address of a decimal point character if the file
        contains an extension, or the address of a null if no
        extension was contained in the handle.

                HCLOSE          ( handle --- return_code )

          Close the file currently open on handle, and return the
        result code from DOS as return_code.

                HCREATE         ( handle --- return_code )

          Create the filename specified by handle, and return the DOS
        result code as return_code.

                HDELETE         ( handle --- return_code )

          Delete the filename as specified by handle, return the
        result code from DOS as return_code.

                HIDELINES       ( --- )

          Specifies that lines loaded with FLOAD NOT be displayed to
        the display screen.

                HOPEN           ( handle --- return_code )

          Given handle the address, open the filename in it, and
        return the result code from DOS as return_code.

                HREAD           ( a1 n1 handle --- n2 )

          Read from file handle into the buffer address a1 for length
        of bytes n1, return n2 the length of bytes actually read. The
        file must already be open. A read from a file is limited to
        65535 bytes.

                HRENAME         ( handle1 handle2 --- return_code )

          Rename the filename specified by handle1 to be the name
        specified in handle2, return the DOS result code as
        return_code.

                HWRITE          ( a1 n1 handle --- n2 )

          Write from address a1 for length n1 bytes to file handle,
        return n2 the length of bytes actually written. The file must
        already be open. A write to a file is limited to 65535
        bytes.

                LINEREAD        ( --- a1 )

          Reads lines from the current file, prebuffered by INBUF,
        which holds 1024 bytes. Returns a1 the address of OUTBUF, a
        256 byte buffer used to hold lines read. When switching to a
        new file, you should use MOVEPOINTER to reset the file
        pointer to the beginning of the file, and reset INLEN to zero
        so the next LINEREAD will cause a read from the disk file.
        The read line length is limited to 255 bytes.

                LIST            ( line_number --- )

          List 18 lines starting at line_number from the currently open
        file. See also L N B OPEN FL

                LOAD            ( line_number --- )

          Start loading the currently open file, at line_number. Load
        through the end of the file if no errors are encountered.






                MOVEPOINTER     ( double_offset handle --- )

          Move the filepointer into the file handle to the offset
        location specified by double_offset. The file must already be
        open.

                PATHSET         ( handle --- f1 )

          Checks the file contained in handle, if it does not contain
        a path, then it applies the current drive and path to the
        handle. Returns f1 FALSE if it succeeded, else TRUE if it
        failed to read the path from DOS.

                RWMODE          ( --- a1 )

          A variable which holds the read/write attributes for any
        file to be opened by HOPEN, normally contains a two (2) for
        read/write, may be set to one (1) for write only, or to zero
        (0) for read only.

                SEEK            ( d1 --- )

          Position the file pointer for the file currently open on
        SHNDL @, to d1, that is SEEK to position d1.

                SEQDOWN         ( --- )

          Close the current file on the current level of the handle
        stack, and step down one level to the previous handle. The
        handle stack is four levels deep.

                SEQUP           ( --- )

          Step up one Handle on the handle stack, if there is a file
        open on that stack level, close it. The stack handle is four
        levels deep.

                SHOWLINES       ( --- )

          Specifies that lines loaded with FLOAD will be displayed to
        the display screen.














        Handle Fields

          A handle contains several fields, and words have been
        defined to traverse to the various fields, here is a picture
        of the data structure of a handle.

            +0        +1                     +66            +68
          [ count ] [ path & filename 00 ] [ attributes ] [ handle ]
            1 byte    64 bytes   +  null     2 bytes        2 bytes
            ^          ^                     ^              ^
            |          |                     |              |
          handle     >NAM                  >ATTRIB        >HNDLE

          Each of the words in the above line, after handle, steps
        from the address returned by the handle, to the field
        indicated.

        Sample of LINEREAD usage.

          A sequential line read word LINEREAD is provided, which
        reads a line at a time from the file open in SHNDL, returning
        an address of a counted string which will include the CRLF
        characters at the end of the line, so you will need to strip
        them off if you don't want them. the LINEREAD word is used as
        follows;

        : sample        ( filename --- )
                open                            \ open a file
                0.0 seek                        \ reset file pointer
                inlen off                       \ clear input buffer
                begin   lineread                \ read a line, returns
                                                \ an address of counted $
                        dup c@                  \ check for length <>0
                while   cr count 2- type        \ type line just read
                                                \ without the CRLF chars.
                repeat  drop                    \ repeat till file empty.
                close ;                         \ close the file.

          This simple example may seem complicated, but it really is
        easy to read the lines of a sequential file, and writing is
        just as easy.

          The word LINEREAD automatically buffers the reads from disk
        in a 1k buffer to minimize the number of DOS calls performed.
        Lines up to 255 characters can be read with LINEREAD, longer
        lines or lines not terminated by a LF will be truncated to
        255 characters.

