home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XSRC_117.ZIP / SWAP_C.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-12-07  |  19.0 KB  |  422 lines

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