www.pudn.com > linuxcici1.rar > C0.ASM


        NAME    c0 
        PAGE    60,132 
;[]------------------------------------------------------------[] 
;|      C0.ASM -- Start Up Code                                 | 
;|                                                              | 
;|      Turbo-C Run Time Library        version 2.0             | 
;|                                                              | 
;|      Copyright (c) 1988 by Borland International Inc.        | 
;|      All Rights Reserved.                                    | 
;[]------------------------------------------------------------[] 
 
        INCLUDE RULES.ASI 
 
_Strict87_	equ	false		; emulation skips peculiar details 
 
;       Segment and Group declarations 
 
_TEXT   SEGMENT BYTE PUBLIC 'CODE' 
_TEXT   ENDS 
_DATA   SEGMENT PARA PUBLIC 'DATA' 
_DATA   ENDS 
IFNDEF  __NOFLOAT__ 
_EMUSEG SEGMENT WORD COMMON 'DATA' 
_EMUSEG ENDS 
ENDIF 
_CRTSEG SEGMENT WORD COMMON 'DATA' 
_CRTSEG ENDS 
_CVTSEG SEGMENT WORD PUBLIC 'DATA' 
_CVTSEG ENDS 
_SCNSEG SEGMENT WORD PUBLIC 'DATA' 
_SCNSEG ENDS 
IFNDEF __HUGE__ 
_BSS    SEGMENT WORD PUBLIC 'BSS' 
_BSS    ENDS 
_BSSEND SEGMENT BYTE PUBLIC 'STACK' 
_BSSEND ENDS 
ENDIF 
IFNDEF __TINY__ 
_STACK  SEGMENT STACK 'STACK' 
_STACK  ENDS 
ENDIF 
 
IFNDEF  __NOFLOAT__ 
 
IF      LDATA 
IFNDEF __HUGE__ 
DGROUP  GROUP   _DATA, _EMUSEG, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ELSE 
DGROUP  GROUP   _DATA, _EMUSEG, _CRTSEG, _CVTSEG, _SCNSEG 
ENDIF 
ELSE 
IFNDEF  __TINY__ 
DGROUP  GROUP   _DATA, _EMUSEG, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ELSE 
DGROUP  GROUP   _TEXT, _DATA, _EMUSEG, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ENDIF 
ENDIF 
 
ELSE 
 
IF      LDATA 
IFNDEF __HUGE__ 
DGROUP  GROUP   _DATA, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ELSE 
DGROUP  GROUP   _DATA, _CRTSEG, _CVTSEG, _SCNSEG 
ENDIF 
ELSE 
IFNDEF  __TINY__ 
DGROUP  GROUP   _DATA, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ELSE 
DGROUP  GROUP   _TEXT, _DATA, _CRTSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND 
ENDIF 
ENDIF 
 
ENDIF 
 
        ASSUME  CS:_TEXT, DS:DGROUP 
 
;       External References 
 
ExtProc@        main,   __CDECL__ 
ExtProc@        _setargv, __CDECL__ 
ExtProc@        _setenvp, __CDECL__ 
ExtProc@        exit,   __CDECL__ 
 
IF      LDATA EQ false 
ExtSym@ _heaplen, WORD,  __CDECL__ 
ENDIF 
ExtSym@ _stklen,  WORD,  __CDECL__ 
 
        SUBTTL  Start Up Code 
        PAGE 
;/*                                                     */ 
;/*-----------------------------------------------------*/ 
;/*                                                     */ 
;/*     Start Up Code                                   */ 
;/*     -------------                                   */ 
;/*                                                     */ 
;/*-----------------------------------------------------*/ 
;/*                                                     */ 
PSPHigh         equ     00002h 
PSPEnv          equ     0002ch 
PSPCmd          equ     00080h 
 
IFDEF	__NOFLOAT__ 
	MINSTACK	equ	128	; minimal stack size in words 
ELSE 
	MINSTACK	equ	256	; minimal stack size in words 
ENDIF 
; 
;       At the start, DS and ES both point to the segment prefix. 
;       SS points to the stack segment except in TINY model where 
;       SS is equal to CS 
; 
_TEXT   SEGMENT 
IFDEF   __TINY__ 
        ORG     100h 
