home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c496 / 1.img / STARTUP.386 / CSTART3S.ASM < prev   
Encoding:
Assembly Source File  |  1991-08-20  |  16.6 KB  |  515 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. ;%       Copyright (C) 1991, by WATCOM Systems Inc. All rights     %
  118. ;%       reserved. No part of this software may be reproduced      %
  119. ;%       in any form or by any means - graphic, electronic or      %
  120. ;%       mechanical, including photocopying, recording, taping     %
  121. ;%       or information storage and retrieval systems - except     %
  122. ;%       with the written permission of WATCOM Systems Inc.        %
  123. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  124. ;
  125. ; startup code for WATCOM C 386 Version 8.5
  126. ;
  127. ;       This must be assembled using the following command:
  128. ;               386asm cstart
  129. ;
  130. ;   NOTE: All C library data should be defined in CRWDATA.ASM -- That way
  131. ;         it's also available to ADS applications (who use ADSSTART.ASM).
  132. ;
  133.         name    cstart
  134.  
  135. .387
  136. .386p
  137.         assume  nothing
  138.  
  139.         extrn   __CMain         : near
  140.         extrn   __DOSseg__      : near
  141.  
  142.         extrn   _edata          : byte          ; end of DATA (start of BSS)
  143.         extrn   _end            : byte          ; end of BSS (start of STACK)
  144.  
  145.         extrn    _dynend        : dword
  146.         extrn    _curbrk        : dword
  147.         extrn    _psp           : word
  148.         extrn    _osmajor       : byte
  149.         extrn    _osminor       : byte
  150.         extrn    _STACKLOW      : dword
  151.         extrn    _STACKTOP      : dword
  152.         extrn    _child         : dword
  153.         extrn   __no87          : word
  154.         extrn    _Extender      : byte
  155.         extrn    _Envptr        : dword
  156.         extrn    _Envseg        : word
  157.         extrn   __FPE_handler   : dword
  158.         extrn  ___FPE_handler   : dword
  159.  
  160. DGROUP group _NULL,_AFTERNULL,CONST,_DATA,DATA,_emu_inits,_emu_init,_emu_inite,EXEC_S,EXEC,EXEC_E,XIB,XI,XIE,_BSS,STACK
  161.  
  162. ; this guarantees that no function pointer will equal NULL
  163. ; (WLINK will keep segment 'BEGTEXT' in front)
  164. ; This segment must be at least 4 bytes in size to avoid confusing the
  165. ; signal function.
  166.  
  167. BEGTEXT  segment use32 word public 'CODE'
  168.         assume  cs:BEGTEXT
  169. forever: jmp    short forever
  170.         nop
  171.         nop
  172.         nop
  173.         nop
  174.         assume  cs:nothing
  175. BEGTEXT  ends
  176.  
  177. _TEXT   segment use32 word public 'CODE'
  178.  
  179.         assume  ds:DGROUP
  180.  
  181. _NULL   segment para public 'BEGDATA'
  182. __nullarea label word
  183.         db      01h,01h,01h,00h
  184.         public  __nullarea
  185. _NULL   ends
  186.  
  187. _AFTERNULL segment word public 'BEGDATA'
  188. _AFTERNULL ends
  189.  
  190. CONST   segment word public 'DATA'
  191. CONST   ends
  192.  
  193. _emu_inits      segment word public 'DATA'
  194. _emu_start      label   word
  195. _emu_inits      ends
  196.  
  197. _emu_init segment word public 'DATA'
  198. __emulator      label   word
  199. ;;      dd      __init87emu
  200. ;;      dd      __fini87emu
  201. _emu_init ends
  202.  
  203. _emu_inite    segment word public 'DATA'
  204. _emu_end        label   word
  205. _emu_inite    ends
  206.  
  207. EXEC_S  segment word public 'DATA'
  208. EXEC_S  ends
  209.  
  210. EXEC    segment word public 'DATA'
  211. EXEC    ends
  212.  
  213. EXEC_E  segment word public 'DATA'
  214. EXEC_E  ends
  215.  
  216. XIB     segment word public 'DATA'
  217. xistart label   byte
  218. XIB     ends
  219. XI      segment word public 'DATA'
  220. XI      ends
  221. XIE     segment word public 'DATA'
  222. xiend   label   byte
  223. XIE     ends
  224.  
  225.  
  226. _DATA    segment word public 'DATA'
  227. X_ERGO          equ     0
  228. X_RATIONAL      equ     1
  229. X_PHARLAP_V2    equ     2
  230. X_PHARLAP_V3    equ     3
  231. X_PHARLAP_V4    equ     4
  232. X_INTEL         equ     5
  233. __GDAptr   dd 0                 ; IGC and Intel Code Builder GDA address
  234. __D16Infoseg   dw       0020h   ; DOS/4G kernel segment
  235.  
  236.         public  __GDAptr
  237.         public  __D16Infoseg
  238. _DATA    ends
  239.  
  240.  
  241. DATA    segment word public 'DATA'
  242. DATA    ends
  243.  
  244. _BSS          segment word public 'BSS'
  245. _BSS          ends
  246.  
  247. STACK_SIZE      equ     1000h
  248.  
  249. STACK   segment para stack 'STACK'
  250.         db      (STACK_SIZE) dup(?)
  251. STACK   ends
  252.  
  253.  
  254.         assume  nothing
  255.         public  _cstart_
  256.         public   __exit
  257.  
  258.         assume  cs:_TEXT
  259.  
  260. _cstart_ proc near
  261.         jmp     short around
  262.  
  263. ;
  264. ; copyright message
  265. ;
  266.         db      "WATCOM C 386 Run-Time system. "
  267.         db      "(c) Copyright by WATCOM Systems Inc. 1989, 1991."
  268.         db      " All rights reserved."
  269. ;
  270. ; miscellaneous code-segment messages
  271. ;
  272. ConsoleName     db      "con",00h
  273. __saved_DS  dw  0               ; save area for DS for interrupt routines
  274.  
  275. around: sti                             ; enable interrupts
  276.  
  277.         assume  ds:DGROUP
  278.  
  279. PSP_SEG equ     24h
  280. ENV_SEG equ     2ch
  281.  
  282.         and     esp,0fffffffch          ; make sure stack is on a 4 byte bdry
  283.         mov     ebx,esp                 ; get sp
  284.         mov      _STACKTOP,ebx          ; set stack top
  285.         mov      _curbrk,ebx            ; set first available memory location
  286.         mov     ax,PSP_SEG              ; get segment address of PSP
  287.         mov      _psp,ax                ; save segment address of PSP
  288. ;
  289. ;       get DOS & Extender version number
  290. ;
  291.         mov     ebx,'PHAR'              ; set ebx to 0
  292.         sub     eax,eax                 ; set eax to 0
  293.         mov     ah,30h
  294.         int     21h                     ; modifies eax,ebx,ecx,edx
  295.         mov      _osmajor,al
  296.         mov      _osminor,ah
  297.         mov     ecx,eax                 ; remember DOS version number
  298.         sub     esi,esi                 ; offset 0 for environment strings
  299.         mov     edi,81H                 ; DOS command buffer es:edi
  300.         shr     eax,16                  ; get top 16 bits of eax
  301.         cmp     ax,'DX'                 ; if top 16 bits = "DX"
  302.         jne     not_pharlap             ; then its pharlap
  303.         sub     bl,'0'                  ; - save major version number
  304.         mov     al,bl                   ; - (was in ascii)
  305.         mov     bx,14h                  ; - get value of Phar Lap data segment
  306.         mov     cx,ENV_SEG              ; - PharLap environment segment
  307.         jmp     short know_ext1         ; else
  308. not_pharlap:                            ; - see if Intel Code Builder
  309.         cmp     ax,'BC'                 ; - if Intel Code Builder
  310.         jne     not_Intel               ; - ... then
  311. GDA_PSPA equ    16                      ; - offset into GDA to PSP address
  312. GDA_LDPT equ    28                      ; - offset into GDA to load address
  313.         mov     __GDAptr,edx            ; - save address of GDA
  314.         mov     esi,edx                 ; - get address of GDA
  315.         mov     edx,GDA_LDPT[esi]       ; - get application load point address
  316.         mov     ebx,esp                 ; - calc amount of memory to keep
  317.         sub     ebx,edx                 ; - ...
  318.         mov     ah,4Ah                  ; - resize to minimum memory
  319.         int     21h                     ; - ...
  320.         mov     bx,ds                   ; - just use ds (FLAT model)
  321.         mov      _psp,ds                ; - save segment address of PSP
  322.         mov     eax,GDA_PSPA[esi]       ; - get address of PSP
  323.         add     edi,eax                 ; - add address of PSP
  324.         sub     esi,esi                 ; - zero esi
  325.         mov     si,02ch[eax]            ; - get environment segment into si
  326.         shl     esi,4                   ; - convert to flat address
  327.         mov     cx,ds                   ; - segment to access environment area
  328.         mov     al,X_INTEL              ; - indicate Intel Code Builder
  329. know_ext1:jmp   short know_extender     ; else
  330. not_Intel:                              ; -
  331.         mov     dx,78h                  ; - see if Rational DOS/4G
  332.         mov     ax,0FF00h               ; - ...
  333.         int     21h                     ; - ...
  334.         cmp     al,0                    ; - ...
  335.         je      short not_DOS4G         ; - quit if not Rational DOS/4G
  336.         mov     ax,gs                   ; - get segment address of kernel
  337.         cmp     ax,0                    ; - if not zero
  338.         je      short rat9              ; - then
  339.         mov     __D16Infoseg,ax         ; - - remember it
  340. rat9:                                   ; - endif
  341.         mov     al,X_RATIONAL           ; - indicate Rational 32-bit Extender
  342.         mov     bx,ds                   ; - just use ds (FLAT model)
  343.         mov      _psp,es                ; - save segment address of PSP
  344.         mov     cx,es:[02ch]            ; - get environment segment into cx
  345.         jmp     short know_extender     ; else
  346. not_DOS4G:                              ; -
  347.         mov     dx,ds                   ; - save ds
  348.         mov     cx,PSP_SEG              ; - get PSP segment descriptor
  349.         mov     ds,cx                   ; - ... into ds
  350.         mov     cx,ds:[02ch]            ; - get environment segment into cx
  351.         mov     ds,dx                   ; - restore ds
  352.         mov     bx,17h                  ; - get writeable code segment for Ergo
  353.         mov     al,X_ERGO               ; - indicate Ergo OS/386
  354. know_extender:                          ; endif
  355.         mov      _Extender,al           ; record extender type
  356.         mov     es,bx                   ; get access to code segment
  357.         mov     es:__saved_DS,ds        ; save DS value
  358.         mov      _Envptr,esi            ; save address of environment strings
  359.         mov      _Envseg,cx             ; save segment of environment area
  360.         push    esi                     ; save address of environment strings
  361. ;
  362. ;       copy command line into bottom of stack
  363. ;
  364.         mov     es, _psp                ; point to PSP
  365.         mov     edx,offset DGROUP:_end
  366.         add     edx,0FH
  367.         and     dl,0F0H
  368.         sub     ecx,ecx
  369.         mov     cl,es:[edi-1]           ; get length of command
  370.         cld                             ; set direction forward
  371.         mov     al,' '
  372.         rep     scasb
  373.         lea     esi,-1[edi]
  374.         mov     edi,edx
  375.         mov     bx,es
  376.         mov     dx,ds
  377.         mov     ds,bx
  378.         mov     es,dx                   ; es:edi is destination
  379.         je      noparm
  380.         inc     ecx
  381.         rep     movsb
  382. noparm: sub     al,al
  383.         stosb                           ; store NULLCHAR
  384.         stosb                           ; assume no pgm name
  385.         pop     esi                     ; restore address of environment strings
  386.         dec     edi                     ; back up pointer 1
  387.         push    edi                     ; save pointer to pgm name
  388.         push    edx                     ; save ds(stored in dx)
  389.         mov     ds,es: _Envseg          ; get segment addr of environment area
  390.         sub     ebp,ebp                 ; assume "no87" env. var. not present
  391. L1:     mov     eax,[esi]               ; get first 4 characters
  392.         or      eax,20202020h           ; map to lower case
  393.         cmp     eax,'78on'              ; check for "no87"
  394.         jne     short L2                ; skip if not "no87"
  395.         cmp     byte ptr 4[esi],'='     ; make sure next char is "="
  396.         jne     short L2                ; no
  397.         inc     ebp                     ; - indicate "no87" was present
  398. L2:     cmp     byte ptr [esi],0        ; end of string ?
  399.         lodsb
  400.         jne     L2                      ; until end of string
  401.         cmp     byte ptr [esi],0        ; end of all strings ?
  402.         jne     L1                      ; if not, then skip next string
  403.         lodsb
  404.         inc     esi                     ; point to program name
  405.         inc     esi                     ; . . .
  406. ;
  407. ;       copy the program name into bottom of stack
  408. ;
  409. L3:     cmp     byte ptr [esi],0        ; end of pgm name ?
  410.         movsb                           ; copy a byte
  411.         jne     L3                      ; until end of pgm name
  412.         pop     ds                      ; restore ds
  413.         pop     esi                     ; restore address of pgm name
  414.         mov     ebx,esp                 ; end of stack in data segment
  415.  
  416.         assume  ds:DGROUP
  417.         mov     __no87,bp               ; set state of "no87" enironment var
  418.         mov      _STACKLOW,edi          ; save low address of stack
  419.         mov      _dynend,ebx            ; set top of dynamic memory area
  420.  
  421.         mov     ecx,offset DGROUP:_end  ; end of _BSS segment (start of STACK)
  422.         mov     edi,offset DGROUP:_edata; start of _BSS segment
  423.         sub     ecx,edi                 ; calc # of bytes in _BSS segment
  424.         mov     dl,cl                   ; save bottom 2 bits of count in edx
  425.         shr     ecx,2                   ; calc # of dwords
  426.         sub     eax,eax                 ; zero the _BSS segment
  427.         rep     stosd                   ; ...
  428.         mov     cl,dl                   ; get bottom 2 bits of count
  429.         and     cl,3                    ; ...
  430.         rep     stosb                   ; ...
  431.  
  432.         mov     eax,offset DGROUP:_emu_start
  433.         mov     edx,offset DGROUP:_emu_end
  434.         cmp     edx,eax                 ; if 387 emulator present
  435.         je      short no_emu            ; then
  436.           call  [eax]                   ; - initialize emulator
  437. no_emu:                                 ; endif
  438.         call    initrtns                ; call initializer routines
  439.         mov     eax,offset DGROUP:_end  ; cmd buffer pointed at by EAX
  440.         add     eax,0FH
  441.         and     al,0F0H
  442.         mov     edx,esi                 ; point EDX at program name
  443.     sub    ebp,ebp            ; ebp=0 indicate end of ebp chain
  444.         call    __CMain
  445. _cstart_ endp
  446.  
  447. ;       don't touch AL in __exit_, it has the return code
  448.  
  449.  __exit  proc near
  450.         jmp     short   ok
  451.  
  452.         public   __exit_with_msg
  453.  
  454. ; input: EAX - pointer to message to print
  455. ;        EDX - exit code
  456.  
  457.  __exit_with_msg:
  458.         push    edx                     ; save return code
  459.         push    eax                     ; save address of msg
  460.         mov     edx,offset ConsoleName
  461.         mov     ax,03d01h               ; write-only access to screen
  462.         int     021h
  463.         mov     bx,ax                   ; get file handle
  464.         pop     edx                     ; restore address of msg
  465.         mov     esi,edx                 ; get address of msg
  466.         cld                             ; make sure direction forward
  467. L4:     lodsb                           ; get char
  468.         cmp     al,0                    ; end of string?
  469.         jne     L4                      ; no
  470.         mov     ecx,esi                 ; calc length of string
  471.         sub     ecx,edx                 ; . . .
  472.         dec     ecx                     ; . . .
  473.         mov     ah,040h                 ; write out the string
  474.         int     021h                    ; . . .
  475.         pop     eax                     ; restore return code
  476. ok:
  477.         push    eax                     ; save return code
  478.         mov     eax,offset DGROUP:_emu_start
  479.         mov     edx,offset DGROUP:_emu_end
  480.         cmp     edx,eax                 ; if 387 emulator present
  481.         je      no_emu1                 ; then
  482.           call  4[eax]                  ; - finalize emulator
  483. no_emu1:                                ; endif
  484.         pop     eax                     ; restore return code
  485.         mov     ah,04cH                 ; DOS call to exit with return code
  486.         int     021h                    ; back to DOS
  487.  __exit  endp
  488.  
  489. initrtns proc   near
  490.         push    esi                     ; save esi
  491.         mov     esi,offset DGROUP:xistart; get start addr of table
  492.         mov     edi,offset DGROUP:xiend  ; get end   addr of table
  493. init1:    cmp   esi,edi                 ; loop through the table
  494.           jae   init9                   ; - quit if done
  495.           sub   edi,4                   ; - point to start of entry
  496.           mov   eax,[edi]               ; - get address of routine
  497.           or    eax,eax                 ; - check for null entry
  498.           je    init1                   ; - try next one if it is null
  499.           call  eax                     ; - call initializer routine
  500.         jmp     init1                   ; endloop
  501. init9:  pop     esi                     ; restore esi
  502.         ret                             ; return
  503. initrtns endp
  504.  
  505.  
  506.         public  __GETDS
  507. __GETDS proc    near
  508.         mov     ds,cs:__saved_DS        ; load saved DS value
  509.         ret                             ; return
  510. __GETDS endp
  511.  
  512. _TEXT   ends
  513.  
  514.         end     _cstart_
  515.