159 lines
3.4 KiB
NASM
159 lines
3.4 KiB
NASM
title stdenvp - standard _setenvp routine
|
|
|
|
;--------------------------------------------------------------------------
|
|
;
|
|
; Microsoft C Compiler Runtime for MS-DOS
|
|
;
|
|
; (C)Copyright Microsoft Corporation, 1984, 1986
|
|
;
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
|
include version.inc
|
|
.xlist
|
|
include cmacros.inc
|
|
include msdos.inc
|
|
.list
|
|
|
|
|
|
sBegin data
|
|
assumes ds,data
|
|
externW _psp ; PSP segment #
|
|
externDP environ ; environment pointer
|
|
|
|
sEnd data
|
|
|
|
sBegin code
|
|
assumes ds,data
|
|
assumes cs,code
|
|
|
|
externNP _myalloc ; allocation routine for arguments
|
|
|
|
cProc _setenvp,<PUBLIC>,<>
|
|
|
|
cBegin
|
|
push bp
|
|
mov ds,[_psp] ; get psp segment
|
|
|
|
assumes ds,nothing
|
|
|
|
; setup envp vector and move environment to heap
|
|
|
|
; DS = PSP, SS = DGROUP
|
|
|
|
xor cx,cx ; cx = 0
|
|
mov ax,cx ; ax = 0 (search byte)
|
|
mov bp,cx ; bp = 0 (envp count)
|
|
mov di,cx ; di = 0 (initial offset)
|
|
dec cx ; cx = ffff (inifinite count)
|
|
|
|
mov si,word ptr DS:[DOS_ENVP]
|
|
or si,si ; test for null envp
|
|
|
|
jz noenv ; none
|
|
mov es,si ; es:di = environment table
|
|
scanenv:
|
|
repnz scasb
|
|
inc bp ; bp = envp count
|
|
scasb
|
|
jnz scanenv
|
|
|
|
noenv:
|
|
inc bp ; bp = envp count + 1
|
|
xchg ax,di ; ax = envlen
|
|
inc ax
|
|
and al,not 1 ; round up to even
|
|
mov di,bp ; di = argument count
|
|
shl bp,1 ; argument count*2
|
|
if sizeD
|
|
shl bp,1 ; argument count*2
|
|
endif
|
|
add ax,bp ; ax = space to allocate
|
|
push ss
|
|
pop ds ; restore DS
|
|
|
|
assumes ds,data
|
|
|
|
; Make sure there is enough memory for the environment.
|
|
; If there is not enough, try to get some from the OS if possible.
|
|
; Register usage at this point:
|
|
; ax = total # bytes needed for environment ptr table and strings
|
|
; di = # of entries in env ptr table = # of env args + 1
|
|
; bp = # bytes required to store env ptr table
|
|
; ss = ds = DGROUP
|
|
; es = PSP segment
|
|
|
|
push di ; save # of env args + 1
|
|
mov di,9 ; error message in case of death.
|
|
call _myalloc ; takes bp = # bytes for ptr table ax = total #
|
|
; bytes
|
|
pop di ; recover # of env args + 1
|
|
|
|
|
|
; Now there is enough memory for the environment, so copy it in.
|
|
; Register usage at this point:
|
|
; dx = size of environment in bytes
|
|
; di = # of entries in env ptr table = # of env args + 1
|
|
; bp points to env table
|
|
; ax is size of env table in bytes.
|
|
; ss = ds = DGROUP
|
|
; es = PSP segment
|
|
|
|
|
|
mov cx,di ; cx = envcnt
|
|
mov di,bp
|
|
add di,ax ; di points past env ptr table
|
|
; store strings there
|
|
mov word ptr [environ],bp ; save envp[]
|
|
if sizeD
|
|
mov word ptr [environ+2],ds ; segment address for large model
|
|
endif
|
|
|
|
push ds
|
|
pop es ; es:di = env dest
|
|
mov ds,si ; ds:0 = env table
|
|
xor si,si
|
|
|
|
; SS = ES = DGROUP
|
|
; DS = PSP segment
|
|
|
|
assumes es,data
|
|
assumes ds,nothing
|
|
|
|
dec cx ; adjust for the last entry of 0000
|
|
jcxz envdone ; done - no environment
|
|
|
|
envloop:
|
|
cmp word ptr [si],';'+'C'*100h ; test if starts with ';C'
|
|
je envstr ; don't save pointer if ';C'
|
|
|
|
mov [bp],di ; save pointer to start of string
|
|
if sizeD
|
|
mov [bp+2],es ; segment address for large model
|
|
add bp,4
|
|
else
|
|
inc bp
|
|
inc bp
|
|
endif
|
|
|
|
envstr:
|
|
lodsb
|
|
stosb
|
|
or al,al
|
|
jnz envstr ; keep copying string
|
|
loop envloop ; more strings to copy
|
|
|
|
envdone:
|
|
mov [bp],cx ; zero terminate envp table
|
|
if sizeD
|
|
mov [bp+2],cx ; extra zero for large model
|
|
endif
|
|
push ss ; DS = DGROUP
|
|
pop ds
|
|
pop bp
|
|
cEnd
|
|
|
|
sEnd code
|
|
|
|
end
|