//drive.h Copyright (C) 1989-2010 I.Pedley (CTPP) Mon 04-Oct-1999 at 21:34:45

//ChaOS IDE drive support

//512-byte structure returned by ATA devices on receiving ATA_IDENTIFY command
struct ATA
{
    UI  gencfg;
    UI  cyls;
    UI  res1;
    UI  heads;
    UI  res2;
    UI  res3;
    UI  spt;
    UI  res4[3];
    UC  serial[20];
    UI  res5;
    UI  res6;
    UI  vspecbytes;
    UC  revision[8];
    UC  model[40];
    UI  multmax;        //max sectors per interrupt on READ/WRITE MULTIPLE
    UI  res7;
    UI  capabilities;
    UI  res8;
    UI  piotiming;
    UI  res9;
    UI  valid;
    UI  logcyls;
    UI  logheads;
    UI  logspt;
    UL  sectors;        //moody sector count up to 8Gb
    UI  multsetting;    //current sectors per interrupt on READ/WRITE MULTIPLE
    UL  lbasectors;     //the REAL sector count, if zero this is a CHS drive?
    UI  res10;
    UI  multiwordDMA;
    UI  piomodes;
    UI  mDMAns;         //minimum multiword DMA transfer cycle/word (nanosecs)
    UI  manDMAns;       //mfr's multiword DMA transfer cycle/word (nanosecs)
    UI  minPIO;         //minimum PIO cycle without IORDY flow control
    UI  minPIOf;        //minimum PIO cycle with IORDY flow control
    UI  res11[11];
    UI  vermajor;       //major version, bit1=ATA-1,bit2=ATA-2,bit3=ATA-3 etc
    UI  verminor;
    UI  cmdset0;
    UI  cmdset1;
    UI  res12[4];
    UC  udmacap;        //udma capabilities
    UC  udmaset;        //udma current setting
    UI  res13[11];
    UL  lba48;
    UI  lba48hi;
    UI  res14[25];
    UI  security;
    UI  res15[126];
    UI  res16;
};

//structure to describe IDE hard disk controller;
struct  HDC
{
    UC  id;
    UC  status;         //last status byte read from HDC->port+7
    UC  error;          //last error  byte read from HDC->port+1
    UC  mode;           //0=none 1=PIO
    UC  intr;           //0x01=controller responds to reset with an interrupt
                        //0x80=used to flag interrupt occured
                        //
    UL  drive1;         //drive 1 detected on this controller
    UL  drive2;         //drive 2 detected on this controller
    UL  port;           //base address of controller
    UL  regport;        //address of controller "reg" port
    UC  irq;
    UC  vector;
    UL  interrupts;
    UC  cmd[8];
    UC  sts[8];
    UL  bmiba;          //address of controller Bus Mastering register set
    UC* udmabuf;        //UDMA buffer, 64k aligned
    UC* udmaprd;        //UDMA Physical region descriptors 64k aligned
    UL  present;
    CH  tag[8];
    VD* master;         //these are DEV*
    VD* slave;
};
//GUID partitions 2.10.2009
struct GPTBL
{
    CH  sig[8];     //must be "EFI PART"
    UL  rev;        //0x00000100
    UL  hdrsiz;     //usually 0x52/92
    UL  crc32;
    UL  res0;
    UL  curlba;     //LBA1
    UL  curlbahi;
    UL  bkplba;      //last LBA on disk
    UL  bkplbahi;
    UL  first;      //first usable LBA after GUID partition table
    UL  firsthi;
    UL  last;       //secondary GUID partition table-1
    UL  lasthi;
    UC  guid[16];
    UL  start;      //start lba of partition table entries
    UL  starthi;
    UL  count;      //number of partition table entries
    UL  ptsiz;      //sizeof a partition table entry
    UL  ptcrc32;    //crc32 of partition table entry array
    UC  res1[420];
};
struct GPART
{
    UC  type[16];
    UC  id[16];
    UL  start;
    UL  starthi;
    UL  end;
    UL  endhi;
    UL  attr;
    UL  attrhi;
    CH  name[72];
};

