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

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