home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 04 / execsw.asc next >
INI File  |  1989-03-27  |  25KB  |  568 lines

  1. [LISTING ONE]
  2.  
  3. program TestExecSwap;
  4. uses
  5.   Dos,ExecSwap; {Keep ExecSwap last}
  6. const
  7.   SwapLoc : array[Boolean] of String[7] = ('on disk', 'in EMS');
  8. var
  9.   Status : Word;
  10. begin
  11.   if not InitExecSwap(HeapPtr, 'SWAP.$$$') then
  12.     WriteLn('Unable to allocate swap space')
  13.   else begin
  14.     WriteLn('Allocated ', BytesSwapped, ' bytes ', SwapLoc[EmsAllocated]);
  15.     SwapVectors;
  16.     Status := ExecWithSwap(GetEnv('COMSPEC'), '');
  17.     SwapVectors;
  18.     WriteLn('Execu status; ', Status);
  19.   end;
  20. end.
  21.  
  22.  
  23. [LISTING TWO]
  24.  
  25. {Copyright (c) 1988 TurboPower Software}
  26. {May be used freely as long as due credit is given}
  27. {$R-,S-}
  28. unit ExecSwap;
  29.   {-Memory-efficient DOS EXEC call}
  30. interface
  31.  
  32. const
  33.   BytesSwapped : LongInt = 0;             {Bytes to swap to EMS/disk}
  34.   EmsAllocated : Boolean = False;         {True when EMS allocated for swap}
  35.   FileAllocated : Boolean = False;        {True when file allocated for swap}
  36.  
  37. function ExecWithSwap(Path, CmdLine : String) : Word;
  38.   {-DOS EXEC supporting swap to EMS or disk}
  39.  
  40. function InitExecSwap(LastToSave : Pointer; SwapFileName : String) : Boolean;
  41.   {-Initialize for swapping, returning TRUE if successful}
  42.  
  43. procedure ShutdownExecSwap;
  44.   {-Deallocate swap area}
  45.  
  46. implementation
  47.  
  48. var
  49.   EmsHandle : Word;               {Handle of EMS allocation block}
  50.   FrameSeg : Word;                {Segment of EMS page frame}
  51.   FileHandle : Word;              {DOS handle of swap file}
  52.   SwapName : String[80];          {ASCIIZ name of swap file}
  53.   SaveExit : Pointer;             {Exit chain pointer}
  54.  
  55.   {$L EXECSWAP}
  56.   function ExecWithSwap(Path, CmdLine : String) : Word; external;
  57.   procedure FirstToSave; external;
  58.   function AllocateSwapFile : Boolean; external;
  59.   procedure DeallocateSwapFile; external;
  60.  
  61.   {$F+}     {These routines could be interfaced for general use}
  62.   function EmsInstalled : Boolean; external;
  63.   function EmsPageFrame : Word; external;
  64.   function AllocateEmsPages(NumPages : Word) : Word; external;
  65.   procedure DeallocateEmsHandle(Handle : Word); external;
  66.   function DefaultDrive : Char; external;
  67.   function DiskFree(Drive : Byte) : LongInt; external;
  68.  
  69.   procedure ExecSwapExit;
  70.   begin
  71.     ExitProc := SaveExit;
  72.     ShutdownExecSwap;
  73.   end;
  74.   {$F-}
  75.  
  76.   procedure ShutdownExecSwap;
  77.   begin
  78.     if EmsAllocated then begin
  79.       DeallocateEmsHandle(EmsHandle);
  80.       EmsAllocated := False;
  81.     end else if FileAllocated then begin
  82.       DeallocateSwapFile;
  83.       FileAllocated := False;
  84.     end;
  85.   end;
  86.  
  87.   function PtrDiff(H, L : Pointer) : LongInt;
  88.   type
  89.     OS = record O, S : Word; end;   {Convenient typecast}
  90.   begin
  91.     PtrDiff := (LongInt(OS(H).S) shl 4+OS(H).O)-
  92.                (LongInt(OS(L).S) shl 4+OS(L).O);
  93.   end;
  94.  
  95.   function InitExecSwap(LastToSave : Pointer;
  96.                         SwapFileName : String) : Boolean;
  97.   const
  98.     EmsPageSize = 16384;            {Bytes in a standard EMS page}
  99.   var
  100.     PagesInEms : Word;              {Pages needed in EMS}
  101.     BytesFree : LongInt;            {Bytes free on swap file drive}
  102.     DriveChar : Char;               {Drive letter for swap file}
  103.   begin
  104.     InitExecSwap := False;
  105.  
  106.     if EmsAllocated or FileAllocated then
  107.       Exit;
  108.     BytesSwapped := PtrDiff(LastToSave, @FirstToSave);
  109.     if BytesSwapped <= 0 then
  110.       Exit;
  111.     SaveExit := ExitProc;
  112.     ExitProc := @ExecSwapExit;
  113.  
  114.     if EmsInstalled then begin
  115.       PagesInEms := (BytesSwapped+EmsPageSize-1) div EmsPageSize;
  116.       EmsHandle := AllocateEmsPages(PagesInEms);
  117.       if EmsHandle <> $FFFF then begin
  118.         EmsAllocated := True;
  119.         FrameSeg := EmsPageFrame;
  120.         if FrameSeg <> 0 then begin
  121.           InitExecSwap := True;
  122.           Exit;
  123.         end;
  124.       end;
  125.     end;
  126.     if Length(SwapFileName) <> 0 then begin
  127.       SwapName := SwapFileName+#0;
  128.       if Pos(':', SwapFileName) = 2 then
  129.         DriveChar := Upcase(SwapFileName[1])
  130.       else
  131.         DriveChar := DefaultDrive;
  132.       BytesFree := DiskFree(Byte(DriveChar)-$40);
  133.       FileAllocated := (BytesFree > BytesSwapped) and AllocateSwapFile;
  134.       if FileAllocated then
  135.         InitExecSwap := True;
  136.     end;
  137.   end;
  138. end.
  139.  
  140. [LISTING THREE]
  141.  
  142. ;EXECSWAP.ASM
  143. ;  Swap memory and exec another program
  144. ;  Copyright (c) 1988 TurboPower Software
  145. ;  May be used freely as long as due credit is given
  146. ;-----------------------------------------------------------------------------
  147. DATA    SEGMENT BYTE PUBLIC
  148.         EXTRN   BytesSwapped:DWORD      ;Bytes to swap to EMS/disk
  149.         EXTRN   EmsAllocated:BYTE       ;True when EMS allocated for swap
  150.         EXTRN   FileAllocated:BYTE      ;True when file allocated for swap
  151.         EXTRN   EmsHandle:WORD          ;Handle of EMS allocation block
  152.         EXTRN   FrameSeg:WORD           ;Segment of EMS page frame
  153.         EXTRN   FileHandle:WORD         ;Handle of DOS swap file
  154.         EXTRN   SwapName:BYTE           ;ASCIIZ name of swap file
  155.         EXTRN   PrefixSeg:WORD          ;Base segment of program
  156. DATA    ENDS
  157. ;-----------------------------------------------------------------------------
  158. CODE    SEGMENT BYTE PUBLIC
  159.         ASSUME  CS:CODE,DS:DATA
  160.         PUBLIC  ExecWithSwap,FirstToSave
  161.         PUBLIC  AllocateSwapFile,DeallocateSwapFile
  162.         PUBLIC  DefaultDrive,DiskFree
  163.         PUBLIC  EmsInstalled,EmsPageFrame
  164.         PUBLIC  AllocateEmsPages,DeallocateEmsHandle
  165. ;-----------------------------------------------------------------------------
  166. FileAttr        EQU     6               ;Swap file attribute (hidden+system)
  167. EmsPageSize     EQU     16384           ;Size of EMS page
  168. FileBlockSize   EQU     32768           ;Size of a file block
  169. StkSize         EQU     128             ;Bytes in temporary stack
  170. lo              EQU     (WORD PTR 0)    ;Convenient typecasts
  171. hi              EQU     (WORD PTR 2)
  172. ofst            EQU     (WORD PTR 0)
  173. segm            EQU     (WORD PTR 2)
  174. ;-----------------------------------------------------------------------------
  175. ;Variables in CS
  176. EmsDevice       DB      'EMMXXXX0',0    ;Name of EMS device driver
  177. UsedEms         DB      0               ;1 if swapping to EMS, 0 if to file
  178. BytesSwappedCS  DD      0               ;Bytes to move during a swap
  179. EmsHandleCS     DW      0               ;EMS handle
  180. FrameSegCS      DW      0               ;Segment of EMS page window
  181. FileHandleCS    DW      0               ;DOS file handle
  182. PrefixSegCS     DW      0               ;Segment of base of program
  183. Status          DW      0               ;ExecSwap status code
  184. LeftToSwap      DD      0               ;Bytes left to move
  185. SaveSP          DW      0               ;Original stack pointer
  186. SaveSS          DW      0               ;Original stack segment
  187. PathPtr         DD      0               ;Pointer to program to execute
  188. CmdPtr          DD      0               ;Pointer to command line to execute
  189. ParasWeHave     DW      0               ;Paragraphs allocated to process
  190. CmdLine         DB      128 DUP(0)      ;Terminated command line passed to DOS
  191. Path            DB      64 DUP(0)       ;Terminated path name passed to DOS
  192. FileBlock1      DB      16 DUP(0)       ;FCB passed to DOS
  193. FileBlock2      DB      16 DUP(0)       ;FCB passed to DOS
  194. EnvironSeg      DW      0               ;Segment of environment for child
  195. CmdLinePtr      DD      0               ;Pointer to terminated command line
  196. FilePtr1        DD      0               ;Pointer to FCB file
  197. FilePtr2        DD      0               ;Pointer to FCB file
  198. TempStack       DB      StkSize DUP(0)  ;Temporary stack
  199. StackTop        LABEL   WORD            ;Initial top of stack
  200. ;-----------------------------------------------------------------------------
  201. ;Macros
  202. MovSeg          MACRO Dest,Src          ;Set one segment register to another
  203.         PUSH    Src
  204.         POP     Dest
  205.                 ENDM
  206.  
  207. MovMem          MACRO Dest,Src          ;Move from memory to memory via AX
  208.         MOV     AX,Src
  209.         MOV     Dest,AX
  210.                 ENDM
  211.  
  212. InitSwapCount   MACRO                   ;Initialize counter for bytes to swap
  213.         MovMem  LeftToSwap.lo,BytesSwappedCS.lo
  214.         MovMem  LeftToSwap.hi,BytesSwappedCS.hi
  215.                 ENDM
  216.  
  217. SetSwapCount    MACRO BlkSize           ;Return CX = bytes to move this block
  218.         LOCAL   FullBlk                 ;...and reduce total bytes left to move
  219.         MOV     CX,BlkSize              ;Assume we'll write a full block
  220.         CMP     LeftToSwap.hi,0         ;Is high word still non-zero?
  221.         JNZ     FullBlk                 ;Jump if so
  222.         CMP     LeftToSwap.lo,BlkSize   ;Low word still a block or more?
  223.         JAE     FullBlk                 ;Jump if so
  224.         MOV     CX,LeftToSwap.lo        ;Otherwise, move what's left
  225. FullBlk:SUB     LeftToSwap.lo,CX        ;Reduce number left to move
  226.         SBB     LeftToSwap.hi,0
  227.                 ENDM
  228.  
  229. NextBlock       MACRO SegReg, BlkSize   ;Point SegReg to next block to move
  230.         MOV     AX,SegReg
  231.         ADD     AX,BlkSize/16           ;Add paragraphs to next segment
  232.         MOV     SegReg,AX               ;Next block to move
  233.         MOV     AX,LeftToSwap.lo
  234.         OR      AX,LeftToSwap.hi        ;Bytes left to move?
  235.                 ENDM
  236.  
  237. EmsCall         MACRO FuncAH            ;Call EMM and prepare to check result
  238.         MOV     AH,FuncAH               ;Set up function
  239.         INT     67h
  240.         OR      AH,AH                   ;Error code in AH
  241.                 ENDM
  242.  
  243. DosCallAH       MACRO FuncAH            ;Call DOS subfunction AH
  244.         MOV     AH,FuncAH
  245.         INT     21h
  246.                 ENDM
  247.  
  248. DosCallAX       MACRO FuncAX            ;Call DOS subfunction AX
  249.         MOV     AX,FuncAX
  250.         INT     21h
  251.                 ENDM
  252.  
  253. InitSwapFile    MACRO
  254.         MOV     BX,FileHandleCS         ;BX = handle of swap file
  255.         XOR     CX,CX
  256.         XOR     DX,DX                   ;Start of file
  257.         DosCallAX 4200h                 ;DOS file seek
  258.                 ENDM
  259.  
  260. HaltWithError   MACRO Level             ;Halt if non-recoverable error occurs
  261.         MOV     AL,Level                ;Set errorlevel
  262.         DosCallAH 4Ch
  263.                 ENDM
  264.  
  265. MoveFast        MACRO                   ;Move CX bytes from DS:SI to ES:DI
  266.         CLD                             ;Forward
  267.         RCR     CX,1                    ;Convert to words
  268.         REP     MOVSW                   ;Move the words
  269.         RCL     CX,1                    ;Get the odd byte, if any
  270.         REP     MOVSB                   ;Move it
  271.                 ENDM
  272.  
  273. SetTempStack    MACRO                   ;Switch to temporary stack
  274.         MOV     AX,OFFSET StackTop      ;Point to top of stack
  275.         MOV     BX,CS                   ;Temporary stack in this code segment
  276.         CLI                             ;Interrupts off
  277.         MOV     SS,BX                   ;Change stack
  278.         MOV     SP,AX
  279.         STI                             ;Interrupts on
  280.                 ENDM
  281. ;-----------------------------------------------------------------------------
  282. ;function ExecWithSwap(Path, CmdLine : string) : Word;
  283. ExecWithSwap    PROC FAR
  284.         PUSH    BP
  285.         MOV     BP,SP                   ;Set up stack frame
  286.  
  287. ;Move variables to CS where we can easily access them later
  288.         MOV     Status,1                ;Assume failure
  289.         LES     DI,[BP+6]               ;ES:DI -> CmdLine
  290.         MOV     CmdPtr.ofst,DI
  291.         MOV     CmdPtr.segm,ES          ;CmdPtr -> command line string
  292.         LES     DI,[BP+10]              ;ES:DI -> Path
  293.         MOV     PathPtr.ofst,DI
  294.         MOV     PathPtr.segm,ES         ;PathPtr -> path to execute
  295.         MOV     SaveSP,SP               ;Save stack position
  296.         MOV     SaveSS,SS
  297.         MovMem  BytesSwappedCS.lo,BytesSwapped.lo
  298.         MovMem  BytesSwappedCS.hi,BytesSwapped.hi
  299.         MovMem  EmsHandleCS,EmsHandle
  300.         MovMem  FrameSegCS,FrameSeg
  301.         MovMem  FileHandleCS,FileHandle
  302.         MovMem  PrefixSegCS,PrefixSeg
  303.         InitSwapCount                   ;Initialize bytes LeftToSwap
  304.  
  305. ;Check for swapping to EMS or file
  306.         CMP     EmsAllocated,0          ;Check flag for EMS method
  307.         JZ      NotEms                  ;Jump if EMS not used
  308.         JMP     WriteE                  ;Swap to EMS
  309. NotEms: CMP     FileAllocated,0         ;Check flag for swap file method
  310.         JNZ     WriteF                  ;Swap to file
  311.         JMP     ESDone                  ;Exit if no swapping method set
  312.  
  313. ;Write to swap file
  314. WriteF: MovSeg  DS,CS                   ;DS = CS
  315.         InitSwapFile                    ;Seek to start of swap file
  316.         JNC     EF0                     ;Jump if success
  317.         JMP     ESDone                  ;Exit if error
  318. EF0:    SetSwapCount FileBlockSize      ;CX = bytes to write
  319.         MOV     DX,OFFSET FirstToSave   ;DS:DX -> start of region to save
  320.         DosCallAH 40h                   ;File write
  321.         JC      EF1                     ;Jump if write error
  322.         CMP     AX,CX                   ;All bytes written?
  323.         JZ      EF2                     ;Jump if so
  324. EF1:    JMP     ESDone                  ;Exit if error
  325. EF2:    NextBlock DS,FileBlockSize      ;Point DS to next block to write
  326.         JNZ     EF0                     ;Loop if bytes left to write
  327.         MOV     UsedEms,0               ;Flag we used swap file for swapping
  328.         JMP     SwapDone                ;Done swapping out
  329.  
  330. ;Write to EMS
  331. WriteE: MOV     ES,FrameSeg             ;ES -> page window
  332.         MOV     DX,EmsHandle            ;DX = handle of our EMS block
  333.         XOR     BX,BX                   ;BX = initial logical page
  334.         MovSeg  DS,CS                   ;DS = CS
  335. EE0:    XOR     AL,AL                   ;Physical page 0
  336.         EmsCall 44h                     ;Map physical page
  337.         JZ      EE1                     ;Jump if success
  338.         JMP     ESDone                  ;Exit if error
  339. EE1:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  340.         XOR     DI,DI                   ;ES:DI -> base of EMS page
  341.         MOV     SI,OFFSET FirstToSave   ;DS:SI -> region to save
  342.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  343.         INC     BX                      ;Next logical page
  344.         NextBlock DS,EmsPageSize        ;Point DS to next page to move
  345.         JNZ     EE0                     ;Loop if bytes left to move
  346.         MOV     UsedEms,1               ;Flag we used EMS for swapping
  347.  
  348. ;Shrink memory allocated to this process
  349. SwapDone:MOV    AX,PrefixSegCS
  350.         MOV     ES,AX                   ;ES = segment of our memory block
  351.         DEC     AX
  352.         MOV     DS,AX                   ;DS = segment of memory control block
  353.         MOV     CX,DS:[0003h]           ;CX = current paragraphs owned
  354.         MOV     ParasWeHave,CX          ;Save current paragraphs owned
  355.         SetTempStack                    ;Switch to temporary stack
  356.         MOV     AX,OFFSET FirstToSave+15
  357.         MOV     CL,4
  358.         SHR     AX,CL                   ;Convert offset to paragraphs
  359.         ADD     BX,AX
  360.         SUB     BX,PrefixSegCS          ;BX = new paragraphs to keep
  361.         DosCallAH 4Ah                   ;SetBlock
  362.         JNC     EX0                     ;Jump if successful
  363.         JMP     EX5                     ;Swap back and exit
  364.  
  365. ;Set up parameters and call DOS Exec
  366. EX0:    MOV     AX,ES:[002Ch]           ;Get environment segment
  367.         MOV     EnvironSeg,AX
  368.         MovSeg  ES,CS                   ;ES = CS
  369.         LDS     SI,PathPtr              ;DS:SI -> path to execute
  370.         MOV     DI,OFFSET Path          ;ES:DI -> local ASCIIZ copy
  371.         CLD
  372.         LODSB                           ;Read current length
  373.         CMP     AL,63                   ;Truncate if exceeds space set aside
  374.         JB      EX1
  375.         MOV     AL,63
  376. EX1:    MOV     CL,AL
  377.         XOR     CH,CH                   ;CX = bytes to copy
  378.         REP     MOVSB
  379.         XOR     AL,AL
  380.         STOSB                           ;ASCIIZ terminate
  381.         LDS     SI,CmdPtr               ;DS:SI -> Command line to pass
  382.         MOV     DI,OFFSET CmdLine       ;ES:DI -> Local terminated copy
  383.         LODSB
  384.         CMP     AL,126                  ;Truncate command if exceeds space
  385.         JB      EX2
  386.         MOV     AL,126
  387. EX2:    STOSB
  388.         MOV     CL,AL
  389.         XOR     CH,CH                   ;CX = bytes to copy
  390.         REP     MOVSB
  391.         MOV     AL,0DH                  ;Terminate with ^M
  392.         STOSB
  393.         MovSeg  DS,CS                   ;DS = CS
  394.         MOV     SI,OFFSET CmdLine
  395.         MOV     CmdLinePtr.ofst,SI
  396.         MOV     CmdLinePtr.segm,DS      ;Store pointer to command line
  397.         INC     SI
  398.         MOV     DI,OFFSET FileBlock1
  399.         MOV     FilePtr1.ofst,DI
  400.         MOV     FilePtr1.segm,ES        ;Store pointer to filename 1, if any
  401.         DosCallAX 2901h                 ;Parse FCB
  402.         MOV     DI,OFFSET FileBlock2
  403.         MOV     FilePtr2.ofst,DI
  404.         MOV     FilePtr2.segm,ES        ;Store pointer to filename 2, if any
  405.         DosCallAX 2901h                 ;Parse FCB
  406.         MOV     DX,OFFSET Path
  407.         MOV     BX,OFFSET EnvironSeg
  408.         DosCallAX 4B00h                 ;Exec
  409.         JC      EX3                     ;Jump if error in DOS call
  410.         XOR     AX,AX                   ;Return zero for success
  411. EX3:    MOV     Status,AX               ;Save DOS error code
  412.  
  413. ;Set up temporary stack and reallocate original memory block
  414.         SetTempStack                    ;Set up temporary stack
  415.         MOV     ES,PrefixSegCS
  416.         MOV     BX,ParasWeHave
  417.         DosCallAH 4Ah                   ;SetBlock
  418.         JNC     EX4                     ;Jump if no error
  419.         HaltWithError 0FFh              ;Must halt if failure here
  420. EX4:    InitSwapCount                   ;Initialize LeftToSwap
  421.  
  422. ;Check which swap method is in use
  423. EX5:    CMP     UsedEms,0
  424.         JZ      ReadF                   ;Jump to read back from file
  425.         JMP     ReadE                   ;Read back from EMS
  426.  
  427. ;Read back from swap file
  428. ReadF:  MovSeg  DS,CS                   ;DS = CS
  429.         InitSwapFile                    ;Seek to start of swap file
  430.         JNC     EF3                     ;Jump if we succeeded
  431.         HaltWithError 0FEh              ;Must halt if failure here
  432. EF3:    SetSwapCount FileBlockSize      ;CX = bytes to read
  433.         MOV     DX,OFFSET FirstToSave   ;DS:DX -> start of region to restore
  434.         DosCallAH 3Fh                   ;Read file
  435.         JNC     EF4                     ;Jump if no error
  436.         HaltWithError 0FEh              ;Must halt if failure here
  437. EF4:    CMP     AX,CX
  438.         JZ      EF5                     ;Jump if full block read
  439.         HaltWithError 0FEh              ;Must halt if failure here
  440. EF5:    NextBlock DS,FileBlockSize      ;Point DS to next page to read
  441.         JNZ     EF3                     ;Jump if bytes left to read
  442.         JMP     ESDone                  ;We're done
  443.  
  444. ;Copy back from EMS
  445. ReadE:  MOV     DS,FrameSegCS           ;DS -> page window
  446.         MOV     DX,EmsHandleCS          ;DX = handle of our EMS block
  447.         XOR     BX,BX                   ;BX = initial logical page
  448.         MovSeg  ES,CS                   ;ES = CS
  449. EE3:    XOR     AL,AL                   ;Physical page 0
  450.         EmsCall 44h                     ;Map physical page
  451.         JZ      EE4                     ;Jump if success
  452.         HaltWithError 0FDh              ;Must halt if failure here
  453. EE4:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  454.         XOR     SI,SI                   ;DS:SI -> base of EMS page
  455.         MOV     DI,OFFSET FirstToSave   ;ES:DI -> region to restore
  456.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  457.         INC     BX                      ;Next logical page
  458.         NextBlock ES,EmsPageSize        ;Point ES to next page to move
  459.         JNZ     EE3                     ;Jump if so
  460.  
  461. ESDone: CLI                             ;Switch back to original stack
  462.         MOV     SS,SaveSS
  463.         MOV     SP,SaveSP
  464.         STI
  465.         MOV     AX,SEG DATA
  466.         MOV     DS,AX                   ;Restore DS
  467.         MOV     AX,Status               ;Return status
  468.         POP     BP
  469.         RET     8                       ;Remove parameters and return
  470. ExecWithSwap    ENDP
  471. ;-----------------------------------------------------------------------------
  472. ;Label marks first location to swap
  473. FirstToSave:
  474. ;-----------------------------------------------------------------------------
  475. ;function AllocateSwapFile : Boolean;
  476. AllocateSwapFile PROC NEAR
  477.         MOV     CX,FileAttr             ;Attribute for swap file
  478.         MOV     DX,OFFSET SwapName+1    ;DS:DX -> ASCIIZ swap name
  479.         DosCallAH 3Ch                   ;Create file
  480.         MOV     FileHandle,AX           ;Save handle assuming success
  481.         MOV     AL,0                    ;Assume failure
  482.         JC      ASDone                  ;Failed if carry set
  483.         INC     AL                      ;Return true for success
  484. ASDone: RET
  485. AllocateSwapFile ENDP
  486. ;-----------------------------------------------------------------------------
  487. ;procedure DeallocateSwapFile;
  488. DeallocateSwapFile PROC NEAR
  489.         MOV     BX,FileHandle           ;Handle of swap file
  490.         DosCallAH 3Eh                   ;Close file
  491.         XOR     CX,CX                   ;Normal attribute
  492.         MOV     DX,OFFSET SwapName+1    ;DS:DX -> ASCIIZ swap name
  493.         DosCallAX 4301h                 ;Set file attribute
  494.         DosCallAH 41h                   ;Delete file
  495.         RET
  496. DeallocateSwapFile ENDP
  497. ;-----------------------------------------------------------------------------
  498. ;function EmsInstalled : Boolean;
  499. EmsInstalled    PROC FAR
  500.         PUSH    DS
  501.         MovSeg  DS,CS                   ;DS = CS
  502.         MOV     DX,OFFSET EmsDevice     ;DS:DX -> EMS driver name
  503.         DosCallAX 3D02h                 ;Open for read/write
  504.         POP     DS
  505.         MOV     BX,AX                   ;Save handle in case one returned
  506.         MOV     AL,0                    ;Assume FALSE
  507.         JC      EIDone
  508.         DosCallAH 3Eh                   ;Close file
  509.         MOV     AL,1                    ;Return TRUE
  510. EIDone: RET
  511. EmsInstalled    ENDP
  512. ;-----------------------------------------------------------------------------
  513. ;function EmsPageFrame : Word;
  514. EmsPageFrame    PROC FAR
  515.         EmsCall 41h                     ;Get page frame
  516.         MOV     AX,BX                   ;AX = segment
  517.         JZ      EPDone                  ;Done if Error = 0
  518.         XOR     AX,AX                   ;Else segment = 0
  519. EPDone: RET
  520. EmsPageFrame    ENDP
  521. ;-----------------------------------------------------------------------------
  522. ;function AllocateEmsPages(NumPages : Word) : Word;
  523. AllocateEmsPages PROC FAR
  524.         MOV     BX,SP                   ;Set up stack frame
  525.         MOV     BX,SS:[BX+4]            ;BX = NumPages
  526.         EmsCall 43h                     ;Allocate EMS
  527.         MOV     AX,DX                   ;Assume success
  528.         JZ      APDone                  ;Done if not 0
  529.         MOV     AX,0FFFFh               ;$FFFF for failure
  530. APDone: RET     2                       ;Remove parameter and return
  531. AllocateEmsPages ENDP
  532. ;-----------------------------------------------------------------------------
  533. ;procedure DeallocateEmsHandle(Handle : Word);
  534. DeallocateEmsHandle PROC FAR
  535.         MOV     BX,SP                   ;Set up stack frame
  536.         MOV     DX,SS:[BX+4]            ;DX = Handle
  537.         EmsCall 45h                     ;Deallocate EMS
  538.         RET     2                       ;Remove parameter and return
  539. DeallocateEmsHandle ENDP
  540. ;-----------------------------------------------------------------------------
  541. ;function DefaultDrive : Char;
  542. DefaultDrive    PROC FAR
  543.         DosCallAH 19h                   ;Get default drive
  544.         ADD     AL,'A'                  ;Convert to character
  545.         RET
  546. DefaultDrive    ENDP
  547. ;-----------------------------------------------------------------------------
  548. ;function DiskFree(Drive : Byte) : LongInt;
  549. DiskFree        PROC FAR
  550.         MOV     BX,SP                   ;Set up stack frame
  551.         MOV     DL,SS:[BX+4]            ;DL = Drive to check
  552.         DosCallAH 36h                   ;Get disk space
  553.         MOV     DX,AX                   ;Return 0FFFFFFFFh for failure
  554.         CMP     AX,0FFFFh               ;Bad drive number?
  555.         JZ      DFDone                  ;Jump if so
  556.         MUL     CX                      ;AX = bytes/cluster
  557.         MUL     BX                      ;DX:AX = bytes free
  558. DFDone: RET     2                       ;Remove parameter and return
  559. DiskFree        ENDP
  560. ;-----------------------------------------------------------------------------
  561. CODE    ENDS
  562.         END
  563.  
  564.  
  565.  
  566.  
  567.  
  568.