//how CHS values are ordered in a partition table entry
struct pCHS{UC h,s,c;};

//structure of a partition table entry
struct  PARTITION
{
    UC   bootable;
    pCHS start;
    UC   system_id;
    pCHS end;
    UL   first_sector;
    UL   sectors;
};
//structure of extra partition table entry
struct  SPARTITION
{
    PARTITION p;
    CH  name[16];   //16 bytes for future use
};

#define PTEXECLEN   0x1be
#define CHPTEXECLEN 0x190
//ChaOS partition table structure
struct  PTSECTOR
{
    UC  jmp[3];
    UI  hC;         //'hC' means its a ChaOS partition table
    UC  mbr[0x18b]; //code and data of partition table executable
    CH  netname[9]; //org 0x190, 0x690 at run time
    UC  edd;        //&0x02=EDD executable (compile-time flag)
                    //&0x01=this boot device is EDD capable (run-time flag)
    UC  drv;
    UC  actual;     //run-time placeholder for partition which booted
    UC  timeout;
    UC  def;
    CH  name[4][8];
    PARTITION p[4];
    UI  sig;
};
//structure of extra partition table, stored at sector 1
struct SPTSECTOR
{
    SPARTITION s[16];   //NB:last two bytes of sector must be 55bb signature
};
//a structure to hold drive translated geometry
struct CHS {UL c,h,s;};

//Chaos FS superblock, at LBA 1
struct CHAOSBLOCK
{
    CH  idstring[16];//"ChaOS block"
    CH  name[16];    //asciiz string used by system as drive identifier
    UL  start;       //sectors reserved for other systems; ChaOS start sector
    UL  startspare;  //reserved for 64-bit LBA's           0x24
    UL  len;         //ChaOS partition length in sectors;  0x28
    UL  lenspare;    //reserved for 64-bit LBA's           0x2c
    UM  date;        //creation date and                   0x20
    UM  time;        //time of this sector                 0x34
    UL  files;       //                                    0x38
    UL  flags;       //used to control flushing to disk    0x3c
    UL  ntb;         //lba of nametable CHAOSFILE          0x30
    UL  ntbspare;    //reserved for 64-bit LBA's           0x44
    UL  ntblen;      //                                    0x48
    UL  dbase;       //lba of CHAOSFILE database           0x4c
    UL  dbasespare;  //reserved for 64-bit LBA's           0x40
    UL  dbaselen;    //                                    0x54
    UL  dbidx;       //lba of CHAOSFILE index              0x58
    UL  dbidxspare;  //reserved for 64-bit LBA's           0x5c
    UL  dbidxlen;    //                                    0x50
    UL  last;        //last CHAOSFILE in chain             0x64
    UL  lastspare;   //reserved for 64-bit LBA's           0x68

    UL  tcounter;    //for MCHAOS                          0x6c
    UC* db;          //                                    0x70
    UC* di;          //                                    0x74
    UL* treexref;    //                                    0x78
    UL  spare[0x61]; //                                    0x7c
};
EX  CH* cbid;       //id string for CHAOSBLOCKS

//basic BIOS drive info returned by int 0x13/0x08
struct BDINFO
{
//returned by int 0x13/0x08
    UL c,h,s;   //BIOS translated geometry for this drive
    UI ax,bx,cx,dx;
//returned by int 0x13/0x41
    UI ext;     //&1=EDD packet read/write;&2=removable media;&4=EBDINFO available
    UI extver;
};
//extension to the extension, if EBDINFO->efdpt not 0xffffffff
struct EFDPT    //Extended Fixed Disk Parameter Table
{
    UI  port0;
    UI  port1;
    UC  id;
    UC  res;
    UC  irq;
    UC  cnt;
    UC  dma;
    UC  pio;
    UI  flg;
    UI  res1;
    UC  rvn;
    UC  cksum;
};
//extended BIOS drive info, available if int 0x13/0x41 returned cx&4
struct EBDINFO
{
    UI  len;    //0x1e to 0x4a seen so far
    UI  flg;
    UL  c,h,s;  //native geometry for this drive
    UL  lbs;
    UL  lbshi;
    UI  bps;
    EFDPT* efdpt;
    UC  extra[0x2c];
};
//BIOS boot CD emulation structure
struct BCDSPEC
{
    UC  len;    //13
    UC  media;  //0=none;1=1.2Mb;2=1.44Mb;3=2.88Mb;4=Hard disk
    UC  drv;
    UC  ctrl;
    UL  lba;
    UI  lun;
    UI  bufseg;
    UI  loadseg;//0x07c default
    UI  sectors;
    UC  ch;     //cyl 0-7       //for hard disk emulation these
    UC  cl;     //cyl 9-8|sec   //numbers seem so be taken from
    UC  dh;     //hd            //partition table entry[0]->end{h;s;c;}
};

