home *** CD-ROM | disk | FTP | other *** search
- ;[]-----------------------------------------------------------------[]
- ;| EXEC.ASM -- Execute a program with Overlay |
- ;| |
- ;| Turbo-C Run Time Library Version 3.0 |
- ;| |
- ;| Copyright (c) 1987,1988,1990 by Borland International Inc. |
- ;| All Rights Reserved. |
- ;[]-----------------------------------------------------------------[]
-
- INCLUDE RULES.ASI
-
- ; Segments Definitions
-
- Header@
-
- ; External References
-
- extrn __IOERROR:near
- extrn __envseg:word
-
- ExtSym@ _psp, WORD, __CDECL__
- ExtSym@ _version, WORD, __CDECL__
-
- ;* Miscellaneous equates */
-
- ExeSignature equ 05A4Dh
-
- ;/* Data for the Loader */
-
- LdDesc STRUC
- LdErrorMsg db 'Exec failure.',00Dh,00Ah
- LdStack db 80H dup(?) ;Loader stack
- LdPSP dw ? ;PSP address
- LdPathName db 80 dup(?) ;File to be loaded
- LdAX dw ? ;Parse file name results
- LdExeSignature dw ? ;EXE header buffer
- LdLength dw ?
- LdNbPages dw ?
- LdNbItems dw ?
- LdHdrSize dw ?
- LdMin dw ?
- LdMax dw ?
- LdSS dw ?
- LdSP dw ?
- LdCheckSum dw ?
- LdIP dw ?
- LdCS dw ?
- LdLoadAddr dw ? ;Load Overlay interface block
- LdRelocFactor dw ? ;Relocation factor to be used
- LdDesc ENDS
-
- SUBTTL Loader program
- PAGE
- ;/* */
- ;/*------------------------------------------------------*/
- ;/* */
- ;/* Loader Program */
- ;/* -------------- */
- ;/* */
- ;/*------------------------------------------------------*/
- ;/* */
- CSeg@
- LoaderDatas db size LdDesc dup (0)
- _Loader PROC NEAR ;CX = EnvSeg, DX = End of Memory
-
- ;/* Setup segment registers */
-
- xor di, di
- mov ax, cs
- mov ds, ax
- mov es, ax
- cli
- mov ss, ax
- lea sp, [di+LdPSP]
- sti
-
- ;/* Load The Program */
-
- push cx
- push dx
- mov ax, 4B03h
- lea bx, [di+LdLoadAddr]
- lea dx, [di+LdPathName]
- int 21h
- pop dx
- pop cx
- jb LoadError
- xor di, di
- cli
- mov ss, [di+LdSS]
- mov sp, [di+LdSP]
- sti
- mov bp, sp
- xor ax, ax
- push ax ;Return to MSDOS for .COM
- mov ax, [di+LdPSP]
- mov ds, ax
- mov es, ax
- mov es:[2h], dx ;Set End of Program into PSP
- mov es:[2ch], cx ;Set EnvSeg into PSP
- mov ax, cs:[di+LdAX] ;AX = validity of FCBs
- jmp dword ptr cs:[LdIP]
-
- ;/* Fatal Error if unable to load the program */
-
- LoadError label near
- mov ah, 040h
- mov bx, 2
- mov cx, LdStack - LdErrorMsg
- xor dx, dx
- int 21h ;Error message on stderr
- mov ax, 4C02h
- int 21h ;exit(2)
- _Loader ENDP
- LoaderSize equ ($ - LoaderDatas + 15) / 16
- wLoaderSize equ LoaderSize * 8
- LoaderVector dd _Loader - LoaderDatas
- SUBTTL Loader program
- PAGE
- ;/* */
- ;/*------------------------------------------------------*/
- ;/* */
- ;/* int _exec(pathP, cmdP, envP); */
- ;/* char *pathP; */
- ;/* char *cmdP; */
- ;/* char *envP; */
- ;/* */
- ;/*------------------------------------------------------*/
- ;/* */
-
- pathP equ 4
-
- IF LDATA
- cmdP equ pathP + 4
- envP equ cmdP + 4
- ELSE
- cmdP equ pathP + 2
- envP equ cmdP + 2
- ENDIF
-
- FileHandle equ 2
- MemSize equ FileHandle + 2
- EnvSize equ MemSize + 2
- EnvAddr equ EnvSize + 4
- OldEnv equ EnvAddr + 2
-
- OldEnvSave dw ?
- UseOldEnv db 1 ;flag, defaults to true
-
- public __exec
- __exec proc near
- push bp
- mov bp, sp
- sub sp, OldEnv
- cld
- push si
- push ds
- push di
- push es
-
- IFDEF __HUGE__
- ExtSym@ DGROUP@, WORD, __PASCAL__
- mov ds, cs:DGROUP@@ ; Get DS if we're huge
- ENDIF
- mov ax,__envseg ;save old environment
- mov cs:OldEnvSave,ax
-
- ;/* Open the file to be loaded */
-
- mov ax, 3d00h
- pushDS_
- LDS_ dx, [bp+pathP]
- int 21h
- popDS_
- mov [bp-FileHandle], ax
- jnb CopyCmdLine
- jmp ExecExit
-
- ;/* Copy the command line into the PSP */
-
- CopyCmdLine label near
- IFDEF __HUGE__
- mov ax, seg _psp@
- mov ds, ax
- ENDIF
- mov es, _psp@
- mov LoaderDatas.LdPSP, es
- mov ax, es:[2ch]
- mov [bp-OldEnv], ax
- mov di, 080h
- pushDS_
- LDS_ si, [bp+cmdP]
- lodsb
- mov dx, si ;Save cmdP for parse
- stosb
- xor cx, cx
- mov cl, al
- inc cx
- rep movsb
-
- ;/* Parse the command line for FCBs */
-
- mov ax, 2901h
- mov si, dx
- mov di, 05ch
- int 21h ;Build FCB 1 in PSP
- mov byte ptr LoaderDatas.LdAX, al
- mov ax, 2901h
- mov di, 06ch
- int 21h ;Build FCB 2 in PSP
- mov byte ptr LoaderDatas.LdAX+1, al
- popDS_
-
- ;/* Get the maximum memory block size */
-
- mov ah, 4Ah
- mov bx, -1
- int 21h
- cmp byte ptr _version@, 3
- jnb GetMaxMem
- sub bx, 280h
-
- GetMaxMem label near
- mov [bp-MemSize], bx
-
- ;/* Compute environment size */
-
- IF LDATA
- mov ax, [bp+envP]
- mov dx, [bp+envP+2]
- ELSE
- mov ax, [bp+envP]
- or ax, ax
- mov dx, ds
- jnz DoWeHaveAnEnv
- cwd
- ENDIF
-
- DoWeHaveAnEnv label near
- mov bx, ax
- or bx, dx
- jnz WeHaveAnEnv
- xor ax, ax
- mov di, ax
- jmp short SetEnvSize
-
- WeHaveAnEnv label near
- mov es, dx
- mov di, ax
- push di
- mov cx, -1
- xor ax, ax
-
- GetEnvSize label near
- repnz scasb
- cmp es:[di], al
- jne GetEnvSize
- dec cx
- add di, 3
- repnz scasb ;/* EnvSize += PathSize */
- dec cx
- mov ax, cx
- neg ax
- pop di
-
- SetEnvSize label near
- mov [bp-EnvAddr], di
- mov [bp-EnvAddr+2], es
- add ax, 15
- mov cx, 4
- shr ax, cl
- mov [bp-EnvSize], ax
-
- mov si,__envseg ;get the arena header for the environ
- dec si
- mov es,si
- cmp ax,word ptr es:[03] ;can we use the orig environ?
- jbe SavePath
-
- dec cs:UseOldEnv ;set to false
- inc ax
- sub [bp-MemSize], ax ;Reserve space for Env
-
- ;/* Save the pathname of the file to be loaded */
- SavePath label near
- LDS_ si, [bp+pathP]
- push cs
- pop es
- lea di, LoaderDatas.LdPathName
-
- CopyPathName label near
- lodsb
- stosb
- or al, al
- jnz CopyPathName
-
- ;/* Process the file according to its type */
-
- mov bx, [bp-FileHandle]
- mov ax, [si-5]
- or ah, ' '
- push cs
- pop ds
- mov di, offset LoaderDatas
- cmp ax, 'c.'
- jne EXEFile
- jmp COMFile
-
- ;/* Here comes all Exec Error */
-
- ExecError label near
- push ax
- mov ah, 3eh
- mov bx, [bp-FileHandle]
- int 21h
- pop ax
- jmp ExecExit
-
- ;/* This file must be an .EXE file */
-
- EXEFile label near
- mov ah, 3fh
- mov cx, LdLoadAddr - LdExeSignature
- lea dx, [di+LdExeSignature]
- int 21h
- jb ExecError
- cmp [di+LdExeSignature], ExeSignature
- mov ax, 11
- jne ExecError
- mov ax, [di+LdNbPages]
- xor dx, dx
- mov dl, ah
- mov ah, al
- xor al, al
- shl ax, 1
- rcl dx, 1 ;DX:AX = NbPages * 512
- add ax, [di+LdLength]
- adc dx, 0
- mov cx, 4
-
- EXECompute label near
- shr dx, 1
- rcr ax, 1
- loop EXECompute
- inc ax
- sub ax, [di+LdHdrSize]
- add ax, [di+LdMin]
- xchg bx, ax
- mov ax, [di+LdPSP]
- add ax, 16
- add [di+LdCS], ax
- add [di+LdSS], ax
- xchg ax, bx
- jmp short IsItEnough
-
- ;/* The file to be loaded is .COM file */
-
- COMFile label near
- mov ax, 4202h
- xor cx, cx
- xor dx, dx
- int 21h
- mov cx, 4
-
- COMCompute label near
- shr dx, 1
- rcr ax, 1
- loop COMCompute
- inc ax
- xchg bx, ax
- mov ax, [di+LdPSP]
- mov [di+LdCS], ax
- mov [di+LdIP], 0100h
- mov [di+LdSS], ax
- add ax, 16
- xchg ax, bx
-
- IsItEnough label near ;AX = Pgm requirements, BX = Pgm Load Addr
- mov [di+LdLoadAddr], bx
- mov [di+LdRelocFactor], bx
- add ax, LoaderSize
- cmp ax, [bp-MemSize]
- mov ax, 8
- jna $+5
- jmp ExecError
-
- ;/* Close the file before load it */
-
- mov ah, 3eh
- mov bx, [bp-FileHandle]
- int 21h
-
- ;/* Takes all the memory above the current program */
-
- mov es, [di+LdPSP]
- mov ah, 4ah
- mov bx, [bp-MemSize]
- int 21h
- jnb $+5
- jmp ExecError
-
- ;/* Move the Loader before loading the overlay */
-
- add bx, [di+LdPSP]
- mov dx, bx ;Save end of memory
- sub bx, LoaderSize+1
- mov word ptr LoaderVector+2, bx
- mov es, bx
- mov cx, wLoaderSize
- mov si, offset LoaderDatas
- xor di, di
- rep movsw
-
- ;/* Copy the environment */
-
- mov es, [bp-OldEnv]
- mov cx, [bp-EnvSize]
- cmp cs:UseOldEnv,0
- jne ReUseEnv
-
- mov ah, 48h
- mov bx, cx
- int 21h
- jb ExecExit
- jmp short CopyEnv
-
- ReUseEnv: mov ax, cs:OldEnvSave
- CopyEnv: mov es, ax
- xor di, di
- lds si, [bp-EnvAddr]
- add cx, cx
- add cx, cx
- add cx, cx
- rep movsw
- push es
-
- ;/* Free the old environment space */
-
- cmp cs:UseOldEnv,0
- jne ReadyToOverlay
- mov es, cs:OldEnvSave
- mov ah, 49h
- int 21h
-
- ;/* Jump to Loader and overlay the current program */
-
- ReadyToOverlay label near
- pop cx
- jmp LoaderVector
-
- ;/* All error conditions set _doserrno and errno */
-
- ExecExit label near
- pop es
- pop di
- pop ds
- pop si
- push ax
- call __IOERROR
- mov sp, bp
- pop bp
- ret
- endp
-
- CSegEnd@
- END