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 / TP-UTIL.ARK / DYNADIR.SRC < prev    next >
Text File  |  1986-01-06  |  8KB  |  211 lines

  1. {->>>>DynaDIR<<<<----------------------------------------------}
  2. {                                                              }
  3. { Filename: DYNADIR.SRC -- Last modified 10/31/85              }
  4. {                                                              }
  5. { This routine returns a pointer to a linked list of type      }
  6. { DIRRec, which must have been previously defined this way,    }
  7. { along with pointer type DIRPtr to point to it:               }
  8. {                                                              }
  9. { DIRPtr = ^DIRRec;                                            }
  10. { DIRRec = RECORD                                              }
  11. {            FileName  : String15;                             }
  12. {            Attrib    : Byte;                                 }
  13. {            FileSize  : Real;                                 }
  14. {            TimeStamp : TimeRec;                              }
  15. {            DateStamp : DateRec;                              }
  16. {            Next      : DIRPtr;                               }
  17. {          END;                                                }
  18. {                                                              }
  19. { The linked list will contain a record for every file in the  }
  20. { current directory.  Since the linked list is out in heap,    }
  21. { your directory data takes up NO space in your data segment.  }
  22. { If there are no files in the current directory, the pointer  }
  23. { returned is equal to NIL.                                    }
  24. {                                                              }
  25. { The types TimeRec and DateRec must also have been defined    }
  26. { in your program prior to using DynaDIR.  They are defined    }
  27. { this way:                                                    }
  28. {                                                              }
  29. { TimeRec = Record                                             }
  30. {             TimeComp   : Integer;                            }
  31. {             TimeString : String80;                           }
  32. {             Hours,Minutes,Seconds,Hundredths : Integer       }
  33. {           End;                                               }
  34. { DateRec = Record                                             }
  35. {             DateComp       : Integer;                        }
  36. {             DateString     : String80;                       }
  37. {             Year,Month,Day : Integer;                        }
  38. {             DayOfWeek      : Integer                         }
  39. {           End;                                               }
  40. {                                                              }
  41. {--------------------------------------------------------------}
  42.  
  43.  
  44. FUNCTION DynaDIR(Filespec : String80) : DIRPtr;
  45.  
  46. TYPE
  47.   String9 = String[9];
  48.   Reg     = RECORD
  49.               CASE Boolean OF
  50.                 False : (Word : Integer);
  51.                 True  : (LoByte,HiByte : Byte)
  52.             END;
  53.  
  54.   Regpack = RECORD
  55.               AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Reg
  56.             END;
  57.  
  58.   DWord   = RECORD
  59.               LoInteger,HiInteger : Integer
  60.             END;
  61.  
  62.  
  63. VAR
  64.   I         : Integer;
  65.   Registers : RegPack;
  66.   Root      : DIRPtr;
  67.   Current   : DIRPtr;
  68.   Prior     : DIRPtr;
  69.   ASCIIZ    : ARRAY[1..81] OF Char;
  70.  
  71.  
  72. {->>>>DTAtoDIR<<<<---------------------------------------------}
  73. {                                                              }
  74. { Local to DYNADIR.SRC -- Last modified 10/31/85               }
  75. {                                                              }
  76. { This routine is local to DynaDIR and should not be extracted }
  77. { for other purposes.  It converts data as returned by DOS     }
  78. { calls $4E & $4F in the Disk Transfer Area (DTA) to a more    }
  79. { tractable form as defined by my own record type DIRRec.      }
  80. { This involves converting the time from a two byte integer to }
  81. { a TimeRec, and the date from an integer to a DateRec.        }
  82. {                                                              }
  83. { As of 10/31/85, this routine is incomplete.  It still cannot }
  84. { calculate the day-of-the-week correctly given the date.  I   }
  85. { am researching Zeller's Congruence and will add it when I    }
  86. { get it to work.                                              }
  87. {--------------------------------------------------------------}
  88.  
  89.  
  90.  
  91. PROCEDURE DTAtoDIR(VAR OutRec : DIRRec);
  92.  
  93. CONST
  94.   MonthTags : ARRAY [1..12] of String9 =
  95.     ('January','February','March','April','May','June','July',
  96.      'August','September','October','November','December');
  97.   DayTags   : ARRAY [1..7] OF String9 =
  98.     ('Sunday','Monday','Tuesday','Wednesday',
  99.      'Thursday','Friday','Saturday');
  100.  
  101. TYPE
  102.   String5 = String[5];
  103.   Dword   = RECORD
  104.               LoInteger,HiInteger : Integer
  105.             END;
  106.   DTAPtr  = ^DTARec;
  107.   DTARec  = RECORD
  108.               Reserved : ARRAY[0..20] OF Byte;
  109.               Attrib   : Byte;
  110.               TimeComp : Integer;
  111.               DateComp : Integer;
  112.               FileSize : DWord;
  113.               FileName : ARRAY[1..13] OF Char
  114.             END;
  115.  
  116. VAR
  117.   I           : Integer;
  118.   Temp1,Temp2 : String5;
  119.   AMPM        : Char;
  120.   InRec       : DTARec;
  121.   Registers   : Regpack;
  122.   CurrentDTA  : DTAPtr;
  123.  
  124. BEGIN
  125.   Registers.AX.Word := $2F00; { Find current location of DTA }
  126.   MSDOS(Registers);
  127.   WITH Registers DO CurrentDTA := Ptr(ES.Word,BX.Word);
  128.   InRec := CurrentDTA^;
  129.   WITH OutRec DO              { Now extract and reformat data }
  130.     BEGIN
  131.       I := 1;                 { Extract the file name field }
  132.       WHILE InRec.FileName[I] <> Chr(0) DO
  133.         BEGIN
  134.           FileName[I] := InRec.FileName[I];
  135.           I := Succ(I)
  136.         END;
  137.       FileName[0] := CHR(I-1);
  138.       Attrib := InRec.Attrib; { Extract the attribute field }
  139.       WITH TimeStamp DO
  140.         BEGIN
  141.           TimeComp := InRec.TimeComp;
  142.           Hours := TimeComp SHR 11;
  143.           Minutes := (TimeComp AND $07E0) SHR 5;
  144.           Seconds := (TimeComp AND $1F) SHL 1;
  145.           Hundredths := 0;
  146.           I := Hours;
  147.           IF HOURS = 0 THEN I := 12;  { 0 hrs = 12 AM }
  148.           IF Hours >= 12 THEN         { 13 hrs = 1 PM etc }
  149.             BEGIN
  150.               IF Hours > 12 THEN I := Hours - 12;
  151.               AMPM := 'p'
  152.             END
  153.           ELSE AMPM := 'a';
  154.           Str(I:2,Temp1); Str(Minutes,Temp2);
  155.           IF Length(Temp2) < 2 THEN Temp2 := '0' + Temp2;
  156.           TimeString := Temp1 + ':' + Temp2 + AMPM
  157.         END;
  158.       WITH DateStamp DO
  159.         BEGIN
  160.           DateComp := InRec.DateComp;
  161.           Day := DateComp AND $1F;
  162.           Month := (DateComp AND $01FF) SHR 5;
  163.           Year  := (DateComp SHR 9) + 1980;
  164.           DayOfWeek := 1;  { Fudge!  Needs Zeller's Congruence! }
  165.           DateString := DayTags[DayOfWeek] + ', ';
  166.           Str(Day,Temp1);
  167.           DateString := DateString +
  168.             MonthTags[Month] + ' ' + Temp1 + ', ';
  169.           Str(Year,Temp1);
  170.           DateString := DateString + Temp1;
  171.         END;
  172.       WITH InRec.FileSize DO  { Convert 4-byte filesize to real }
  173.         FileSize := (HiInteger*65536.0)+LoInteger;
  174.       Next := NIL;            { Initialize the "next" pointer }
  175.     END
  176. END;
  177.  
  178.  
  179. BEGIN
  180.   {First step is to convert Filespec string to ASCIIZ:}
  181.   Filespec := Filespec + CHR(0);  { Append binary zero to Filespec }
  182.   Move(Filespec[1],ASCIIZ,Sizeof(Filespec));
  183.   WITH Registers DO
  184.     BEGIN
  185.       AX.Word := $4E00;       { $4E = Find First }
  186.       DS.Word := Seg(ASCIIZ); { Put address of ASCIIZ }
  187.       DX.Word := Ofs(ASCIIZ); { in DS : DX }
  188.     END;
  189.   MSDOS(Registers);           { Make FIND FIRST DOS call... }
  190.   IF Registers.AX.Word = 2 THEN DynaDIR := NIL
  191.     ELSE
  192.       BEGIN
  193.         New(Root);            { Convert first find to DIR format }
  194.         DTAtoDIR(Root^);
  195.         Prior := Root;
  196.         IF Registers.AX.Word <> 18 THEN
  197.           REPEAT
  198.             Registers.AX.Word := $4F00;
  199.             MSDOS(Registers);   { Make FIND NEXT DOS call... }
  200.             IF Registers.AX.Word <> 18 THEN
  201.               BEGIN
  202.                 New(Current);
  203.                 DTAtoDIR(Current^);  { Convert additional finds }
  204.                 Prior^.Next := Current;  { to DIRRec format }
  205.                 Prior := Prior^.Next
  206.               END
  207.           UNTIL Registers.AX.Word = 18;
  208.         DynaDIR := Root;
  209.       END
  210. END;  {DynaDIR}
  211. _PORT]:=$05;     { 300 b