struct HDG
{
    UL  lbs;
    UL  lbshi;
    UL  bps;
    UL  cap;
    UL  c,h,s;
    UL  bdrv;
    PTSECTOR pt;
    BDINFO  bd;
    EBDINFO ebd;
    BCDSPEC bs;
};

////structure to describe physical drive
//struct  HARD
//{
//    HDG hdg;
//    HDC* hdc;           //controller for this drive;
//    UL  cylinders;      //\
//    UL  heads;          //==as reported by ATA
//    UL  sectorspertrack;///
//    UL  busy;
//    CHS trans;          //translated geometry
//    UC  id;             //controller's drive number for this disk unit
//    UC  mode;           //0=no drive 1=CHS 2=LBA
//    UC  udma;
//    UC  partitions;     //0=no partition table found
//    UC  ldrives;        //0=no logical drives found
//    UC  readonly;       //
//    UL  err;            //last error code accessing this drive
//    UL  bytespersector;
//    UL  totalsectors;
//    UL  seekcyl;
//
//    UL  current_head;
//    UL  current_cylinder;
//    UL  current_sector;
//    SL  logicalsector;
//    ATA      ata;
////    PTSECTOR   pt;
//    SPTSECTOR  spt;
//    CHAOSBLOCK cb;
//    UL  cflba;
//    CH  tag[10];        //Chaos tag for this device
//};

struct BOOTSECTOR;
struct CHAOSBLOCK;
struct CHAOSFILE;
struct CACHE
{
    UL  sectors;
    UL* sectorlba;
    UC* sectorflg;
    UC* sectorbuf;
    UC* sectorbufend;
    UL  current;
    UL  hits,misses;
};

#define lfBSY   0x00000001
#define lfRMV   0x00000002
#define lfLFN   0x00000004
#define lfCPY   0x00000008

//structure to describe logical drive
struct  LDRIVE
{
    VD*     usr;        //backlink to DEV system
    UL      userno;     //non-zero for a remote drive
    UL      remidx;     //index of LDRIVE in remote LD[] array
    UC      readonly;
    UC      removable;
    UC      dirfilter;
    UC      media;
    UL      filesystem; //0=none
    UL      extset;     //file extension set for this drive
    UL      flg;
    BOOTSECTOR* b;
    PARTITION   P;      //copy of partition table entry for this LDRIVE
    UL      ptlba;      //back-link to physical location of
    UL      ptentry;    //the partition table entry
    UL      start;      //LBA of start of the partition
    UL      end;
    GPART   gp;
    UL      len;
    UL      capacity;
    UL      bps;
    UL      spc;
    UL      fat;
    UL      root;
    UL      data;
    UL      driveletter;//should match DOS drive letter
    CH      tag[10];    //Chaos tag for his drive
    CH      vol[11];    //volume label from dos boot sector
    CH      oem[8];     //OEM name from dos boot sector
    CH      cd[128];    //current directory
    UL      cdcluster;  //cluster of start of current directory
    UL      rootentries;
    UL      fatentries;
    UL      spf;        //sectors per fat
    UL      updateFAT;
    UL      fbvalid;
    UC*     fatbuffer;
    UC*     fatmodified;
//fields to support CHAOSFILE system
    CHAOSBLOCK* cb;     //memory copy of CHAOSBLOCK, contains file counter
    CH*     ntb;        //memory copy of nametable
    UL      ntblen;
    CHAOSFILE* cf;      //ready for memory buffering of CHAOSFILES
    UL      memfiles;   //size of memory buffer, to be created using
                        //cb->files+extras;
    UL      cfmem;      //set to 1 when memory buffering is running

//new sector cacheing for LDRIVES
    UL      cacheing;   //set to 1 when sector cache is on
    UL      cachesize;  //sector cache size in Kilobytes
    CACHE   cache;
    UL      bd,cyls,hds,spt;
};

