home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c495 / watcm951.arj / STARTUP.386 / CSTART3R.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-02-16  |  10.9 KB  |  400 lines

  1. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. ;%  Copyright (C) 1988-1993 by WATCOM International Corp. All    %
  3. ;%  rights reserved. No part of this software may be reproduced %
  4. ;%  in any form or by any means - graphic, electronic or    %
  5. ;%  mechanical, including photocopying, recording, taping    %
  6. ;%  or information storage and retrieval systems - except    %
  7. ;%  with the written permission of WATCOM International Corp.    %
  8. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9. ;
  10. ; startup code for WATCOM C/C++32 Version 9.5
  11. ;
  12. ;    This must be assembled using the following command:
  13. ;        386asm cstart
  14. ;    To create startup code for Ergo's DPMI DOS extender
  15. ;        386asm cstart -define ERGO_DPMI
  16. ;
  17. ;   NOTE: All C library data should be defined in CRWDATA.ASM -- That way
  18. ;      it's also available to ADS applications (who use ADSSTART.ASM).
  19. ;
  20.     name    cstart
  21.  
  22. .387
  23. .386p
  24.     assume    nothing
  25.  
  26.     extrn    __CMain     : near
  27.     extrn    __InitRtns    : near
  28.     extrn    __FiniRtns    : near
  29.     extrn    __DOSseg__    : near
  30. ifdef ERGO_DPMI
  31.     extrn    _InitAPIExtensions : near
  32. endif
  33.  
  34.     extrn    _edata        : byte        ; end of DATA (start of BSS)
  35.     extrn    _end        : byte        ; end of BSS (start of STACK)
  36.  
  37.     extrn    __dynend    : dword
  38.     extrn    __curbrk    : dword
  39.     extrn    __psp        : word
  40.     extrn    __osmajor    : byte
  41.     extrn    __osminor    : byte
  42.     extrn    __STACKLOW    : dword
  43.     extrn    __STACKTOP    : dword
  44.     extrn    __child     : dword
  45.     extrn    __no87        : word
  46.     extrn    __Extender    : byte
  47.     extrn    __Envptr    : dword
  48.     extrn    __Envseg    : word
  49.     extrn    __FPE_handler    : dword
  50.     extrn  ___FPE_handler    : dword
  51.     extrn    __LpCmdLine    : dword
  52.     extrn    __LpPgmName    : dword
  53.  
  54. DGROUP group _NULL,_AFTERNULL,CONST,_DATA,DATA,XIB,XI,XIE,YIB,YI,YIE,_BSS,STACK
  55.  
  56. ; this guarantees that no function pointer will equal NULL
  57. ; (WLINK will keep segment 'BEGTEXT' in front)
  58. ; This segment must be at least 4 bytes in size to avoid confusing the
  59. ; signal function.
  60.  
  61. BEGTEXT  segment use32 para public 'CODE'
  62.     assume    cs:BEGTEXT
  63. forever    label    near
  64.     int    3h
  65.     jmp    short forever
  66. ___begtext label byte
  67.     nop    ;3
  68.     nop    ;4
  69.     nop    ;5
  70.     nop    ;6
  71.     nop    ;7
  72.     nop    ;8
  73.     nop    ;9
  74.     nop    ;A
  75.     nop    ;B
  76.     nop    ;C
  77.     nop    ;D
  78.     nop    ;E
  79.     nop    ;F
  80.     public ___begtext
  81.     assume    cs:nothing
  82. BEGTEXT  ends
  83.  
  84. _TEXT    segment use32 dword public 'CODE'
  85.  
  86.     assume    ds:DGROUP
  87.  
  88. _NULL    segment para public 'BEGDATA'
  89. __nullarea label word
  90.     db    01h,01h,01h,00h
  91.     public    __nullarea
  92. _NULL    ends
  93.  
  94. _AFTERNULL segment word public 'BEGDATA'
  95. _AFTERNULL ends
  96.  
  97. CONST    segment word public 'DATA'
  98. CONST    ends
  99.  
  100. XIB    segment word public 'DATA'
  101. XIB    ends
  102. XI    segment word public 'DATA'
  103. XI    ends
  104. XIE    segment word public 'DATA'
  105. XIE    ends
  106.  
  107. YIB    segment word public 'DATA'
  108. YIB    ends
  109. YI    segment word public 'DATA'
  110. YI    ends
  111. YIE    segment word public 'DATA'
  112. YIE    ends
  113.  
  114.  
  115. _DATA     segment dword public 'DATA'
  116. X_ERGO        equ    0
  117. X_RATIONAL    equ    1
  118. X_PHARLAP_V2    equ    2
  119. X_PHARLAP_V3    equ    3
  120. X_PHARLAP_V4    equ    4
  121. X_PHARLAP_V5    equ    5
  122. X_INTEL     equ    9
  123. __GDAptr   dd 0         ; IGC and Intel Code Builder GDA address
  124. __D16Infoseg   dw    0020h    ; DOS/4G kernel segment
  125. __x386_zero_base_selector dw 0    ; base 0 selector for X-32VM
  126.  
  127.     public    __GDAptr
  128.     public    __D16Infoseg
  129.     public    __x386_zero_base_selector
  130. ifdef ERGO_DPMI
  131. __MEMHandle    dd    0    ; handle for linear base of image
  132.     public    __MEMHandle
  133. endif
  134. _DATA     ends
  135.  
  136.  
  137. DATA    segment word public 'DATA'
  138. DATA    ends
  139.  
  140. _BSS          segment word public 'BSS'
  141. _BSS          ends
  142.  
  143. STACK_SIZE    equ    1000h
  144.  
  145. STACK    segment para stack 'STACK'
  146.     db    (STACK_SIZE) dup(?)
  147. STACK    ends
  148.  
  149.  
  150.     assume    nothing
  151.     public    _cstart_
  152.     public    __exit_
  153.  
  154.     assume    cs:_TEXT
  155.  
  156. _cstart_ proc near
  157.     jmp    short around
  158.  
  159. ;
  160. ; copyright message
  161. ;
  162.     db    "WATCOM C/C++32 Run-Time system. "
  163.         db      "(c) Copyright by WATCOM International Corp. 1988-1993."
  164.     db    " All rights reserved."
  165.     align    4
  166.     dd    ___begtext    ; make sure dead code elimination
  167.                 ; doesn't kill BEGTEXT
  168. __saved_DS  dw    0        ; save area for DS for interrupt routines
  169. ;
  170. ; miscellaneous code-segment messages
  171. ;
  172. ConsoleName    db    "con",00h
  173.  
  174. around: sti                ; enable interrupts
  175.  
  176.     assume    ds:DGROUP
  177.  
  178. PSP_SEG equ    24h
  179. ENV_SEG equ    2ch
  180.  
  181.     and    esp,0fffffffch        ; make sure stack is on a 4 byte bdry
  182.     mov    ebx,esp         ; get sp
  183.     mov    __STACKTOP,ebx        ; set stack top
  184.     mov    __curbrk,ebx        ; set first available memory location
  185. ifdef ERGO_DPMI
  186.     mov    ax,es            ; get segment address of PSP
  187.     mov    __psp,ax        ; save segment address of PSP
  188.     mov    __MEMHandle,esi        ;
  189.     call    _InitAPIExtensions    ;
  190.     mov    al,X_ERGO        ; indicate Ergo DOS Extender
  191.     mov    bx,ds            ; force bx = DGROUP
  192.     sub    esi,esi         ; offset 0 for environment strings
  193.     mov    cx,es:[02Ch]        ; get segment for environment strings
  194.     mov    edi,81H         ; DOS command buffer _psp:edi
  195. else
  196.     mov    ax,PSP_SEG        ; get segment address of PSP
  197.     mov    __psp,ax        ; save segment address of PSP
  198. ;
  199. ;    get DOS & Extender version number
  200. ;
  201.     mov    ebx,'PHAR'        ; set ebx to 0
  202.     sub    eax,eax         ; set eax to 0
  203.     mov    ah,30h
  204.     int    21h            ; modifies eax,ebx,ecx,edx
  205.     mov    __osmajor,al
  206.     mov    __osminor,ah
  207.     mov    ecx,eax         ; remember DOS version number
  208.     sub    esi,esi         ; offset 0 for environment strings
  209.     mov    edi,81H         ; DOS command buffer es:edi
  210.     shr    eax,16            ; get top 16 bits of eax
  211.     cmp    ax,'DX'         ; if top 16 bits = "DX"
  212.     jne    not_pharlap        ; then its pharlap
  213.     sub    bl,'0'            ; - save major version number
  214.     mov    al,bl            ; - (was in ascii)
  215.     mov    bx,ds            ; - get value of Phar Lap data segment
  216.     mov    cx,ENV_SEG        ; - PharLap environment segment
  217.     jmp    short know_ext1     ; else
  218. not_pharlap:                ; - see if Intel Code Builder
  219.     cmp    ax,'BC'         ; - if Intel Code Builder
  220.     jne    not_Intel        ; - ... then
  221. GDA_PSPA equ    16            ; - offset into GDA to PSP address
  222. GDA_LDPT equ    28            ; - offset into GDA to load address
  223.     mov    __GDAptr,edx        ; - save address of GDA
  224.     mov    esi,edx         ; - get address of GDA
  225.     mov    edx,GDA_LDPT[esi]    ; - get application load point address
  226.     mov    ebx,esp         ; - calc amount of memory to keep
  227.     sub    ebx,edx         ; - ...
  228.     mov    ah,4Ah            ; - resize to minimum memory
  229.     int    21h            ; - ...
  230.     mov    bx,ds            ; - just use ds (FLAT model)
  231.     mov    __psp,ds        ; - save segment address of PSP
  232.     mov    eax,GDA_PSPA[esi]    ; - get address of PSP
  233.     add    edi,eax         ; - add address of PSP
  234.     sub    esi,esi         ; - zero esi
  235.     mov    si,02ch[eax]        ; - get environment segment into si
  236.     shl    esi,4            ; - convert to flat address
  237.     mov    cx,ds            ; - segment to access environment area
  238.     mov    al,X_INTEL        ; - indicate Intel Code Builder
  239. know_ext1:jmp    short know_extender    ; else
  240. not_Intel:                ; -
  241.     mov    dx,78h            ; - see if Rational DOS/4G
  242.     mov    ax,0FF00h        ; - ...
  243.     int    21h            ; - ...
  244.     cmp    al,0            ; - ...
  245.     je    short not_DOS4G     ; - quit if not Rational DOS/4G
  246.     mov    ax,gs            ; - get segment address of kernel
  247.     cmp    ax,0            ; - if not zero
  248.     je    short rat9        ; - then
  249.     mov    __D16Infoseg,ax     ; - - remember it
  250. rat9:                    ; - endif
  251.     mov    al,X_RATIONAL        ; - indicate Rational 32-bit Extender
  252.     mov    bx,ds            ; - just use ds (FLAT model)
  253.     mov    __psp,es        ; - save segment address of PSP
  254.     mov    cx,es:[02ch]        ; - get environment segment into cx
  255.     jmp    short know_extender    ; else
  256. not_DOS4G:                ; -
  257.     mov    dx,ds            ; - save ds
  258.     mov    cx,PSP_SEG        ; - get PSP segment descriptor
  259.     mov    ds,cx            ; - ... into ds
  260.     mov    cx,ds:[02ch]        ; - get environment segment into cx
  261.     mov    ds,dx            ; - restore ds
  262.     mov    bx,17h            ; - get writeable code segment for Ergo
  263.     mov    al,X_ERGO        ; - indicate Ergo OS/386
  264. know_extender:                ; endif
  265. endif
  266.     mov    __Extender,al        ; record extender type
  267.     mov    es,bx            ; get access to code segment
  268.     mov    es:__saved_DS,ds    ; save DS value
  269.     mov    __Envptr,esi        ; save address of environment strings
  270.     mov    __Envseg,cx        ; save segment of environment area
  271.     push    esi            ; save address of environment strings
  272. ;
  273. ;    copy command line into bottom of stack
  274. ;
  275.     mov    es,__psp        ; point to PSP
  276.     mov    edx,offset DGROUP:_end
  277.     add    edx,0FH
  278.     and    dl,0F0H
  279.     sub    ecx,ecx
  280.     mov    cl,es:[edi-1]        ; get length of command
  281.     cld                ; set direction forward
  282.     mov    al,' '
  283.     rep    scasb
  284.     lea    esi,-1[edi]
  285.     mov    edi,edx
  286.     mov    bx,es
  287.     mov    dx,ds
  288.     mov    ds,bx
  289.     mov    es,dx            ; es:edi is destination
  290.     je    noparm
  291.     inc    ecx
  292.     rep    movsb
  293. noparm: sub    al,al
  294.     stosb                ; store NULLCHAR
  295.     stosb                ; assume no pgm name
  296.     pop    esi            ; restore address of environment strings
  297.     dec    edi            ; back up pointer 1
  298.     push    edi            ; save pointer to pgm name
  299.     push    edx            ; save ds(stored in dx)
  300.     mov    ds,es:__Envseg        ; get segment addr of environment area
  301.     sub    ebp,ebp         ; assume "no87" env. var. not present
  302. L1:    mov    eax,[esi]        ; get first 4 characters
  303.     or    eax,20202020h        ; map to lower case
  304.     cmp    eax,'78on'        ; check for "no87"
  305.     jne    short L2        ; skip if not "no87"
  306.     cmp    byte ptr 4[esi],'='    ; make sure next char is "="
  307.     jne    short L2        ; no
  308.     inc    ebp            ; - indicate "no87" was present
  309. L2:    cmp    byte ptr [esi],0    ; end of string ?
  310.     lodsb
  311.     jne    L2            ; until end of string
  312.     cmp    byte ptr [esi],0    ; end of all strings ?
  313.     jne    L1            ; if not, then skip next string
  314.     lodsb
  315.     inc    esi            ; point to program name
  316.     inc    esi            ; . . .
  317. ;
  318. ;    copy the program name into bottom of stack
  319. ;
  320. L3:    cmp    byte ptr [esi],0    ; end of pgm name ?
  321.     movsb                ; copy a byte
  322.     jne    L3            ; until end of pgm name
  323.     pop    ds            ; restore ds
  324.     pop    esi            ; restore address of pgm name
  325.     mov    ebx,esp         ; end of stack in data segment
  326.  
  327.     assume    ds:DGROUP
  328.     mov    __no87,bp        ; set state of "no87" enironment var
  329.     mov    __STACKLOW,edi        ; save low address of stack
  330.     mov    __dynend,ebx        ; set top of dynamic memory area
  331.  
  332.     mov    ecx,offset DGROUP:_end    ; end of _BSS segment (start of STACK)
  333.     mov    edi,offset DGROUP:_edata; start of _BSS segment
  334.     sub    ecx,edi         ; calc # of bytes in _BSS segment
  335.     mov    dl,cl            ; save bottom 2 bits of count in edx
  336.     shr    ecx,2            ; calc # of dwords
  337.     sub    eax,eax         ; zero the _BSS segment
  338.     rep    stosd            ; ...
  339.     mov    cl,dl            ; get bottom 2 bits of count
  340.     and    cl,3            ; ...
  341.     rep    stosb            ; ...
  342.  
  343.     mov    eax,offset DGROUP:_end    ; cmd buffer pointed at by EAX
  344.     add    eax,0FH
  345.     and    al,0F0H
  346.     mov    __LpCmdLine,eax        ; save command line address
  347.     mov    __LpPgmName,esi        ; save program name address
  348.     call    __InitRtns        ; call initializer routines
  349.     sub    ebp,ebp            ; ebp=0 indicate end of ebp chain
  350.     call    __CMain
  351. _cstart_ endp
  352.  
  353. ;    don't touch AL in __exit_, it has the return code
  354.  
  355. __exit_  proc near
  356.     jmp    short    ok
  357.  
  358.     public    __exit_with_msg_
  359.  
  360. ; input: EAX - pointer to message to print
  361. ;     EDX - exit code
  362.  
  363. __exit_with_msg_:
  364.     push    edx            ; save return code
  365.     push    eax            ; save address of msg
  366.     mov    edx,offset ConsoleName
  367.     mov    ax,03d01h        ; write-only access to screen
  368.     int    021h
  369.     mov    bx,ax            ; get file handle
  370.     pop    edx            ; restore address of msg
  371.     mov    esi,edx         ; get address of msg
  372.     cld                ; make sure direction forward
  373. L4:    lodsb                ; get char
  374.     cmp    al,0            ; end of string?
  375.     jne    L4            ; no
  376.     mov    ecx,esi         ; calc length of string
  377.     sub    ecx,edx         ; . . .
  378.     dec    ecx            ; . . .
  379.     mov    ah,040h         ; write out the string
  380.     int    021h            ; . . .
  381.     pop    eax            ; restore return code
  382. ok:
  383.     push    eax            ; save return code
  384.     call    __FiniRtns        ; call finializer routines
  385.     pop    eax            ; restore return code
  386.     mov    ah,04cH         ; DOS call to exit with return code
  387.     int    021h            ; back to DOS
  388. __exit_  endp
  389.  
  390.     public    __GETDS
  391.     align    4
  392. __GETDS proc    near
  393.     mov    ds,cs:__saved_DS    ; load saved DS value
  394.     ret                ; return
  395. __GETDS endp
  396.  
  397. _TEXT    ends
  398.  
  399.     end    _cstart_
  400.