home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9203 / driver / drvlib.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-04-05  |  4.6 KB  |  134 lines

  1. Unit DrvLib;   { Bibliothek der Treiberfunktionen }
  2. {$A-}
  3. Interface
  4. uses Dos, DosUtils;
  5.  
  6. Type
  7.   DriverPointer = ^DriverHead;
  8.   DriverHead = Record      { Gerätetreiber-Kopf }
  9.     DNext: DriverPointer;  { Zeiger auf den nächsten Treiber }
  10.     DAttr: Word;       { Geräteattribut, <> Func $4400! }
  11.     DStrat: Word;      { Offset-Adresse der "Strategy"-Routine }
  12.     DIntr: Word;       { Offset-Adresse der "Interrupt"-Routine }
  13.     case Integer of
  14.       0: (Name: Array[1..8] of Char);
  15.       1: (Drives: Byte);
  16.   end;
  17.  
  18. Function GetFirstHeader: DriverPointer;  { liefert die Adresse von NUL }
  19. Function LocateDriver(DriverName: String): DriverPointer; { Treiberadresse }
  20. Procedure ShowDriver(p: DriverPointer);  { Ausgabe Daten Treiberkopf }
  21. Procedure CallStrategy(Driver: DriverPointer; ParmBlock: Pointer);
  22. Procedure CallInterrupt(Driver: DriverPointer);
  23.  
  24. Implementation
  25.  
  26. Function GetFirstHeader: DriverPointer;  { liefert die Adresse von NUL }
  27. var Regs: Registers;
  28. begin
  29.   with Regs do
  30.   begin
  31.     AH := $52; Intr($21,Regs);
  32.     if Lo(DosVersion) < 3 then GetFirstHeader := Ptr(ES,BX+$18)
  33.      else if DosVersion = $3 then GetFirstHeader := Ptr(ES,BX+$28)
  34.      else GetFirstHeader := Ptr(ES,BX+$22);
  35.   end;
  36. end;
  37.  
  38. { Sucht die Treiber-Kette von DOS ab und ermittelt das Attribut
  39.   sowie die Aufrufadressen der Strategie- und Interrupt-Routinen.
  40.   Bei Aufruf mit einem Nullstring wird der zuletzt eingebaute
  41.   Blocktreiber lokalisiert, ansonsten gehts um Zeichentreiber.
  42. }
  43. Function LocateDriver(DriverName: String): DriverPointer;
  44. var Regs: Registers;
  45.     DHead: DriverPointer;  { Zeiger auf den aktuellen Treiberkopf }
  46.     DosV: Word;   { Dos-Versionsnummer, umgedreht }
  47.     SearchBlock: Boolean;
  48. begin
  49.   if Length(DriverName) = 0 then SearchBlock := True
  50.   else
  51.   begin    { Treibernamen auf volle Länge bringen, soweit notwendig }
  52.     while Length(DriverName) < 8 do DriverName := DriverName + ' ';
  53.     SearchBlock := False;
  54.   end;
  55.  
  56.   { DOS-Datenbereich ermitteln. Je nach Version steht der Kopf der
  57.     Treiberkette (Gerät NUL) hier ab dem Offset $17, $28 oder $22:
  58.   }
  59.   Regs.AH := $52; Intr($21,Regs);   { DOS-Datenbereich }
  60.   DosV := Swap(DosVersion);  { $1403 (20.3) -> $0314 (3.20) }
  61.   if DosV < $0300 then DHead := Ptr(Regs.ES,Regs.BX+$17)
  62.      else if DosV < $030A then DHead := Ptr(Regs.ES,Regs.BX+$28)
  63.      else DHead := Ptr(Regs.ES,Regs.BX+$22);   { Version 4.x, 5.0 }
  64.  
  65.   { Hat die Sache geklappt? }
  66.   if DHead^.Name <> 'NUL     ' then  { 'NUL'+ 5 Leerzeichen }
  67.   begin
  68.     Writeln('Kopf der Treiberkette (NUL) nicht gefunden!');
  69.     Writeln('Welches Betriebssystem ist das?');
  70.     Halt;
  71.   end;
  72.  
  73.   { Absuchen der Kette nach dem entsprechenden Gerät oder dem
  74.     zuletzt eingebauten Blocktreiber }
  75.   while (not SearchBlock and (DHead^.Name <> DriverName)) or
  76.          (SearchBlock and ((DHead^.DAttr and $8000) <> 0)) do
  77.   begin
  78.     DHead := DHead^.DNext;     { nächster Treiberkopf }
  79.     if Ofs(DHead^) = $FFFF then  { Kettenende? }
  80.       begin
  81.         LocateDriver := NIL; Exit;
  82.       end;
  83.   end;
  84.   LocateDriver := DHead;
  85. end;
  86.  
  87. { Ausgabe der Daten eines Treiberkopfes }
  88. Procedure ShowDriver(p: DriverPointer);
  89. var x: Integer;
  90. begin
  91.   if p = NIL then
  92.   begin
  93.     Writeln('Treiber nicht lokalisierbar!');
  94.     Halt;
  95.   end;
  96.   with p^ do
  97.   begin
  98.     if (DAttr and $8000) <> 0 then
  99.     begin
  100.       Write('Gerät ');
  101.       for x:= 1 to 8 do Write(Name[x]);
  102.     end
  103.     else Write('Block, (',Drives,' Lw.)');
  104.     Writeln(' - Attr: $',HexW(DAttr),
  105.             ', Strat: $', HexP(Ptr(Seg(p^),DStrat)),
  106.             ', Intr: $', HexP(Ptr(Seg(p^),DIntr)));
  107.   end;
  108. end;
  109.  
  110. { Aufruf der Strategie-Routine, d.h. Übergabe Parameterblock }
  111. Procedure CallStrategy(Driver: DriverPointer; ParmBlock: Pointer);
  112. var DStrategy: Pointer;   { Adresse der "Strategie"-Routine }
  113. begin
  114.   DStrategy := Ptr(Seg(Driver^),Driver^.DStrat);
  115.   inline($C4/$5E/<ParmBlock/      { asm les bx,[ParmBlock]  }
  116.          $FF/$9E/DStrategy        {     call [DStrategy]    }
  117.         );                        { end;                    }
  118. end;
  119.  
  120. { Aufruf der Interrupt-Routine, d.h. Ausführung der Funktion }
  121. Procedure CallInterrupt(Driver: DriverPointer);
  122. var DInterrupt: Pointer;  { Adresse der "Interrupt"-Routine }
  123. begin
  124.   DInterrupt := Ptr(Seg(Driver^),Driver^.DIntr);
  125.   inline($55/                 { asm push  bp   ; nur für DR-DOS }
  126.          $1E/                 {     push  ds            }
  127.          $FF/$9E/DInterrupt/  {     call [DInterrupt]   }
  128.          $1F/                 {     pop   ds            }
  129.          $5D                  {     pop   bp   ; dito           }
  130.         );                    { end;                    }
  131. end;
  132.  
  133. end.
  134.