//defines for LDRIVE->filesystem
#define     FAT12   0xfa12
#define     FAT16   0xfa16
#define     FAT32   0xfa32
#define     NTFS    0x5346544e
#define     ISO9660 0x9660
#define     LINEXT2 0xeee2
#define     CHAOS   0xca05

//LDRIVE absolute LBA read and write, range-checked
SL  read (LDRIVE* l,UL lba,UL sectors,VD* buf);
SL  write(LDRIVE* l,UL lba,UL sectors,VD* buf);

//flags for removable media state
#define     FIXED       0x00000000
#define     REMOVABLE   0x00000001
#define     BOOTCD      0x000000cd
#define     INVALID     0x80000000


//defines for HDC->mode field
#define mNONE           0       //controller is not present
#define mCHS            1       //use CHS command format (Cyl,Head,Sector)
#define mLBA            2       //use LBA command format (Logical Block Address)
#define mCDLBA          3       //CD  LBA command format
#define mUDMA2          4
#define mUDMA4          5
#define mONTRACK        6       //use CHS with 63-sector offset for
                                //partitionstart and partitionend
#define mRAM            7       //used to support ramdrives
#define mCDINIT         8       //CD mode used during media init
#define mBIOS           9       //Bios Int 13h access

//UL  hardread (HARD* h,UL lba,UL sectors,VD* buf);
//UL  hardwrite(HARD* h,UL lba,UL sectors,VD* buf);

//just like a DOS BPB, with jmp[] and oem[] tagging along at the beginning
struct BOOTSECTOR
{
    UC  jmp[3];
    CH  oem[8];
    UI  bytes_per_sector;
    UC  sectors_per_cluster;
    UI  sectors_reserved;
    UC  fats;
    UI  root_entries;
    UI  total_sectors;
    UC  mediabyte;
    UI  sectors_per_fat;
    UI  sectors_per_track;
    UI  heads;
    UL  hidden_sectors;
    UL  ext_totalsectors;
    UI  physicaldrivenumber;
    UC  extbootsignature;
    UL  serial;                     //valid if extbootsignature is 0x29
    CH  volume[11];                 //  "            "
    CH  fatscheme[8];               //  "            "
};
struct FAT32BOOTSECTOR
{
    UC  jmp[3];
    CH  oem[8];
    UI  bytes_per_sector;
    UC  sectors_per_cluster;
    UI  sectors_reserved;
    UC  fats;
    UI  root_entries;
    UI  total_sectors;
    UC  mediabyte;
    UI  sectors_per_fat;
    UI  sectors_per_track;
    UI  heads;
    UL  hidden_sectors;
    UL  ext_totalsectors;
    UL  spf;                        //WIN95 additional fields
    UL  dontknow1;                  //if b->sectors_per_fat==0
    UL  rootdircluster;
    UL  dontknow2[4];
    UI  physicaldrivenumber;
    UC  extbootsignature;
    UL  serial;                     //valid if extbootsignature is 0x29
    CH  volume[11];                 //  "            "
    CH  fatscheme[8];               //  "            "
};

