home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / t_power / chain.asm < prev    next >
Encoding:
Assembly Source File  |  1988-10-27  |  14.3 KB  |  321 lines

  1. ;*******************************************************
  2. ;                    CHAIN.ASM 5.00
  3. ;        Copyright (c) TurboPower Software 1987.
  4. ;                 All rights reserved.
  5. ;*******************************************************
  6.  
  7. ;Set the following define to 1 and reassemble CHAIN
  8. ;if you need to run under DOS 2.X
  9. DOS2X = 0
  10.  
  11. DSEG    SEGMENT WORD PUBLIC
  12.  
  13.         EXTRN   CloseFilesBeforeChaining:BYTE   ;Variable in CHAIN.PAS
  14.         EXTRN   PrefixSeg:WORD                  ;Variable in SYSTEM
  15.  
  16. DSEG    ENDS
  17.  
  18. CSEG    SEGMENT BYTE PUBLIC
  19.  
  20.         ASSUME  CS:CSEG,DS:DSEG
  21.  
  22.         PUBLIC  Chain4
  23.         PUBLIC  SetIntVec
  24.         EXTRN   RestoreVectors:NEAR             ;Routine to restore vectors
  25.  
  26. ;The following values must be exact
  27. ;They'll need changing if anything after label CodeToRelocate changes
  28. CodeLen        EQU     02Ch                     ;Bytes of code to relocate
  29. MaxCmdLen      EQU     052h                     ;Maximum length of command line
  30.  
  31. ;Although more reliable, the following generates several NOPs in object code
  32. ;CodeLen = offset Dummy-offset CodeToRelocate   ;Length of code in PSP
  33. ;MaxCmdLen = 07Eh-CodeLen                       ;Maximum length of command line
  34.  
  35. FirstHandle     EQU     5                       ;First file handle to close
  36.  
  37. ;**************************************************************** SetIntVec
  38. ; procedure SetIntVec(Num : Byte; Vec : pointer);
  39. ;   set interrupt Num to point to Vec
  40.  
  41. SetIntVec PROC NEAR
  42.         MOV     BX,SP                           ;Stack frame
  43.         MOV     CX,DS                           ;Save DS
  44.         MOV     AH,25h                          ;Set vector
  45.         MOV     AL,SS:[BX+6]                    ;AL = Num
  46.         LDS     DX,SS:[BX+2]                    ;DS:DX = Vec
  47.         INT     21h
  48.         MOV     DS,CX                           ;Restore DS
  49.         RET     6
  50. SetIntVec ENDP
  51.  
  52. ;**************************************************************** Chain4
  53. ; function Chain4(Path, CmdLine : string) : word;
  54. ;   Turbo 4 equivalent of chaining
  55.  
  56. ;Parameters
  57. PathArg         EQU     DWORD PTR [BP+10]       ;File to chain to
  58. CmdLine         EQU     DWORD PTR [BP+6]        ;Command line to pass
  59.  
  60. ;Local variables
  61. CsInit          EQU     WORD PTR [BP-30+16h]    ;Fields within EXE header
  62. IpInit          EQU     WORD PTR [BP-30+14h]    ; ...
  63. StackPtr        EQU     WORD PTR [BP-30+10h]
  64. StackSeg        EQU     WORD PTR [BP-30+0Eh]
  65. MinHeap         EQU     WORD PTR [BP-30+0Ah]
  66. EXEPages        EQU     WORD PTR [BP-30+04h]
  67. EXEHeader       EQU     WORD PTR [BP-30]        ;EXE header from file
  68. Path            EQU     BYTE PTR [BP-94]        ;ASCIIZ path string
  69.  
  70. Chain4  PROC    FAR
  71.  
  72.         PUSH    BP
  73.         MOV     BP,SP                           ;Set up stack frame
  74.         SUB     SP,94                           ;Make space for locals
  75.  
  76. ;Validate pathname and convert to ASCIIZ
  77.         PUSH    DS                              ;Save DS for later
  78.         PUSH    SS
  79.         POP     ES                              ;ES = SS
  80.         LEA     DI,Path                         ;ES:DI => ASCIIZ path
  81.         MOV     BX,DI                           ;Save offset of ASCIIZ
  82.         LDS     SI,PathArg                      ;DS:SI => file path in Turbo string
  83.         ASSUME  DS:nothing
  84.         CLD                                     ;Forward
  85.         LODSB                                   ;Get length byte
  86.         CMP     AL,63                           ;Longer than 63 characters?
  87.         JB      StoreASCIIZ
  88.         MOV     AL,63                           ;Truncate it
  89. StoreASCIIZ:
  90.         MOV     CL,AL                           ;CX = length
  91.         XOR     CH,CH
  92.         REP     MOVSB                           ;Copy to local Path
  93.         XOR     AL,AL                           ;Make ASCIIZ
  94.         STOSB
  95.  
  96. ;Assure file exists
  97.         PUSH    SS
  98.         POP     DS                              ;DS = SS
  99.         MOV     DX,BX                           ;DS:DX => ASCIIZ path
  100.         MOV     AX,3D00h                        ;Open file read-only
  101.         INT     21h
  102.         JNC     FileFound                       ;OK, file was found
  103.  
  104. Error:  POP     DS                              ;Restore DS
  105.         ASSUME  DS:DSEG
  106. Error1: MOV     SP,BP                           ;Return with error code in AX
  107.         POP     BP                              ;Restore BP
  108.         RET     8                               ;Remove parameters from stack
  109.  
  110. ;Read file header
  111. FileFound:
  112.         MOV     BX,AX                           ;BX = file handle
  113.         LEA     DX,ExeHeader                    ;DS:DX => ExeHeader
  114.         MOV     CX,28                           ;Read 28 bytes
  115.         MOV     AH,3Fh                          ;DOS read file
  116.         INT     21h
  117.         JC      Error                           ;Error if carry set
  118.         CMP     AX,2                            ;At least 2 bytes read?
  119.         MOV     AX,30                           ;Prepare for Read Fault error
  120.         JB      Error                           ;Error if 2 bytes not read
  121.  
  122. ;Determine how much memory program needs
  123.         CMP     ExeHeader,5A4Dh                 ;Is it EXE format?
  124.         JE      ExeFileSize                     ;Yes, treat it as such
  125.  
  126. ;Get non-EXE file size
  127.         MOV     AX,4202h                        ;Seek to end of file
  128.         XOR     CX,CX
  129.         XOR     DX,DX
  130.         INT     21h
  131.         JC      Error                           ;Error if carry set
  132.         MOV     CX,4                            ;Divide bytes by 16
  133. NextShiftR:
  134.         SHR     DX,1                            ;Shift a LongInt right
  135.         RCR     AX,1
  136.         LOOP    NextShiftR
  137.         JMP SHORT CloseFile                     ;DX:AX has paragraphs needed
  138.  
  139. ;Get EXE image size
  140. ExeFileSize:
  141.         MOV     AX,EXEPages                     ;Get pages in EXE image
  142.         XOR     DX,DX
  143.         MOV     CX,5                            ;Multiply by 32
  144. NextShiftL:
  145.         SHL     AX,1                            ;Shift a LongInt left
  146.         RCL     DX,1
  147.         LOOP    NextShiftL                      ;DX:AX has paragraphs
  148.         ADD     AX,MinHeap                      ;Add minimum data/stack/heap
  149.         ADC     DX,0
  150.  
  151. ;Close file (DOS will reopen it)
  152. CloseFile:
  153.         MOV     CX,AX                           ;Save paragraphs in CX
  154.         MOV     AH,3Eh                          ;Close file
  155.         INT     21h
  156.         JC      Error                           ;Error if carry set
  157.  
  158. ;See if more than 640K bytes requested
  159.         MOV     AX,8                            ;Prepare for insufficient memory
  160.         OR      DX,DX                           ;DX must be zero
  161.         JNZ     Error                           ;Error if more than 640K
  162.  
  163. ;Determine available memory space
  164.         POP     DS                              ;Restore DS
  165.         ASSUME  DS:DSEG
  166.         MOV     ES,PrefixSeg                    ;Main program segment
  167.         MOV     AH,4Ah                          ;Setblock
  168.  
  169. IF DOS2X                                        ;Runs under DOS 2.X or 3
  170.         MOV     BX,CX
  171.         ADD     BX,1000h
  172.         INT     21h                             ;BX = Required space+64K bytes
  173.  
  174. ELSE                                            ;Runs only under DOS 3 or later
  175.         MOV     BX,0FFFFh                       ;Ask for everything
  176.         INT     21h                             ;BX has available paragraphs
  177. ;Assure sufficient memory available for overlay
  178.         MOV     AX,BX
  179.         SUB     AX,10h                          ;Leave space for PSP
  180.         CMP     AX,CX                           ;Sufficient space?
  181.         MOV     AX,8                            ;Prepare for insufficient memory
  182.         JB      Error1                          ;Error if less
  183. ENDIF
  184.  
  185. ;Allocate all available space
  186.         MOV     AH,4Ah                          ;Ask again for what we can get
  187.         INT     21h
  188.         JC      Error1                          ;Error if carry set now
  189.  
  190. ;Prepare to move stack to top of memory
  191.         MOV     AX,ES                           ;Base of program
  192.         ADD     AX,BX                           ;Add all available paragraphs
  193.         SUB     AX,1000h                        ;Room for full stack segment
  194.         MOV     CS:TmpSS,AX                     ;Store temporary SS for later
  195.  
  196. ;Close secondary file handles (don't touch StdIn,StdOut,StdErr,StdPrn)
  197.         CMP     CloseFilesBeforeChaining,0      ;Should we close files?
  198.         JZ      RestoreInts                     ;No, skip this
  199.         MOV     BX,FirstHandle                  ;Start with handle 5
  200.         MOV     CX,20-FirstHandle               ;20 handles total
  201. NextHandle:
  202.         MOV     AH,3Eh                          ;DOS close file
  203.         INT     21h
  204.         INC     BX                              ;Ignore errors
  205.         LOOP    NextHandle
  206.  
  207. ;Restore interrupt vectors taken over by SYSTEM library
  208. RestoreInts:
  209.         PUSH    ES
  210.         CALL    RestoreVectors
  211.         POP     ES
  212.  
  213. ;Set up command line for chained program
  214.         LDS     SI,CmdLine                      ;DS:SI points to command line
  215.         MOV     DI,80h                          ;ES:DI => command line in PSP
  216.         LODSB                                   ;Get length byte
  217.         CMP     AL,MaxCmdLen                    ;Is is too long?
  218.         JB      StoreCmdLine                    ;No, don't truncate
  219.         MOV     AL,MaxCmdLen                    ;Truncate
  220. StoreCmdLine:
  221.         STOSB                                   ;Store length byte
  222.         MOV     BX,DI                           ;Save start of command line
  223.         MOV     CL,AL
  224.         XOR     CH,CH
  225.         REP     MOVSB                           ;Copy parameter to command line
  226.         MOV     AL,0Dh                          ;Terminate with <Enter>
  227.         STOSB
  228.  
  229. ;Initialize FCB's for new program
  230.         PUSH    ES
  231.         POP     DS                              ;DS = ES
  232.         MOV     SI,BX                           ;DS:SI => command line to parse
  233.         MOV     DI,005Ch                        ;ES:DI => FCB1
  234.         MOV     AX,2901h                        ;Init FCB1
  235.         INT     21h
  236.         MOV     DI,006Ch                        ;ES:DI => FCB2
  237.         MOV     AX,2901h                        ;Init FCB2
  238.         INT     21h
  239.  
  240. ;Save initialization data for new program
  241.         MOV     BX,ES                           ;Store prefix seg in BX
  242.         MOV     CS:NewCS,BX                     ;Assume COM file
  243.         MOV     CS:NewSS,BX
  244.         ADD     BX,10h                          ;BX = base segment of image
  245.         CMP     ExeHeader,5A4Dh                 ;Is it EXE format?
  246.         JNE     MoveCode                        ;No, COM file already initialized
  247.         MOV     AX,CsInit                       ;Get initial CS from EXE header,
  248.         ADD     AX,BX                           ;   relocate segment,
  249.         MOV     CS:NewCS,AX                     ;   save it for later
  250.         MOV     AX,IpInit                       ;Initial IP
  251.         MOV     CS:NewIP,AX
  252.         MOV     AX,StackSeg                     ;Initial SS
  253.         ADD     AX,BX
  254.         MOV     CS:NewSS,AX
  255.         MOV     AX,StackPtr                     ;Initial SP
  256.         MOV     CS:NewSP,AX
  257.  
  258. ;Move code into PSP
  259. MoveCode:
  260.         MOV     CX,CodeLen                      ;Bytes to move
  261.         MOV     DI,100h                         ;DI => end of new code
  262.         SUB     DI,CX                           ;ES:DI => destination of new code
  263.         MOV     CS:TmpIP,DI                     ;Store address to jump to
  264.         MOV     CS:TmpCS,ES
  265.         PUSH    CS
  266.         POP     DS                              ;DS = CS
  267.         MOV     SI,offset CodeToRelocate        ;DS:SI => code to relocate
  268.         REP     MOVSB                           ;Copy the code to PSP
  269.  
  270. ;Prepare for EXEC call
  271.         MOV     AX,BX                           ;AX = Base segment
  272.         STOSW
  273.         STOSW                                   ;Initialize EXEC block
  274.         PUSH    SS
  275.         POP     DS                              ;DS = SS
  276.         LEA     DX,Path                         ;DS:DX => Path of file
  277.         MOV     BX,100h                         ;ES:BX => EXEC block
  278.         MOV     AX,4B03H                        ;Load Overlay
  279.         CLI
  280.         MOV     SS,CS:TmpSS                     ;Put stack at top
  281.         MOV     SP,0FFFEh                       ;  of memory
  282.         STI
  283.         DB      0EAh                            ;JMP FAR to code in PSP
  284. TmpIP   DW      0                               ;Patched in with offset
  285. TmpCS   DW      0                               ;Patched in with segment
  286. TmpSS   DW      0                               ;Temporary stack segment
  287.  
  288. ;-----------------------------------------------------------------------------
  289. ;Code relocated to and executed in PSP
  290. CodeToRelocate:
  291.         INT     21h                             ;Call DOS EXEC
  292.         JNC     GoodLoad                        ;Check for error
  293.         INT     20h                             ;Error is rare
  294.                                                 ; just halt if EXEC failed
  295. GoodLoad:
  296.         MOV     DX,CS                           ;Get base of program
  297.         MOV     DS,DX                           ;Initialize DS
  298.         MOV     ES,DX                           ;Initialize ES
  299.         MOV     AH,4Ah                          ;DOS SetBlock
  300.         MOV     BX,0FFFFh                       ;Ask for everything
  301.         INT     21h                             ;BX has available paragraphs
  302.         ADD     BX,DX                           ;Top of memory
  303.         MOV     DS:[0002h],BX                   ;Store in PSP that Turbo uses
  304.         CLI                                     ;Interrupts off
  305.         MOV     SS,DS:[0FEh]                    ;Initialize stack
  306.         MOV     SP,DS:[0FCh]
  307.         STI                                     ;Interrupts on again
  308.         DB      0EAh                            ;JMP FAR to start of code
  309. NewIP   DW      100h                            ;Patched in with start offset
  310. NewCS   DW      0                               ;Patched in with start segment
  311. NewSP   DW      0FFFEh                          ;Patched in with new SP
  312. NewSS   DW      0                               ;Patched in with new SS
  313.  
  314. Chain4  ENDP
  315.  
  316. Dummy   LABEL   BYTE                            ;Used to measure code to move
  317.  
  318. CSEG    ENDS
  319.  
  320.         END
  321.