home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / b / bc3.zip / BC3C0.ASM < prev    next >
Assembly Source File  |  1992-02-12  |  28KB  |  844 lines

  1.         NAME    c0
  2.         PAGE    60,132
  3.         LOCALS
  4. ;[]------------------------------------------------------------[]
  5. ;|      C0.ASM -- Start Up Code                                 |
  6. ;|                                                              |
  7. ;|      Turbo C++ Run Time Library                              |
  8. ;|                                                              |
  9. ;|      Copyright (c) 1987, 1991 by Borland International Inc.  |
  10. ;|      All Rights Reserved.                                    |
  11. ;[]------------------------------------------------------------[]
  12.  
  13.                 __C0__ = 1
  14. INCLUDE         RULES.ASI
  15.  
  16. ;       Segment and Group declarations
  17.  
  18. _TEXT           SEGMENT BYTE PUBLIC 'CODE'
  19.                 ENDS
  20. _FARDATA        SEGMENT PARA PUBLIC 'FAR_DATA'
  21.                 ENDS
  22. _FARBSS         SEGMENT PARA PUBLIC 'FAR_BSS'
  23.                 ENDS
  24. IFNDEF __TINY__
  25. _OVERLAY_       SEGMENT PARA PUBLIC 'OVRINFO'
  26.         ENDS
  27. _1STUB_     SEGMENT PARA PUBLIC 'STUBSEG'
  28.         ENDS
  29. ENDIF
  30. _DATA           SEGMENT PARA PUBLIC 'DATA'
  31.                 ENDS
  32. _INIT_          SEGMENT WORD PUBLIC 'INITDATA'
  33. InitStart       label byte
  34.                 ENDS
  35. _INITEND_       SEGMENT BYTE PUBLIC 'INITDATA'
  36. InitEnd         label byte
  37.                 ENDS
  38. _EXIT_          SEGMENT WORD PUBLIC 'EXITDATA'
  39. ExitStart       label byte
  40.                 ENDS
  41. _EXITEND_       SEGMENT BYTE PUBLIC 'EXITDATA'
  42. ExitEnd         label byte
  43.                 ENDS
  44. _CVTSEG         SEGMENT WORD PUBLIC 'DATA'
  45.                 ENDS
  46. _SCNSEG         SEGMENT WORD PUBLIC 'DATA'
  47.                 ENDS
  48. IFNDEF __HUGE__
  49.   _BSS          SEGMENT WORD PUBLIC 'BSS'
  50.                 ENDS
  51.   _BSSEND       SEGMENT BYTE PUBLIC 'BSSEND'
  52.                 ENDS
  53. ENDIF
  54. IFNDEF __TINY__
  55.   _STACK        SEGMENT STACK 'STACK'
  56.                 ENDS
  57. ENDIF
  58.  
  59.         ASSUME  CS:_TEXT, DS:DGROUP
  60.  
  61. ;       External References
  62.  
  63. extrn       _main:DIST
  64. extrn       _exit:DIST
  65. extrn       __exit:DIST
  66. extrn       __nfile:word
  67. extrn       __setupio:near          ;required!
  68. extrn       __stklen:word
  69. IF LDATA EQ false
  70. extrn       __heaplen:word
  71. ENDIF
  72.  
  73.         SUBTTL  Start Up Code
  74.         PAGE
  75. ;/*                                                     */
  76. ;/*-----------------------------------------------------*/
  77. ;/*                                                     */
  78. ;/*     Start Up Code                                   */
  79. ;/*     -------------                                   */
  80. ;/*                                                     */
  81. ;/*-----------------------------------------------------*/
  82. ;/*                                                     */
  83. PSPHigh         equ     00002h
  84. PSPEnv          equ     0002ch
  85. PSPCmd          equ     00080h
  86.  
  87.                 public  __AHINCR
  88. __AHINCR        equ     1000h
  89.                 public  __AHSHIFT
  90. __AHSHIFT       equ     12
  91.  
  92. IFDEF   __NOFLOAT__
  93. MINSTACK        equ     128     ; minimal stack size in words
  94. ELSE
  95. MINSTACK        equ     256     ; minimal stack size in words
  96. ENDIF
  97. ;
  98. ;       At the start, DS and ES both point to the segment prefix.
  99. ;       SS points to the stack segment except in TINY model where
  100. ;       SS is equal to CS
  101. ;
  102. _TEXT           SEGMENT
  103. IFDEF           __TINY__
  104.                 ORG     100h
  105. ENDIF
  106. STARTX          PROC    NEAR
  107. ;       Save general information, such as :
  108. ;               DGROUP segment address
  109. ;               DOS version number
  110. ;               Program Segment Prefix address
  111. ;               Environment address
  112. ;               Top of far heap
  113.  
  114. IFDEF   __TINY__
  115.                 mov     dx, cs          ; DX = GROUP Segment address
  116. ELSE
  117.                 mov     dx, DGROUP      ; DX = GROUP Segment address
  118. ENDIF
  119. IFNDEF    __BOSS__
  120.                 mov     cs:DGROUP@@, dx ;  __BOSS__
  121. ENDIF
  122.                 mov     ah, 30h
  123.                 int     21h             ; get DOS version number
  124.                 mov     bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr
  125.                 mov     bx, ds:[PSPEnv] ; BX = Environment Segment address
  126.                 mov     ds, dx
  127.                 mov     _version@, ax   ; Keep major and minor version number
  128.                 mov     _psp@, es       ; Keep Program Segment Prefix address
  129.                 mov     _envseg@, bx    ; Keep Environment Segment address
  130.                 mov     word ptr _heaptop@ + 2, bp
  131. ;
  132. ;       Save several vectors and install default divide by zero handler.
  133. ;
  134.                 call    SaveVectors
  135.  
  136. IFDEF    __BOSS__
  137. ; Determine if in real mode
  138.             mov    ax,0FB42h    ; find out if DPMI loader is here
  139.         mov    bx,1        ; get info function
  140.         int    2fh        ;
  141.  
  142.         push    ax        ;
  143.         mov    ax, cs        ; now, save DGROUP
  144.         add    ax, cx        ;
  145.         mov    es, ax        ;
  146.         mov    dx, ds        ;
  147.         mov    es:DGROUP@@, dx     ;
  148.         mov    es:CSalias@@, ax ;
  149.         pop    ax         ;
  150.  
  151. ;        cmp    ax,0001h    ; if not "TRUE"
  152. ;        JNE    InRealMode
  153.  
  154. ; 8 is the value of the alias selector
  155. ; in this system
  156.         MOV    _protected@, cx
  157.         MOV    _hugeincval@, cx
  158.         clc
  159.         mov    ax, cx
  160.         xor    cx, cx
  161.         or    ax, ax
  162.         je    @@gotshift
  163. @@shiftcnt:
  164.         rcr    ax,1
  165.         jc    @@gotshift
  166.         inc    cx
  167.         jmp    @@shiftcnt        
  168. @@gotshift:
  169.         mov    _shiftcount@,cx
  170.  
  171. ; used by emulator
  172. ;        PUSH    DS
  173. ;        MOV    AX, 0E502H      ; prot kernel function, get LDT alias
  174. ;        INT    21H
  175. ;        POP    DS
  176. ;        MOV    _LDT@, AX
  177.  
  178. ;        cmp    _protected@,0001h    ; if not "TRUE"
  179. ;        JNE    InRealMode
  180.  
  181.         .286P
  182. IFE    LDATA                    
  183.         mov    dx, ds            ;
  184. ;        LSL    AX, DX            ;
  185. ;        DEC    AX            ;
  186.         MOV    AX, 0FFFEh        ;
  187.         MOV    SP, AX            ;
  188.         MOV    SS, DX            ;
  189. ENDIF                        
  190.         .8086
  191. ;        JMP    BossSkip
  192.  
  193. InRealMode    label    near
  194.  
  195. ENDIF
  196.  
  197. ;       Count the number of environment variables and compute the size.
  198. ;       Each variable is ended by a 0 and a zero-length variable stops
  199. ;       the environment. The environment can NOT be greater than 32k.
  200.  
  201.                 les     di, dword ptr _envLng@
  202.                 mov     ax, di
  203.                 mov     bx, ax
  204.                 mov     cx, 07FFFh      ; Environment cannot be > 32 Kbytes
  205.                 cld
  206. @@EnvLoop:
  207.                 repnz   scasb
  208.                 jcxz    InitFailed      ; Bad environment !!!
  209. IFDEF __BOSS__
  210.                 jmp     InitOK
  211. InitFailed:     jmp     near ptr _abort
  212. InitOK:
  213. ENDIF
  214.      
  215.                 inc     bx              ; BX = Nb environment variables
  216.                 cmp     es:[di], al
  217.                 jne     @@EnvLoop       ; Next variable ...
  218.                 or      ch, 10000000b
  219.                 neg     cx
  220.                 mov     _envLng@, cx    ; Save Environment size
  221.                 mov     cx, dPtrSize / 2
  222.                 shl     bx, cl
  223.                 add     bx, dPtrSize * 4
  224.                 and     bx, not ((dPtrSize * 4) - 1)
  225.                 mov     _envSize@, bx   ; Save Environment Variables Nb.
  226.  
  227. IFNDEF __BOSS__
  228.  
  229. ;       Determine the amount of memory that we need to keep
  230.  
  231. IFDEF _DSSTACK_
  232.                 mov     dx, ds
  233. ELSE
  234.                 mov     dx, ss
  235. ENDIF
  236.                 sub     bp, dx          ; BP = remaining size in paragraphs
  237. IF LDATA
  238.                 mov     di, seg __stklen
  239.                 mov     es, di
  240.                 mov     di, es:__stklen ; DI = Requested stack size
  241. ELSE
  242.                 mov     di, __stklen    ; DI = Requested stack size
  243. ENDIF
  244. ;
  245. ; Make sure that the requested stack size is at least MINSTACK words.
  246. ;
  247.                 cmp     di, 2*MINSTACK  ; requested stack big enough ?
  248.                 jae     AskedStackOK
  249.                 mov     di, 2*MINSTACK  ; no --> use minimal value
  250. IF LDATA
  251.                 mov     es:__stklen, di ; override requested stack size
  252. ELSE
  253.                 mov        __stklen, di ; override requested stack size
  254. ENDIF
  255.  
  256. AskedStackOK    label   near
  257. IFDEF _DSSTACK_
  258.                 add     di, offset DGROUP: edata@
  259.                 jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes
  260. ENDIF
  261. IF LDATA EQ false
  262.                 add     di, __heaplen
  263.                 jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes
  264. ENDIF
  265.                 mov     cl, 4
  266.                 shr     di, cl          ; $$$ Do not destroy CL $$$
  267.                 inc     di              ; DI = DS size in paragraphs
  268.                 cmp     bp, di
  269. IF LDATA EQ false
  270.                 jb      InitFailed      ; Not enough memory
  271.                 cmp     __stklen, 0
  272.                 je      ExpandDS        ; Expand DS up to 64 Kb
  273.                 cmp     __heaplen, 0
  274.                 jne     ExcessOfMemory  ; Much more available than needed
  275. ExpandDS        label   near
  276.                 mov     di, 1000h
  277.                 cmp     bp, di
  278.                 ja      ExcessOfMemory  ; Enough to run the program
  279.                 mov     di, bp
  280.                 jmp     short ExcessOfMemory  ; Enough to run the program
  281. ELSE
  282.                 jnb     ExcessOfMemory  ; Much more available than needed
  283. ENDIF
  284.  
  285. ;       All initialization errors arrive here
  286.  
  287. InitFailed      label   near
  288.                 jmp     near ptr _abort
  289.  
  290. ;       Return to DOS the amount of memory in excess
  291. ;       Set far heap base and pointer
  292.  
  293. ExcessOfMemory  label   near
  294.                 mov     bx, di
  295.                 add     bx, dx
  296.                 mov     word ptr _heapbase@ + 2, bx
  297.                 mov     word ptr _brklvl@ + 2, bx
  298.                 mov     ax, _psp@
  299.                 sub     bx, ax          ; BX = Number of paragraphs to keep
  300.                 mov     es, ax          ; ES = Program Segment Prefix address
  301.                 mov     ah, 04Ah
  302.                 push    di              ; preserve DI
  303.                 int     021h            ; this call clobbers SI,DI,BP !!!!!!
  304.                 pop     di              ; restore  DI
  305.  
  306.                 shl     di, cl          ; $$$ CX is still equal to 4 $$$
  307.  
  308.                 cli                     ; req'd for pre-1983 88/86s
  309.                 mov     ss, dx          ; Set the program stack
  310.                 mov     sp, di
  311.                 sti
  312.  
  313. IFNDEF _DSSTACK_
  314.                 mov     ax, seg __stklen
  315.                 mov     es, ax
  316.                 mov     es:__stklen, di ; If separate stack segment, save size
  317. ENDIF
  318.  
  319. ENDIF ; __BOSS__
  320.  
  321. IFNDEF  __HUGE__
  322.  
  323. ;       Reset uninitialized data area
  324.  
  325.                 xor     ax, ax
  326.                 mov     es, cs:DGROUP@@
  327.                 mov     di, offset DGROUP: bdata@
  328.                 mov     cx, offset DGROUP: edata@
  329.                 sub     cx, di
  330.                 cld
  331.                 rep     stosb
  332. ENDIF
  333.  
  334. ;   If default number of file handles have changed then tell DOS
  335.                 cmp     __nfile, 20
  336.                 jbe     @@NoChange
  337.  
  338.                 cmp     _osmajor@, 3   ; Check for >= DOS 3.3
  339.                 jb      @@NoChange
  340.                 ja      @@DoChange
  341.                 cmp     _osminor@, 1Eh
  342.                 jb      @@NoChange
  343. @@DoChange:
  344.                 mov     ax, 5801h      ; Set last fit allocation
  345.                 mov     bx, 2
  346.                 int     21h
  347.                 jc      @@BadInit
  348.  
  349.                 mov     ah, 67h        ; Expand handle table
  350.                 mov     bx, __nfile
  351.                 int     21h
  352.                 jc      @@BadInit
  353.  
  354.                 mov     ah, 48h        ; Allocate 16 bytes to find new
  355.                 mov     bx, 1          ;   top of memory address
  356.                 int     21h
  357.                 jc      @@BadInit
  358.                 inc     ax             ; Adjust address to point after block
  359.                 mov     word ptr _heaptop@ + 2, ax
  360.  
  361.                 dec     ax             ; Change back and release block
  362.                 mov     es, ax
  363.                 mov     ah, 49h
  364.                 int     21h
  365.                 jc      @@BadInit
  366.  
  367.                 mov     ax, 5801h      ; Set first fit allocation
  368.                 mov     bx, 0
  369.                 int     21h
  370.                 jnc     @@NoChange
  371.  
  372. @@BadInit:      jmp near ptr _abort
  373.  
  374. @@NoChange:
  375.  
  376. ;       Prepare main arguments
  377.  
  378.                 mov     ah, 0
  379.                 int     1ah                     ; get current BIOS time in ticks
  380.                 mov     word ptr _StartTime@,dx ; save it for clock() fn
  381.                 mov     word ptr _StartTime@+2,cx
  382.         or    al,al            ; was midnight flag set?
  383.         jz    @@NotMidnight
  384.         mov    ax,40h            ; set BIOS midnight flag
  385.         mov    es,ax            ;  at 40:70
  386.         mov    bx,70h
  387.         mov    byte ptr es:[bx],1
  388.             
  389. @@NotMidnight:
  390.                 xor     bp,bp                   ; set BP to 0 for overlay mgr
  391.  
  392.                 mov     es, cs:DGROUP@@
  393.                 mov     si,offset DGROUP:InitStart      ;si = start of table
  394.                 mov     di,offset DGROUP:InitEnd        ;di = end of table
  395.                 call    StartExit
  396.  
  397. ;       ExitCode = main(argc,argv,envp);
  398.  
  399. IF      LDATA
  400.                 push    word ptr __C0environ+2
  401.                 push    word ptr __C0environ
  402.                 push    word ptr __C0argv+2
  403.                 push    word ptr __C0argv
  404. ELSE
  405.                 push    word ptr __C0environ
  406.                 push    word ptr __C0argv
  407. ENDIF
  408.                 push    __C0argc
  409.                 call    _main
  410.  
  411. ;       Flush and close streams and files
  412.  
  413.                 push    ax
  414.                 call    _exit
  415.  
  416. ;---------------------------------------------------------------------------
  417. ;       _cleanup()      call all #pragma exit cleanup routines.
  418. ;       _checknull()    check for null pointer zapping copyright message
  419. ;       _terminate(int) exit program with error code
  420. ;
  421. ;       These functions are called by exit(), _exit(), _cexit(),
  422. ;       and _c_exit().
  423. ;---------------------------------------------------------------------------
  424.  
  425. ;       Call cleanup routines
  426.  
  427. __cleanup       PROC    DIST
  428.                 PUBLIC  __cleanup
  429.  
  430.                 mov     es, cs:DGROUP@@
  431.                 push    si
  432.                 push    di
  433.                 mov     si,offset DGROUP:ExitStart
  434.                 mov     di,offset DGROUP:ExitEnd
  435.                 call    StartExit
  436.                 pop     di
  437.                 pop     si
  438.                 ret
  439. __cleanup       ENDP
  440.  
  441. ;       Check for null pointers before exit
  442.  
  443. __checknull     PROC    DIST
  444.                 PUBLIC  __checknull
  445.  
  446. IF      LDATA EQ false
  447.   IFNDEF  __TINY__
  448.                 push    si
  449.                 push    di
  450.                 mov     es, cs:DGROUP@@
  451.                 xor     ax, ax
  452.                 mov     si, ax
  453.                 mov     cx, lgth_CopyRight
  454. ComputeChecksum label   near
  455.                 add     al, es:[si]
  456.                 adc     ah, 0
  457.                 inc     si
  458.                 loop    ComputeChecksum
  459.                 sub     ax, CheckSum
  460.                 jz      @@SumOk
  461.                 mov     cx, lgth_NullCheck
  462.                 mov     dx, offset DGROUP: NullCheck
  463.                 call    ErrorDisplay
  464. @@SumOK:        pop     di
  465.                 pop     si
  466.   ENDIF
  467. ENDIF
  468.                 ret
  469. __checknull     ENDP
  470.  
  471. ;       Exit to DOS
  472.  
  473. __terminate     PROC    DIST
  474.                 PUBLIC  __terminate
  475.                 mov     bp,sp
  476.                 mov     ah,4Ch
  477.                 mov     al,[bp+cPtrSize]
  478.                 int     21h                     ; Exit to DOS
  479. __terminate     ENDP
  480.  
  481. STARTX          ENDP
  482.  
  483.         SUBTTL  Vector save/restore & default Zero divide routines
  484.         PAGE
  485. ;[]------------------------------------------------------------[]
  486. ;|                                                              |
  487. ;| Interrupt Save/Restore routines and default divide by zero   |
  488. ;| handler.                                                     |
  489. ;|                                                              |
  490. ;[]------------------------------------------------------------[]
  491.  
  492. ZeroDivision    PROC    FAR
  493.                 mov     cx, lgth_ZeroDivMSG
  494.                 mov     dx, offset DGROUP: ZeroDivMSG
  495.                 jmp     MsgExit3
  496. ZeroDivision    ENDP
  497.  
  498. ;--------------------------------------------------------------------------
  499. ;       savevectors()
  500. ;
  501. ;       Save vectors for 0, 4, 5 & 6 interrupts.  This is for extended
  502. ;       signal()/raise() support as the signal functions can steal these
  503. ;       vectors during runtime.
  504. ;--------------------------------------------------------------------------
  505. SaveVectors     PROC    NEAR
  506.                 push    ds
  507. ; Save INT 0
  508.                 mov     ax, 3500h
  509.                 int     021h
  510.                 mov     word ptr _Int0Vector@, bx
  511.                 mov     word ptr _Int0Vector@+2, es
  512. ; Save INT 4
  513.                 mov     ax, 3504h
  514.                 int     021h
  515.                 mov     word ptr _Int4Vector@, bx
  516.                 mov     word ptr _Int4Vector@+2, es
  517. ; Save INT 5
  518.                 mov     ax, 3505h
  519.                 int     021h
  520.                 mov     word ptr _Int5Vector@, bx
  521.                 mov     word ptr _Int5Vector@+2, es
  522. ; Save INT 6
  523.                 mov     ax, 3506h
  524.                 int     021h
  525.                 mov     word ptr _Int6Vector@, bx
  526.                 mov     word ptr _Int6Vector@+2, es
  527. ;
  528. ;       Install default divide by zero handler.
  529. ;
  530.                 mov     ax, 2500h
  531.                 mov     dx, cs
  532.                 mov     ds, dx
  533.                 mov     dx, offset ZeroDivision
  534.                 int     21h
  535.  
  536.                 pop     ds
  537.                 ret
  538. SaveVectors     ENDP
  539.  
  540. ;--------------------------------------------------------------------------
  541. ;       _restorezero() puts back all the vectors that SaveVectors took.
  542. ;
  543. ;NOTE : TSRs must BE AWARE that signal() functions which take these 
  544. ;       vectors will be deactivated if the keep() function is executed.
  545. ;       If a TSR wants to use the signal functions when it is active it 
  546. ;       will have to save/restore these vectors itself when activated and
  547. ;       deactivated.
  548. ;--------------------------------------------------------------------------
  549. __restorezero   PROC    DIST
  550.                 PUBLIC  __restorezero
  551. IFDEF   __HUGE__
  552.                 push    ds
  553.                 mov     ds, cs: DGROUP@@
  554. ENDIF
  555.         mov    ax, 1686h        ;; test mode
  556.         int    2fh
  557.         or    al, al
  558.         jz    unhookProt
  559.  
  560.                 push    ds
  561.                 mov     ax, 2500h
  562.                 lds     dx, _Int0Vector@
  563.                 int     21h
  564.                 pop     ds
  565.  
  566.                 push    ds
  567.                 mov     ax, 2504h
  568.                 lds     dx, _Int4Vector@
  569.                 int     21h
  570.                 pop     ds
  571.  
  572.                 push    ds
  573.                 mov     ax, 2505h
  574.                 lds     dx, _Int5Vector@
  575.                 int     21h
  576.                 pop     ds
  577.  
  578. IFNDEF   __HUGE__
  579.                 push    ds
  580. ENDIF
  581.                 mov     ax, 2506h
  582.                 lds     dx, _Int6Vector@
  583.                 int     21h
  584.                 pop     ds
  585.         jmp    __rzeroExit
  586. unhookProt:
  587.                 mov     ax, 201h
  588.         mov    bl, 0
  589.                 mov     dx, word ptr _Int0Vector@
  590.                 mov     cx, word ptr _Int0Vector@+2
  591.                 int     31h
  592.  
  593.                 mov     ax, 201h
  594.         mov    bl, 4
  595.                 mov     dx, word ptr _Int4Vector@
  596.                 mov     cx, word ptr _Int4Vector@+2
  597.                 int     31h
  598.  
  599.                 mov     ax, 201h
  600.         mov    bl, 5
  601.                 mov     dx, word ptr _Int5Vector@
  602.                 mov     cx, word ptr _Int5Vector@+2
  603.                 int     31h
  604.         
  605.                 mov     ax, 201h
  606.         mov    bl, 6
  607.                 mov     dx, word ptr _Int6Vector@
  608.                 mov     cx, word ptr _Int6Vector@+2
  609.                 int     31h
  610. __rzeroExit:
  611.                 ret
  612.                 ENDP
  613.  
  614. ;------------------------------------------------------------------
  615. ;  Loop through a startup/exit (SE) table, 
  616. ;  calling functions in order of priority.
  617. ;  ES:SI is assumed to point to the beginning of the SE table
  618. ;  ES:DI is assumed to point to the end of the SE table
  619. ;  First 64 priorities are reserved by Borland
  620. ;------------------------------------------------------------------
  621. PNEAR           EQU     0
  622. PFAR            EQU     1
  623. NOTUSED         EQU     0ffh
  624.  
  625. SE              STRUC
  626. calltype        db      ?                       ; 0=near,1=far,ff=not used
  627. priority        db      ?                       ; 0=highest,ff=lowest
  628. addrlow         dw      ?
  629. addrhigh        dw      ?
  630. SE              ENDS
  631.  
  632. StartExit       proc near
  633. @@Start:        cmp     si,offset DGROUP:InitStart      ; startup or exit?
  634.                 je      @@StartLow              ; it's startup
  635.                 xor     ah,ah                   ; start with high priority
  636.                 jmp     short @@SaveEnd
  637. @@StartLow:     mov     ah,0ffh                 ;start with lowest priority
  638. @@SaveEnd:      mov     dx,di                   ;set sentinel to end of table
  639.                 mov     bx,si                   ;bx = start of table
  640.  
  641. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  642.                 je      @@EndOfTable            ;yes, exit the loop
  643.                 cmp     es:[bx.calltype],NOTUSED;check the call type
  644.                 je      @@Next
  645.                 cmp     si,offset DGROUP:InitStart      ; startup or exit?
  646.                 je      @@CompareHigh           ; it's startup
  647.                 cmp     ah,es:[bx.priority]     ; it's exit
  648.                 jmp     short @@CheckPrior      ; if priority too low, skip
  649. @@CompareHigh:  cmp     es:[bx.priority],ah     ;check the priority
  650. @@CheckPrior:   ja      @@Next                  ;too high?  skip
  651.                 mov     ah,es:[bx.priority]     ;keep priority
  652.                 mov     dx,bx                   ;keep index in dx
  653. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  654.                 jmp     @@TopOfTable
  655.  
  656. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  657.                 je      @@Done                  ;yes, quit
  658.                 mov     bx,dx                   ;bx = highest priority item
  659.                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  660.                 mov     es:[bx.calltype],NOTUSED;wipe the call type
  661.                 push    es                      ;save es
  662.                 je      @@NearCall
  663.  
  664. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  665.                 pop     es                      ;restore es
  666.                 jmp     short @@Start
  667.  
  668. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  669.                 pop     es                      ;restore es
  670.                 jmp     short @@Start
  671.  
  672. @@Done:         ret
  673.                 endp
  674.  
  675. ;------------------------------------------------------------------
  676.  
  677. ErrorDisplay    PROC    NEAR
  678.                 mov     ah, 040h
  679.                 mov     bx, 2
  680.                 int     021h
  681.                 ret
  682. ErrorDisplay    ENDP
  683.  
  684. _abort          PROC    DIST
  685.                 PUBLIC  _abort
  686.                 mov     cx, lgth_abortMSG
  687.                 mov     dx, offset DGROUP: abortMSG
  688. MsgExit3        label   near
  689.                 mov     ds, cs: DGROUP@@
  690.                 call    ErrorDisplay
  691. CallExit3       label   near
  692.                 mov     ax, 3
  693.                 push    ax
  694.                 call    __exit           ; _exit(3);
  695.                 ENDP
  696.  
  697. ; The DGROUP@ variable is used to reload DS with DGROUP
  698.  
  699. PubSym@         DGROUP@, <dw    _TEXT>, __PASCAL__
  700.  
  701. IFDEF    __BOSS__
  702. PubSym@        CSalias@,<dw    ?>, __PASCAL__
  703. ENDIF
  704.  
  705.  
  706. ; __MMODEL is used to determine the memory model or the default
  707. ; pointer types at run time.
  708.  
  709.                 public __MMODEL
  710. __MMODEL        dw      MMODEL
  711.  
  712. _TEXT           ENDS
  713.  
  714.                 SUBTTL  Start Up Data Area
  715.                 PAGE
  716. ;[]------------------------------------------------------------[]
  717. ;|      Start Up Data Area                                      |
  718. ;|                                                              |
  719. ;|      WARNING         Do not move any variables in the data   |
  720. ;|                      segment unless you're absolutely sure   |
  721. ;|                      that it does not matter.                |
  722. ;[]------------------------------------------------------------[]
  723.  
  724. _DATA           SEGMENT
  725.  
  726. ;       Magic symbol used by the debug info to locate the data segment
  727.                 public DATASEG@
  728. DATASEG@        label   byte
  729.  
  730. ;       The CopyRight string must NOT be moved or changed without
  731. ;       changing the null pointer check logic
  732.  
  733. CopyRight       db      4 dup(0)
  734.                 db      'Borland C++ - Copyright 1991 Borland Intl.',0
  735. lgth_CopyRight  equ     $ - CopyRight
  736.  
  737. IF      LDATA EQ false
  738. IFNDEF  __TINY__
  739. CheckSum        equ     00D5Ch
  740. NullCheck       db      'Null pointer assignment', 13, 10
  741. lgth_NullCheck  equ     $ - NullCheck
  742. ENDIF
  743. ENDIF
  744.  
  745. ZeroDivMSG      db      'Divide error', 13, 10
  746. lgth_ZeroDivMSG equ     $ - ZeroDivMSG
  747.  
  748. abortMSG        db      'Abnormal program termination', 13, 10
  749. lgth_abortMSG   equ     $ - abortMSG
  750.  
  751. ;
  752. ;                       Interrupt vector save areas
  753. ;       
  754. ;       Interrupt vectors 0,4,5 & 6 are saved at startup and then restored
  755. ;       when the program terminates.  The signal/raise functions might
  756. ;       steal these vectors during execution.
  757. ;
  758. ;       Note: These vectors save area must not be altered 
  759. ;             without changing the save/restore logic.
  760. ;
  761. PubSym@         _Int0Vector     <dd     0>,             __CDECL__
  762. PubSym@         _Int4Vector     <dd     0>,             __CDECL__
  763. PubSym@         _Int5Vector     <dd     0>,             __CDECL__
  764. PubSym@         _Int6Vector     <dd     0>,             __CDECL__
  765. ;
  766. ;                       Miscellaneous variables
  767. ;       
  768. PubSym@         _C0argc,        <dw     0>,             __CDECL__
  769. dPtrPub@        _C0argv,        0,                      __CDECL__
  770. dPtrPub@        _C0environ,     0,                      __CDECL__
  771. PubSym@         _envLng,        <dw     0>,             __CDECL__
  772. PubSym@         _envseg,        <dw     0>,             __CDECL__
  773. PubSym@         _envSize,       <dw     0>,             __CDECL__
  774. PubSym@         _psp,           <dw     0>,             __CDECL__
  775. PubSym@         _version,       <label word>,           __CDECL__
  776. PubSym@         _osversion,     <label word>,           __CDECL__
  777. PubSym@         _osmajor,       <db     0>,             __CDECL__
  778. PubSym@         _osminor,       <db     0>,             __CDECL__
  779. PubSym@         errno,          <dw     0>,             __CDECL__
  780. PubSym@         _StartTime,     <dw   0,0>,             __CDECL__
  781.  
  782.  
  783. IFDEF __BOSS__
  784. PubSym@        _protected    <dw    0>,        __CDECL__
  785. PubSym@     _shiftcount,    <dw    12>,        __CDECL__
  786. PubSym@     _hugeincval,    <dw    1000h>,        __CDECL__
  787. ENDIF
  788.  
  789. ;       Memory management variables
  790.  
  791. IF      LDATA EQ false
  792. PubSym@         __heapbase,     <dw   DGROUP:edata@>,   __CDECL__
  793. ENDIF
  794. IFNDEF __HUGE__
  795. PubSym@         __brklvl,       <dw   DGROUP:edata@>,   __CDECL__
  796. ENDIF
  797. PubSym@         _heapbase,      <dd   0>,       __CDECL__
  798. PubSym@         _brklvl,        <dd   0>,       __CDECL__
  799. PubSym@         _heaptop,       <dd   0>,       __CDECL__
  800.  
  801. ;       If stack in DS and Large data model then override location of __emu
  802.  
  803. IFDEF   _DSSTACK_
  804. IF      LDATA
  805. public  __emu
  806. __emu   db      044h    DUP (0)
  807.         db      0CCh    DUP (?)
  808. ENDIF
  809. ENDIF
  810.  
  811. _DATA           ENDS
  812.  
  813.  
  814. _CVTSEG         SEGMENT
  815. PubSym@         _RealCvtVector, <label  word>,  __CDECL__
  816.                 ENDS
  817.  
  818. _SCNSEG         SEGMENT
  819. PubSym@         _ScanTodVector,  <label word>,  __CDECL__
  820.                 ENDS
  821.  
  822. IFNDEF __HUGE__
  823. _BSS            SEGMENT
  824. bdata@          label   byte
  825.                 ENDS
  826.  
  827. _BSSEND         SEGMENT
  828. edata@          label   byte
  829.                 ENDS
  830. ENDIF
  831.  
  832. IFNDEF __TINY__
  833. _STACK          SEGMENT
  834. IFDEF __BOSS__
  835.     IF LDATA
  836.                 db      1400h dup(?)
  837.     ENDIF
  838. ELSE
  839.                 db      128 dup(?)               ;minimum stack size
  840. ENDIF  ; __BOSS__
  841.                 ENDS
  842. ENDIF  ; __TINY__
  843.                 END     STARTX
  844.