{ ****************************** PATHS.PAS *******************************}
{ These procedures perform various functions to paths under PCMSDos 2.0   }
{ They are designed to be $Included into one's TURBO PASCAL program       }
{ Written by:         Clark Walker                                        }
{                     CompuServe 76010,346                                }
{ ************************************************************************}

{ ************************************************************************}
{             This procedure will get the current directory               }
{ ************************************************************************}
PROCEDURE CurrDir(    Drive   : Char    ;    { Drive A,B,C, etc           }
                  var Path    : String80;    { Current path returned here }
                  var error   : integer);    { See dos 2.0 manual pg D-14 }
VAR
   I             :  Integer;
BEGIN
   error := 0;
   regs.ax := $4700;                       { Dos function to get curr dir }
   regs.dx := Ord(Drive) - Ord('A') + 1;   { Dos uses 1,2,3.. not A,B,C.. }
   regs.ds := seg(Path);                   { Point to area to hold path   }
   regs.si := ofs(Path);                   { Func 47 use DS:SI            }
   regs.si := regs.si + 1;                 { Point past string length byte}
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { Error 15 = bad drive         }
   I := 1;
   While Path[I] <> chr(0) do I := I + 1;  { Dos puts chr(0) at end       }
   Path[0]:=chr(I-1);                      { Set length byte in string    }
END;

{ ************************************************************************}
{             This procedure will create a subdirectory                   }
{ ************************************************************************}
PROCEDURE MkDir(var Asciiz   : String80;    { Full path (Drive:\path)     }
                var error    : integer );   { See dos 2.0 manual pg D-14  }
BEGIN
   error := 0;
   regs.ax := $3900;                       { Dos function to make dir     }
   regs.ds := seg(Asciiz);                 { Point to drive:\path param   }
   regs.dx := ofs(Asciiz);
   regs.dx := regs.dx + 1;                 { Func 39 uses DS:DX           }
   Asciiz[Length(Asciiz)+1]:=chr(0);       { dos wants it to end in chr(0)}
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { See dos manual Page D-14     }
   if error = 2 then error := 0;           { Dos reports 'file not found' }
                                           { .. error (incorrectly) I hope}
END;

{ ************************************************************************}
{             This procedure will delete a subdirectory                   }
{ ************************************************************************}
PROCEDURE RmDir(var Asciiz   : String80;    { Full path (Drive:\path)     }
                var error    : integer );   { See dos 2.0 manual pg D-14  }
BEGIN
   error := 0;
   regs.ax := $3A00;                       { Dos function to remote dir   }
   regs.ds := seg(Asciiz);                 { Point to drive:\path param   }
   regs.dx := ofs(Asciiz);
   regs.dx := regs.dx + 1;                 { Func 3A uses DS:DX           }
   Asciiz[Length(Asciiz)+1]:=chr(0);       { dos wants it to end in chr(0)}
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { See dos manual Page D-14     }
END;

{ ************************************************************************}
{          This procedure will change to a different directory            }
{ ************************************************************************}
{   After changing directories, any access within turbo or outside turbo  }
{   to the drive in the Asciiz string will result in this directory being }
{   accessed.                                                             }
{ ************************************************************************}
PROCEDURE ChDir(var Asciiz   : String80;    { Full path (Drive:\path)     }
                var error    : integer );   { See dos 2.0 manual pg D-14  }
BEGIN
   error := 0;
   regs.ax := $3B00;                       { Dos function to change dir   }
   regs.ds := seg(Asciiz);                 { Point to drive:\path param   }
   regs.dx := ofs(Asciiz);
   regs.dx := regs.dx + 1;                 { Func 3B uses DS:DX           }
   Asciiz[Length(Asciiz)+1]:=chr(0);       { dos wants it to end in chr(0)}
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { See dos manual Page D-14     }
END;

{ ************************************************************************}
{          This procedure will delete a file in a directory               }
{ ************************************************************************}
PROCEDURE DelFile(var Asciiz   : String80;  { Full path (Drive:\path\file)}
                  var error    : integer ); { See dos 2.0 manual pg D-14  }
BEGIN
   error := 0;
   regs.ax := $4100;                       { Dos function to del via dir  }
   regs.ds := seg(Asciiz);                 { Point to drive:\path param   }
   regs.dx := ofs(Asciiz);
   regs.dx := regs.dx + 1;                 { Func 41 uses DS:DX           }
   Asciiz[Length(Asciiz)+1]:=chr(0);       { dos wants it to end in chr(0)}
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { See dos manual Page D-14     }
END;

{ ************************************************************************}
{      This procedure will rename a file using a directory path           }
{ ************************************************************************}
{  Using this procedure you can MOVE a file between directories keeping   }
{  in mind the second (to) directory\file is on the same drive.           }
{ ************************************************************************}
{  Note: If you specify a drive in PATH it must be the same as that in    }
{  Asciiz. In fact, if it is not your current drive you MUST specify a    }
{  drive.  Note, You will get error code 255 (invalid drive) when you     }
{  specify the drive and it is not your current 'logged on' drive.        }
{ ************************************************************************}
PROCEDURE RenFile(var Asciiz   : String80;  { Full path (Drive:\path\file)}
                  var Path     : String80;  { \Path\File.name or filename }
                  var error    : integer ); { See dos 2.0 manual pg D-14  }
BEGIN
   error := 0;
   regs.ax := $5600;                       { Dos function to move files   }
   regs.ds := seg(Asciiz);                 { Point to drive:\path param   }
   regs.dx := ofs(Asciiz);
   regs.dx := regs.dx + 1;                 { Point past length byte       }
   regs.es := seg(Path);
   regs.di := ofs(Path);
   regs.di := regs.di + 1;
   Asciiz[Length(Asciiz)+1]:=chr(0);       { dos wants it to end in chr(0)}
   Path[Length(Path)+1]:=chr(0);
   Intr($21,regs);                         { Call Dos using interupt 21   }
   error := regs.ax and $FF;               { See dos manual Page D-14     }
END;

{ ************************************************************************}
{  This function will return your current disk drive id (A,B,C, etc.).    }
{ ************************************************************************}
FUNCTION  CurrDrive : Char;                  { A,B,C, etc.                }
BEGIN
   regs.ax := $1900;                         { Dos function returns drive }
   Intr($21,regs);
   CurrDrive := chr(lo(regs.ax)+ord('A'));   { 0=A, 1=B, etc              }
END;

{ ************************************************************************}
{         This procedure will change your 'logged on disk'                }
{ ************************************************************************}
PROCEDURE ChgDrive  (Drive : Char);          { A,B,C, etc.                }
BEGIN
   regs.ax := $0E00;                         { Dos function changes drive }
   regs.dx := ord(drive) - ord('A');         { Dos uses 0,1,2 not A,B,C   }
   Intr($21,regs);
END;

{ ************************************************************************}
{    This function will return the free disk space on any drive           }
{ ************************************************************************}
FUNCTION  FreeSpace (Drive : Char) : Real;   { A,B,C, etc.                }
VAR
   AvailClusters,SectorsPerCluster,BytesPerSector : Real;
BEGIN
   regs.ax := $3600;                         { Dos function for free space}
   regs.dx := ord(drive) - ord('A') + 1;     { Dos uses 1,2,3 for A,B,C   }
   Intr($21,regs);
   { returns: bx=avail clusters dx=total clusters
              cx=bytes per sector ax=sectors per cluster }
   AvailClusters := regs.bx;
   SectorsPerCluster := regs.ax;
   BytesPerSector := regs.cx;
   FreeSpace := AvailClusters * SectorsPerCluster * BytesPerSector;
END;
                   