ENDIF 
STARTX          PROC    NEAR 
;       Save general information, such as : 
;               DGROUP segment address 
;               DOS version number 
;               Program Segment Prefix address 
;               Environment address 
;               Top of far heap 
 
IFDEF   __TINY__ 
                mov     dx, cs          ; DX = GROUP Segment address 
ELSE 
                mov     dx, DGROUP      ; DX = GROUP Segment address 
ENDIF 
                mov     cs:DGROUP@@, dx 
                mov     ah, 30h 
                int     21h 
                mov     bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr 
                mov     bx, ds:[PSPEnv] ; BX = Environment Segment address 
                mov     ds, dx 
                mov     _version@, ax   ; Keep major and minor version number 
                mov     _psp@, es       ; Keep Program Segment Prefix address 
                mov     _envseg@, bx    ; Keep Environment Segment address 
                mov     word ptr _heaptop@ + 2, bp 
                mov     _8087@, -1 
; 
;       Save several vectors and install default divide by zero handler. 
; 
                call    SaveVectors 
 
;       Look for a '87' environment variable, and use this loop to 
;       count the number of environment variables and to compute the 
;       environment size. 
;       Each variable is ended by a 0 and a zero-length variable stops 
;       the environment. The environment can NOT be greater than 32k. 
 
                les     di, dword ptr _envLng@ 
                mov     ax, di 
                mov     bx, ax 
                mov     cx, 07FFFh      ; Environment cannot be > 32 Kbytes 
IsIt87Var       label   near 
                cmp     word ptr es:[di], '78' 
                jne     GetVarLng 
                mov     dx, es:[di+2] 
                cmp     dl, '=' 
                jne     GetVarLng 
                and     dh, not ' ' 
                inc     _8087@ 
                cmp     dh, 'Y' 
                jne     GetVarLng 
                inc     _8087@ 
GetVarLng       label   near 
                repnz   scasb 
                jcxz    InitFailed      ; Bad environment !!! 
                inc     bx              ; BX = Nb environment variables 
                cmp     es:[di], al 
                jne     IsIt87Var       ; Next variable ... 
                or      ch, 10000000b 
                neg     cx 
                mov     _envLng@, cx     ; Save Environment size 
                mov     cx, dPtrSize / 2 
                shl     bx, cl 
                add     bx, dPtrSize * 4 
                and     bx, not ((dPtrSize * 4) - 1) 
                mov     _envSize@, bx   ; Save Environment Variables Nb. 
 
;       Determine the amount of memory that we need to keep 
 
IF      LDATA 
                mov     dx, ss 
                sub     bp, dx          ; BP = remaining size in paragraphs 
IFDEF   __HUGE__ 
                mov     di, seg _stklen@ 
                mov     es, di 
                mov     di, es:_stklen@ ; DI = Requested stack size 
ELSE 
                mov     di, _stklen@    ; DI = Requested stack size 
ENDIF 
; 
; Make sure that the requested stack size is at least MINSTACK words. 
; 
                cmp     di, 2*MINSTACK  ; requested stack big enough ? 
                jae     AskedStackOK 
                mov     di, 2*MINSTACK  ; no --> use minimal value 
IFDEF   __HUGE__ 
                mov     es:_stklen@, di ; override requested stack size 
ELSE 
                mov        _stklen@, di ; override requested stack size 
ENDIF 
AskedStackOK    label   near 
                mov     cl, 4 
                shr     di, cl          ; $$$ Do not destroy CL $$$ 
                inc     di              ; DI = Stack size in paragraphs 
                cmp     bp, di 
                jnb     ExcessOfMemory  ; Much more available than needed 
ELSE 
                mov     dx, ds 
                sub     bp, dx          ; BP = remaining size in paragraphs 
                mov     di, _stklen@    ; DI = Requested stack size 
; 
; Make sure that the requested stack size is at least MINSTACK words. 
; 
                cmp     di, 2*MINSTACK  ; requested stack big enough ? 
                jae     AskedStackOK 
                mov     di, 2*MINSTACK  ; no --> use minimal value 
                mov     _stklen@, di    ; override requested stack size 
