home *** CD-ROM | disk | FTP | other *** search
- { 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 };