home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Fortran.51 / DISK5 / DOS / STDENVP.AS$ / STDENVP.bin
Text File  |  1989-08-31  |  8KB  |  335 lines

  1.     page    ,132
  2.     title    stdenvp - standard _setenvp routine
  3. ;***
  4. ;stdenvp.asm - standard _setenvp routine
  5. ;
  6. ;    Copyright (c) 1985-1990, Microsoft Corporation.  All rights reserved.
  7. ;
  8. ;Purpose:
  9. ;    This module is called by the C start-up routine to set up "environ".
  10. ;    It copies the environment strings and a null-terminated table of
  11. ;    pointers to those strings into the heap.
  12. ;    The global symbol "_environ" is set to point to this array.
  13. ;
  14. ;*******************************************************************************
  15.  
  16.  
  17. include version.inc
  18. .xlist
  19. include cmacros.inc
  20. include msdos.inc
  21. include rterr.inc
  22. .list
  23.  
  24. ifdef FARSTACK
  25. ife sizeD
  26.     error <You cannot have a far stack in Small or Medium memory models.>
  27. endif
  28. endif
  29.  
  30. externNP _myalloc        ; allocation routine for arguments
  31.  
  32. sBegin    data
  33. assumes ds,data
  34.  
  35. externDP environ        ; environment pointer
  36. externW _psp            ; PSP segment #
  37. externB _acfinfo        ; _C_FILE_INFO string
  38.  
  39. sEnd    data
  40.  
  41. sBegin    code
  42. assumes ds,data
  43. assumes cs,code
  44. ifndef FARSTACK
  45. assumes ss,data
  46. endif
  47.  
  48. page
  49. ;***
  50. ;_stdenvp - set up "envp" for C programs
  51. ;
  52. ;Purpose:
  53. ;    Reads the environment and build the envp array for C programs.
  54. ;
  55. ;Entry:
  56. ;    The environment strings occur at the beginning of the segment.
  57. ;    The list of environment strings is terminated by an extra null
  58. ;    byte.  Thus two null bytes in a row indicate the end of the
  59. ;    last environment string and the end of the environment, resp.
  60. ;
  61. ;Exit:
  62. ;    "environ" points to a null-terminated list of pointers to ASCIZ
  63. ;    strings, each of which is of the form "VAR=VALUE".  The strings
  64. ;    are copied from the environment segment into space allocated on
  65. ;    the heap.  The list of pointers is also located on there.
  66. ;
  67. ;Uses:
  68. ;    Locks the environment segment before use, and unlocks afterward
  69. ;    Allocates space on the heapfor the environment strings
  70. ;    and a list of pointers to them.
  71. ;
  72. ;    All registers except DS, SS, and BP are modified
  73. ;    Note especially that SI and DI are NOT preserved!
  74. ;
  75. ;Exceptions:
  76. ;
  77. ;*******************************************************************************
  78.  
  79. cProc    _setenvp,<PUBLIC>,<ds>
  80.  
  81. if sizeD
  82.     localW    envseg        ; segment OS environment segment
  83.     localW    envtab        ; segment environment pointer table
  84. ifdef FARSTACK
  85.     localW    datagroup    ; segment of the DGROUP
  86. endif ;FARSTACK
  87. endif ;sizeD
  88.  
  89. cBegin
  90.  
  91.     mov    es,[_psp]    ; es = PSP seg
  92.     assumes es,nothing
  93.     mov    bx,word ptr es:[DOS_ENVP]
  94.     mov    es,bx        ; es = OS environment segment
  95. if sizeD
  96.     mov    [envseg],es    ; save OS seg on stack for later
  97. endif
  98. ifdef FARSTACK
  99.     mov    [datagroup],ds    ; save DGROUP for later
  100. endif
  101.  
  102. ;
  103. ; --- Scan the list of environment strings calculating the following
  104. ; values:
  105. ;    (1) si will count the number of environment strings
  106. ;    (2) di will count the number of bytes the strings occupy
  107. ; Stop on a null string
  108. ;
  109. ; bx = es = OS environment segment
  110. ; ds = DGROUP
  111. ;
  112.  
  113.     xor    ax,ax        ; ax = 0 (search byte)
  114.     xor    si,si        ; si = 0 (env pointer count)
  115.     xor    di,di        ; di = 0 (initial offset)
  116.     mov    cx,-1        ; cx = ffff (infinite count)
  117.  
  118.     or    bx,bx        ; OS env seg == NULL ??
  119.     jz    noenv        ; yes, no environment
  120.     cmp    byte ptr es:[0],0 ; OS env seg start with null byte ??
  121.     je    noenv        ; yes, no environment
  122.  
  123. scanenv:
  124.     repnz    scasb
  125.     inc    si        ; si = envp count
  126.     scasb
  127.     jnz    scanenv
  128.  
  129. noenv:
  130.     mov    ax,di        ; ax = length of env strings
  131.     inc    ax
  132.     and    al,not 1    ; round up to even
  133.  
  134.     inc    si        ; si = env pointer count + 1 (for null)
  135.     mov    di,si        ; di = env pointer count (save)
  136.     shl    si,1        ; si = env pointer count * 2
  137. if    sizeD
  138.     shl    si,1        ; si = env pointer count * 4
  139. endif
  140.  
  141. ;
  142. ; --- Allocate space for environment strings
  143. ; ax = # bytes for env strings
  144. ; si = # bytes for env pointers
  145. ; di = # of pointers
  146. ; es = OS environment segment
  147. ; ds = ss = DGROUP  (ss = stack for FARSTACK)
  148. ;
  149.     ; allocate space for strings
  150.                 ; ax = size needed for strings
  151.     mov    cx,_RT_SPACEENV ; error message in case of death.
  152.     call    _myalloc    ; takes ax = total # of bytes needed
  153. if    sizeD
  154.     push    dx        ; push segment to string area
  155. endif
  156.     push    ax        ; push offset to string area
  157.  
  158.     ; allocate space for the pointer table
  159.  
  160.     mov    ax,si        ; ax = space for pointers
  161.     call    _myalloc    ; takes ax = total # of bytes needed
  162.     mov    word ptr [environ],ax    ; init environ
  163. if    sizeD
  164.     mov    word ptr [environ+2],dx ; segment address for large model
  165.     mov    word ptr [envtab],dx    ; save segment here too
  166. endif
  167.  
  168. ;
  169. ; --- Successfully allocated space for env table and strings
  170. ; Init registers for env copy loop
  171. ;
  172. ; ax = offset to env table area
  173. ; di = # of pointers
  174. ; es = OS environment segment
  175. ; ds = DGROUP
  176. ; tos = offset to string area
  177. if sizeD
  178. ; tos-2 = segment to string area
  179. endif
  180. ;
  181.  
  182. env_ok:
  183.  
  184. if sizeD
  185.     push    es
  186.     pop    ds        ; ds = OS env segment
  187.     assumes es,nothing
  188.     assumes ds,nothing
  189. else
  190.     push    es
  191.     push    ds
  192.     pop    es        ; es = DGROUP
  193.     pop    ds        ; ds = OS env segment
  194.     assumes es,data
  195.     assumes ds,nothing
  196. endif
  197.  
  198.     mov    cx,di        ; cx = envcnt
  199.     mov    bx,ax        ; bx = offset env pointers area
  200.     xor    si,si        ; si = OS env string area
  201.     pop    di        ; di = offset env string area
  202. if sizeD
  203.     pop    es        ; es:di = pointer env string area
  204. endif
  205.  
  206.  
  207. ;
  208. ; --- Check for no environment
  209. ;
  210.  
  211.     dec    cx        ; adjust for the last entry of 0000
  212.     jcxz    envdone     ;   done - no environment
  213.  
  214. ;
  215. ; --- Loop through the environment
  216. ; (1) Setup the environment table of pointers (environ)
  217. ; (2) Copy the environment strings into our address space
  218. ; (3) Do NOT copy the _C_FILE_INFO string
  219. ;
  220. if sizeD
  221. ; cx = # of env strings left to copy
  222. ; bx = offset of env pointer table
  223. ; ds:si = pointer to OS environment area
  224. ; es:di = pointer to next envstrg destination
  225. else
  226. ; cx = # of env strings left to copy
  227. ; ds:si = offset  to OS environment area
  228. ; es:bx = offset of env pointer table
  229. ; es:di = pointer to next envstrg destination
  230. ; es = DGROUP
  231. endif
  232.  
  233. envloop:
  234.  
  235.     ; --- Check for _C_FILE_INFO
  236.  
  237.     mov    ax,ds:[si]    ; get first two bytes of string
  238. ifdef FARSTACK
  239.     push    ds
  240.     mov    ds,[datagroup]
  241.     assumes ds,data
  242.     cmp    ax,word ptr [_acfinfo]    ; compare to "_C"
  243.     pop    ds
  244.     assumes ds,nothing
  245. else
  246.     cmp    ax,word ptr ss:[_acfinfo]    ; is it "_C" ?
  247. endif ;FARSTACK
  248.     jne    not_cfi     ; nope, continue
  249.  
  250.     push    cx        ; save context
  251.     push    si
  252.     push    di
  253. if sizeD
  254.     push    es
  255. ifdef FARSTACK
  256.     mov    es,[datagroup]    ; es = DGROUP
  257. else
  258.     push    ss
  259.     pop    es        ; es = DGROUP
  260. endif ;FARSTACK
  261. endif
  262.  
  263.     mov    di,dataOFFSET _acfinfo    ; es:di = pointer to _C_FILE_INFO
  264.     mov    cx,6        ; length of string in words
  265.     repe    cmpsw        ; compare the strings
  266.  
  267. if sizeD
  268.     pop    es        ; restore context
  269. endif
  270.     pop    di
  271.     pop    si
  272.     pop    cx
  273.                 ; is it _C_FILE_INFO ??
  274.     je    envcopy     ; yes, don't store this one
  275.     ;fall thru        ; nope, store it
  276.  
  277.     ; --- store env string pointer in table
  278.  
  279. not_cfi:
  280.  
  281. if sizeD
  282.     mov    ds,[envtab]    ; ds:bx = next table entry
  283. endif
  284.                 ; es:di = next env string area
  285. if sizeD
  286.     mov    ds:[bx],di    ; save env string pointer in table
  287.     mov    ds:[bx+2],es
  288.     add    bx,4        ; bump table pointer
  289. else
  290.     mov    es:[bx],di    ; save env string pointer in table
  291.     inc    bx        ; bump table pointer
  292.     inc    bx
  293. endif
  294.  
  295.     ; --- copy string from OS segment into our memory
  296.  
  297. envcopy:
  298.  
  299. if sizeD
  300.     mov    ds,[envseg]    ; ds:si = string in OS seg
  301. endif
  302.  
  303. envcpy:
  304.     lodsb            ; get a char from OS segment
  305.     stosb            ; copy into library space
  306.     or    al,al        ; end of string ??
  307.     jnz    envcpy        ; nope, continue copying string
  308.  
  309.     loop    envloop     ; do the next environment variable
  310.  
  311. ;
  312. ; --- Done copying strings
  313. ; put a null at the end of the envtab table
  314. ;
  315.  
  316. envdone:
  317.  
  318. if sizeD
  319.     mov    ds,[envtab]        ; ds:bx = env table pointer
  320.     mov    ds:[bx],cx        ; store a null
  321.     mov    ds:[bx+2],cx
  322. else
  323.     mov    es:[bx],cx        ; store a null
  324. endif
  325.  
  326. if sizeD
  327. cEnd
  328. else
  329. cEnd    <nolocals>
  330. endif
  331.  
  332. sEnd    code
  333.  
  334.     end
  335.