home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
zcat
/
tptool19.lbr
/
OS-MSDOS.PQS
/
OS-MSDOS.PAS
Wrap
Pascal/Delphi Source File
|
1991-01-31
|
4KB
|
119 lines
{ OS-MSDOS.PAS }
{ put all MS-DOS specific code in this file }
procedure listcat;
{ list MS-DOS directory filenames on current (logged) drive. }
{ Derived from DIRECTRY.PAS and QDL.PAS in "Turbo Tutor", 1984. }
{ Mods by W. Kempton, Jan 1985-- Fix three bugs: 1) never found
first filename, 2) overflowed NamR, 3) added a null at end of name.
(For a textbook, that's mighty buggy.) Save file names in buffer
before writing them. Adapt to K&R Software Tools STDIO. Clean up
code.
}
{ works under MS-DOS 2.0, but not 1.0 }
const
SizeOfDTA = 43;
SizeOfMask= 12;
NameSize = 13; { must be > longest filename }
MaxFiles = 255;
type
RegRec =
record
AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
end;
Name = packed array [1..NameSize] of char;
var
Regs : RegRec;
DTA : array [ 1..SizeOfDTA ] of Byte;
Mask : array [1..SizeOfMask] of Char;
DirBuf : array [1..MaxFiles] of Name;
OutName : XSTRING;
SaveDTASeg,
SaveDTAOfs,
NameCount,
ErrorNum, I,j : Integer;
procedure ErrorCheck;
begin
if ErrorNum <> 0 then error('List: system call error');
end;
procedure SetDTA( Segment, Offset : Integer; var Error : Integer );
begin
Regs.AX := $1A00; { Function used to set the DTA }
Regs.DS := Segment; { store the parameter Segment in DS }
Regs.DX := Offset; { " " " Offset in DX }
MSDos( Regs ); { Set DTA location }
Error := Regs.AX and $FF; { get Error return }
end; { of proc SetDTA }
procedure GetCurrentDTA( var Segment, Offset : Integer;
var Error : Integer );
begin
Regs.AX := $2F00; { Function used to get current DTA address }
MSDos( Regs ); { Exicute MSDos function request }
Segment := Regs.ES; { Segment of DTA returned by DOS }
Offset := Regs.BX; { Offset of DTA returned }
Error := Regs.AX and $FF;
end; { GetCurrentDTA }
procedure GetName(var NameCount: integer);
{ use MS-DOS call to get one name from system table--highly Turbo-specific }
var
I: integer; { char count }
begin
if NameCount = 0
then Regs.AX := $4e00 { get first directory entry }
else Regs.AX := $4f00; { get next directory entry }
Regs.CX := 22; { Store the option }
MSDos(Regs); { Execute MSDos call }
ErrorNum := Regs.AX and $FF; { Get Error return }
if (ErrorNum = 0) then
begin { valid filename; store in NamR }
I := 1;
NameCount := NameCount+1;
repeat
DirBuf[NameCount,I] := CHR(DTA[30+I]);
I := I + 1;
until not (DirBuf[NameCount,I-1] in [' '..'~']) or (I>=NameSize);
DirBuf[NameCount,I] := CHR(ENDSTR); { mark end of name string }
end;
end { GetName };
begin { listcat }
GetCurrentDTA(SaveDTASeg,SaveDTAOfs, ErrorNum); { save DTA address }
ErrorCheck;
for i:= 1 to SizeOfDTA do DTA[i]:= 0; { zero local DTA }
SetDTA(Seg(DTA),Ofs(DTA),ErrorNum); ErrorCheck;
ErrorNum := 0;
{ FillChar(Mask,SizeOfMask,0);} { Initialize mask }
Mask := '????????.???'; { global search }
Regs.DX := Ofs(Mask);
Regs.DS := Seg(Mask);
NameCount := 0; { get file names from system }
repeat
GetName(NameCount);
until ErrorNum <> 0;
SetDTA(SaveDTASeg,SaveDTAOfs, ErrorNum); { restore original DTA }
ErrorCheck;
for I := 1 to NameCount do { write names from DirBuf }
begin
j := 1;
repeat
OutName[j] := ord(DirBuf[I,j]); j := j+1;
until ord(DirBuf[I,(j-1)]) = ENDSTR;
PUTSTR(OutName,STDOUT); { K&R output to STDOUT }
PUTC(NEWLINE);
end;
end { listcat };