home *** CD-ROM | disk | FTP | other *** search
- ;[]------------------------------------------------------------[]
- ;| C0W.ASM -- Start Up Code For Windows |
- ;[]------------------------------------------------------------[]
-
- ;
- ; C/C++ Run Time Library - Version 8.0
- ;
- ; Copyright (c) 1991, 1997 by Borland International
- ; All Rights Reserved.
- ;
- ; $Revision: 8.2 $
-
- locals
-
- .286
-
- __C0__ = 1
- include RULES.ASI
-
- ASSUME CS:_TEXT, DS:DGROUP
-
- public __acrtused ;satisfy MS for now
- __acrtused equ 0
- IFNDEF __DPMI16__
- public __WINMAINCALL ; used internally
- ENDIF
- public __INITAPPCALLED ; used internally
-
- IFNDEF __DPMI16__
- extrn WINMAIN:DIST
- ENDIF
-
- extrn INITAPP:far
- extrn INITTASK:far
- extrn FATALEXIT:far
- extrn WAITEVENT:far
- extrn LOCKSEGMENT:far
- extrn UNLOCKSEGMENT:far
- extrn GETWINFLAGS:far
- IFDEF __LARGE__
- extrn MESSAGEBOX:far
- ENDIF
- IFDEF __DPMI16__
- extrn _main:DIST
- extrn _OkToInitWindowsRTL:DIST
- extrn __abort:DIST
- ENDIF
- extrn _exit:DIST
- extrn __exit:DIST
- extrn __exitbuf:DIST
- extrn __exitfopen:DIST
- extrn __exitopen:DIST
- extrn __setupio:near ;required!
- extrn __ExceptInit:DIST
-
- public __DestructorCount ;Offset to global destructor count
- __DestructorCount EQU 10H
- public __Exception_list ;Offset to global exception list
- __Exception_list EQU 14H
- NULL segment
- db 16 dup (0) ;Windows
- db 4 dup (0) ;destructor count
- db 2 dup (0) ;exception list
- db 4 dup (0) ;exception vptr
- db 6 dup (0) ;reserved
- db 2 dup (0) ;VBX control jump vector
- ;MUST be at SS:20h
- db 2 dup (0) ;reserved
- ends
-
- _CVTSEG segment
- public __RealCvtVector
- __RealCvtVector label word
- ends
-
- _SCNSEG segment
- public __ScanTodVector
- __ScanTodVector label word
- ends
-
- _FPSEG segment
- public __FPVector
- __FPVector dd 0
- ends
-
- _DATA segment
- public _errno
- _errno dw 0
- public __protected
- __protected dw 0
- public __8086
- __8086 dw 0
- public __8087
- __8087 dw 0
- public __psp
- __psp dw 0
- public __hInstance
- __hInstance dw 0
- public __hPrev
- __hPrev dw 0
- public __pszCmdline
- __pszCmdline dw 0
- public __cmdShow
- __cmdShow dw 0
- public __version
- __version label word
- public __osversion
- __osversion label word
- public __osmajor
- __osmajor db 0
- public __osminor
- __osminor db 0
- public __osmode ;Used for OS/2 protected mode by MS,
- __osmode db 0 ; currently set to 0 under Windows
- public __WinAllocFlag ;Used by malloc to get additional flags
- __WinAllocFlag dw 0 ; to pass to GlobalAlloc (for DLL use)
- public __LockWIN87EM ;Used do lock down WIN87EM to avoid
- __LockWIN87EM dw 1 ; DLL unload ordering problem
- public __abend
- __abend dw 0 ;Signals abnormal end, don't run destructors etc.
-
- IFDEF __DPMI16__
- extrn __C0environ:dword
- extrn __C0argv:dword
- extrn __C0argc:word
- ENDIF
-
- CopyRight db 'Borland C++ - Copyright 1995 Borland Intl.',0
-
- IFDEF __LARGE__
- CGFailMessage db 'CodeGuard cannot be run with multiple processes',0
- CGMessageTitle db 'CodeGuard Message',0
- CGFail dw 0
- ENDIF
-
- IFDEF __DPMI16__
- DPMI16Error_s db 'This DPMI16 application was linked incorrectly and'
- db ' will fail.',10,13,'$'
- ENDIF
- ends
-
- _TEXT segment
-
- Main proc near
- IFDEF __LARGE__
- jmp @@Start
-
- db 'CGINITCB' ; signature
- dw offset CGFail ; offset in DGROUP of status word
- ENDIF
- @@Start:
-
- ;Windows initialization. Sets up registers and stack.
-
- IFDEF __DPMI16__
- mov ax, seg DGROUP
- mov ds, ax
- ENDIF
- push bx cx es
- xor ax,ax
- push ax
- call __ExceptInit
- pop ax
- pop es cx bx
-
- ;INITTASK returns:
- ; 'Failure:
- ; AX = zero if it failed
- ; Success:
- ; AX = 1
- ; CX = stack limit
- ; DX = cmdShow parameter to CreateWindow
- ; ES:BX = -> DOS format command line (ES = PSP address)
- ; SI = hPrevinstance
- ; DI = hinstance
- call INITTASK
- or ax,ax
- jnz @@OK
- jmp @@Fail
- @@OK: mov word ptr ss:[__Exception_list], -1
- mov __psp,es
- mov word ptr __pszCmdline,bx
- mov __hPrev,si
- mov __hInstance,di
- mov __cmdShow,dx
-
- IF LDATA EQ false
- mov ax,-1
- push ax
- call LOCKSEGMENT
- ENDIF
-
- ;Clear _BSS, uninitialized data area
-
- IFNDEF __HUGE__
- xor ax, ax
- push ds
- pop es
- mov di,offset DGROUP:BeginBSS
- mov cx,offset DGROUP:EndBSS
- sub cx,di
- cld
- rep
- stosb
- ENDIF
-
- ;Init the Windows App
-
- xor ax,ax
- push ax
- call WAITEVENT
- push __hInstance
- call INITAPP
- __INITAPPCALLED:
-
- IFDEF __LARGE__
- ;Check whether CodeGuard detected multiple clients
- cmp CGFail,0
- je @@TestInit
- ;If so then display message and fail initializaion
- pusha
- call MESSAGEBOX pascal, 0, ds offset CGFailMessage, ds offset CGMessageTitle, 1010h ; MB_ICONSTOP | MB_SYSTEMMODAL
- popa
- xor ax,ax
- ENDIF
-
- ;Test whether INITAPP suceeded
- @@TestInit: or ax,ax
- jnz @@InitOK
- jmp @@Fail
- @@InitOK:
-
- ;Determine DOS version
-
- mov ah, 30h
- int 21h
- mov __version, ax ; save minor and major revision
-
- ;Determine whether we are in protected mode
-
- call GETWINFLAGS
- test ax,1 ; WF_PMODE = 1
- jz @@realmode ; Note: GETWINFLAGS returns a long,
- ; so if WF_PMODE changed it could be
- ; in the high word.
- mov __protected, 8 ; Eight is for convenience.
- @@realmode:
-
- ;Test for 8086/8087 presence
-
- test ax,0400h ; WF_8087 = 0x0400
- jz @@no8087
- mov __8087, 1
- @@no8087:
- and ax,08h+04h+02h ; WF_CPU486|WF_CPU386|WF_CPU286
- shr ax,1 ; Convert to 4 or 2 or 1 or 0
- test ax,0004h ; Have 4, 486 done
- jnz @@NoAdjust
- or ax,ax ; Have 0, 8086 done
- jz @@NoAdjust
- inc ax ; Have 2 or 1, need 3 or 2
- @@NoAdjust:
- mov __8086,ax ; Set CPU Type
-
-
- IFDEF __DPMI16__
- ;
- ; Here we attempt to prevent an early death caused by linking
- ; the libs in the wrong order
- ;
- call _OkToInitWindowsRTL
- or ax, ax
- jnz DPMI16Error
- ENDIF
-
- ;Call our initialization functions, including C++ static constructors.
-
- mov ax,ds
- mov es,ax
- mov si,offset DGROUP:InitStart ;si = start of table
- mov di,offset DGROUP:InitEnd ;di = end of table
- call Initialize
-
- IFDEF __DPMI16__
- ;Set up and call _main for DPMI16 application
-
- push word ptr [__C0environ+2]
- push word ptr [__C0environ]
- push word ptr [__C0argv+2]
- push word ptr [__C0argv]
- push [__C0argc]
- call _main
- ELSE
- ;Set up and call WinMain for Windows application
- push __hInstance
- push __hPrev
- push __psp
- push word ptr __pszCmdline
- push __cmdShow
- __WINMAINCALL: call WINMAIN
- ENDIF
- push ax ; Push return value
-
- cmp __abend, 0
- jne @@abnormalexit
- call _exit ; Normal exit
- @@abnormalexit: call __exit ; Abnormal exit, don't call destructors etc.
-
- IFDEF __DPMI16__
- DPMI16Error:
- mov ah, 9
- mov dx, offset DPMI16Error_s
- int 21h
- call __abort
- ENDIF
- ;---------------------------------------------------------------------------
- ; _cleanup() call all #pragma exit cleanup routines.
- ; _checknull() check for null pointer zapping copyright message
- ; _terminate(int) exit program with error code
- ; _restorezero() restore interrupt vectors
- ;
- ; These functions are called by exit(), _exit(), _cexit(),
- ; and _c_exit().
- ;---------------------------------------------------------------------------
-
- ; Call cleanup routines
-
- __cleanup PROC DIST
- PUBLIC __cleanup
-
- mov ax,ds
- mov es,ax
- push si
- push di
- mov si,offset DGROUP:ExitStart
- mov di,offset DGROUP:ExitEnd
- call Cleanup
- pop di
- pop si
- ret
- __cleanup ENDP
-
- ; Check for null pointers before exit. NO-OP on Windows.
-
- __checknull PROC DIST
- PUBLIC __checknull
- ret
- __checknull ENDP
-
- ; Restore grabbed interrupt vectors. NO-OP on Windows.
-
- __restorezero PROC DIST
- PUBLIC __restorezero
- ret
- __restorezero ENDP
-
- ; Exit to DOS
-
- __terminate PROC DIST
- PUBLIC __terminate
-
- IF LDATA EQ false
- mov ax,-1
- push ax
- call UNLOCKSEGMENT
- ENDIF
- mov bp,sp
- mov al,[bp+cPtrSize]
- mov ah,4ch ;exit
- int 21h
- __terminate ENDP
-
- @@Fail: mov al,0ffh
- push ax
- call _exit
-
- mov ah,4ch ;exit
- int 21h
- endp
-
- ; Return default data segment in AX
-
- __GetDGROUP PROC FAR
- PUBLIC __GetDGROUP
- mov ax, ss
- ret
- endp
-
- ;------------------------------------------------------------------
- ; Loop through a startup/exit (SE) table,
- ; calling functions in order of priority.
- ; ES:SI is assumed to point to the beginning of the SE table
- ; ES:DI is assumed to point to the end of the SE table
- ; First 64 priorities are reserved by Borland
- ;------------------------------------------------------------------
- PNEAR EQU 0
- PFAR EQU 1
- NOTUSED EQU 0ffh
-
- SE STRUC
- calltype db ? ; 0=near,1=far,ff=not used
- priority db ? ; 0=highest,ff=lowest
- addrlow dw ?
- addrhigh dw ?
- SE ENDS
-
- Initialize proc near
- @@Start: mov ax,100h ;start with lowest priority
- mov dx,di ;set sentinel to end of table
- mov bx,si ;bx = start of table
-
- @@TopOfTable: cmp bx,di ;and the end of the table?
- je @@EndOfTable ;yes, exit the loop
- cmp es:[bx.calltype],NOTUSED;check the call type
- je @@Next
- mov cl, es:[bx.priority] ;move priority to CX
- xor ch, ch
- cmp cx,ax ;check the priority
- jae @@Next ;too high? skip
- mov ax,cx ;keep priority
- mov dx,bx ;keep index in dx
- @@Next: add bx,SIZE SE ;bx = next item in table
- jmp @@TopOfTable
-
- @@EndOfTable: cmp dx,di ;did we exhaust the table?
- je @@Done ;yes, quit
- mov bx,dx ;bx = highest priority item
- cmp es:[bx.calltype],PNEAR ;is it near or far?
- mov es:[bx.calltype],NOTUSED;wipe the call type
- push es ;save es
- je @@NearCall
-
- @@FarCall: call DWORD PTR es:[bx.addrlow]
- pop es ;restore es
- jmp short @@Start
-
- @@NearCall: call WORD PTR es:[bx.addrlow]
- pop es ;restore es
- jmp short @@Start
-
- @@Done: ret
- endp
-
- Cleanup proc near
- @@Start: mov ah,0 ;start with highest priority
- mov dx,di ;set sentinel to end of table
- mov bx,si ;bx = start of table
-
- @@TopOfTable: cmp bx,di ;and the end of the table?
- je @@EndOfTable ;yes, exit the loop
- cmp es:[bx.calltype],NOTUSED;check the call type
- je @@Next
- cmp es:[bx.priority],ah ;check the priority
- jb @@Next ;too low? skip
- mov ah,es:[bx.priority] ;keep priority
- mov dx,bx ;keep index in dx
- @@Next: add bx,SIZE SE ;bx = next item in table
- jmp @@TopOfTable
-
- @@EndOfTable: cmp dx,di ;did we exhaust the table?
- je @@Done ;yes, quit
- mov bx,dx ;bx = highest priority item
- cmp es:[bx.calltype],PNEAR ;is it near or far?
- mov es:[bx.calltype],NOTUSED;wipe the call type
- push es ;save es
- je @@NearCall
-
- @@FarCall: call DWORD PTR es:[bx.addrlow]
- pop es ;restore es
- jmp short @@Start
-
- @@NearCall: call WORD PTR es:[bx.addrlow]
- pop es ;restore es
- jmp short @@Start
-
- @@Done: ret
- endp
-
- ends
-
- end Main
-