home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / vrac / sk210f.zip / EXECSWAP.ASM < prev    next >
Assembly Source File  |  1989-05-02  |  21KB  |  436 lines

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