home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / tcpp / examples / startup / c0.asm < prev    next >
Encoding:
Assembly Source File  |  1990-06-09  |  24.2 KB  |  738 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, 1990 by Borland International Inc.  |
  10. ;|      All Rights Reserved.                                    |
  11. ;[]------------------------------------------------------------[]
  12.  
  13.         INCLUDE RULES.ASI
  14.  
  15. ;       Segment- und Group-Deklarationen
  16.  
  17. _TEXT           SEGMENT BYTE PUBLIC 'CODE'
  18.                 ENDS
  19. _FARDATA    SEGMENT PARA PUBLIC 'FAR_DATA'
  20.                 ENDS
  21. IFNDEF __TINY__
  22. _OVERLAY_       SEGMENT PARA PUBLIC 'OVRINFO'
  23.         ENDS
  24. ENDIF
  25. _INIT_          SEGMENT WORD PUBLIC 'INITDATA'
  26. InitStart       label byte
  27.                 ENDS
  28. _INITEND_       SEGMENT BYTE PUBLIC 'INITDATA'
  29. InitEnd         label byte
  30.                 ENDS
  31. _EXIT_          SEGMENT WORD PUBLIC 'EXITDATA'
  32. ExitStart       label byte
  33.                 ENDS
  34. _EXITEND_       SEGMENT BYTE PUBLIC 'EXITDATA'
  35. ExitEnd         label byte
  36.                 ENDS
  37. IFNDEF __TINY__
  38. _1STUB_     SEGMENT PARA PUBLIC 'STUBSEG'
  39.         ENDS
  40. ENDIF
  41. _DATA           SEGMENT PARA PUBLIC 'DATA'
  42.                 ENDS
  43. _CVTSEG         SEGMENT WORD PUBLIC 'DATA'
  44.                 ENDS
  45. _SCNSEG         SEGMENT WORD PUBLIC 'DATA'
  46.                 ENDS
  47. IFNDEF __HUGE__
  48.   _BSS          SEGMENT WORD PUBLIC 'BSS'
  49.                 ENDS
  50.   _BSSEND       SEGMENT BYTE PUBLIC 'ENDBSS'
  51.                 ENDS
  52. ENDIF
  53. IFNDEF __TINY__
  54.   _STACK        SEGMENT STACK 'STACK'
  55.                 ENDS
  56. ENDIF
  57.  
  58. IFNDEF __NOFLOAT__
  59.   IF LDATA
  60.     IFDEF  __HUGE__
  61.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG
  62.     ELSE
  63.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  64.     ENDIF
  65.     IGROUP GROUP _INIT_,_INITEND_
  66.     EGROUP GROUP _EXIT_,_EXITEND_
  67.   ELSE
  68.     IFDEF __TINY__
  69.       DGROUP GROUP _TEXT,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  70.     ELSE
  71.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  72.       IGROUP GROUP _INIT_,_INITEND_
  73.       EGROUP GROUP _EXIT_,_EXITEND_
  74.     ENDIF
  75.   ENDIF
  76. ELSE
  77.   IF LDATA
  78.     IFDEF __HUGE__
  79.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG
  80.     ELSE
  81.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  82.     ENDIF
  83.     IGROUP GROUP _INIT_,_INITEND_
  84.     EGROUP GROUP _EXIT_,_EXITEND_
  85.   ELSE
  86.     IFDEF __TINY__
  87.       DGROUP GROUP _TEXT,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  88.     ELSE
  89.       DGROUP GROUP _DATA,_CVTSEG,_SCNSEG,_BSS,_BSSEND
  90.       IGROUP GROUP _INIT_,_INITEND_
  91.       EGROUP GROUP _EXIT_,_EXITEND_
  92.     ENDIF
  93.   ENDIF
  94. ENDIF
  95.  
  96.         ASSUME  CS:_TEXT, DS:DGROUP
  97.  
  98. ;       Externe Referenzen
  99.  
  100. extrn        _main:DIST
  101. extrn        _exit:DIST
  102. extrn        __exitbuf:DIST
  103. extrn        __exitfopen:DIST
  104. extrn        __exitopen:DIST
  105. extrn        __setupio:near            ; wird unbedingt benötigt !
  106. extrn        __stklen:word
  107. IF LDATA EQ false
  108. extrn        __heaplen:word
  109. ENDIF
  110.  
  111.         SUBTTL  Start Up Code
  112.         PAGE
  113. ;/*                                                     */
  114. ;/*-----------------------------------------------------*/
  115. ;/*                                                     */
  116. ;/*     Start Up Code                                   */
  117. ;/*     -------------                                   */
  118. ;/*                                                     */
  119. ;/*-----------------------------------------------------*/
  120. ;/*                                                     */
  121. PSPHigh         equ     00002h
  122. PSPEnv          equ     0002ch
  123. PSPCmd          equ     00080h
  124.  
  125.                 public  __AHINCR
  126. __AHINCR        equ     1000h
  127.                 public  __AHSHIFT
  128. __AHSHIFT       equ     12
  129.  
  130. IFDEF    __NOFLOAT__
  131. MINSTACK        equ     128     ; minimale Stackgröße in Worten
  132. ELSE
  133. MINSTACK        equ     256     ; minimale Stackgröße in Worten
  134. ENDIF
  135. ;
  136. ;       Am Programmanfang zeigen sowohl DS als auch ES auf den
  137. ;       Segment-Prefix (PSP). SS zeigt auf das Stack-Segment,
  138. ;       außer im Model TINY, in dem SS den gleichen Wert wie CS hat.
  139. ;
  140. _TEXT           SEGMENT
  141. IFDEF           __TINY__
  142.                 ORG     100h
  143. ENDIF
  144. STARTX          PROC    NEAR
  145. ;      Sichern von allgemeinen Informationen wie z. B.
  146. ;               DGROUP Segmentadresse
  147. ;               DOS Versions-Nr.
  148. ;               Program Segment Prefix (PSP)-Adresse
  149. ;               Adresse des Environments
  150. ;               Anfang des "Far-Heaps"
  151.  
  152. IFDEF   __TINY__
  153.         mov     dx, cs          ; DX = GROUP Segmentadresse
  154. ELSE
  155.         mov     dx, DGROUP      ; DX = GROUP Segmentadresse
  156. ENDIF
  157.                 mov     cs:DGROUP@@, dx
  158.                 mov     ah, 30h
  159.         int     21h             ; DOS Versions-Nr. ermitteln
  160.         mov     bp, ds:[PSPHigh]; BP = Größte Speichersegmentadresse
  161.         mov     bx, ds:[PSPEnv] ; BX = Adresse des Environment-Segments
  162.         mov     ds, dx
  163.         mov     _version@, ax   ; DOS-Versions-Nr. speichern
  164.         mov     _psp@, es       ; Program Segment Prefix (PSP)-Adresse speichern
  165.         mov     _envseg@, bx    ; Environment-Segmentadresse speichern
  166.         mov     word ptr _heaptop@ + 2, bp
  167. ;
  168. ;       Sichern von einigen Interrupt-Vektoren und Installieren eines
  169. ;       Standard-Handlers zur Behandlung von "Division durch 0"
  170.  
  171.         call    SaveVectors
  172.  
  173. ;       Ermitteln de Anzahl der Environment-Variablen und Brechnen der
  174. ;       Größe. Jede Variable endet mit 0 und eine Variable mit Länge 0
  175. ;       beendet das Environment. Das Environment kann unter keinen
  176. ;       Umständen größer als 32 kB werden.
  177.  
  178.                 les     di, dword ptr _envLng@
  179.                 mov     ax, di
  180.                 mov     bx, ax
  181.         mov     cx, 07FFFh      ; Environment kann nicht größer als 32 kB werden
  182.         cld
  183. @@EnvLoop:
  184.                 repnz   scasb
  185.         jcxz    InitFailed      ; Ungültiges Environment !!!
  186.         inc     bx              ; BX = Anzahl der Environment-Variablen
  187.         cmp     es:[di], al
  188.         jne     @@EnvLoop       ; nächste Variable ...
  189.         or      ch, 10000000b
  190.         neg     cx
  191.         mov     _envLng@, cx    ; Größe des Envrionments sichern
  192.         mov     cx, dPtrSize / 2
  193.         shl     bx, cl
  194.         add     bx, dPtrSize * 4
  195.         and     bx, not ((dPtrSize * 4) - 1)
  196.         mov     _envSize@, bx   ; Anzahl der Environment-Variablen sichern
  197.  
  198. ;       Ermitteln des benötigten Speichers
  199.  
  200. IF      LDATA
  201.                 mov     dx, ss
  202.         sub     bp, dx          ; BP = verbleibende Größe in Paragraphen
  203.   IFDEF   __HUGE__
  204.                 mov     di, seg __stklen
  205.                 mov     es, di
  206.         mov     di, es:__stklen ; DI = Angeforderte Stackgröße
  207.   ELSE
  208.         mov     di, __stklen    ; DI = Angeforderte Stackgröße
  209.   ENDIF
  210. ;
  211. ; Überprüfung, ob der angeforderte Stack mindestens MINSTACK Wörter groß ist
  212. ;
  213.         cmp     di, 2*MINSTACK  ; ist der angeforderte Stack groß genug ?
  214.         jae     AskedStackOK
  215.         mov     di, 2*MINSTACK  ; nein --> minimalen Wert benutzen
  216.   IFDEF   __HUGE__
  217.         mov     es:__stklen, di ; angeforderte Stackgröße überschreiben
  218.   ELSE
  219.         mov        __stklen, di ; angeforderte Stackgröße überschreiben
  220.   ENDIF
  221. AskedStackOK    label   near
  222.                 mov     cl, 4
  223.         shr     di, cl          ; $$$ CL darf nicht zerstört werden $$$
  224.         inc    di
  225.         cmp     bp, di        ; DI = Stack-Größe in Paragraphen
  226.         jnb     ExcessOfMemory  ; Speicher reicht locker aus ...
  227. ELSE
  228.                 mov     dx, ds
  229.         sub     bp, dx          ; BP = verbleibende Größe in Paragraphen
  230.         mov     di, __stklen    ; DI = angeforderte Stack-Größe
  231. ;
  232. ;
  233. ; Überprüfung, ob der angeforderte Stack mindestens MINSTACK Wörter groß ist
  234. ;
  235.         cmp     di, 2*MINSTACK  ; ist der angeforderte Stack groß genug ?
  236.         jae     AskedStackOK
  237.         mov     di, 2*MINSTACK  ; nein --> minimalen Wert benutzen
  238.         mov     __stklen, di    ; angeforderte Stackgröße überschreiben
  239. AskedStackOK    label   near
  240.                 add     di, offset DGROUP: edata@
  241.         jb      InitFailed      ; Datensegment darf nicht > 64 kB werden
  242.         add     di, __heaplen
  243.         jb      InitFailed      ; Datensegment darf nicht > 64 kB werden
  244.         mov     cl, 4
  245.         shr     di, cl          ; $$$ CL darf nicht zerstört werden $$$
  246.         inc     di              ; DI = DS Größe in Paragraphen
  247.         cmp     bp, di
  248.         jb      InitFailed      ; Nicht genügend Speicher
  249.         cmp     __stklen, 0
  250.         je      ExpandDS        ; DS bis auf 64 kB erweitern
  251.         cmp     __heaplen, 0
  252.         jne     ExcessOfMemory  ; Speicher reicht locker aus ...
  253. ExpandDS        label   near
  254.                 mov     di, 1000h
  255.                 cmp     bp, di
  256.         ja      ExcessOfMemory  ;Genügend Speicher, um das Programm ablaufen zu lassen
  257.         mov     di, bp
  258.         jmp     short ExcessOfMemory  ; Genügend Speicher, um das Programm ablaufen zu lassen
  259. ENDIF
  260.  
  261. ; Alle Initialisierungsfehler kommen hier an
  262.  
  263. InitFailed      label   near
  264.                 jmp     near ptr _abort
  265.  
  266.  
  267. ;       Rückgabe des überflüssigen Speichers an DOS
  268. ;       Startadresse des Far Heaps und Zeiger setzen
  269.  
  270. ExcessOfMemory  label   near
  271.                 mov     bx, di
  272.                 add     bx, dx
  273.                 mov     word ptr _heapbase@ + 2, bx
  274.                 mov     word ptr _brklvl@ + 2, bx
  275.                 mov     ax, _psp@
  276.         sub     bx, ax          ; BX = Anzahl der Paragraphen die behaltenw erden sollen
  277.         mov     es, ax          ; ES = Adresse des Program Segment Prefix(PSP)
  278.         mov     ah, 04Ah
  279.         push    di              ; DI sichern
  280.         int     021h            ; dieser Aufruf zerstört SI,DI,BP !!!!!!
  281.         pop     di              ; DI restaurieren
  282.  
  283.         shl     di, cl          ; $$$ CX besitzt immer noch den Wert 4 $$$
  284.  
  285.         cli                     ; erforderlich für 8086/88-CPU'S
  286.                     ; die vor 1983 hergestellt wurden
  287.         mov     ss, dx          ; Programm-Stack einrichten
  288.         mov     sp, di
  289. IF      LDATA
  290.         mov     __stklen, di    ; Stack-Größe sichern
  291. ENDIF
  292.                 sti
  293.  
  294. IFNDEF  __HUGE__
  295.  
  296. ;       Den nicht-initialisierten Datenbereich mit 0 vorbelegen
  297.  
  298.                 xor     ax, ax
  299.                 mov     es, cs:DGROUP@@
  300.                 mov     di, offset DGROUP: bdata@
  301.                 mov     cx, offset DGROUP: edata@
  302.                 sub     cx, di
  303.                 cld
  304.             rep     stosb
  305. ENDIF
  306.  
  307. ;       Kommandozeilen-Parameter vorbereiten
  308.  
  309.                 mov    ah, 0
  310.         int    1ah            ; aktuelle BIOS-Zeit in "Ticks" ermitteln
  311.         mov    word ptr _StartTime@,dx    ; für die Funktion clock() sichern
  312.         mov    word ptr _StartTime@+2,cx
  313.  
  314.         xor    bp,bp            ; BP für den Overlay Manager auf 0 setzen
  315.  
  316. IFNDEF __TINY__
  317.                 mov     ax,IGROUP
  318.                 mov     ds,ax
  319.         mov     si,offset IGROUP:InitStart    ;si = Anfang der Tabelle
  320.         mov     di,offset IGROUP:InitEnd    ;di = Ende der Tabelle
  321. ELSE
  322.         mov     si,offset DGROUP:InitStart    ;si = Anfang der Tabelle
  323.         mov     di,offset DGROUP:InitEnd    ;di = Ende der Tabelle
  324. ENDIF
  325.                 call    StartExit
  326.                 mov     ds, cs:DGROUP@@
  327.  
  328. ;       ExitCode = main(argc,argv,envp);
  329.  
  330. IF      LDATA
  331.                 push    word ptr __C0environ+2
  332.                 push    word ptr __C0environ
  333.                 push    word ptr __C0argv+2
  334.                 push    word ptr __C0argv
  335. ELSE
  336.                 push    word ptr __C0environ
  337.                 push    word ptr __C0argv
  338. ENDIF
  339.                 push    __C0argc
  340.                 call    _main
  341.  
  342. ; Um Platz zu sparen, benutzen wir hier selbstmodifizierenden Code
  343. ; Die JA-Anweisungen der Startup-/Exit-Logik werden durch die JB-Anweisung
  344. ; ersetzt. Dies erlaubt uns, die Tabelle der auszuführenden Funktionen
  345. ; in der umgekehrten Reihenfolge zu durchsuchen. Außerdem wird die
  346. ; Konstante, die bei der ersten Anweisung in ah gespeichert wird,
  347. ; auf 0 geändert.
  348.  
  349.         mov     byte ptr cs:JA_JB,72h
  350.         mov     byte ptr cs:StartExit+1,0
  351.  
  352. ;       Puffer aller Streams und Dateien leeren und schließen
  353.  
  354.                 push    ax
  355.                 call    _exit
  356.  
  357. ;---------------------------------------------------------------------------
  358. ;    _exit()
  359. ;
  360. ;       Restaurieren der Interrupt-Vektore, die während des Startup-Codes
  361. ;       gesichert wurden. signal()-Funktionen könnten die Interrupt-
  362. ;       Vektoren 0, 4, 5 oder sechs geändert haben.
  363. ;
  364. ;    Überprüfung auf NULL pointer-Fehler.
  365. ;
  366. ;    Rückkehr nach DOS.
  367. ;
  368. ; Hinweis: _exit schließt keine Dateien und führt auch keinerlei
  369. ;          benutzerdefinierte exit-Funktionen aus. Dies ist lediglich
  370. ;          ein minimaler Ausstieg (Aufräumen und Beenden).
  371.  
  372. ;---------------------------------------------------------------------------
  373. __exitclean    PROC    NEAR
  374.         PUBLIC    __exitclean
  375. IFNDEF __TINY__
  376.                 mov     ax,EGROUP
  377.                 mov     ds,ax
  378.                 mov     si,offset EGROUP:ExitStart
  379.                 mov     di,offset EGROUP:ExitEnd
  380. ELSE
  381.                 mov     si,offset DGROUP:ExitStart
  382.                 mov     di,offset DGROUP:ExitEnd
  383. ENDIF
  384.                 call    StartExit
  385.  
  386.                 mov     ds, cs:DGROUP@@
  387. IF LPROG
  388.         call    dword ptr [__exitbuf]
  389.         call    dword ptr [__exitfopen]
  390.         call    dword ptr [__exitopen]
  391.         push    ax                      ;Stack bereinigen, so daß der Rückgabewert
  392.                         ;für DOS an der "richtigen" Stelle steht
  393. ELSE
  394.         call    word ptr [__exitbuf]
  395.         call    word ptr [__exitfopen]
  396.         call    word ptr [__exitopen]
  397. ENDIF
  398.         ENDP
  399.  
  400. __exit        PROC    DIST
  401.         PUBLIC    __exit
  402.                 mov     ds, cs:DGROUP@@
  403.  
  404.         call    DIST ptr __restorezero    ; Interrupt-Vektoren restaurieren
  405.  
  406. IF      LDATA EQ false
  407.   IFNDEF  __TINY__
  408.  
  409. ;       Vor dem Beenden auf NULL-Pointer überprüfen
  410.  
  411.                 xor     ax, ax
  412.                 mov     si, ax
  413.                 mov     cx, lgth_CopyRight
  414. ComputeChecksum label   near
  415.                 add     al, [si]
  416.                 adc     ah, 0
  417.                 inc     si
  418.                 loop    ComputeChecksum
  419.                 sub     ax, CheckSum
  420.                 jz      ExitToDOS
  421.                 mov     cx, lgth_NullCheck
  422.                 mov     dx, offset DGROUP: NullCheck
  423.                 call    ErrorDisplay
  424.   ENDIF
  425. ENDIF
  426.  
  427. ;       Rückkehr nach DOS
  428.  
  429. ExitToDOS       label   near
  430.                 mov     bp,sp
  431.                 mov     ah,4Ch
  432.                 mov     al,[bp+cPtrSize]
  433.         int     21h                     ; Rückkehr nach DOS
  434.         ENDP
  435. STARTX          ENDP
  436.  
  437.     SUBTTL  Sichern/Restaurieren der Vektoren und Handler für "Division durch 0"
  438.     PAGE
  439. ;[]------------------------------------------------------------[]
  440. ;|                                                              |
  441. ;| Sichern/Restaurieren der Interruptvektoren und Handler für   |
  442. ;| die Division durch 0                                         |
  443. ;|                                                              |
  444. ;[]------------------------------------------------------------[]
  445.  
  446. ZeroDivision    PROC    FAR
  447.                 mov     cx, lgth_ZeroDivMSG
  448.                 mov     dx, offset DGROUP: ZeroDivMSG
  449.                 jmp     MsgExit3
  450. ZeroDivision    ENDP
  451.  
  452. ;--------------------------------------------------------------------------
  453. ;    savevectors()
  454. ;
  455. ;       Sichern der Interrupt-Vektoren 0, 4, 5 & 6. Dies wird benötigt,
  456. ;       da die Funktion signal() diese Vektoren während der Laufzeit
  457. ;       verändern kann.
  458. ;--------------------------------------------------------------------------
  459. SaveVectors    PROC    NEAR
  460.                 push    ds
  461. ; INT 0 sichern
  462.         mov     ax, 3500h
  463.         int     021h
  464.         mov     word ptr _Int0Vector@, bx
  465.         mov     word ptr _Int0Vector@+2, es
  466. ; INT 4 sichern
  467.         mov     ax, 3504h
  468.         int     021h
  469.         mov     word ptr _Int4Vector@, bx
  470.         mov     word ptr _Int4Vector@+2, es
  471. ; INT 5 sichern
  472.         mov     ax, 3505h
  473.                 int     021h
  474.                 mov     word ptr _Int5Vector@, bx
  475.         mov     word ptr _Int5Vector@+2, es
  476. ; INT 6 sichern
  477.         mov     ax, 3506h
  478.                 int     021h
  479.                 mov     word ptr _Int6Vector@, bx
  480.                 mov     word ptr _Int6Vector@+2, es
  481. ;
  482. ;    Default-Handler für "Division durch 0" installieren.
  483. ;
  484.                 mov     ax, 2500h
  485.                 mov     dx, cs
  486.                 mov     ds, dx
  487.                 mov     dx, offset ZeroDivision
  488.                 int     21h
  489.  
  490.                 pop     ds
  491.                 ret
  492. SaveVectors    ENDP
  493.  
  494. ;--------------------------------------------------------------------------
  495. ;    restorezero() restauriert alle Interrupt-Vektoren, die
  496. ;       SaveVectors gesichert hat.
  497. ;
  498. ; Achtung : Bei speicherresidenten Programmen (TSR) muß beachtet werden, daß
  499. ; signal()-Funkionen abgeschaltet werden, falls die Funktion keep()
  500. ; aufgerufen wird.
  501.  
  502. ; Falls ein TSR-Programm diese Funktionen benutzen will, wenn es
  503. ; aktiviert ist, dann muß es diese Interrupt-Vektoren bei Aktivierung und
  504. ; Deaktivierung selbst sichern bzw. restaurieren
  505.  
  506. ;--------------------------------------------------------------------------
  507. __restorezero     PROC    DIST
  508.         PUBLIC    __restorezero
  509. IFDEF   __HUGE__
  510.                 push    ds
  511.                 mov     ds, cs: DGROUP@@
  512. ENDIF
  513.                 push    ds
  514.                 mov     ax, 2500h
  515.                 lds     dx, _Int0Vector@
  516.                 int     21h
  517.         pop    ds
  518.  
  519.         push    ds
  520.                 mov     ax, 2504h
  521.                 lds     dx, _Int4Vector@
  522.                 int     21h
  523.         pop    ds
  524.  
  525.         push    ds
  526.                 mov     ax, 2505h
  527.                 lds     dx, _Int5Vector@
  528.                 int     21h
  529.         pop    ds
  530.  
  531. IFNDEF   __HUGE__
  532.         push    ds
  533. ENDIF
  534.                 mov     ax, 2506h
  535.                 lds     dx, _Int6Vector@
  536.                 int     21h
  537.                 pop     ds
  538.  
  539.                 ret
  540.         ENDP
  541.  
  542. ;------------------------------------------------------------------
  543. ; Schleife durch eine Startup-/Exit-Tabelle (SE-Tabelle), die
  544. ; die Funktionen in der Reihenfolge ihrer Priorität aufruft.
  545.  
  546. ; DS:SI muß auf den Beginn der SE-Tabelle zeigen
  547. ; DS:DI muß auf das Ende der SE-Tabelle zeigen
  548. ; Die ersten 64 Prioritäten sind von Borland reserviert
  549. ;------------------------------------------------------------------
  550. PNEAR           EQU     0
  551. PFAR            EQU     1
  552. NOTUSED         EQU     0ffh
  553.  
  554. SE              STRUC
  555. calltype        db      ?                       ; 0=near,1=far,ff=unbenutzt
  556. priority        db      ?                       ; 0=höchste,ff=niedrigste
  557. addrlow         dw      ?
  558. addrhigh        dw      ?
  559. SE              ENDS
  560.  
  561. StartExit       PROC    NEAR
  562. @@Start:        mov     ah,0ffh                 ; beginnen wir mit der niedrigsten Priorität
  563.         mov     dx,di                   ; dx auf Ende der Tabelle setzen
  564.         mov     bx,si                   ; bx = Anfang der Tabelle
  565.  
  566. @@TopOfTable:   cmp     bx,di                   ; Tabellenende erreicht ?
  567.         je      @@EndOfTable            ; ja, Schleife beenden
  568.         cmp     [bx.calltype],NOTUSED   ; Aufruftyp überprüfen
  569.         je      @@Next
  570.         cmp     [bx.priority],ah        ; Priorität überprüfen
  571. JA_JB:          ja      @@Next                  ; zu hoch ?  überspringen
  572.         mov     ah,[bx.priority]        ; Priorität beibehalten
  573.         mov     dx,bx                   ; Index in dx beibehalten
  574. @@Next:         add     bx,SIZE SE              ; bx = nächster Tabelleneintrag
  575.         jmp     @@TopOfTable
  576.  
  577. @@EndOfTable:   cmp     dx,di                   ; Tabellenende erreicht ?
  578.         je      @@Done                  ; Ja, Beenden
  579.         mov     bx,dx                   ; bx = höchste Priorität
  580.         push    ds                      ; ds sichern
  581.         pop     es
  582.                 push    es                      ; es = ds
  583.         cmp     [bx.calltype],PNEAR     ; near oder far ?
  584.         mov     [bx.calltype],NOTUSED   ; Aufruftyp überschreiben
  585.         mov     ds, cs:DGROUP@@
  586.         je      @@NearCall
  587.  
  588. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  589.         pop     ds                      ; ds restaurieren
  590.         jmp     @@Start
  591.  
  592. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  593.         pop     ds                      ; ds restaurieren
  594.         jmp     @@Start
  595.  
  596. @@Done:         ret
  597. StartExit       ENDP
  598.  
  599. ErrorDisplay    PROC    NEAR
  600.                 mov     ah, 040h
  601.                 mov     bx, 2
  602.                 int     021h
  603.                 ret
  604. ErrorDisplay    ENDP
  605.  
  606. _abort        PROC    DIST
  607.         PUBLIC    _abort
  608.                 mov     cx, lgth_abortMSG
  609.                 mov     dx, offset DGROUP: abortMSG
  610. MsgExit3        label   near
  611.                 mov     ds, cs: DGROUP@@
  612.                 call    ErrorDisplay
  613. CallExit3       label   near
  614.                 mov     ax, 3
  615.                 push    ax
  616.                 call    __exit           ; _exit(3);
  617.         ENDP
  618.  
  619. ; die DGROUP@-Variable wird benutzt, um DS mit DGROUP zu laden
  620.  
  621. PubSym@        DGROUP@, <dw    ?>, __PASCAL__
  622.  
  623. ; __MMODEL wird benutzt, um das Speichermodell oder den voreingestellten
  624. ; Zeigertyp zur Laufzeit zu ermitteln
  625.  
  626.         public __MMODEL
  627. __MMODEL    dw    MMODEL
  628.  
  629.         ENDS
  630.  
  631.         SUBTTL  Start Up Datenbereich
  632.         PAGE
  633. ;[]------------------------------------------------------------[]
  634. ;|      Start Up Datenbereich                      |
  635. ;|                                                              |
  636. ;|      WARNUNG         Verschieben Sie keine Variablen im      |
  637. ;|                      Datensegment, wenn Sie nicht völlig     |
  638. ;|                      sicher sind, daß dies ungefährlich ist. |
  639. ;[]------------------------------------------------------------[]
  640.  
  641. _DATA        SEGMENT
  642.  
  643. ;       "Magisches" Symbol, das von den Debug-Infos benutzt wird, um das
  644. ;       Datensegment zu lokalisieren
  645.         public DATASEG@
  646. DATASEG@    label    byte
  647.  
  648. ;       Der CopyRight-String darf unter keinen Umständen geändert oder
  649. ;       verschoben werden, ohne gleichzeitig die Überprüfungs-Routine
  650. ;       für NULL-Pointer zu verändern
  651.  
  652. CopyRight       db      4 dup(0)
  653.                 db      'Turbo C++ - Copyright 1990 Borland Intl.',0
  654. lgth_CopyRight  equ     $ - CopyRight
  655.  
  656. IF      LDATA EQ false
  657. IFNDEF  __TINY__
  658. CheckSum        equ     00CA5h
  659. NullCheck       db      'Null pointer assignment', 13, 10
  660. lgth_NullCheck  equ     $ - NullCheck
  661. ENDIF
  662. ENDIF
  663.  
  664. ZeroDivMSG      db      'Divide error', 13, 10
  665. lgth_ZeroDivMSG equ     $ - ZeroDivMSG
  666.  
  667. abortMSG        db      'Abnormal program termination', 13, 10
  668. lgth_abortMSG   equ     $ - abortMSG
  669.  
  670. ;
  671. ;        Hier werden die Interrupt-Vektoren gesichert
  672. ;
  673. ;    Die Interrupt-Vektoren 0,4,5 & 6 werden beim Programmstart gesichert
  674. ;       und restauriert, wenn das Programm beendet wird. Die Funktion
  675. ;       signal() könnte diese Vektoren während des Programmlaufes verändern
  676. ;
  677. ;       Hinweis : Dieser Speicherbereich für die Interrupt-Vektoren darf
  678. ;          nicht verändert werden, wenn nicht gleichzeitig die
  679. ;          Sicherungs-/Restaurierungs-Logik geändert wird.
  680.  
  681. PubSym@         _Int0Vector    <dd     0>,             __CDECL__
  682. PubSym@         _Int4Vector    <dd     0>,             __CDECL__
  683. PubSym@         _Int5Vector    <dd     0>,             __CDECL__
  684. PubSym@         _Int6Vector    <dd     0>,             __CDECL__
  685. ;
  686. ;            Verschiedene Variablen
  687. ;
  688. PubSym@         _C0argc,        <dw     0>,             __CDECL__
  689. dPtrPub@        _C0argv,        0,                      __CDECL__
  690. dPtrPub@        _C0environ,     0,                      __CDECL__
  691. PubSym@         _envLng,        <dw     0>,             __CDECL__
  692. PubSym@         _envseg,        <dw     0>,             __CDECL__
  693. PubSym@         _envSize,       <dw     0>,             __CDECL__
  694. PubSym@         _psp,           <dw     0>,             __CDECL__
  695. PubSym@         _version,       <label word>,           __CDECL__
  696. PubSym@         _osmajor,       <db     0>,             __CDECL__
  697. PubSym@         _osminor,       <db     0>,             __CDECL__
  698. PubSym@         errno,          <dw     0>,             __CDECL__
  699. PubSym@         _StartTime,     <dw   0,0>,             __CDECL__
  700.  
  701.  
  702. ;       Variable zur Speicherverwaltung
  703.  
  704. IF      LDATA EQ false
  705. PubSym@         __heapbase,     <dw   DGROUP:edata@>,   __CDECL__
  706. PubSym@         __brklvl,       <dw   DGROUP:edata@>,   __CDECL__
  707. ENDIF
  708. PubSym@         _heapbase,      <dd   0>,       __CDECL__
  709. PubSym@         _brklvl,        <dd   0>,       __CDECL__
  710. PubSym@         _heaptop,       <dd   0>,       __CDECL__
  711.  
  712.             ENDS
  713.  
  714. _CVTSEG     SEGMENT
  715. PubSym@         _RealCvtVector, <label  word>,  __CDECL__
  716.             ENDS
  717.  
  718. _SCNSEG     SEGMENT
  719. PubSym@         _ScanTodVector,  <label word>,  __CDECL__
  720.             ENDS
  721.  
  722. IFNDEF __HUGE__
  723. _BSS        SEGMENT
  724. bdata@          label   byte
  725.         ENDS
  726.  
  727. _BSSEND        SEGMENT
  728. edata@          label   byte
  729.             ENDS
  730. ENDIF
  731.  
  732. IFNDEF __TINY__
  733. _STACK      SEGMENT
  734.         db      128 dup(?)               ;minimale Stack-Größe
  735.         ENDS
  736. ENDIF
  737.             END     STARTX
  738.