home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TURBOPAS
/
TDIR.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
2000-06-30
|
11KB
|
358 lines
{
CP/M-80 directory program written in Turbo Pascal 2.0.
Based loosely on wildcard.pas, author and compiler unknown.
Accepts ambiguous file names and displays sorted directory.
File sizes rounded to next 1k increment.
Steve Fox - Albuquerque RCP/M (505)299-5974
Version 1.0 29 Mar 1985
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Revised 23 Apr 85 by : William L. Mabee, CRNA Followin attributes added
Functions :
Centered
Dash
ConstStr
Procedures :
PutItUp
Changed Code to allow automatic display of logged DU directory will allow
code to be included in Turbo Pascal Program or chaining from main turbo
routine.
Added prompt for which drive change source for your own system
if you have more than two drives add something like ['A..P']; and
change appropriate prompt.
Added code to display total amount disk space used.
Added header.
}
Program dir;
label start;
const
columns = 4;
fence = ' | ';
header = 'File Ext Size File Ext Size File Ext Size File Ext Size';
type
CharSet = set of char;
FileName = string[14]; { d:filename.ext }
str80 = string[80];
StrStd = string[127];
FilePtr = ^FileDescr;
FileDescr =
record
fname: FileName; { Name of a matching file }
fsize: integer; { Size of file }
Next: FilePtr; { Points to next name on linked list }
end;
FileBlock =
record
case boolean of
true:
(drive: byte; { Byte code }
fname: array[1..11] of char; { File name }
extent, { Current extent }
s1, s2, reccount: byte; { Used to compute file size }
dn: array[16..31] of byte);
false:
(init: array[1..32] of byte);
end;
var
CH : Char;
entries: integer; { Count of directory entries }
prototype: FileName; { Directory mask }
first: FilePtr; { Start of linked list }
searchblk: FileBlock; { Block for search }
CtrPrg: File;
Function ConstStr(C : Char; N : Integer) : Str80;
var
S : string[80];
begin
if N < 0 then
N := 0;
S[0] := Chr(N);
FillChar(S[1],N,C);
ConstStr := S;
end;
Function Centered(TheString:Str80):Str80;
begin
Centered := ConstStr(' ',((80 - Length(TheString)) Div 2)) +
TheString;
end;
Function Dash(Spaces : Integer) : Str80;
var
Column : Integer;
Temp : Str80;
begin
Temp :='';
For Column := 1 to Spaces do
begin
Temp := Temp + '-';
Dash := Temp;
end;
end;
Function Tab(Spaces : Integer) : Str80;
var
Column : Integer;
Temp : Str80;
begin
Temp :='';
For Column := 1 to Spaces do
begin
Temp := Temp + '-';
Dash := Temp;
end;
end;
Procedure Choice( Prompt : Str80;
Term : CharSet;
var TC : Char );
var
Ch : Char;
begin
GotoXY(1,23); Write(Prompt); ClrEol;
repeat
Read(Kbd,Ch);
TC := Upcase(Ch);
if not (TC in Term) then
write(^G);
until TC in Term;
Write(Ch);
end;
Procedure ClearFrame;
var
I : Integer;
begin
for I := 20 downto 3 do
begin
GotoXY(1,I + 1); ClrEol ;
end;
end;
procedure GetMask(var prototype: FileName);
{ Get ambiguous file name and expand into directory mask (prototype) }
var
i, j: integer;
line: StrStd;
function trim(st: StrStd): StrStd;
{ Trim leading and trailing blanks }
var
i, j: integer;
begin
i := 1;
j := length(st);
while (st[i] = ' ') and (i <= j) do
i := succ(i);
while (st[j] = ' ') and (j >= i) do
j := pred(j);
trim := copy(st, i, j - i + 1)
end;
function pad(line: StrStd; i: integer): StrStd;
{ Pad line with spaces to length of i }
begin
while length(line) < i do
line := line + ' ';
pad := line
end;
begin
repeat
Choice('Directory for which drive ( A or B ) ? ',['A','B'],Ch);
until Ch <> '';
ClearFrame;
line := Ch+':*.*';
line := trim(line);
for i := 1 to length(line) do
line[i] := UpCase(line[i]);
if line = ''
then line := '*.*';
line := pad(line, 14);
prototype := copy(line, 1, 14);
FillChar(searchblk.init, 32, 0);
with searchblk do
begin
if prototype[2] = ':'
then
begin
drive := succ(ord(prototype[1]) - ord('A'));
i := 3
end
else
begin
drive := 0;
i := 1
end;
fname := ' ';
j := 1;
repeat
begin
if prototype[i] = '*'
then while j <= 8 do
begin
fname[j] := '?';
j := succ(j)
end
else
begin
fname[j] := prototype[i];
j := succ(j)
end
end;
i := succ(i)
until (j > 8) or (prototype[i] = '.');
while (prototype[i] <> '.') and (prototype[i] <> ' ') do
i := succ(i);
i := succ(i);
j := 9;
repeat
begin
if prototype[i] = '*'
then while j <= 11 do
begin
fname[j] := '?';
j := succ(j)
end
else
begin
fname[j] := prototype[i];
j := succ(j)
end
end;
i := succ(i)
until (j > 11) or (prototype[i] = '.');
extent := ord('?');
s1 := ord('?');
s2 := ord('?')
end
end;
procedure ReadDir(prototype: filename; var entries: integer; var first: FilePtr);
{ Create an alphabetized list of files which match the prototype }
const
findfirst = 17; { BDOS function - search for first file }
findnext = 18; { BDOS function - search for next file}
setdma = 26; { BDOS function - set dma buffer address }
fcb = $80; { Default dma buffer address }
type
dirblock = array [0..3] of FileBlock;
fileblptr = ^FileBlock;
var
off: integer; { dir entry offset or end flag }
fn: FileName;
answerblk: dirblock; { block to receive file name }
procedure insertfile(fn: FileName; fs: integer; var entries: integer; var first: FilePtr);
{ Insert a new file name in the alphabetic list }
var
f, { file name entry being created }
this, previous: FilePtr; { followers for insertion }
begin
previous := nil;
this := first;
while (this <> nil) and (this^.fname < fn) do
begin
previous := this;
this := this^.next
end;
if this^.fname <> fn
then
begin
entries := succ(entries);
new(f);
f^.fname := fn;
f^.fsize := fs;
f^.next := this;
if previous = nil
then first := f
else previous^.next := f
end
else if this^.fsize < fs
then this^.fsize := fs
end;
begin { ReadDir }
entries := 0;
first := nil;
BDOS(setdma, addr(answerblk));
off := BDOS(findfirst, addr(searchblk));
while off <> 255 do
begin
with answerblk[off] do
if (ord(fname[10]) and $80) = 0 { Non-system? }
then
begin
drive := 11; { File name length }
move(drive, fn, 12); { File name }
insert('.', fn, 9);
insertfile(fn, reccount + (extent + (s2 shl 5)) shl 7, entries, first)
end;
off := BDOS(findnext, addr(searchblk));
end;
BDOS(setdma, fcb) { Restore DMA buffer }
end;
procedure DispDir(entries: integer; first: FilePtr);
{ Display directory list }
var
i, size,totsize: integer;
OldName: FilePtr;
begin
i := 0;
totsize := 0;
GotoXY(1,6);
WriteLn(Header); WriteLn;
while first <> nil do
begin { Scan the whole list }
size := first^.fsize shr 3;
totsize := totsize + size;
if 0 <> (first^.fsize mod 8)
then size := succ(size);
write(first^.fname, size:4, 'k');
i := succ(i);
Oldname := first;
first := first^.Next; { Go to next on chain }
dispose(Oldname); { Reclaim space }
if i < columns
then write(fence)
else
begin
writeln;
i := 0
end
end;
WriteLn;
WriteLn;
write('Total number of Files : ',entries);
writeln(' Using a total of : ',totsize,' K');
end;
begin { main }
ClrScr;
GotoXY(1,1); Writeln(ConstStr('-',79)); WriteLn; Write(ConstStr('-',79));
GotoXY(1,2); Write(Centered('Disk Directory Routine'));
GotoXY(1,22); Writeln(ConstStr('-',79)); WriteLn; Write(ConstStr('-',79));
start :
clearFrame;
GetMask(prototype); { Read mask }
ReadDir(prototype, entries, first); { Read directory }
DispDir(entries, first); { Display directory }
repeat
Choice('Do directory on another drive ( Y or N ) : ',['Y','N'],CH);
if Ch = 'Y' then goto start;
until Ch = 'N';
ClrScr;
end.