AskedStackOK    label   near 
                add     di, offset DGROUP: edata@ 
                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes 
                add     di, _heaplen@ 
                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes 
                mov     cl, 4 
                shr     di, cl          ; $$$ Do not destroy CL $$$ 
                inc     di              ; DI = DS size in paragraphs 
                cmp     bp, di 
                jb      InitFailed      ; Not enough memory 
                cmp     _stklen@, 0 
                je      ExpandDS        ; Expand DS up to 64 Kb 
                cmp     _heaplen@, 0 
                jne     ExcessOfMemory  ; Much more available than needed 
ExpandDS        label   near 
                mov     di, 1000h 
                cmp     bp, di 
                ja      ExcessOfMemory  ; Enough to run the program 
                mov     di, bp 
                jmp     short ExcessOfMemory  ; Enough to run the program 
ENDIF 
 
;       All initialization errors arrive here 
 
InitFailed      label   near 
                jmp     near ptr abort@ 
 
;       Return to DOS the amount of memory in excess 
;       Set far heap base and pointer 
 
ExcessOfMemory  label   near 
                mov     bx, di 
                add     bx, dx 
                mov     word ptr _heapbase@ + 2, bx 
                mov     word ptr _brklvl@ + 2, bx 
                mov     ax, _psp@ 
                sub     bx, ax          ; BX = Number of paragraphs to keep 
                mov     es, ax          ; ES = Program Segment Prefix address 
                mov     ah, 04Ah 
                push    di              ; preserve DI 
                int     021h            ; this call clobbers SI,DI,BP !!!!!! 
                pop     di              ; restore  DI 
; 
;	Set the program stack.  Take care to prevent the disastrous 
;	interrupt that could happen with a stack that is half switched. 
; 
                shl     di, cl          ; $$$ CX is still equal to 4 $$$ 
 
		cli 
                mov     ss, dx 
                mov     sp, di 
		sti 
 
IFNDEF  __HUGE__ 
 
;       Reset uninitialized data area 
 
                xor     ax, ax 
                mov     es, cs:DGROUP@@ 
                mov     di, offset DGROUP: bdata@ 
                mov     cx, offset DGROUP: edata@ 
                sub     cx, di 
	        rep     stosb 
ENDIF 
 
IFNDEF  __NOFLOAT__ 
 
;       Install floating point software 
 
                push    cs              ;Simulation of a FAR call 
                call    ds:[__emu1st] 
ENDIF 
 
;       Prepare main arguments 
 
                call    _setargv@ 
                call    _setenvp@ 
 
                mov	ah, 0 
                int	1ah			; get current BIOS time in ticks 
                mov	word ptr _StartTime@,dx	; save it for clock() fn 
                mov	word ptr _StartTime@+2,cx 
 
IFNDEF  __OLDCONIO__ 
IF      LPROG 
                push    cs              ; Simulation of a FAR call 
ENDIF 
                call    ds:[__crt1st]   ; Initialize window sizes, etc. 
ENDIF 
 
;       ExitCode = main(argc,argv,envp); 
 
IF      LDATA 
                push    word ptr environ@+2 
                push    word ptr environ@ 
                push    word ptr _argv@+2 
                push    word ptr _argv@ 
ELSE 
                push    word ptr environ@ 
                push    word ptr _argv@ 
ENDIF 
                push    _argc@ 
                call    main@ 
 
;       Flush and close streams and files 
 
                push    ax 
                call    exit@ 
 
;--------------------------------------------------------------------------- 
;	_exit() 
; 
;       Restore interrupt vectors taken during startup.  signal() functions 
;	could have grabbed vectors 0, 4, 5 or 6. 
; 
;	Check for NULL pointer errors. 
; 
;	Exit to DOS. 
; 
;NOTE : _exit() doesn't close any files or run exit functions.  This is a 
;	minimal 'cleanup & quit' program exit. 
;--------------------------------------------------------------------------- 
PubProc@        _exit,  __CDECL__ 
                mov     ds, cs:DGROUP@@ 
 
IF      LPROG 
                call    far ptr _restorezero@	; restore captured INT vectors 
ELSE 
                call    near ptr _restorezero@ 
ENDIF 
 
IFNDEF  __NOFLOAT__ 
 
