home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c496 / 1.img / STARTUP.386 / CSTART3R.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-08-20  |  16.0 KB  |  400 lines

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