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