home *** CD-ROM | disk | FTP | other *** search
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Written by Laszlo S. Gonc for Turbo Version 3.0 *)
- (* *)
- (* Can be contacted via Gene Plantz IBBS *)
- (* (312) 885-9557 or (312) 882-4227 *)
- (* my user ID is #0537 *)
- (* *)
- (* The directory procedure mimics the display of diskette file information *)
- (* as that of the DIR command in PC-DOS. *)
- (* *)
- (* After finding many half-assed routines all over the place for getting *)
- (* a directory from Turbo, I decided to write one myself that actually *)
- (* handled problems like a diskette not having a volume label. *)
- (* *)
- (* However, no matter how much you strive for perfection, Murphy's law *)
- (* will always hold a firm grip on the programming world. The PRINTDIR *)
- (* procedure will print a directory of your diskette showing filename, *)
- (* size, date, and time. *)
- (* *)
- (* A MAJOR problem exists in the routine that determines the file creation *)
- (* time, and for the life of me, I cannot figure out what the problem is. *)
- (* The curious aspect is that the correct time is given SOMETIMES. *)
- (* *)
- (* If anyone can solve this problem, please let me know and upload the *)
- (* edited version to Gene Plantz IBBS. Thanks in advance. *)
- (*--------------------------------------------------------------------------*)
-
- type regPack = record case integer of
- 1 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: integer);
- 2 : (AL,AH,BL,BH,CL,CH,DL,DH : byte );
- end;
- st80 = string[80];
-
- var cursor : integer;
- regs : regpack;
- (*--------------------------------------------------------------------------*)
- (* Procedures to turn the cursor on and off. *)
- (*--------------------------------------------------------------------------*)
- procedure cursorOff;
- begin
- regs.AX := $0300;
- intr ($10,regs);
- cursor := regs.CX;
- regs.AX := $0100;
- regs.CX := $2000;
- intr ($10,regs)
- end;
-
- procedure cursorOn;
- begin
- regs.AX := $0100;
- regs.CX := cursor;
- intr ($10,regs)
- end;
-
- (*--------------------------------------------------------------------------*)
- (* Procedure to read the keyboard (extended scan codes as well). *)
- (*--------------------------------------------------------------------------*)
- procedure get (var ch:char);
- begin
- read (kbd,ch);
- if (ch = #27) and keypressed then
- begin
- read (kbd,ch);
- case ch of
- #15 : ch := ^O; { tab backwards }
- #72 : ch := ^E; { cursor up, control-E }
- #75 : ch := ^S; { cursor left, control-S }
- #77 : ch := ^D; { cursor right, control-D }
- #80 : ch := ^X; { cursor down, control-X }
- #82 : ch := ^V; { insert }
- #83 : ch := ^G; { delete }
- else ch := #00;
- end;
- end;
- end;
-
- (*--------------------------------------------------------------------------*)
- (* Procedure to accept input, format (row,column,size,datatype,string,esc) *)
- (*--------------------------------------------------------------------------*)
- procedure accept (r,c,l,d:integer; var temp:st80; var esc:boolean);
- var x : integer;
- ch : char;
- ins : boolean;
- procedure println;
- begin
- cursorOff;
- gotoxy (c,r);
- write (temp);
- clreol;
- gotoxy (x,r);
- cursorOn;
- end;
- procedure format;
- begin
- if x < c + l - 1 then
- begin
- if ins then
- temp := copy (temp,1,x - c) + ch + copy (temp,x - c + 1,c + l - x - 1)
- else temp := copy (temp,1,x - c) + ch + copy (temp,x - c + 2,c + l - x);
- x := x + 1;
- end
- else begin
- if x = c + l - 1 then
- x := x + 1;
- temp := copy (temp,1,l - 1) + ch;
- end;
- end;
- begin
- esc := false;
- ins := false;
- x := c;
- println;
- repeat
- get (ch);
- if ch = #27 then
- begin
- esc := true;
- temp := '';
- exit;
- end;
- case ch of
- #4 : if x < c + length (temp) then
- x := x + 1;
- #7 : temp := copy (temp,1,x - c) + copy (temp,x - c + 2,l);
- #8 : if not (x <= c) then
- begin
- delete (temp,x - c,1);
- x := x - 1;
- end;
- #9 : x := c + length (temp);
- #15 : x := c;
- #19 : if x > c then
- x := x - 1;
- #22 : ins := not (ins);
- else if ch <> #13 then
- case d of
- 1 : if upcase (ch) in
- [#33,#35..#38,#40..#42,#44..#57,#63..#90,#95,#96,#123,#125]
- then format;
- end;
- end;
- println;
- until ch in [#13];
- end;
-
- (*--------------------------------------------------------------------------*)
- (* Procedure to draw a border in high video at the specified coordinates. *)
- (*--------------------------------------------------------------------------*)
- procedure border (ux,uy,lx,ly:integer);
- var x : integer;
- begin
- cursorOff;
- gotoxy (ux,uy);
- write (#213);
- for x := ux + 1 to lx - 1 do
- write (#205);
- write (#184);
- for x := uy + 1 to ly - 1 do
- begin
- gotoxy (ux,x);
- write (#179);
- gotoxy (lx,x);
- write (#179);
- end;
- gotoxy (ux,ly);
- write (#212);
- for x := ux + 1 to lx - 1 do
- write (#205);
- write (#190);
- cursorOn;
- end;
-
- (*--------------------------------------------------------------------------*)
- (* Procedure to display 'Press any key to continue...' *)
- (*--------------------------------------------------------------------------*)
- procedure presskey;
- begin
- writeln;
- write (' Press any key to continue...');
- repeat until keypressed;
- end;
-
- (*--------------------------------------------------------------------------*)
- (* Procedure to give a directory of a diskette. *)
- (*--------------------------------------------------------------------------*)
- procedure printDir;
- type
- info = record
- filename : string[20];
- size : real;
- time : string[6];
- date : string[8];
- attribute : string[2];
- end;
- char80 = array[1..80] of char;
- var
- numberFiles,
- DTAseg, DTAofs,
- setDTAseg, setDTAofs,
- error, option,
- x, y, z : integer;
- r : real;
- DTA : array[1..43] of byte;
- month, day, hour, min : string[2];
- year : string[4];
- field : string[12];
- name,temp,cdi : string[80];
- ch : char;
- mask : char80;
- entry : info;
- flag,esc : boolean;
- procedure setDTA (segment,offset:integer; var error:integer);
- begin
- regs.AX := $1A00;
- regs.DS := segment;
- regs.DX := offset;
- msdos (regs);
- error := regs.AX and $FF;
- end;
- procedure getCurrentDTA (var segment,offset,error:integer);
- begin
- regs.AX := $2F00;
- msdos (regs);
- segment := regs.ES;
- offset := regs.BX;
- error := regs.AX and $FF;
- end;
- procedure getEntry (var entry:info; segment,offset,option:integer; var error:integer);
- begin
- error := 0;
- getdir (0,cdi);
- if flag then
- begin
- if option = 8 then
- chdir (copy (cdi,1,2) + '\')
- else chdir (cdi);
- regs.AX := $4E00;
- regs.DS := seg (mask);
- regs.DX := ofs (mask);
- regs.CX := option;
- end
- else begin
- regs.AX := $4F00;
- regs.CX := option;
- end;
- msdos (regs);
- error := regs.AX and $FF;
- with entry do
- begin
- attribute := '..';
- x := mem[segment:offset + 21];
- if ((x and 223) = 0) or ((x and 1) = 1) then
- attribute := 'R.';
- if (x and 16) = 16 then
- insert ('D',attribute,2);
-
-
- (* Determine the creation time of the file. Works SOMETIMES ?! *)
- x := mem[segment:offset + 23];
- str ((x shr 3):2,hour);
- x := 8 * (x and 3);
- x := x + (mem[segment:offset + 22] shr 5);
- str (x,min);
- if length (min) < 2 then
- min := '0' + min;
- val (hour,y,z);
- case y of
- 0 : begin
- hour := '12';
- ch := 'a';
- end;
- 1..11 : ch := 'a';
- 12 : ch := 'p';
- 13..23 : begin
- str (y - 12,hour);
- ch := 'p';
- end;
- end;
- time := hour + ':' + min + ch;
- (* End file creation time determination algorithm. *)
-
- x := mem[segment:offset + 25];
- str ((80 + (x shr 1)):2,year);
- x := 8 * (x and 1);
- x := x + (mem[segment:offset + 24] shr 5);
- str (x:2,month);
- x := mem[segment:offset + 24];
- str ((x and 31),day);
- if length (day) < 2 then
- day := '0' + day;
- date := month + '-' + day + '-' + year;
- size := 0;
- size := mem[segment:offset + 26] +
- mem[segment:offset + 27] * 256.0 +
- mem[segment:offset + 28] * 65536.0 +
- mem[segment:offset + 29] * 16777200.0;
- x := 1;
- repeat
- name[x] := chr (mem[segment:offset + 29 + x ]);
- x := x + 1;
- until (not (name[x-1] in [' '..'~']));
- name[0] := chr (x-1);
- filename := name;
- if option <> 8 then
- begin
- if pos ('.',filename) <> 0 then
- begin
- if (copy (filename,1,1) = '.') or (copy (filename,1,2) = '..') then
- begin
- for x := 1 to 12 - length (filename) do
- filename := filename + ' ';
- end
- else begin
- if pos ('.',filename) < 9 then
- for x := 1 to 9 - pos ('.',filename) do
- insert (' ',filename, pos ('.',filename));
- if length (filename) < 12 then
- for x := 1 to 12 - length (filename) do
- filename := filename + ' ';
- delete (filename,9,1);
- insert (' ',filename,9);
- end;
- end
- else for x := 1 to 13 - length (filename) do
- filename := filename + ' ';
- end;
- if attribute[2] = 'D' then
- insert ('<DIR>',filename,14);
- end;
- end;
- procedure initFilename;
- begin
- for x := 1 to 21 do
- DTA[x] := 0;
- for x := 1 to 80 do
- begin
- mask[x] := chr (0);
- name[x] := chr (0);
- end;
- name[0] := chr (0);
- getCurrentDTA (DTAseg,DTAofs,error);
- setDTAseg := seg (DTA);
- setDTAofs := ofs (DTA);
- setDTA (setDTAseg,setDTAofs,error);
- error := 0;
- for x := 1 to length (field) do
- mask[x] := field[x];
- end;
- begin
- gotoxy (2,20);
- write ('Directory mask:');
- temp := '';
- accept (20,18,12,1,temp,esc);
- if esc then exit;
- border (38,1,80,24);
- cursorOff;
- window (39,2,79,23);
- gotoxy (1,1);
- field := '*.*' + chr (0);
- initFilename;
- option := 8;
- flag := true;
- getEntry (entry,setDTAseg,setDTAofs,option,error);
- delete (entry.filename,pos ('.',entry.filename),1);
- write (' Volume in drive ',copy (cdi,1,1));
- if (error = 0) then
- writeln (' is ',entry.filename)
- else writeln (' has no label');
- writeln;
- setDTA (DTAseg,DTAofs,error);
- if temp = '' then
- field := '*.*' + chr (0)
- else field := temp + chr (0);
- numberFiles := 0;
- initFilename;
- option := 16;
- getEntry (entry,setDTAseg,setDTAofs,option,error);
- flag := false;
- with entry do
- begin
- if (error = 0) then
- begin
- if attribute[2] = 'D' then
- writeln (filename:19,date:12,time:8)
- else writeln (filename:14,size:7:0,date:10,time:8);
- end
- else writeln (' File not found');
- if attribute[1] = 'R' then
- numberFiles := numberFiles + 1;
- end;
- while (error = 0) do
- begin
- getEntry (entry,setDTAseg,setDTAofs,option,error);
- with entry do
- begin
- if (error = 0) then
- begin
- if attribute[1] = 'R' then
- numberFiles := numberFiles + 1;
- if attribute[2] = 'D' then
- writeln (filename:19,date:12,time:8)
- else writeln (filename:14,size:7:0,date:10,time:8);
- end;
- end;
- end;
- setDTA (DTAseg,DTAofs,error);
- regs.AX := $36 shl 8;
- regs.DX := 0;
- msdos (regs);
- r := regs.CX;
- writeln (' ',numberFiles:3,' file(s)',' ',regs.AX * regs.BX * r:12:0,' bytes free');
- presskey;
- window (1,1,80,25);
- cursorOn;
- end;