home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 21.ddi / START16.PAK / C0D.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-12-02  |  14.0 KB  |  388 lines

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