Unit d2libr;

Interface


  Type
    PBuf = ^TBuf;
    TBuf = Array [0..64000] Of Byte;

    Procedure LibLoad(N:String);


Implementation

Uses
  d2type,dos,d2tabx86,dt2x86;



  Type

    PLibList = ^TLibList;
    TLibList = Record
      Name:PString;
      Lib:PBuf;
      Size:Word;
      Next:PLibList;
    End;


  Var
    LibList:PLibList;

  Procedure ExtractItems(Lib:PLibList);
  Var
    Pos,Nxt,Cur,Last:Word;
    N:String;
    Flg,Pr,Sz:Byte;
    V:pTerm;
  Begin
    Last:=Lib^.Size;
    Nxt:=Lib^.Lib^[0]+$100*Lib^.Lib^[1];
    While Nxt<>0 Do Begin
      Pos:=Nxt-5;
      Cur:=Nxt-5;
      Nxt:=Lib^.Lib^[Pos]+$100*Lib^.Lib^[Pos+1];
      Flg:=Lib^.Lib^[Pos+2];
      Pr:=Lib^.Lib^[Pos+3];
      Sz:=Lib^.Lib^[Pos+4];
      Inc(Pos,5);
      {---}
      N:='';
      While Lib^.Lib^[Pos]<>0 Do Begin
        N:=N+Char(Lib^.Lib^[Pos]);
        Inc(Pos);
      End; Inc(Pos);
      V:=Tab.AddTerm(N,_SUB,Pr,_EXTRN);
      V^.Loc:=Sz;
      V^.Body:=Ptr(Seg(Lib^.Lib^),Ofs(Lib^.Lib^)+Pos);
      V^.Size:=Last-Pos;
      Last:=Cur;
      {---}
{      WriteLn(N:32,'  ...  ',V^.Size:6,' bytes');}
    End;
  End;

  Function IfLibLoad(N:String):Boolean;
  Var
    Pos:PLibList;
  Begin
    Pos:=LibList;
    While (Pos<>Nil) And (Pos^.Name^.GetStr<>N) Do Pos:=Pos^.Next;
    IfLibLoad:=Pos<>Nil;
  End;

  Procedure LibLoad(N:String);
  Var
    F:File;
    S:Array[0..4]Of Char;
    T:PLibList;
    Path:String;
  Begin
    If Not IfLibLoad(N) Then Begin
      Path:=fsearch(N+'.LIB',LibraryDir);
      If Path='' Then errorMsg(Input,'cann''t load library ('+N+')');
      Assign(F,Path);
      Reset(F,SizeOf(Byte));
      BlockRead(F,S,SizeOf(S));
      If S <> ('lib2d') Then errorMsg(Input,'unknown library format');
      New(T);
      With T^ Do Begin
        Next:=LibList;
        Name:=New(PString,Init(N));
        Size:=FileSize(F)-SizeOf(S);
        GetMem(Lib,Size);
        BlockRead(F,Lib^,Size);
      End;
      LibList:=T;
      Close(F);
      ExtractItems(T);
    End;
  End;


Begin
  LibList:=Nil;
End.