//struct DOSDIRENTRY
//{
//    CH  name[8];
//    CH  ext[3];
//    UC  attr;
//    LDRIVE* l;              //these 10 reserved bytes in DOS serve in CHAOS as a
//    UI  directorycluster;   //placeholder for the logical LDRIVE* holding this
//    UI  directorysector;    //file and the directory entry's position in terms
//    UI  directoryentry;     //of cluster,sector,entry
//                            //3.12.99 WIN95 uses the fields too, particlarly
//                            //UI directoryentry, which holds the top 16 bits of
//    UI  time;               //the FAT32 cluster number
//    UI  date;
//    UI  cluster;
//    UL  size;
//};
struct DOSDIRENTRY
{
    CH  name[8];
    CH  ext[3];
    UC  attr;
    UL  res1;
    UL  res2;
    UI  clusterhi;          //top 16 bits of the FAT32 cluster number
    UI  time;
    UI  date;
    UI  clusterlo;
    UL  size;
};
struct DOSLFNENTRY
{
    CH  name[8];
    CH  ext[3];
    UC  attr;
    UC  res;
    UC  crmsec;             //creation time and date
    UI  crhrmin;
    UI  crdate;
    UI  lastaccessdate;
    UI  clusterhi;
    UI  time;
    UI  date;
    UI  clusterlo;
    UL  size;
};
struct DOSFILE              //memory structure used by ChaOS to handle DOS files
{
    UL  error;
    DOSDIRENTRY d;
    LDRIVE* l;
    UL  cluster;
    UL  lba;
    UL  dirstartcluster;
    UL  dircluster;
    UL  dirnextcluster;
    UL  dirsector;
    UL  direntry;
    UL  lfcksum;
    UL  lflba;
    UL  lfdirentry;
    CH  longfilename[256];
    UC  tempsector[512];
};

#define ftNORMAL    0x00
#define ftRDONLY    0x01
#define ftHIDDEN    0x02
#define ftSYSTEM    0x04
#define ftVOLUME    0x08
#define ftSUBDIR    0x10
#define ftARCHIVE   0x20

UL  getnextcluster (LDRIVE* l,UL cluster);
UL  allocatecluster(LDRIVE* l,UL prev);
VD  freecluster    (LDRIVE* l,UL cluster);
UL  findfreecluster(LDRIVE* l);

//generic file system error codes
//expand to text message using

VD  clidosfileerrormsg(UL n);

#define FILENOTFOUND        0x80000001
#define FILEALREADYEXISTS   0x80000002
#define WILDCARDCHAR        0x80000003
#define ILLEGALCHAR         0x80000004
#define WILDCARDPATH        0x80000005
#define ILLEGALPATH         0x80000006
#define ILLEGALNAME         0x80000007
#define ILLEGALEXT          0x80000008
#define PATHONLY            0x80000009
#define MEDIAERROR          0x8000000a
#define NOPATH              0x8000000b
#define NONAME              0x8000000c
#define ILLEGALDRIVE        0x8000000d
#define ILLEGALCLUSTER      0x8000000e
#define DIRECTORYNOTEMPTY   0x8000000f
#define SOFTWAREERROR       0x80000010
#define NOMEDIA             0x80000011
#define NOMEMORY            -2L
#define DRIVEONLY           0x80000013
#define DRIVEISREADONLY     0x80000014
#define ACCESSDENIED        0x80000015
#define DEVICETIMEOUT       0x80000016
#define DEVICEINTTIMEOUT    0x80000017
#define DEVICEERROR         0x80000018
#define INVALIDCOMMAND      0x80000019
#define DEVICEBUSY          0x80000020
#define ROOTDIRECTORYFULL   0x80000021
#define READERROR           0x80000022
#define WRITEERROR          0x80000023
#define DISKFULL            0x80000024
#define BEYONDEND           0x80000025
#define CHAINENDSEARLY      0x80000026
#define DIRECTORYNOTFOUND   0x80000027
#define SECTORNOTFOUND      0x80000028
#define BRANCHNOTFOUND      0x80000029
#define ENDOFROOTDIRECTORY  0x80000030
#define NOTASUBDIRECTORY    0x80000031
#define CORRUPTSUBDIR       0x80000032
#define INSUFFICIENTSPACE   0x80000033
#define NOFILESYSTEM        0x80000034
#define NOSUPPORT           0x80000035


