=== Direct File Access V. 1.0 ===
=== Library Documentation ===

Contents

  1. General
    1.1. Legal Stuff & Contacting the Programmer
    1.2. About

  2. DFA function descriptions
  3. The demo programs
  4. Using DFA in RXE programs
  5. Special Thanks

1. General

1.1. Legal Stuff & Contacting the Programmer

DFA library is freeware, feel free to copy and distribute it like you want. It also comes with the source this time, you can read and study or modify it for your own purposes.

NOTE: This library comes with absolutely no warranty, use is on own risk!!! Bugs or problems are not known at the moment, but if you encounter any, I would be pleased if you tell me. Also suggestions are welcome every time. My Email address(es) is(are):

DFA's homepage is:

See it also in the UCF File Sharing Area.


1.2. About

This library provides direct access to drives and files stored in the flash or ROM without using DOS file I/O. That means: The library comes with the source, this doc and two example programs.

2. Function descriptions

type pbytes = ^tbytes;
     tbytes = array[0..0] of byte;
A linear buffer of bytes located somewhere in memory. Pointers returned on files are pbyte structures.
type pdrivebank = ^tdrivebank;
     tdrivebank = record
                    drive: char; {current drive 'B','C',...,'Q'; '-' = none}
                    files: byte; {number of files on disk; 0 = invalid disk or file system}

                    drive_sectors: word; {number of disk sectors}
                    fat_sectors  : word; {number of sectors required for FAT}
                    vzone_sectors: word; {number of sectors required for disk valudation zone}

                    drivesize: longint; {disk size in bytes = sum of all file sizes}
                    fat      : pbytes;  {pointer to file allocation table (FAT)}
                  end;
This structure is used for managing drives. Before accessing a file from a memory bank, the according drive must be selected.
type pdrivebanks = ^tdrivebanks;
     tdrivebanks = array[0..3] of tdrivebank;

var drivebanks: tdrivebanks; {drivebanks 0..3 are mapped into EMS slots 2,3,4 and 5}
There are 4 drivebanks you can use to map drives into, where flash drives always occupy 1 bank and for ROM drives this depends on the drive's size.

However, when using DFA in RXE programs, note that you mustn't remap drivebank 0, see 4. Using DFA in RXE programs therefore.
type string8 = string[8];
     string3 = string[3];

type pdfa = ^tdfa;
     tdfa = record
              fsect: word;    {first sector of file relative to end of FAT}
              fsize: longint; {file size in bytes}
              fbuff: pbytes;  {pointer to file contents/first byte of file}
              findx: byte;

              fname: string8; {file name}
              fext: string3;  {file name extension}

              year: word;    {file date}
              day,mon: byte;
              s,m,h: byte;   {file time}
            end;
The tdfa structure is used to hold file information.
const maperr: boolean = false; {error: cannot map drive to bank, disk too big}
      dfaerr: boolean = false; {error: file not found                        }
These variables hold error codes when you executed a DFA operation. MAPERR is true, when it's impossible to map a drive into a bank. This is when for example the drive number is invalid (e.g. W:\) or you want to map a drive that uses three banks into bank 2 (where you only may map drives using one or two banks).
function getdrivebankmap(bank: byte): char; {get current drivebank drive     }
procedure getdrivebank(bank: byte);         {get disk info for drivebank     }
procedure getdrivebanks;                    {get disk info for all drivebanks}
procedure mapdrivebank(drive: char; bank: byte); {map drive into drivebank   + get info}
procedure mapdrivebanks;                         {map drives into drivebanks + get info}
Drive mapping functions.

Before doing anything with DFA, you always should call GETDRIVEBANKS determining which drives currently are mapped and storing infos about them in the DRIVEBANKS variable (on startup, bank 0 normally is the drive that the program was started from). Rather like GETDRIVEBANKS, GETDRIVEBANK determines which drive is mapped into a bank and stores the drive info to DRIVEBANKS, but with one certain bank only.

GETDRIVEBANKMAP returns the drive char of the drive mapped into a bank.

Finally, MAPDRIVEBANK is used to map a certain drive into a certain bank. Always check MAPERR variable afterwards, which is true on fail (details see above). Also, when using DFA in RXE programs you mustn't remap drivebank 0, see 4. Using DFA in RXE programs therefore.
{get size of a string stored in FAT string format}
function fatstringsize(buff: pbytes; size: byte): byte;
{get direct file access for file at FAT index}
procedure getdfa(var dfa: tdfa; bank,index: byte);
{get direct file access for first file (name) in FAT}
procedure getdfaname(var dfa: tdfa; bank,pos: byte; fname: string8);
{get direct file access for first file (extension) in FAT}
procedure getdfaext(var dfa: tdfa; bank,pos: byte; fext: string3);
{get direct file access for first file (name).(extension) in FAT}
procedure getdfanameext(var dfa: tdfa; bank,pos: byte; fname: string8; fext: string3);
{get pointer to byte pos in file; usefull for files > 64KB allocating more than one segment}
function dfaseek(dfa: tdfa; pos: longint): pbytes;
These finally are the file access functions assuming that the according drive is mapped proper.

3. The Demo programs

There are two demo programs + source included in this library package that you can learn how to use Direct File Access.

4. Using DFA in RXE programs

When you want to do this, there's one thing you have to take a look for: You may browse the drive currently mapped to drive 0, but NEVER EVER REMAP IT! This would cause your program to crash (you may remap banks 1 to 3 though).

The reason why is quite simple: Rxe programs aren't executed in the RAM, but in the flash. On startup, the drive where the program is located is mapped to bank 0 (for RXE as well as EXE), and an RXE is executed in bank 0 therefore. Remapping bank 0 thus would mean the CPU keeps executing it's code from that location in the address space where it did before, but the contents have completely changed (namely replaced by the contents of another drive).

5. Special Thanks

Special Thanks to:

Dscoshpe (Walter Hanau)
Oliver Coupelon