home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / dossys / execswap / execwswp.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1990-11-05  |  6.0 KB  |  209 lines

  1. {
  2. Copyright (c) 1988,1990 TurboPower Software
  3. May be used freely as long as due credit is given
  4.  
  5. Version 1.1 - 3/15/89
  6.   save and restore EMS page map
  7. Version 1.2 - 3/29/89
  8.   add more compiler directives (far calls off, boolean short-circuiting)
  9.   add UseEmsIfAvailable to disable EMS usage when desired
  10. Version 1.3 - 5/02/89
  11.   fix problem with exit chain when InitExecSwap/ShutdownExecSwap called
  12.     more than once in a program
  13.   flush swap file before execing
  14. Version 1.4 - 10/11/89
  15.   created new PAS/ASM series called EXECWSWP (ExecWinWithSwap)
  16.   combines the features of EXECWIN and EXECSWAP
  17. Version 1.5 - 11/5/90
  18.   TP6 changes (to int21)
  19. }
  20.  
  21. {$R-,S-,F-,O-,I-,B-}
  22. unit ExecWSwp;
  23.   {-Memory-efficient Windowed DOS EXEC call}
  24.  
  25. interface
  26.  
  27. uses
  28.   Dos, OpDos;
  29.  
  30. const
  31.   UseEmsIfAvailable : Boolean = True;     {True to use EMS if available}
  32.   BytesSwapped : LongInt = 0;             {Bytes to swap to EMS/disk}
  33.   EmsAllocated : Boolean = False;         {True when EMS allocated for swap}
  34.   FileAllocated : Boolean = False;        {True when file allocated for swap}
  35.   NewInt21Addr : Pointer = nil;           {Filled in by InstallInt21}
  36.  
  37. function ExecWinWithSwap(Path, CmdLine : String;
  38.                          Xlo, Ylo, Xhi, Yhi : Byte;
  39.                          Attr : Byte) : Word;
  40.   {-Windowed DOS EXEC supporting swap to EMS or disk}
  41.  
  42. function InitExecSwap(LastToSave : Pointer; SwapFileName : String) : Boolean;
  43.   {-Initialize for swapping, returning TRUE if successful}
  44.  
  45. procedure ShutdownExecSwap;
  46.   {-Deallocate swap area}
  47.  
  48. function ExecWindow(Command : string; UseSecond : Boolean;
  49.                     Xlo, Ylo, Xhi, Yhi : Byte;
  50.                     Attr : Byte) : Integer;
  51.   {-Exec a program in a window}
  52.  
  53. implementation
  54.  
  55. var
  56.   EmsHandle : Word;               {Handle of EMS allocation block}
  57.   FrameSeg : Word;                {Segment of EMS page frame}
  58.   FileHandle : Word;              {DOS handle of swap file}
  59.   SwapName : String[80];          {ASCIIZ name of swap file}
  60.   SaveExit : Pointer;             {Exit chain pointer}
  61.  
  62.   WindPos : Word;
  63.   WindLo : Word;
  64.   WindHi : Word;
  65.   WindAttr : Byte;
  66.  
  67. {$IFDEF Ver60}
  68.   var
  69.     TmpInt21 : Pointer;
  70. {$ENDIF}
  71.  
  72. type
  73.   ByteCast =
  74.     record
  75.       LoB, HiB : Byte;
  76.     end;
  77.  
  78.   {$L EXECWSWP}
  79.   function ExecWinWithSwap(Path, CmdLine : String;
  80.                            Xlo, Ylo, Xhi, Yhi : Byte;
  81.                            Attr : Byte) : Word; external;
  82.   procedure FirstToSave; external;
  83.   function AllocateSwapFile : Boolean; external;
  84.   procedure DeallocateSwapFile; external;
  85.   procedure CheckCursor; external;
  86.   procedure InstallInt21; external;
  87.   procedure RestoreInt21; external;
  88.   procedure UpdateCsVars(Xlo, Ylo, Xhi, Yhi, Attr : Byte); external;
  89.  
  90.   {$F+}     {These routines could be interfaced for general use}
  91.   function EmsInstalled : Boolean; external;
  92.   function EmsPageFrame : Word; external;
  93.   function AllocateEmsPages(NumPages : Word) : Word; external;
  94.   procedure DeallocateEmsHandle(Handle : Word); external;
  95.   function DefaultDrive : Char; external;
  96.   function DiskFree(Drive : Byte) : LongInt; external;
  97.  
  98.   procedure ExecSwapExit;
  99.   begin
  100.     ExitProc := SaveExit;
  101.     ShutdownExecSwap;
  102.   end;
  103.   {$F-}
  104.  
  105.   procedure ShutdownExecSwap;
  106.   begin
  107.     if EmsAllocated then begin
  108.       DeallocateEmsHandle(EmsHandle);
  109.       EmsAllocated := False;
  110.     end else if FileAllocated then begin
  111.       DeallocateSwapFile;
  112.       FileAllocated := False;
  113.     end;
  114.   end;
  115.  
  116.   function PtrDiff(H, L : Pointer) : LongInt;
  117.   type
  118.     OS = record O, S : Word; end;   {Convenient typecast}
  119.   begin
  120.     PtrDiff := (LongInt(OS(H).S) shl 4+OS(H).O)-
  121.                (LongInt(OS(L).S) shl 4+OS(L).O);
  122.   end;
  123.  
  124.   function InitExecSwap(LastToSave : Pointer;
  125.                         SwapFileName : String) : Boolean;
  126.   const
  127.     EmsPageSize = 16384;            {Bytes in a standard EMS page}
  128.   var
  129.     PagesInEms : Word;              {Pages needed in EMS}
  130.     BytesFree : LongInt;            {Bytes free on swap file drive}
  131.     DriveChar : Char;               {Drive letter for swap file}
  132.   begin
  133.     InitExecSwap := False;
  134.  
  135.     if EmsAllocated or FileAllocated then
  136.       Exit;
  137.     BytesSwapped := PtrDiff(LastToSave, @FirstToSave);
  138.     if BytesSwapped <= 0 then
  139.       Exit;
  140.  
  141.     if UseEmsIfAvailable and EmsInstalled then begin
  142.       PagesInEms := (BytesSwapped+EmsPageSize-1) div EmsPageSize;
  143.       EmsHandle := AllocateEmsPages(PagesInEms);
  144.       if EmsHandle <> $FFFF then begin
  145.         EmsAllocated := True;
  146.         FrameSeg := EmsPageFrame;
  147.         if FrameSeg <> 0 then begin
  148.           InitExecSwap := True;
  149.           Exit;
  150.         end;
  151.       end;
  152.     end;
  153.     if Length(SwapFileName) <> 0 then begin
  154.       SwapName := SwapFileName+#0;
  155.       if Pos(':', SwapFileName) = 2 then
  156.         DriveChar := Upcase(SwapFileName[1])
  157.       else
  158.         DriveChar := DefaultDrive;
  159.       BytesFree := DiskFree(Byte(DriveChar)-$40);
  160.       FileAllocated := (BytesFree > BytesSwapped) and AllocateSwapFile;
  161.       if FileAllocated then
  162.         InitExecSwap := True;
  163.     end;
  164.   end;
  165.  
  166.   function ExecWindow(Command : string; UseSecond : Boolean;
  167.                       Xlo, Ylo, Xhi, Yhi : Byte;
  168.                       Attr : Byte) : Integer;
  169.     {-Exec a program in a window}
  170.   begin
  171.     {Validate window}
  172.     if (Xlo > Xhi) or (Ylo > Yhi) or (Xlo < 1) or (Ylo < 1) then begin
  173.       ExecWindow := 99;
  174.       Exit;
  175.     end;
  176.  
  177.     {Store global copies of window data for interrupt handler}
  178.     UpdateCsVars(Xlo, Ylo, Xhi, Yhi, Attr);
  179.  
  180.     {Assure cursor is in window}
  181.     CheckCursor;
  182.  
  183.     {Take over interrupt}
  184.     InstallInt21;
  185.  
  186.   {$IFDEF Ver60}
  187.     {Prevent SwapVectors from undoing our int21 change}
  188.     TmpInt21 := SaveInt21;
  189.     SaveInt21 := NewInt21Addr;
  190.   {$ENDIF}
  191.  
  192.     {Exec the program}
  193.     ExecWindow := ExecDos(Command, UseSecond, NoExecDosProc);
  194.  
  195.   {$IFDEF Ver60}
  196.     SaveInt21 := TmpInt21;
  197.   {$ENDIF}
  198.  
  199.     {Restore interrupt}
  200.     RestoreInt21;
  201.   end;
  202.  
  203. begin
  204.   SaveExit := ExitProc;
  205.   ExitProc := @ExecSwapExit;
  206. end.
  207.  
  208.  
  209.