home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / START16.PAK / C0W.ASM < prev    next >
Assembly Source File  |  1995-08-29  |  12KB  |  449 lines

  1. ;[]------------------------------------------------------------[]
  2. ;|      C0W.ASM -- Start Up Code For Windows                    |
  3. ;[]------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 6.5
  7. ;       Copyright (c) 1991, 1994 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. IFNDEF __DPMI16__
  20.         public  __WINMAINCALL           ; used internally
  21. ENDIF
  22.         public  __INITAPPCALLED         ; used internally
  23.  
  24. IFNDEF __DPMI16__
  25. extrn           WINMAIN:DIST
  26. ENDIF
  27.  
  28. extrn           INITAPP:far
  29. extrn           INITTASK:far
  30. extrn           FATALEXIT:far
  31. extrn           WAITEVENT:far
  32. extrn           LOCKSEGMENT:far
  33. extrn           UNLOCKSEGMENT:far
  34. extrn           GETWINFLAGS:far
  35. IFDEF __DPMI16__
  36.   extrn         _main:DIST
  37.   extrn         _OkToInitWindowsRTL:DIST
  38.   extrn         __abort:DIST
  39. ENDIF
  40. extrn           _exit:DIST
  41. extrn           __exit:DIST
  42. extrn           __exitbuf:DIST
  43. extrn           __exitfopen:DIST
  44. extrn           __exitopen:DIST
  45. extrn           __setupio:near                  ;required!
  46. extrn           __ExceptInit:DIST
  47.  
  48.         public __DestructorCount        ;Offset to global destructor count
  49. __DestructorCount EQU  10H
  50.         public __Exception_list         ;Offset to global exception list
  51. __Exception_list  EQU  14H
  52. NULL            segment
  53.         db      16 dup (0)              ;Windows
  54.         db       4 dup (0)              ;destructor count
  55.         db       2 dup (0)              ;exception list
  56.         db       4 dup (0)              ;exception vptr
  57.         db       6 dup (0)              ;reserved
  58.         db       2 dup (0)              ;VBX control jump vector
  59.                         ;MUST be at SS:20h
  60.         db       2 dup (0)              ;reserved
  61.         ends
  62.  
  63. _CVTSEG         segment
  64.         public __RealCvtVector
  65. __RealCvtVector label word
  66.         ends
  67.  
  68. _SCNSEG         segment
  69.         public __ScanTodVector
  70. __ScanTodVector label word
  71.         ends
  72.  
  73. _FPSEG          segment
  74.         public __FPVector
  75. __FPVector      dd      0
  76.         ends
  77.  
  78. _DATA           segment
  79.         public _errno
  80. _errno          dw      0
  81.         public __protected
  82. __protected     dw      0
  83.         public __8086
  84. __8086          dw      0
  85.         public __8087
  86. __8087          dw      0
  87.         public __psp
  88. __psp           dw      0
  89.         public __hInstance
  90. __hInstance     dw      0
  91.         public __hPrev
  92. __hPrev         dw      0
  93.         public __pszCmdline
  94. __pszCmdline    dw      0
  95.         public __cmdShow
  96. __cmdShow       dw      0
  97.         public __version
  98. __version       label word
  99.         public __osversion
  100. __osversion     label word
  101.         public __osmajor
  102. __osmajor       db      0
  103.         public __osminor
  104. __osminor       db      0
  105.         public __osmode         ;Used for OS/2 protected mode by MS,
  106. __osmode        db      0               ;  currently set to 0 under Windows
  107.         public __WinAllocFlag   ;Used by malloc to get additional flags
  108. __WinAllocFlag  dw      0               ;  to pass to GlobalAlloc (for DLL use)
  109.         public __LockWIN87EM    ;Used do lock down WIN87EM to avoid
  110. __LockWIN87EM   dw      1               ;  DLL unload ordering problem
  111.         public  __abend
  112. __abend         dw      0               ;Signals abnormal end, don't run destructors etc.
  113.  
  114. IFDEF __DPMI16__
  115.   extrn         __C0environ:dword
  116.   extrn         __C0argv:dword
  117.   extrn         __C0argc:word
  118. ENDIF
  119.  
  120. CopyRight       db      'Borland C++ - Copyright 1994 Borland Intl.',0
  121. IFDEF __DPMI16__
  122. DPMI16Error_s   db      'This DPMI16 application was linked incorrectly and'
  123.         db      ' will fail.',10,13,'$'
  124. ENDIF
  125.         ends
  126.  
  127. _TEXT           segment
  128.  
  129. Main            proc near
  130.  
  131. ;Windows initialization.  Sets up registers and stack.
  132.  
  133. IFDEF   __DPMI16__
  134.         mov     ax, seg DGROUP
  135.         mov     ds, ax
  136. ENDIF
  137.  
  138.         push    bx cx es
  139.         xor     ax,ax
  140.         push    ax
  141.         call    __ExceptInit
  142.         pop     ax
  143.         pop     es cx bx
  144.  
  145.         ;INITTASK returns:
  146.         ;  'Failure:
  147.         ;    AX = zero if it failed
  148.         ;  Success:
  149.         ;    AX = 1
  150.         ;    CX = stack limit
  151.         ;    DX = cmdShow parameter to CreateWindow
  152.         ;    ES:BX = -> DOS format command line (ES = PSP address)
  153.         ;    SI = hPrevinstance
  154.         ;    DI = hinstance
  155.         call    INITTASK
  156.         or      ax,ax
  157.         jnz     @@OK
  158.         jmp     @@Fail
  159. @@OK:           mov     word ptr ss:[__Exception_list], -1
  160.         mov     __psp,es
  161.         mov     word ptr __pszCmdline,bx
  162.         mov     __hPrev,si
  163.         mov     __hInstance,di
  164.         mov     __cmdShow,dx
  165.  
  166. IF LDATA EQ false
  167.         mov     ax,-1
  168.         push    ax
  169.         call    LOCKSEGMENT
  170. ENDIF
  171.  
  172. ;Clear _BSS, uninitialized data area
  173.  
  174. IFNDEF  __HUGE__
  175.         xor     ax, ax
  176.         push    ds
  177.         pop     es
  178.         mov     di,offset DGROUP:BeginBSS
  179.         mov     cx,offset DGROUP:EndBSS
  180.         sub     cx,di
  181.         cld
  182.         rep
  183.         stosb
  184. ENDIF
  185.  
  186. ;Init the Windows App
  187.  
  188.         xor     ax,ax
  189.         push    ax
  190.         call    WAITEVENT
  191.         push    __hInstance
  192.         call    INITAPP
  193. __INITAPPCALLED:or      ax,ax
  194.         jnz     @@InitOK
  195.         jmp     @@Fail
  196. @@InitOK:
  197.  
  198. ;Determine DOS version
  199.  
  200.         mov     ah, 30h
  201.         int     21h
  202.         mov     __version, ax   ; save minor and major revision
  203.  
  204. ;Determine whether we are in protected mode
  205.  
  206.         call    GETWINFLAGS
  207.         test    ax,1            ; WF_PMODE = 1
  208.         jz      @@realmode      ; Note:  GETWINFLAGS returns a long,
  209.                     ; so if WF_PMODE changed it could be
  210.                     ; in the high word.
  211.         mov     __protected, 8  ; Eight is for convenience.
  212. @@realmode:
  213.  
  214. ;Test for 8086/8087 presence
  215.  
  216.         test    ax,0400h        ; WF_8087 = 0x0400
  217.         jz      @@no8087
  218.         mov     __8087, 1
  219. @@no8087:
  220.         and     ax,08h+04h+02h  ; WF_CPU486|WF_CPU386|WF_CPU286
  221.         shr     ax,1            ; Convert to 4 or 2 or 1 or 0
  222.         test    ax,0004h        ; Have 4, 486 done
  223.         jnz     @@NoAdjust
  224.         or      ax,ax           ; Have 0, 8086 done
  225.         jz      @@NoAdjust
  226.         inc     ax              ; Have 2 or 1, need 3 or 2
  227. @@NoAdjust:
  228.         mov     __8086,ax       ; Set CPU Type
  229.  
  230.  
  231. IFDEF  __DPMI16__
  232. ;
  233. ; Here we attempt to prevent an early death caused by linking
  234. ; the libs in the wrong order
  235. ;
  236.         call    _OkToInitWindowsRTL
  237.         or      ax, ax
  238.         jnz     DPMI16Error
  239. ENDIF
  240.  
  241. ;Call our initialization functions, including C++ static constructors.
  242.  
  243.         mov     ax,ds
  244.         mov     es,ax
  245.         mov     si,offset DGROUP:InitStart      ;si = start of table
  246.         mov     di,offset DGROUP:InitEnd        ;di = end of table
  247.         call    Initialize
  248.  
  249. IFDEF __DPMI16__
  250. ;Set up and call _main for DPMI16 application
  251.  
  252.         push    word ptr [__C0environ+2]
  253.         push    word ptr [__C0environ]
  254.         push    word ptr [__C0argv+2]
  255.         push    word ptr [__C0argv]
  256.         push    [__C0argc]
  257.         call    _main
  258. ELSE
  259. ;Set up and call WinMain for Windows application
  260.         push    __hInstance
  261.         push    __hPrev
  262.         push    __psp
  263.         push    word ptr __pszCmdline
  264.         push    __cmdShow
  265. __WINMAINCALL:  call    WINMAIN
  266. ENDIF
  267.         push    ax      ; Push return value
  268.  
  269.         cmp     __abend, 0
  270.         jne     @@abnormalexit
  271.         call    _exit   ; Normal exit
  272. @@abnormalexit: call    __exit  ; Abnormal exit, don't call destructors etc.
  273.  
  274. IFDEF  __DPMI16__
  275. DPMI16Error:
  276.         mov     ah, 9
  277.         mov     dx, offset DPMI16Error_s
  278.         int     21h
  279.         call    __abort
  280. ENDIF
  281. ;---------------------------------------------------------------------------
  282. ;       _cleanup()      call all #pragma exit cleanup routines.
  283. ;       _checknull()    check for null pointer zapping copyright message
  284. ;       _terminate(int) exit program with error code
  285. ;       _restorezero()  restore interrupt vectors
  286. ;
  287. ;       These functions are called by exit(), _exit(), _cexit(),
  288. ;       and _c_exit().
  289. ;---------------------------------------------------------------------------
  290.  
  291. ;       Call cleanup routines
  292.  
  293. __cleanup       PROC    DIST
  294.         PUBLIC  __cleanup
  295.  
  296.         mov     ax,ds
  297.         mov     es,ax
  298.         push    si
  299.         push    di
  300.         mov     si,offset DGROUP:ExitStart
  301.         mov     di,offset DGROUP:ExitEnd
  302.         call    Cleanup
  303.         pop     di
  304.         pop     si
  305.         ret
  306. __cleanup       ENDP
  307.  
  308. ;       Check for null pointers before exit.  NO-OP on Windows.
  309.  
  310. __checknull     PROC    DIST
  311.         PUBLIC  __checknull
  312.         ret
  313. __checknull     ENDP
  314.  
  315. ;       Restore grabbed interrupt vectors.  NO-OP on Windows.
  316.  
  317. __restorezero     PROC    DIST
  318.         PUBLIC  __restorezero
  319.         ret
  320. __restorezero     ENDP
  321.  
  322. ;       Exit to DOS
  323.  
  324. __terminate     PROC    DIST
  325.         PUBLIC  __terminate
  326.  
  327. IF LDATA EQ false
  328.         mov     ax,-1
  329.         push    ax
  330.         call    UNLOCKSEGMENT
  331. ENDIF
  332.         mov     bp,sp
  333.         mov     al,[bp+cPtrSize]
  334.         mov     ah,4ch                  ;exit
  335.         int     21h
  336. __terminate     ENDP
  337.  
  338. @@Fail:         mov     al,0ffh
  339.         push    ax
  340.         call    _exit
  341.  
  342.         mov     ah,4ch                  ;exit
  343.         int     21h
  344.         endp
  345.  
  346. ;       Return default data segment in AX
  347.  
  348. __GetDGROUP     PROC    FAR
  349.         PUBLIC  __GetDGROUP
  350.         mov     ax, ss
  351.         ret
  352.         endp
  353.  
  354. ;------------------------------------------------------------------
  355. ;  Loop through a startup/exit (SE) table,
  356. ;  calling functions in order of priority.
  357. ;  ES:SI is assumed to point to the beginning of the SE table
  358. ;  ES:DI is assumed to point to the end of the SE table
  359. ;  First 64 priorities are reserved by Borland
  360. ;------------------------------------------------------------------
  361. PNEAR           EQU     0
  362. PFAR            EQU     1
  363. NOTUSED         EQU     0ffh
  364.  
  365. SE              STRUC
  366. calltype        db      ?                       ; 0=near,1=far,ff=not used
  367. priority        db      ?                       ; 0=highest,ff=lowest
  368. addrlow         dw      ?
  369. addrhigh        dw      ?
  370. SE              ENDS
  371.  
  372. Initialize      proc near
  373. @@Start:        mov     ax,100h                 ;start with lowest priority
  374.         mov     dx,di                   ;set sentinel to end of table
  375.         mov     bx,si                   ;bx = start of table
  376.  
  377. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  378.         je      @@EndOfTable            ;yes, exit the loop
  379.         cmp     es:[bx.calltype],NOTUSED;check the call type
  380.         je      @@Next
  381.         mov     cl, es:[bx.priority]    ;move priority to CX
  382.         xor     ch, ch
  383.         cmp     cx,ax                   ;check the priority
  384.         jae     @@Next                  ;too high?  skip
  385.         mov     ax,cx                   ;keep priority
  386.         mov     dx,bx                   ;keep index in dx
  387. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  388.         jmp     @@TopOfTable
  389.  
  390. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  391.         je      @@Done                  ;yes, quit
  392.         mov     bx,dx                   ;bx = highest priority item
  393.         cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  394.         mov     es:[bx.calltype],NOTUSED;wipe the call type
  395.         push    es                      ;save es
  396.         je      @@NearCall
  397.  
  398. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  399.         pop     es                      ;restore es
  400.         jmp     short @@Start
  401.  
  402. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  403.         pop     es                      ;restore es
  404.         jmp     short @@Start
  405.  
  406. @@Done:         ret
  407.         endp
  408.  
  409. Cleanup         proc near
  410. @@Start:        mov     ah,0                    ;start with highest priority
  411.         mov     dx,di                   ;set sentinel to end of table
  412.         mov     bx,si                   ;bx = start of table
  413.  
  414. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  415.         je      @@EndOfTable            ;yes, exit the loop
  416.         cmp     es:[bx.calltype],NOTUSED;check the call type
  417.         je      @@Next
  418.         cmp     es:[bx.priority],ah     ;check the priority
  419.         jb      @@Next                  ;too low?  skip
  420.         mov     ah,es:[bx.priority]     ;keep priority
  421.         mov     dx,bx                   ;keep index in dx
  422. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  423.         jmp     @@TopOfTable
  424.  
  425. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  426.         je      @@Done                  ;yes, quit
  427.         mov     bx,dx                   ;bx = highest priority item
  428.         cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  429.         mov     es:[bx.calltype],NOTUSED;wipe the call type
  430.         push    es                      ;save es
  431.         je      @@NearCall
  432.  
  433. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  434.         pop     es                      ;restore es
  435.         jmp     short @@Start
  436.  
  437. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  438.         pop     es                      ;restore es
  439.         jmp     short @@Start
  440.  
  441. @@Done:         ret
  442.         endp
  443.  
  444.         ends
  445.  
  446.         end Main
  447.