//defines for navigating Linux partitions
//
#define BLOCKSIZE   1024
#define EXT2MAGIC   0xef53
#define ROOTINODE   2
struct  SUPERBLOCK
{
    UL  inodes;
    UL  blocks;
    UL  reservedblocks;
    UL  freeblocks;
    UL  freeinodes;
    UL  data;
    UL  blocksize;
    UL  fragsize;
    UL  blockspergroup;
    UL  fragspergroup;
    UL  inodespergroup;
    UL  mtime;
    UL  wtime;
    UI  mcount;
    SI  maxmcount;
    UI  magic;
    UI  state;
    UI  errors;
    UI  pad;
    UL  lastcheck;
    UL  checkinterval;
    UL  creator;
    UL  revision;
    UI  defresuid;
    UI  defresgid;
    UL  res[235];
};

struct GROUPDSC
{
    UL  blockbitmap;
    UL  inodebitmap;
    UL  inodetable;
    UI  freeblocks;
    UI  freeinodes;
    UI  useddirs;
    UI  pad;
    UL  res[3];
};

struct  INODE
{
    UI  mode;
    UI  uid;
    UL  size;
    UL  atime;
    UL  ctime;
    UL  mtime;
    UL  dtime;
    UI  gid;
    UI  links;
    UL  blocks;
    UL  flags;
    UL  osd1;
    UL  block[15];

    UL  version;
    UL  fileacl;
    UL  diracl;
    UL  fragaddr;
    UC  frag;
    UC  fragsize;
    UI  pad;
    UL  res[2];
};

//Special inode numbers
#define EXT2_BAD_INO             1      //Bad blocks inode
#define EXT2_ROOT_INO            2      //Root inode
#define EXT2_ACL_IDX_INO         3      //ACL inode
#define EXT2_ACL_DATA_INO        4      //ACL inode
#define EXT2_BOOT_LOADER_INO     5      //Boot loader inode
#define EXT2_UNDEL_DIR_INO       6      //Undelete directory inode
#define EXT2_FIRST_INO          11      //First non reserved inode

//see foundations notes in cfs.ctp

//UL  chaosblocklba(HARD* h);     //returns LBA of CHAOSBLOCK on a hard disk

//heap.h definitions are duplicated here for reference
#define LASTHEAPITEM 0x80000000
#define FREEHEAPITEM 0x40000000

//flags for memory cacheing of CHAOSFILES
#define CFPRESENT    0x00000001
#define CFNOTEMPTY   0x00000002
#define CFMODIFIED   0x00000004
#define CFDBASE      0x00000010
#define CFIDX        0x00000020
#define CFADVANCED   0x00000800

#define CFMAGIC      0x1ef105ca

//CHAOSFILE is embryo file record
struct CHAOSFILE
{
    UL  lba;            //lba of this block on disk
    UL  lbaspare;       //reserved for 64-bit LBA's
    UL  prev;           //lba of previous file in chain (not currently used)
    UL  prevspare;      //reserved for 64-bit LBA's
    UL  next;           //lba of next file in chain 0x10
    UL  nextspare;      //reserved for 64-bit LBA's
    UL  len;            //length of block in sectors, including header
    UL  lenspare;       //reserved for 64-bit LBA's
    UL  type;           //0=empty,                  0x20
                        //1=bootstrap
                        //2=standalone .XEC
                        //3=nametable
                        //see ftype.h for other file types
                        //other values available for expansion apart from:
                        //>0x80000000=archived file otherwise file is latest
    UL  flags;          //0x00000001=modified       0x24
                        //0x80000000=LASTHEAPITEM
                        //0x40000000=FREEHEAPITEM
    UL  ver;            //                          0x28
    UL  magic;          //set to 0xca05f11e         0x2c

//file name matching area is 144 bytes from here (148 including archive no)
//note that file type is intended to be free-form for the programmer to use
//and is NOT checked by system during name matching
    UM  nesting;        //subdirectories in [tree]  0x30
    UM  memtree[15];    //sorted subdirectory array 0x34
    CH  name[64];       //                          0x70
    CH  ext [16];       //                          0xb0
    UL  archive;        //modified sequence number  0xc0
//end of file name matching area

    UM  tree[15];       //prime subdirectory array  0xc4
    UM  date;           //                         0x100
    UM  time;           //                         0x104
    UL  flen;           //byte length of file      0x108
    UL  flenspare;      //reserved for 64-bit file lengths
    UL  clen;           //compressed byte length of file if non-zero
    UL  clenspare;      //reserved for 64-bit file lengths

