home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK7 / SOURCE / STARTUP / WIN / CRT0.AS$ / CRT0
Encoding:
Text File  |  1991-11-06  |  12.5 KB  |  681 lines

  1.     page    ,132
  2.     title    crt0.asm - Windows C lib startup
  3. ;***
  4. ;crt0.asm - Windows C lib startup
  5. ;
  6. ;    Copyright (c) 1988-1992, Microsoft Corporation.  All rights reserved.
  7. ;
  8. ;Purpose:
  9. ;
  10. ;    Startup code for Windows C runtime libraries.
  11. ;
  12. ;*******************************************************************************
  13.  
  14. ;*******************************;*
  15.     DOSSEG            ;* specifies DOS SEGment ordering *
  16. ;*******************************;*
  17.  
  18. ;*******************************;*
  19. IFDEF _SEARCH_RECORD
  20.     INCLUDELIB LIBW     ;* Library Search Record for windows
  21. ENDIF
  22. ;*******************************;*
  23.  
  24. ?DF=    1            ; this is special for c startup
  25.  
  26. _STARTUPBLD = 1         ; special flag for includes
  27.  
  28. .xlist
  29. include version.inc
  30. ?PLM = 1
  31. include cmacros.inc
  32. include msdos.inc
  33. include defsegs.inc
  34. include rterr.inc
  35. include stdlib.inc
  36. .list
  37.  
  38. ;
  39. ; See what win target we're building for
  40. ;
  41.  
  42. ifdef _WINDLL
  43.     ifdef   _NOCRT
  44.     IF1
  45.     %out ! Building DLL / NOCRT lib (?NOCRTDW.LIB)
  46.     ENDIF
  47.     ;
  48.     ; In the DLL/NOCRT model, we don't need ANY startup code!
  49.     ; Define a new symbol to help us do this easily.
  50.     ;
  51.     _WINDLL_NOCRT equ 1
  52.     else
  53.     IF1
  54.     %out ! Building DLL window libs (?DLLCW.LIB)
  55.     ENDIF
  56.     endif
  57.     ifdef _QWIN
  58.     %err
  59.     %out ! ERROR - _QWIN not valid for _WINDLL models!
  60.     endif
  61. else
  62.     ifdef   _NOCRT
  63.     IF1
  64.     %out ! Building STATIC / NOCRT lib (?NOCRTW.LIB)
  65.     ENDIF
  66.     else
  67.     IF1
  68.     %out ! Building STATIC window libs (?LIBCW.LIB)
  69.     ENDIF
  70.     endif
  71. endif
  72.  
  73. ;
  74. ; See if we want the debug screen swapping symbols resolved
  75. ;
  76.     _DEBUGSCREEN equ 1        ; debug screen swapping
  77.  
  78. ;
  79. ; Exit() redirection for fatal termination
  80. ; (Currently, this is called by FP but could be used by other
  81. ; components as well.)
  82. ;
  83.  
  84. ifdef _WINDLL
  85.     ; No exit() routine in DLLs so abort!
  86.     alias    <__error_exit>     = <_abort>
  87. else
  88.     alias    <__error_exit>     = <_exit>
  89. endif
  90.  
  91. ;
  92. ; Define code segment
  93. ;
  94.  
  95. CrtDefSegs <code>
  96.  
  97. ;
  98. ; Define data segment order for data.
  99. ;
  100.  
  101. CrtDefSegs <null,data,cdata,const,bss>
  102.  
  103.  
  104. assumes DS,DATA
  105.  
  106. ;
  107. ; NULL Segment definition
  108. ;
  109.  
  110. externW <pLocalHeap,pAtomTable>
  111.  
  112. sBegin      NULL
  113.             DD  0
  114. labelW      <PUBLIC,rsrvptrs>
  115. maxRsrvPtrs = 5
  116.          DW  maxRsrvPtrs
  117.          DW  maxRsrvPtrs DUP (0)
  118. sEnd        NULL
  119.  
  120. ;
  121. ; Resolve definitions to pull in CRT
  122. ;
  123.  
  124. public    __acrtused        ; trick to force in startup
  125.     __acrtused = 9876h    ; funny value not easily matched in SYMDEB
  126.  
  127.  
  128. public    __fptaskdata        ; stub out __fptaskdata so that
  129.     __fptaskdata = 9876h    ; non-Windows emulator is not brought in
  130.  
  131. ifdef _DEBUGSCREEN
  132. public    __aDBused        ; debug value used by QC
  133.     __aDBused = 0d6d6h
  134.  
  135. public    __aDBdoswp
  136.     __aDBdoswp = 0d6d6h
  137. endif
  138.  
  139. ifndef _NOCRT
  140.     extrn    __acrtmsg:abs    ; trick to pull in startup messages (CRT0MSG.ASM)
  141. endif
  142.  
  143. ;
  144. ; Absolutes used at runtime to determine what model the program is
  145. ;
  146.  
  147. public    __sizec
  148.     __sizec = sizeC
  149.  
  150. public    __sized
  151.     __sized = sizeD
  152.  
  153.  
  154. ;
  155. ; Data declarations
  156. ;
  157.  
  158. sBegin      DATA
  159.  
  160. ifndef _NOCRT
  161.  
  162.     externB __cpumode        ; real/protected flag
  163.     externW __osversion        ; OS version number (WIN)
  164.     externW __dosversion        ; OS version number (DOS)
  165.     externW  ___argc        ; arg count
  166.     externDP ___argv        ; arg array
  167.     externDP __environ        ; environment array
  168.  
  169.     ifndef  _WINDLL
  170.     externW  __psp            ; psp:0 (paragraph #)
  171.     endif
  172.  
  173.     ifdef _QWIN
  174.        externW     __qwinused        ; QWIN in-use flag
  175.     endif
  176.  
  177. endif ;!_NOCRT
  178.  
  179. ifdef    _WINDLL
  180.  
  181.     globalW  _STKHQQ,STACKSLOP    ; Set DLL stack to max size
  182.  
  183.     globalW  __hModule,0        ; parameters for LIBMAIN
  184.     globalW  __wDataSeg,0
  185.     globalW  __wHeapSize,0
  186.     globalD  __lpszCmdLine,0
  187.  
  188. ifndef _NOCRT
  189.     globalB __dllinit,0        ; 0 = DLL not initialized
  190. endif
  191.  
  192. else    ;!_WINDLL
  193.  
  194.     globalW _STKHQQ,0        ; stack limit
  195.  
  196.     globalW __hPrevInstance,0    ; parameters for WINMAIN
  197.     globalW __hInstance,0
  198.     globalD __lpszCmdLine,0
  199.     globalW __cmdShow,0
  200.  
  201. endif    ;_WINDLL
  202.  
  203. ; Heap segment limits for compiler range checking
  204.  
  205.     globalW _aseglo,1        ; lowest segment
  206.     globalW _aseghi,0FFFFh        ; highest segment
  207.  
  208. ifdef _DEBUGSCREEN
  209.     globalW ___aDBswpflg,0        ; debugger screen swap
  210.     globalW ___aDBrterr,0
  211. endif
  212.  
  213. sEnd        DATA
  214.  
  215. ;
  216. ; Externs
  217. ;
  218.  
  219.     extrn       __WINFLAGS:abs    ; Windows status flags
  220.  
  221. ifdef    _WINDLL
  222.  
  223.     externFP   <LOCALINIT>        ; Windows heap init routine
  224.  
  225.     ifdef   _NOCRT
  226.     externFP   <LIBMAIN>        ; User's main code
  227.     else
  228.     externFP   <LOCKSEGMENT>    ; Lock down a segment
  229.     externFP   <WEP>        ; DLL termination routine
  230.     endif
  231.  
  232. else    ;!_WINDLL
  233.  
  234.     externFP   <LOCKSEGMENT>    ; Lock down a segment
  235.     externFP   <INITTASK>        ; Init new task
  236.  
  237.  
  238.     ifdef   _NOCRT
  239.     externP    <WINMAIN>        ; User's main code
  240.     else
  241.     externNP   <__amsg_exit>    ; Fatal error
  242.     ifdef _QWIN
  243.         externNP   <__wcinit>    ; Init the QWIN layer
  244.     endif
  245.     endif
  246.  
  247.     externFP   <WAITEVENT>
  248.     externFP   <INITAPP>
  249.  
  250. endif    ;_WINDDLL
  251.  
  252. ifndef    _NOCRT
  253.  
  254.     externFP   <GETVERSION>     ; Get windows version
  255.  
  256. if sizeC
  257.     extern       __stubmain:far    ; Alternate main()
  258.     extern       _main(__stubmain):far; Weak extern to main()
  259. else
  260.     extern       __stubmain:near    ; Alternate main()
  261.     extern       _main(__stubmain):near;Weak extern to main()
  262. endif
  263.  
  264.     externP    <__cinit>        ; C lib initialization
  265.     externP    <__setenvp>        ; set up envp[] array
  266.  
  267.     ifndef  _WINDLL
  268.     externP    <__setargv>        ; set up argv[] array
  269.     externP    <__exit>        ; Quick exit
  270.     externP    <_exit>        ; Normal exit
  271.     endif   ;!_WINDLL
  272.  
  273. endif    ;_NOCRT
  274.  
  275.  
  276. sBegin  CODE
  277. assumes CS,CODE
  278.  
  279. ;
  280. ; Save __WINFLAGS in code segment so we don't need DS to access it.
  281. ;
  282.     globalW   __wflags,__WINFLAGS
  283.  
  284.  
  285. ifndef    _WINDLL
  286. ifdef  _NOCRT
  287.  
  288. page
  289. ;***
  290. ; _exit, __exit - Resolve these in the _NOCRT object
  291. ;
  292. ;Purpose:
  293. ;
  294. ;Entry:
  295. ;
  296. ;Exit:
  297. ;
  298. ;Uses:
  299. ;
  300. ;Exceptions:
  301. ;
  302. ;*******************************************************************************
  303.  
  304. cProc    __exit,<PUBLIC,C>
  305. cBegin    <nogen>
  306.     ;fall through
  307. cEnd    <nogen>
  308.  
  309. cProc    _exit, <PUBLIC,C>
  310. cBegin    <nogen>
  311.     pop    ax        ; eat the return offset
  312. if sizeC
  313.     pop    ax        ; if large code, eat the segment too
  314. endif
  315.     pop    ax        ; grab the status code
  316.     callos    terminate    ; OS exit
  317.     ;*** NEVER RETURNS ***
  318. cEnd    <nogen>
  319.  
  320. endif    ;_NOCRT
  321. endif    ;!_WINDLL
  322.  
  323. ifndef    _WINDLL_NOCRT        ; No startup code in WINDLL/NOCRT libs!
  324.  
  325. page
  326. ;***
  327. ; _astart - C library startup code
  328. ;
  329. ;Purpose:
  330. ;
  331. ;  WIN STATIC Application startup code:
  332. ;
  333. ;       1. call INITTASK to process task parameters
  334. ;    2. init _cpumode, etc.
  335. ;    3. call WAITEVENT(NULL) and INITAPP(hInstance);
  336. ;    4. Perform C lib initialization
  337. ;    5. Init argv and envp
  338. ;    6. call main() / WINMAIN()
  339. ;    7. call exit with parameter returned from main/WINMAIN
  340. ;
  341. ;  WIN DLL startup code:
  342. ;
  343. ;    1. Init the local heap if one exists and then calls
  344. ;    2. Init the C startup code
  345. ;    3. Set DLL init complete flag
  346. ;    4. Call the user's main()/Libmain() routine
  347. ;
  348. ;
  349. ;Entry:
  350. ;    WIN DLL entry:
  351. ;
  352. ;    di = handle of the module instance
  353. ;    ds = library data segment
  354. ;    cx = heap size
  355. ;    es:si = command line segment:offset
  356. ;
  357. ;    [NOTE: The command line seg:off (es:si) is always NULL (!),
  358. ;    but we need to pass this through to LibMain for upward
  359. ;    compatibility with previous versions.]
  360. ;
  361. ;Exit:
  362. ;
  363. ;Uses:
  364. ;
  365. ;Exceptions:
  366. ;
  367. ;*******************************************************************************
  368.  
  369. ifndef _WINDLL
  370.  
  371. ;
  372. ; --- Error exit ---
  373. ;
  374.  
  375. error_exit:
  376.         mov     al,0FFh
  377.     cCall    __exit,<ax>        ; quick exit with error code
  378.     ;*** NEVER RETURNS ***
  379.  
  380. endif    ;!_WINDLL
  381.  
  382. ;
  383. ; --- Entry ---
  384. ;
  385.  
  386. ifdef _WINDLL
  387. cProc    __astart,<PUBLIC,C,FAR>
  388.  
  389.  
  390. cBegin    <nolocals>
  391.     push    di            ; save si/di
  392.     push    si
  393. else
  394. labelNP <PUBLIC,__astart>
  395. endif
  396.  
  397. ifdef _WINDLL
  398.  
  399. ;
  400. ; Save our input values for later reference
  401. ;
  402.     mov    __hModule,di        ; handle of the module instance
  403.     mov    __wDataSeg,ds        ; library data segment
  404.     mov    __wHeapSize,cx        ; heap size
  405.     mov    word ptr __lpszCmdline,bx ; Save command line
  406.     mov    word ptr __lpszCmdline+2,si
  407.  
  408. ;
  409. ; Init the local heap
  410. ; cx = local heap size (0 = no heap)
  411.  
  412.     jcxz    @F         ; jump if no heap specified
  413.  
  414.     ; LocalInit((LPSTR)start, WORD wHeapSize);
  415.     push    ds         ; Heap segment
  416.         xor     ax,ax
  417.     push    ax         ; Heap start offset in segment
  418.     push    cx         ; Heap end offset in segment
  419.     call    LocalInit     ; try to initialise it
  420.     or    ax,ax         ; did it do it ok ?
  421.     jz    done         ; quit if it failed
  422. @@:
  423.  
  424. else    ;!_WINDLL
  425.  
  426. ;
  427. ; Set up a dummy stack frame (as an "anchor")
  428. ;
  429.  
  430.     xor    bp,bp            ; zero bp and tos
  431.     push    bp
  432.  
  433. ;
  434. ; Perform windows initialization
  435. ;
  436.  
  437.         cCall   INITTASK
  438.     or    ax,ax            ; init work ok ?
  439.     jz    error_exit        ; if not, error
  440.  
  441. ;   Success:
  442. ;    AX = 1
  443. ;    CX = stack limit
  444. ;    DX = cmdShow parameter to CreateWindow
  445. ;    ES:BX = -> DOS format command line (ES = PSP address)
  446. ;    SI = hPrevInstance
  447. ;    DI = hInstance
  448.  
  449.  
  450. ;
  451. ; Save our input values for later reference
  452. ;
  453.  
  454. ifndef _NOCRT
  455.         mov     __psp,es                ; Remember PSP for runtimes
  456. endif
  457.  
  458.     add    cx,STACKSLOP        ; add in stack slop space
  459.     jc    error_exit        ; if overflow, return error
  460.     mov    _STKHQQ,cx        ; Setup for _stackavail
  461.  
  462.     mov    __hPrevInstance,si
  463.     mov    __hInstance,di
  464.  
  465.     mov    word ptr __lpszCmdline,bx ; Save command line
  466.     mov    word ptr __lpszCmdline+2,es
  467.  
  468.     mov    __cmdShow,dx
  469.  
  470. endif    ;!_WINDLL
  471.  
  472. if sizeD
  473. ;
  474. ; Make sure DGROUP can't move in large data models
  475. ;
  476.     mov    ax,0ffffh
  477.     cCall    LOCKSEGMENT, <ax>
  478. endif
  479.  
  480. ifndef _NOCRT
  481. ;
  482. ; Init _cpumode, _osversion, etc.
  483. ; [Note that _osmode is already set to _WIN_MODE.]
  484. ;
  485.     call    GETVERSION        ; get version of WIN
  486.     mov    [__osversion],ax    ;
  487.  
  488.     callos    version         ; get version of DOS
  489.     mov    [__dosversion],ax    ; save it
  490.  
  491.     ; Set real/protect mode (set to protect mode by default)
  492.     test    __wflags,WF_PMODE    ; Are we in protect mode ??
  493.     jnz    @F            ; yes, already set up
  494.     mov    al,_REAL_MODE        ; no, real mode
  495.     mov    [__cpumode],al
  496. @@:
  497.  
  498. ifndef _WINDLL
  499. ;
  500. ; Init this windows task
  501. ;
  502.         xor     ax,ax
  503.         cCall   WAITEVENT,<ax>          ; Clear initial PostEvent that got this task started.
  504.     cCall    INITAPP,<__hInstance>    ; do windows task initialization
  505.     or    ax,ax            ; init work ok ??
  506.     jz    error_exit        ; if not, error return
  507.  
  508. endif    ;!_WINDLL
  509.  
  510. ;
  511. ; Init C Runtime
  512. ;
  513.  
  514.     call    __cinit         ; initialize runtime
  515.  
  516. ;
  517. ; Init args and environment
  518. ;
  519.  
  520. ifndef _WINDLL
  521.         call    __setargv               ; initialize ___argc and ___argv
  522. endif
  523.         call    __setenvp               ; initialize __environ
  524.  
  525.  
  526. ifndef _WINDLL
  527. ifdef _QWIN
  528. ;
  529. ; Init the QWIN layer.
  530. ; We must do this after WAITEVENT and INITAPP.    We must also do this
  531. ; after argv[0] is initialized.
  532. ;
  533.     call    __wcinit    ; init the QWIN system
  534. endif    ;_QWIN
  535. endif    ;!_WINDLL
  536.  
  537.  
  538. endif    ; _NOCRT
  539.  
  540. ifdef _WINDLL
  541. ;
  542. ; Indicate that DLL is initialize (for WEP's benefit)
  543. ;
  544.  
  545.     inc    [__dllinit]    ; !0 = DLL initialized
  546. endif
  547.  
  548. ;
  549. ; Call the user's code
  550. ;
  551.  
  552. ifdef    _NOCRT
  553.  
  554. ifdef    _WINDLL
  555.     cCall    LIBMAIN,<__hModule,__wDataSeg,__wHeapSize,__lpszCmdLine>
  556. else    ;!_WINDLL
  557.     cCall    WINMAIN,<__hInstance,__hPrevInstance,__lpszCmdline,__cmdShow>
  558. endif    ;_WINDLL
  559.  
  560. else    ;!_NOCRT
  561.  
  562. if    sizeD
  563.     push    word ptr [__environ+2] ; the environment is not always in DS
  564. endif
  565.     push    word ptr [__environ]
  566.  
  567. if    sizeD
  568.     push    word ptr [___argv+2] ; the arguments are not always in DS
  569. endif
  570.     push    word ptr [___argv]
  571.  
  572.     push    [___argc]    ; argument count
  573.  
  574.     call    _main        ; main ( argc , argv , envp )
  575.  
  576. if    sizeD
  577.     add    sp,10
  578. else
  579.     add    sp,6
  580. endif
  581.  
  582. endif    ;_NOCRT
  583.  
  584. ;
  585. ; --- Exit ---
  586. ; ax = return code
  587. ;
  588.  
  589. ifdef    _WINDLL
  590.     pop    si            ; restore si, di
  591.     pop    di
  592. done:
  593. cEnd    <nolocals>            ; return to lib loader
  594. else
  595.     cCall    _exit,<ax>        ; exit with okay parameter
  596.     ;*** NEVER RETURNS ***
  597. endif    ;_WINDLL
  598.  
  599.  
  600. page
  601. ;***
  602. ; _nomain - No main procedure
  603. ;
  604. ;Purpose:
  605. ;    We get here if there is no main() or WinMain()/LibMain()
  606. ;    procedure.
  607. ;
  608. ;    EXE - Must have a main/Winmain so if we get here we
  609. ;    terminate with a fatal error.
  610. ;
  611. ;    DLL - The main/LibMain is optional so just return.
  612. ;
  613. ;Entry: <void>
  614. ;
  615. ;Exit:
  616. ;    EXE: Fatal runtime error
  617. ;    DLL: AX=1 (success)
  618. ;
  619. ;Uses:
  620. ;
  621. ;Exceptions:    <see above>
  622. ;
  623. ;*******************************************************************************
  624.  
  625. ifdef _WINDLL
  626.  
  627. ;int _far pascal Libmain( hModule, wDataSeg, wHeapSize, lpszCmdLine)
  628.  
  629. cProc    __nomain,<PUBLIC,PASCAL,FAR>,<>
  630.  
  631.     parmW hModule
  632.     parmW wDataSeg
  633.     parmW wHeapSize
  634.     parmD lpszCmdLine
  635.  
  636. cBegin    <nolocals>
  637.  
  638.     mov    ax,1        ; return success
  639.  
  640. cEnd    <nolocals>
  641.  
  642. else    ;!_WINDLL
  643.  
  644. ifndef    _NOCRT
  645.  
  646. labelP    <PUBLIC,__nomain>
  647.     mov    ax,_RT_NOMAIN    ; No main error
  648.     jmp    __amsg_exit    ; die
  649.  
  650. endif    ;!_NOCRT
  651.  
  652. endif    ;_WINDLL
  653.  
  654. endif    ;!_WINDLL_NOCRT
  655.  
  656.  
  657. sEnd     CODE
  658.  
  659.  
  660. ;
  661. ; EXE/DLL starting address
  662. ;
  663.  
  664. ifdef _WINDLL_NOCRT
  665.  
  666. ; DLL/NOCRT = No starting address
  667. xend    macro
  668.     END
  669.     endm
  670.  
  671. else
  672.  
  673. ;STATIC and DLL/CRT = Begin at __astart
  674. xend    macro
  675.     end __astart
  676.     endm
  677.  
  678. endif    ;_WINDLL_NOCRT
  679.  
  680.     xend
  681.