telegard/execswap.pas

185 lines
4.7 KiB
ObjectPascal

{
Copyright (c) 1988 TurboPower Software
May be used freely as long as due credit is given
Version 1.1 - 3/15/89
save and restore EMS page map
Version 1.2 - 3/29/89
add more compiler directives (far calls off, boolean short-circuiting)
add UseEmsIfAvailable to disable EMS usage when desired
Version 1.3 - 5/02/89
fix problem with exit chain when InitExecSwap/ShutdownExecSwap called
more than once in a program
flush swap file before execing
}
{$A+,B-,E+,F+,I-,L-,N-,O-,R-,S-,V-}
unit ExecSwap;
{-Memory-efficient DOS EXEC call}
interface
const
UseEmsIfAvailable : Boolean = True; {True to use EMS if available}
BytesSwapped : LongInt = 0; {Bytes to swap to EMS/disk}
EmsAllocated : Boolean = False; {True when EMS allocated for swap}
FileAllocated : Boolean = False; {True when file allocated for swap}
function ExecWithSwap(Path, CmdLine : String) : Word;
{-DOS EXEC supporting swap to EMS or disk}
function InitExecSwap(LastToSave : Pointer; SwapFileName : String) : Boolean;
{-Initialize for swapping, returning TRUE if successful}
procedure ShutdownExecSwap;
{-Deallocate swap area}
implementation
var
EmsHandle : Word; {Handle of EMS allocation block}
FrameSeg : Word; {Segment of EMS page frame}
FileHandle : Word; {DOS handle of swap file}
SwapName : String[80]; {ASCIIZ name of swap file}
SaveExit : Pointer; {Exit chain pointer}
{rcg11172000 stubs follow...}
(*
{$L EXECSWAP}
function ExecWithSwap(Path, CmdLine : String) : Word; external;
procedure FirstToSave; external;
function AllocateSwapFile : Boolean; external;
procedure DeallocateSwapFile; external;
{$F+} {These routines could be interfaced for general use}
function EmsInstalled : Boolean; external;
function EmsPageFrame : Word; external;
function AllocateEmsPages(NumPages : Word) : Word; external;
procedure DeallocateEmsHandle(Handle : Word); external;
function DefaultDrive : Char; external;
function DiskFree(Drive : Byte) : LongInt; external;
*)
procedure DeallocateEmsHandle(Handle : Word);
begin
end;
function ExecWithSwap(Path, CmdLine : String) : Word;
begin
writeln('STUB: execswap.pas; ExecWithSwap()...');
ExecWithSwap := 0;
end;
procedure FirstToSave;
begin
end;
function AllocateSwapFile : Boolean;
begin
AllocateSwapFile := false;
end;
procedure DeallocateSwapFile;
begin
end;
function EmsInstalled : Boolean;
begin
EmsInstalled := false;
end;
function EmsPageFrame : Word;
begin
EmsPageFrame := 0;
end;
function AllocateEmsPages(NumPages : Word) : Word;
begin
AllocateEmsPages := 0;
end;
function DefaultDrive : Char;
begin
DefaultDrive := #103; { 'C' }
end;
function DiskFree(Drive : Byte) : LongInt;
begin
DiskFree := 10000000;
end;
procedure ExecSwapExit;
begin
ExitProc := SaveExit;
ShutdownExecSwap;
end;
{$F-}
procedure ShutdownExecSwap;
begin
if EmsAllocated then begin
DeallocateEmsHandle(EmsHandle);
EmsAllocated := False;
end else if FileAllocated then begin
DeallocateSwapFile;
FileAllocated := False;
end;
end;
function PtrDiff(H, L : Pointer) : LongInt;
type
OS = record O, S : Word; end; {Convenient typecast}
begin
PtrDiff := (LongInt(OS(H).S) shl 4+OS(H).O)-
(LongInt(OS(L).S) shl 4+OS(L).O);
end;
function InitExecSwap(LastToSave : Pointer;
SwapFileName : String) : Boolean;
const
EmsPageSize = 16384; {Bytes in a standard EMS page}
var
PagesInEms : Word; {Pages needed in EMS}
BytesFree : LongInt; {Bytes free on swap file drive}
DriveChar : Char; {Drive letter for swap file}
begin
InitExecSwap := False;
if EmsAllocated or FileAllocated then
Exit;
BytesSwapped := PtrDiff(LastToSave, @FirstToSave);
if BytesSwapped <= 0 then
Exit;
if UseEmsIfAvailable and EmsInstalled then begin
PagesInEms := (BytesSwapped+EmsPageSize-1) div EmsPageSize;
EmsHandle := AllocateEmsPages(PagesInEms);
if EmsHandle <> $FFFF then begin
EmsAllocated := True;
FrameSeg := EmsPageFrame;
if FrameSeg <> 0 then begin
InitExecSwap := True;
Exit;
end;
end;
end;
if Length(SwapFileName) <> 0 then begin
SwapName := SwapFileName+#0;
if Pos(':', SwapFileName) = 2 then
DriveChar := Upcase(SwapFileName[1])
else
DriveChar := DefaultDrive;
BytesFree := DiskFree(Byte(DriveChar)-$40);
FileAllocated := (BytesFree > BytesSwapped) and AllocateSwapFile;
if FileAllocated then
InitExecSwap := True;
end;
end;
begin
SaveExit := ExitProc;
ExitProc := @ExecSwapExit;
end.