    UL  padding[58];    //pad to 512 bytes

};

SL  chaosmalloc(LDRIVE* l,CHAOSFILE* cf,UL bytes);
SL  chaosfree  (LDRIVE* l,CHAOSFILE* cf);
SL  cfread     (LDRIVE* l,CHAOSFILE* cf,UL lba);
SL  cfwrite    (LDRIVE* l,CHAOSFILE* cf);
SL  read       (LDRIVE* l,CHAOSFILE* cf,VD* buf,UL bytes,UL filepos);
SL  write      (LDRIVE* l,CHAOSFILE* cf,VD* buf,UL bytes,UL filepos);


//structure and functions for parsing file paths
struct  PATH
{
    LDRIVE* l;
    UL  flags;
    UC  nesting;
    UC  noname;
    UC  noext;
    UC  wildcard;
    UC  namewildcard;
    UC  extwildcard;
    UC  current;
    UC  defaultdrive;
    UL  attr;           //fields for
    UM  date;           //passing file
    UM  time;           //parameters between
    UL  len;            //different
    UL  ver;            //filesystems
    UL  type;
    UL  archno;

                        //fields to pass findfirst/findnext info
                        //usage:  DOS                    Unix       Chaos
    UL  node;           // start cluster of file     file inode     file lba (relative to start of partition
    UL  dirnode;        // cluster of dir entry      dir inode      not used
    UL  dirsector;      //  sector in that cluster      not used    not used
    UL  direntry;       //   entry in that sector   directory index not used

    UC* dirbuf;         //added 14.4.2002 to provide generic directory
    UL  dirbuflen;      //buffering...when buffering is on, dirbufptr
    UC* dirbufptr;      //points to current memory-buffered directory entry

    UL  error;          //used to return generic file system errors
    CH  remote[16];
    CH  drive [16];
    CH  name  [64];     //storage area for findfirst/findnext
    CH  ext   [16];     //to return found filename
    CH  branch[16][64];
    CH  wname [64];     //pattern for findfirst/findnext matching
    CH  wext  [64];     //which may include wildcards
};
SL  splitpath       (CH* str,PATH* sp);
SL  interpretpathasdirectory(PATH* sp);
VD  clearextwildcards       (PATH* sp);
VD  clidisplaysplitpath     (PATH* sp);
VD  buildpathstring         (PATH* sp,CH* str);
VD  builddrivepathstring    (PATH* sp,CH* str);
VD  buildwpathstring        (PATH* sp,CH* str);
VD  buildwdrivepathstring   (PATH* sp,CH* str);

//globals in hard.ctp used to manage IDE devices
//EX  HARD    HD[8];
//EX  UC*     hdcDMAbuf;

//globals used to manage LDRIVES
#define MAXLDRIVES  50

EX  LDRIVE  LD[MAXLDRIVES];
EX  UL      ldrives;
EX  LDRIVE* LDcur;
EX  UL      ldcur;
EX  UL      dosdrives;

UL  partitionstart(PARTITION* p,UL hds,UL spt);
UL  partitionend  (PARTITION* p,UL hds,UL spt);

SL  isFDD(LDRIVE* l);

//logical drive file extension sets
CH* fsext(LDRIVE* l,UL type);
CH* htmext(LDRIVE* l);
//CH* c__ext(LDRIVE* l);
//CH* ctpext(LDRIVE* l);
//CH* objext(LDRIVE* l);
//CH* intext(LDRIVE* l);
//CH* lstext(LDRIVE* l);
//CH* lnkext(LDRIVE* l);
//CH* mapext(LDRIVE* l);
//CH* tmpext(LDRIVE* l);
//CH* libext(LDRIVE* l);
//CH* binext(LDRIVE* l);
//CH* drvext(LDRIVE* l);
//CH* jobext(LDRIVE* l);
//CH* xecext(LDRIVE* l);
//CH* tsrext(LDRIVE* l);
//CH* mx_ext(LDRIVE* l);
SL  filterextension(LDRIVE* srcl,CH* oldext,LDRIVE* dstl,CH* newext);