;       Restore interrupt vectors taken by __emu1st 
 
                push    cs              ;Simulation of a FAR call 
                call    ds:[__emuLast] 
ENDIF 
 
IF      LDATA EQ false 
IFNDEF  __TINY__ 
 
;       Check for null pointers before exit 
 
                xor     ax, ax 
                mov     si, ax 
                mov     cx, lgth_CopyRight 
                cld 
ComputeChecksum label   near 
                add     al, [si] 
                adc     ah, 0 
                inc     si 
                loop    ComputeChecksum 
                sub     ax, CheckSum 
                jz      ExitToDOS 
                mov     cx, lgth_NullCheck 
                mov     dx, offset DGROUP: NullCheck 
                call    ErrorDisplay 
ENDIF 
ENDIF 
 
;       Exit to DOS 
 
ExitToDOS       label   near 
                mov     bp,sp 
                mov     ah,4Ch 
                mov     al,[bp+cPtrSize] 
                int     21h                     ; Exit to DOS 
EndProc@        _exit, __CDECL__ 
STARTX          ENDP 
 
        SUBTTL  Vector save/restore & default Zero divide routines 
        PAGE 
;[]------------------------------------------------------------[] 
;|                                                              | 
;| Interrupt Save/Restore routines and default divide by zero   | 
;| handler.                                                     | 
;|                                                              | 
;[]------------------------------------------------------------[] 
 
ZeroDivision    PROC    FAR 
                mov     cx, lgth_ZeroDivMSG 
                mov     dx, offset DGROUP: ZeroDivMSG 
                jmp     MsgExit3 
ZeroDivision    ENDP 
 
;-------------------------------------------------------------------------- 
;	savevectors() 
; 
;	Save vectors for 0, 4, 5 & 6 interrupts.  This is for extended 
;	signal()/raise() support as the signal functions can steal these 
;	vectors during runtime. 
;-------------------------------------------------------------------------- 
SaveVectors	PROC    NEAR 
                push    ds 
; Save INT 0 
                mov     ax, 3500h 
                int     021h 
                mov     word ptr _Int0Vector@, bx 
                mov     word ptr _Int0Vector@+2, es 
; Save INT 4 
                mov     ax, 3504h 
                int     021h 
                mov     word ptr _Int4Vector@, bx 
                mov     word ptr _Int4Vector@+2, es 
; Save INT 5 
                mov     ax, 3505h 
                int     021h 
                mov     word ptr _Int5Vector@, bx 
                mov     word ptr _Int5Vector@+2, es 
; Save INT 6 
                mov     ax, 3506h 
                int     021h 
                mov     word ptr _Int6Vector@, bx 
                mov     word ptr _Int6Vector@+2, es 
; 
;	Install default divide by zero handler. 
; 
                mov     ax, 2500h 
                mov     dx, cs 
                mov     ds, dx 
                mov     dx, offset ZeroDivision 
                int     21h 
 
                pop     ds 
                ret 
SaveVectors	ENDP 
 
;-------------------------------------------------------------------------- 
;	restorezero() puts back all the vectors that SaveVectors took. 
; 
;NOTE : TSRs must BE AWARE that signal() functions which take these  
;	vectors will be deactivated if the keep() function is executed. 
;	If a TSR wants to use the signal functions when it is active it  
;	will have to save/restore these vectors itself when activated and 
;	deactivated. 
;-------------------------------------------------------------------------- 
PubProc@        _restorezero, __CDECL__ 
 
IFDEF   __HUGE__ 
                push    ds 
                mov     ds, cs: DGROUP@@ 
ENDIF 
                push    ds 
                mov     ax, 2500h 
                lds     dx, _Int0Vector@ 
                int     21h 
		pop	ds 
 
		push	ds 
                mov     ax, 2504h 
                lds     dx, _Int4Vector@ 
                int     21h 
		pop	ds 
 
		push	ds 
                mov     ax, 2505h 
                lds     dx, _Int5Vector@ 
                int     21h 
		pop	ds 
 
IFNDEF   __HUGE__ 
		push	ds 
ENDIF 
                mov     ax, 2506h 
                lds     dx, _Int6Vector@ 
                int     21h 
                pop     ds 
 
                ret 
