home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / START16.PAK / C0D.ASM < prev    next >
Encoding:
Assembly Source File  |  1997-05-06  |  15.7 KB  |  465 lines

  1. ;[]------------------------------------------------------------[]
  2. ;|      C0D.ASM -- Start Up Code For Windows DLLs               |
  3. ;[]------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 8.0
  7. ;       Copyright (c) 1991, 1997 by Borland International
  8. ;       All Rights Reserved.
  9. ; $Revision:   8.2  $
  10.  
  11.                 locals
  12.  
  13.                 __C0__ = 1
  14. include         RULES.ASI
  15.  
  16.                 ASSUME CS:_TEXT, DS:DGROUP
  17.  
  18.                 public  __acrtused              ;satisfy MS for now
  19. __acrtused      equ     0
  20.  
  21.  
  22.                 extrn LIBMAIN:far       ;the C routine to be called
  23.                 extrn LOCALINIT:far     ;Windows heap init routine
  24.                 extrn LOCKSEGMENT:far
  25.                 extrn UNLOCKSEGMENT:far
  26.                 extrn GETWINFLAGS:far
  27.                 extrn __WEP:far
  28.                 extrn __cexit:DIST
  29. ifdef    __LARGE__
  30. ifndef    _BUILDRTLDLL
  31.                 extrn GETMODULEHANDLE:far
  32.                 extrn GETPROCADDRESS:far
  33.                 extrn __LockDLL:DIST
  34. else
  35.         extrn ___cg_init:DIST
  36.         extrn ___cg_exit:DIST
  37.         extrn __CG_QUIET:DIST
  38. endif
  39. endif
  40.                 extrn __setupio:near    ;required!
  41.  
  42.                 public LibEntry         ;Entry point for the DLL
  43.                 publicdll WEP
  44.  
  45. NULL            segment
  46.                 db      16 dup (0)              ;Windows
  47.                 db       4 dup (0)              ;destructor count
  48.                 db       2 dup (0)              ;exception list
  49.                 db       4 dup (0)              ;exception vptr
  50.                 db       6 dup (0)              ;reserved
  51.                 db       2 dup (0)              ;VBX control jump vector
  52.                                                 ;MUST be at SS:20h
  53.                 db       2 dup (0)              ;reserved
  54.                 ends
  55.  
  56. _CVTSEG         segment
  57.                 public __RealCvtVector
  58. __RealCvtVector label word
  59.                 ends
  60.  
  61. _SCNSEG         segment
  62.                 public __ScanTodVector
  63. __ScanTodVector label word
  64.                 ends
  65.  
  66. _FPSEG          segment
  67.                 public __FPVector
  68. __FPVector      dd      0
  69.                 ends
  70.  
  71. _DATA           segment
  72.                 public _errno
  73. _errno          dw      0
  74.                 public __protected
  75. __protected     dw      0
  76.                 public __8086
  77. __8086          dw      0
  78.                 public __8087
  79. __8087          dw      0
  80.                 public __version
  81. __version       label word
  82.                 public __osversion
  83. __osversion     label word
  84.                 public __osmajor
  85. __osmajor       db      0
  86.                 public __osminor
  87. __osminor       db      0
  88.                 public __osmode         ;Used for OS/2 protected mode by MS,
  89. __osmode        db      0               ;currently set to 0 under Windows
  90.                 public __hInstance
  91. __hInstance     dw      0
  92.                 public __WinAllocFlag   ;Used by malloc for additional flags
  93. __WinAllocFlag  dw      2000h           ;to pass to GlobalAlloc (used in DLLs)
  94.                                         ;default value is GMEM_SHARE
  95.                 public __LockWIN87EM    ;Used do lock down WIN87EM to avoid
  96. __LockWIN87EM   dw      1               ;DLL unload ordering problem
  97.  
  98. ifdef    __LARGE__
  99. ifndef    _BUILDRTLDLL
  100.                 public __LockRTLHandle
  101. __LockRTLHandle dw      0               ;Handle of RTLDLL (locked)
  102. FREELIBRARYPROC    dd    0        ;True address of FreeLibrary
  103. KERNELSTRING    db    "KERNEL", 0    ;Name of KERNEL.EXE
  104. FREELIBRARYSTRING db    "FREELIBRARY", 0;Name of FreeLibrary procedure
  105. endif
  106. endif
  107.  
  108.             public  __abend
  109. __abend        label   word
  110. _abend          dw      1               ;If LibEntry is called gets set to
  111.                                         ;normal state (0).  If it is 1 then
  112.                                         ;exit routines are not performed
  113.                                         ;Gets set to 1 if DLL is terminated
  114.                                         ;by a call to abort() or _exit().
  115.  
  116. CopyRight       db      'Borland C++ - Copyright 1995 Borland Intl.',0
  117.                 ends
  118.  
  119. _TEXT           segment
  120.  
  121. LibEntry        proc far
  122.                 mov     __hInstance, di ;save SI and DI
  123.                 push    si
  124.  
  125.                 push    di              ;handle of the module instance
  126.                 push    ds              ;library data segment
  127.                 push    cx              ;heap size
  128.                 push    es              ;command line segment
  129.                 push    si              ;command line offset
  130.  
  131.                 ;if we have some heap then initialize it
  132.                 jcxz    @@Init          ;jump if no heap specified
  133.  
  134.                 ;call the Windows function LocalInit() to set up the heap
  135.                 ;LocalInit(uint segment, uint startOffset, uint endOffset)
  136.  
  137.                 push    ds              ;Heap segment
  138.                 xor     ax,ax
  139.                 push    ax              ;Heap start offset in segment
  140.                 push    cx              ;Heap end offset in segment
  141.                 call    LOCALINIT
  142.                 xchg    ax,cx
  143.                 jcxz    @@JmpExit       ;quit if it failed
  144.                 jmp     short @@Init
  145. @@JmpExit:      jmp     @@Exit
  146.  
  147. @@Init:
  148.  
  149. IF LDATA EQ false
  150.                 mov     ax,-1
  151.                 push    ax
  152.                 call    LOCKSEGMENT
  153. ENDIF
  154.  
  155.                 ;Clear _BSS, uninitialized data area
  156.  
  157.                 xor     ax, ax
  158.                 push    ds
  159.                 pop     es
  160.                 mov     di,offset DGROUP:BeginBSS
  161.                 mov     cx,offset DGROUP:EndBSS
  162.                 sub     cx,di
  163.                 cld
  164.                 rep
  165.                 stosb
  166.  
  167. ;Determine DOS version
  168.  
  169.                 mov     ah, 30h
  170.                 int     21h
  171.                 mov     __version, ax   ; save minor and major revision
  172.  
  173. ;Determine whether we are in protected mode
  174.  
  175.                 call    GETWINFLAGS
  176.                 test    ax,1            ; WF_PMODE = 1
  177.                 jz      @@realmode      ; Note:  GETWINFLAGS returns a long,
  178.                                         ; so if WF_PMODE changed it could be
  179.                                         ; in the high word.
  180.                 mov     __protected, 8  ; Eight is for convenience.
  181. @@realmode:
  182.  
  183. ;Test for 8087 presence
  184.  
  185.                 test    ax,0400h        ; WF_8087 = 0x0400
  186.                 jz      @@no8087
  187.                 mov     __8087, 1
  188. @@no8087:
  189.                 and     ax,08h+04h+02h  ; WF_CPU486|WF_CPU386|WF_CPU286
  190.                 shr     ax,1            ; Convert to 4 or 2 or 1 or 0
  191.                 test    ax,0004h        ; Have 4, 486 done
  192.                 jnz     @@NoAdjust
  193.                 or      ax,ax           ; Have 0, 8086 done
  194.                 jz      @@NoAdjust
  195.                 inc     ax              ; Have 2 or 1, need 3 or 2
  196. @@NoAdjust:
  197.                 mov     __8086,ax       ; Set CPU Type
  198.  
  199. ifdef    _BUILDRTLDLL
  200. ;Init CG
  201.         call    ___cg_init
  202.         test    ax,ax
  203.         jnz    @@Exit
  204. endif
  205.         
  206. ;Call our initialization functions, including C++ static constructors.
  207.  
  208.                 mov     ax,ds
  209.                 mov     es,ax
  210.                 mov     si,offset DGROUP:InitStart      ;si = start of table
  211.                 mov     di,offset DGROUP:InitEnd        ;di = end of table
  212.  
  213.                 call    Initialize
  214.                 mov     _abend, 0                       ; Set LibEntry called
  215.  
  216.                 ;invoke the C routine to do any special initialization
  217. @@Main:         call    LIBMAIN         ;invoke the 'C' routine (result in AX)
  218.                 or  ax, ax
  219.  
  220. ifdef    __LARGE__
  221. ifndef    _BUILDRTLDLL
  222.                 jz  @@LibMainRet
  223.  
  224.                 push    ax
  225.                 call    __LockDLL
  226.                 mov     __LockRTLHandle, ax
  227.                 push    ds
  228.         mov    ax, OFFSET KERNELSTRING
  229.         push    ax
  230.                 call    GETMODULEHANDLE
  231.                 push    ax
  232.                 push    ds
  233.         mov     ax, OFFSET FREELIBRARYSTRING
  234.                 push    ax
  235.                 call    GETPROCADDRESS
  236.                 mov    word ptr [FREELIBRARYPROC + 0], ax
  237.                 mov    word ptr [FREELIBRARYPROC + 2], dx
  238.                 pop ax
  239. @@LibMainRet:
  240. endif
  241. endif
  242.                 mov     di, __hInstance ;restore SI and DI
  243.                 pop     si
  244.                 ret
  245.  
  246. @@Exit:         mov ax, 0               ;set return code
  247.                 pop si                  ;remove arguments to LIBMAIN
  248.                 pop es                  ;  since we didn't call it.
  249.                 pop cx
  250.                 pop ds
  251.                 pop di
  252.                 pop si                  ;restore saved SI.  DI is restored
  253.                 ret                     ;  by removing arguments to LIBMAIN
  254.                 endp
  255.  
  256. ;---------------------------------------------------------------------------
  257. ;       _cleanup()      call all #pragma exit cleanup routines.
  258. ;       _checknull()    check for null pointer zapping copyright message
  259. ;       _terminate(exitcode, quick)     exit program with error code
  260. ;       _restorezero()  restore interrupt vectors
  261. ;
  262. ;       These functions are called by exit(), _exit(), _cexit(),
  263. ;       and _c_exit().
  264. ;---------------------------------------------------------------------------
  265.  
  266. ;       Call cleanup routines
  267.  
  268. __cleanup       PROC    DIST
  269.                 PUBLIC  __cleanup
  270.  
  271.                 mov     ax,ds
  272.                 mov     es,ax
  273.                 push    si
  274.                 push    di
  275.                 mov     si,offset DGROUP:ExitStart
  276.                 mov     di,offset DGROUP:ExitEnd
  277.                 call    Cleanup
  278.                 pop     di
  279.                 pop     si
  280.                 ret
  281. __cleanup       ENDP
  282.  
  283. ;       Check for null pointers before exit.  NO-OP on Windows.
  284.  
  285. __checknull     PROC    DIST
  286.                 PUBLIC  __checknull
  287.                 ret
  288. __checknull     ENDP
  289.  
  290. ;       Restore grabbed interrupt vectors.  NO-OP on Windows.
  291.  
  292. __restorezero     PROC    DIST
  293.                 PUBLIC  __restorezero
  294.                 ret
  295. __restorezero     ENDP
  296.  
  297. ;       Exit to DOS
  298. ;
  299. ; Usage:        void _terminate(int exitcode, int quick);
  300.  
  301. __terminate     PROC    DIST
  302.                 PUBLIC  __terminate
  303.  
  304.                 mov     bp,sp
  305.                 mov     al,[bp+cPtrSize]        ; get exitcode
  306.                 mov     ah,4ch
  307.                 int     21h
  308.                 ret
  309.                 endp
  310.  
  311. WEP             proc    windows pascal far nParam:WORD
  312.                 push    si
  313.                 push    di
  314.  
  315.                 cmp     _abend, 0
  316.                 jne     @@error
  317.  
  318. ifdef    _BUILDRTLDLL
  319. ;Tell CG not to display message box
  320.         call    __CG_QUIET
  321. endif
  322.  
  323.                 push    nParam
  324.                 call    __WEP
  325.                 push    ax
  326.                 call    __cexit         ; perform cleanup without exiting
  327.  
  328. @@unlock:
  329.  
  330. ifdef    __LARGE__
  331. ifndef    _BUILDRTLDLL
  332.         mov    ax, __LockRTLHandle
  333.         or    ax, ax
  334.         jz    @@RTLNotLocked
  335.         push    ax
  336.         call    dword ptr [FREELIBRARYPROC]
  337. @@RTLNotLocked:
  338. endif
  339. endif
  340.  
  341. ifdef    _BUILDRTLDLL
  342. ;Init CG
  343.         call    ___cg_exit
  344. endif
  345.  
  346. IF LDATA EQ false
  347.                 mov     ax,-1
  348.                 push    ax
  349.                 call    UNLOCKSEGMENT
  350. ENDIF
  351.  
  352.                 pop     ax
  353.                 pop     di
  354.                 pop     si
  355.                 ret
  356.  
  357. @@error:
  358.                 push    1
  359.                 jmp     @@unlock
  360.  
  361.                 endp
  362.  
  363. ;       Return default data segment in AX
  364.  
  365. __GetDGROUP     PROC    FAR
  366.                 PUBLIC  __GetDGROUP
  367.                 mov     ax, DGROUP
  368.                 ret
  369.                 endp
  370.  
  371. ;------------------------------------------------------------------
  372. ;  Loop through a startup/exit (SE) table,
  373. ;  calling functions in order of priority.
  374. ;  ES:SI is assumed to point to the beginning of the SE table
  375. ;  ES:DI is assumed to point to the end of the SE table
  376. ;  First 64 priorities are reserved by Borland
  377. ;------------------------------------------------------------------
  378. PNEAR           EQU     0
  379. PFAR            EQU     1
  380. NOTUSED         EQU     0ffh
  381.  
  382. SE              STRUC
  383. calltype        db      ?                       ; 0=near,1=far,ff=not used
  384. priority        db      ?                       ; 0=highest,ff=lowest
  385. addrlow         dw      ?
  386. addrhigh        dw      ?
  387. SE              ENDS
  388.  
  389. Initialize      proc near
  390. @@Start:        mov     ax,100h                 ;start with lowest priority
  391.                 mov     dx,di                   ;set sentinel to end of table
  392.                 mov     bx,si                   ;bx = start of table
  393.  
  394. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  395.                 je      @@EndOfTable            ;yes, exit the loop
  396.                 cmp     es:[bx.calltype],NOTUSED;check the call type
  397.                 je      @@Next
  398.                 mov     cl, es:[bx.priority]    ;move priority to CX
  399.                 xor     ch, ch
  400.                 cmp     cx,ax                   ;check the priority
  401.                 jae     @@Next                  ;too high?  skip
  402.                 mov     ax,cx                   ;keep priority
  403.                 mov     dx,bx                   ;keep index in dx
  404. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  405.                 jmp     @@TopOfTable
  406.  
  407. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  408.                 je      @@Done                  ;yes, quit
  409.                 mov     bx,dx                   ;bx = highest priority item
  410.                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  411.                 mov     es:[bx.calltype],NOTUSED;wipe the call type
  412.                 push    es                      ;save es
  413.                 je      @@NearCall
  414.  
  415. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  416.                 pop     es                      ;restore es
  417.                 jmp     short @@Start
  418.  
  419. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  420.                 pop     es                      ;restore es
  421.                 jmp     short @@Start
  422.  
  423. @@Done:         ret
  424.                 endp
  425.  
  426. Cleanup         proc near
  427. @@Start:        mov     ah,0                    ;start with highest priority
  428.                 mov     dx,di                   ;set sentinel to end of table
  429.                 mov     bx,si                   ;bx = start of table
  430.  
  431. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  432.                 je      @@EndOfTable            ;yes, exit the loop
  433.                 cmp     es:[bx.calltype],NOTUSED;check the call type
  434.                 je      @@Next
  435.                 cmp     es:[bx.priority],ah     ;check the priority
  436.                 jb      @@Next                  ;too low?  skip
  437.                 mov     ah,es:[bx.priority]     ;keep priority
  438.                 mov     dx,bx                   ;keep index in dx
  439. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  440.                 jmp     @@TopOfTable
  441.  
  442. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  443.                 je      @@Done                  ;yes, quit
  444.                 mov     bx,dx                   ;bx = highest priority item
  445.                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  446.                 mov     es:[bx.calltype],NOTUSED;wipe the call type
  447.                 push    es                      ;save es
  448.                 je      @@NearCall
  449.  
  450. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  451.                 pop     es                      ;restore es
  452.                 jmp     short @@Start
  453.  
  454. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  455.                 pop     es                      ;restore es
  456.                 jmp     short @@Start
  457.  
  458. @@Done:         ret
  459.                 endp
  460.  
  461.                 ends
  462.                 end LibEntry
  463.