EndProc@        _restorezero, __CDECL__ 
 
        SUBTTL  Miscellaneous 
        PAGE 
;[]------------------------------------------------------------[] 
;|                                                              | 
;|      Miscellaneous functions                                 | 
;|                                                              | 
;[]------------------------------------------------------------[] 
 
IFNDEF  __NOFLOAT__ 
NoEmulator      PROC    FAR 
                mov     _8087@, 0 
                ret 
NoEmulator      ENDP 
ENDIF 
 
IFNDEF  __OLDCONIO__ 
Proc@           NoConsole, __CDECL__ 
                ret 
EndProc@        NoConsole, __CDECL__ 
ENDIF 
 
ErrorDisplay    PROC    NEAR 
                mov     ah, 040h 
                mov     bx, 2 
                int     021h 
                ret 
ErrorDisplay    ENDP 
 
PubProc@        abort,  __CDECL__ 
                mov     cx, lgth_abortMSG 
                mov     dx, offset DGROUP: abortMSG 
MsgExit3        label   near 
                mov     ds, cs: DGROUP@@ 
                call    ErrorDisplay 
CallExit3       label   near 
                mov     ax, 3 
                push    ax 
                call    _exit@          ; _exit(3); 
EndProc@        abort, __CDECL__ 
 
;       The DGROUP@ variable is used to reload DS with DGROUP 
 
PubSym@ DGROUP@, , __PASCAL__ 
_TEXT   ENDS 
 
        SUBTTL  Start Up Data Area 
        PAGE 
;[]------------------------------------------------------------[] 
;|      Start Up Data Area                                      | 
;|                                                              | 
;|      WARNING         Do not move any variables in the data   | 
;|                      segment unless you're absolutely sure   | 
;|                      that it does not matter.                | 
;|                                                              | 
;[]------------------------------------------------------------[] 
 
_DATA   SEGMENT 
 
;       The CopyRight string must NOT be moved or changed without 
;       changing the null pointer check logic 
 
CopyRight       db      4 dup(0) 
                db      'Turbo-C - Copyright (c) 1988 Borland Intl.',0 
lgth_CopyRight  equ     $ - CopyRight 
 
IF      LDATA EQ false 
IFNDEF  __TINY__ 
CheckSum        equ     00D37h 
NullCheck       db      'Null pointer assignment', 13, 10 
lgth_NullCheck  equ     $ - NullCheck 
ENDIF 
ENDIF 
 
ZeroDivMSG      db      'Divide error', 13, 10 
lgth_ZeroDivMSG equ     $ - ZeroDivMSG 
 
abortMSG        db      'Abnormal program termination', 13, 10 
lgth_abortMSG   equ     $ - abortMSG 
 
; 
;			Interrupt vector save areas 
;	 
;	Interrupt vectors 0,4,5 & 6 are saved at startup and then restored 
;	when the program terminates.  The signal/raise functions might 
;	steal these vectors during execution. 
; 
PubSym@         _Int0Vector	
, __CDECL__ PubSym@ _Int4Vector
, __CDECL__ PubSym@ _Int5Vector
, __CDECL__ PubSym@ _Int6Vector
, __CDECL__ ; ; Miscellaneous variables ; PubSym@ _argc, , __CDECL__ dPtrPub@ _argv, 0, __CDECL__ dPtrPub@ environ, 0, __CDECL__ PubSym@ _envLng, , __CDECL__ PubSym@ _envseg, , __CDECL__ PubSym@ _envSize, , __CDECL__ PubSym@ _psp, , __CDECL__ PubSym@ _version,
, __CDECL__ PubSym@ _brklvl,
, __CDECL__ PubSym@ _heaptop,
, __CDECL__ IF LDATA EQ false IFNDEF __NOFLOAT__ ; Emulator variables INCLUDE emuvars.asi ENDIF ENDIF _DATA ENDS IFNDEF __NOFLOAT__ _EMUSEG SEGMENT __emu1st dw NoEmulator __emuLast dw NoEmulator _EMUSEG ENDS ENDIF IFNDEF __OLDCONIO__ _CRTSEG SEGMENT __crt1st dw NoConsole@ _CRTSEG ENDS ENDIF _CVTSEG SEGMENT PubSym@ _RealCvtVector,