home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c500 / 1.ddi / STARTUP.ADS / ADSSTART.ASM
Encoding:
Assembly Source File  |  1992-05-28  |  21.4 KB  |  575 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. ;%       This module was modified for use with AutoCAD's protect   %
  10. ;%       mode ADI and ADS.  AutoCAD is a registered trademark of   %
  11. ;%       Autodesk, Inc.                                            %
  12. ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  13. ;
  14. ; startup code for WATCOM C 386 Version 9.0
  15. ;
  16. ;       This must be assembled using the following command:
  17. ;               386asm adsstart
  18. ;
  19.         name    adsstart
  20.  
  21. .387
  22. .386p
  23.  
  24. comment @
  25.         Modified for AutoLISP and protect mode ADI
  26.  
  27.         Expects to be called at starting address as a subroutine, rather
  28.         than as an executable program from the operating system.  Stack
  29.         and segment registers must be correctly set up; and some
  30.         additional information is expected in these registers:
  31.  
  32.         ECX     Compatibility-check value.  Must be equal to (our
  33.                 locally defined symbol) chkval.  If it isn't, we assume
  34.                 we are erroneously being executed as an independent
  35.                 separate program.  This won't work, so we exit
  36.                 immediately to the system.
  37.  
  38.         DS:ESI  Pointer to structure containing initialization information.
  39.                 A minimum structure size of 8 bytes is mandatory (12 bytes
  40.                 if PADI is set).  The first 4 bytes of the structure must
  41.                 contain the number of bytes making up the structure.  The
  42.                 second 4 bytes must contain the initial heapsize of the
  43.                 child process, obtained from the loader in AutoCAD.  If
  44.                 PADI is set, the third 4 bytes must contain the physical
  45.                 address of the packet buffer in AutoCAD to be used for
  46.                 communication with protect mode ADI drivers.  All subsequent
  47.                 bytes are the business between AutoCAD and the loaded child
  48.                 process and may vary.
  49.  
  50.         The value we return is the argument to exit() which terminates us.
  51.         We preserve no registers, not even SS and SP.
  52.  
  53.         Some protected mode ADI, ADS, and AutoLISP modifications are
  54.         conditioned on the tag ACAD.
  55.  
  56.         Some code for ADS only is included only if the tag ADS is
  57.         predefined (e.g., in the assembler command line).
  58.  
  59.         Code required for AutoCAD protected mode ADI drivers only is included
  60.         by setting PADI in the assembler command line.
  61.         @
  62.  
  63. ACAD   equ  1   ; Protect mode ADI and AutoLISP version of module.
  64. minmem equ  4   ; Offset within the structure containing initialization
  65.                 ; information to the inital heap size of the child process.
  66. ifdef   PADI
  67. physadr equ 8   ; Offset within the structure containing initialization
  68.                 ; information to the physical address of a buffer shared
  69.                 ; between AutoCAD and a protect mode ADI driver.
  70. endif   ; PADI
  71.  
  72.  
  73.         assume  nothing
  74.  
  75.         extrn   __CMain         : near
  76.     extrn    __InitRtns    : near
  77.     extrn    __FiniRtns    : near
  78. ife     ACAD
  79.         extrn   __SAVDS         : near
  80. endif   ; ACAD
  81.         extrn   __DOSseg__      : near
  82.  
  83. if      ACAD
  84. ifdef   ADS
  85. getinitinfo     equ    adsi_getinitinfo
  86. map_phys_mem    equ    ads_map_phys_mem
  87. endif   ; ADS
  88. ifndef  PADI
  89.         extrn   getinitinfo     : near          ; initialize child process
  90.                                                 ; loaded by AutoCAD
  91. endif   ; !PADI
  92. ;
  93. ; map_phys_mem allows a 3rd party to install a routine to map physical
  94. ; memory between the stack and heap
  95. ;
  96. extrn   map_phys_mem            : near
  97. endif   ; ACAD
  98.  
  99.         extrn   _edata          : byte          ; end of DATA (start of BSS)
  100.         extrn   _end            : byte          ; end of BSS (start of STACK)
  101.  
  102.         extrn   _dynend         : dword
  103.         extrn   _curbrk         : dword
  104.         extrn   _psp            : word
  105.         extrn   _osmajor        : byte
  106.         extrn   _osminor        : byte
  107.         extrn   _STACKLOW       : dword
  108.         extrn   _STACKTOP       : dword
  109.         extrn   _child          : dword
  110.         extrn  __no87           : word
  111.         extrn   _Extender       : byte
  112.         extrn   _Envptr         : dword
  113.         extrn   _Envseg         : word
  114.         extrn   __FPE_handler   : dword
  115.         extrn  ___FPE_handler   : dword
  116.     extrn    _LpCmdLine    : dword
  117.     extrn    _LpPgmName    : dword
  118.  
  119. DGROUP group _NULL,_AFTERNULL,CONST,_DATA,DATA,XIB,XI,XIE,YIB,YI,YIE,_BSS,STACK
  120.  
  121. ; this guarantees that no function pointer will equal NULL
  122. ; (WLINK will keep segment 'BEGTEXT' in front)
  123.  
  124. BEGTEXT  segment use32 word public 'CODE'
  125.         assume  cs:BEGTEXT
  126. forever: jmp    short forever
  127.         assume  cs:nothing
  128. BEGTEXT  ends
  129.  
  130. _TEXT   segment use32 word public 'CODE'
  131.  
  132.         assume  ds:DGROUP
  133.  
  134. _NULL   segment para public 'BEGDATA'
  135. __nullarea label word
  136.         db      01h,01h,01h,00h
  137.         public  __nullarea
  138. _NULL   ends
  139.  
  140. _AFTERNULL segment word public 'BEGDATA'
  141. _AFTERNULL ends
  142.  
  143. CONST   segment word public 'DATA'
  144. CONST   ends
  145.  
  146. XIB     segment word public 'DATA'
  147. XIB     ends
  148. XI      segment word public 'DATA'
  149. XI      ends
  150. XIE     segment word public 'DATA'
  151. XIE     ends
  152.  
  153. YIB     segment word public 'DATA'
  154. YIB     ends
  155. YI      segment word public 'DATA'
  156. YI      ends
  157. YIE     segment word public 'DATA'
  158. YIE     ends
  159.  
  160.  
  161. _DATA   segment dword public 'DATA'
  162.  
  163. if      ACAD
  164. chkval  equ     1234            ; magic interface-compatibility code
  165. ifndef  ADS                     ; Avoid excess globals for ADS
  166.         public   brkflg, stkflg
  167.         public   info_off, info_sel
  168. endif   ; ADS
  169.         public  __fsavcw
  170. ifdef   PADI
  171.         public  cbufadr
  172.         align 4
  173. cbufadr  dd     0               ; ptr to common pg between ACAD and PADI
  174. phys_adr  dd    0               ; physical address of common page
  175. endif   ; PADI
  176. brkflg   dd     0               ; set nonzero for Control C
  177. stkflg   dd     0               ; set nonzero for stack overflow
  178. info_off dd     0               ; Offset of initialization info struct
  179. info_sel dw     0               ; Selector of initialization info struct
  180. rtnaddr   df    0               ; Caller's return address.
  181. min_mem   dd    0               ; inital driver heap size
  182. sav_ds    dw    0
  183. my_ds     dw    0
  184. __fsavcw  dw    0               ; for saving AutoLISP's floating point cntl word
  185. interr    db    "Incompatible program interface",0Dh,0Ah,"$"
  186. endif   ; ACAD
  187.  
  188. _DATA   ends
  189.  
  190. DATA    segment word public 'DATA'
  191. DATA    ends
  192.  
  193. _BSS          segment word public 'BSS'
  194. _BSS          ends
  195.  
  196. if      ACAD
  197. STACK_SIZE      equ     4000h
  198. else
  199. STACK_SIZE      equ     1000h
  200. endif   ; ACAD
  201.  
  202. STACK   segment para stack 'STACK'
  203. stk     label   word
  204.         db      (STACK_SIZE) dup(?)
  205. STACK   ends
  206.  
  207.  
  208.         assume  nothing
  209.         public  _cstart_
  210.         public   __exit
  211.  
  212.         assume  cs:_TEXT
  213.  
  214. _cstart_ proc near
  215.         jmp     short around
  216.  
  217. ;
  218. ; copyright message
  219. ;
  220.         db      "WATCOM C 386 Run-Time system. "
  221.         db      "(c) Copyright by WATCOM Systems Inc. 1989, 1991."
  222.         db      " All rights reserved."
  223. ;
  224. ; miscellaneous code-segment messages
  225. ;
  226. ConsoleName     db      "con",00h
  227.  
  228. around: sti                             ; enable interrupts
  229.  
  230.         assume  ds:DGROUP
  231.  
  232. PSP_SEG equ     24h
  233. ENV_SEG equ     2ch
  234.  
  235. if      ACAD
  236.         ; Save AutoLISP's floating point control word, to be restored by
  237.         ; adsi_farcl() before returning to AutoLISP
  238. ifndef  EADI
  239.         fnstcw  __fsavcw
  240. endif
  241.  
  242.         cmp     ecx,chkval              ; Proper chkval argument?
  243.         je      m00
  244.         mov     edx,offset interr       ; "Incompatible program interface"
  245.         mov     ah,9
  246.         int     21h                     ; Print message.
  247.         mov     ax,4C01h
  248.         int     21h                     ; Exit to DOS.
  249. m00:
  250.         mov     info_off,esi            ; offset of initialization info struct
  251.         mov     info_sel,dx             ; selector of info struct
  252.         mov     es,dx
  253.         mov     eax,es:[esi].minmem
  254.         mov     min_mem,eax             ; initial heap size of driver
  255. ifdef   PADI
  256.         mov     eax,es:[esi].physadr
  257.         mov     phys_adr,eax            ; phys addr of pg w/ PADI packet buffer
  258. endif   ; PADI
  259.         mov     ax,ds
  260.         mov     es,ax
  261.         pop     dword ptr rtnaddr       ; Save return address, offset
  262.         pop     ax
  263.         mov     word ptr rtnaddr+4,ax   ;    and segment.
  264.         mov     my_ds,ds                ; Save DS for use in __SAVDS()
  265. endif   ; ACAD
  266.  
  267.         mov     ax,PSP_SEG              ; get segment address of PSP
  268.         mov      _psp,ax                ; save segment address of PSP
  269.         mov     es,ax                   ; point to PSP
  270.         and     esp,0fffffffch          ; make sure stack is on a 4 byte bdry
  271.         mov     ebx,esp                 ; get sp
  272.         mov      _STACKTOP,ebx          ; set stack top
  273.         mov      _curbrk,ebx            ; set first available memory location
  274. ;
  275. ;       get DOS & Extender version number
  276. ;
  277.         mov     ebx,'PHAR'              ; set ebx to 0
  278.         sub     eax,eax                 ; set eax to 0
  279.         mov     ah,30h
  280.         int     21h                     ; modifies eax,ebx,ecx,edx
  281.         mov      _osmajor,al
  282.         mov      _osminor,ah
  283.         mov     ecx,eax                 ; remember DOS version number
  284.         shr     eax,16                  ; get top 16 bits of eax
  285.         cmp     ax,'DX'                 ; if top 16 bits = "DX"
  286.         sete    al                      ; then its Pharlap
  287.         jne     not_pharlap             ; if its pharlap
  288.         sub     bl,'0'                  ; - save major version number
  289.         mov     al,bl                   ; - (was in ascii)
  290.         mov     bx,14h                  ; - get value of Phar Lap data segment
  291.         jmp     short know_extender     ; else
  292. not_pharlap:                            ; - see if Rational DOS/4G
  293.         mov     dx,78h                  ; - ...
  294.         mov     ax,0FF00h               ; - ...
  295.         int     21h                     ; - ...
  296.         mov     bx,17h                  ; - get writeable code segment for Ergo
  297.         cmp     al,0                    ; - ...
  298.         je      short know_extender     ; - quit if not Rational DOS/4G
  299.         mov     al,1                    ; - indicate Rational 32-bit Extender
  300.         mov     bx,ds                   ; - just use ds (FLAT model)
  301.         mov      _psp,es                ; - save segment address of PSP
  302. ;
  303. know_extender:                          ; endif
  304.         mov      _Extender,al           ; record extender type
  305. ;;      mov     es,bx                   ; get access to code segment
  306. ;;      mov     es:__saved_DS,ds        ; save DS value
  307.  
  308. ;
  309. ;       copy command line into bottom of stack
  310. ;
  311.         mov     es, _psp                ; point to PSP
  312.         mov     edx,offset DGROUP:_end
  313.         add     edx,0FH
  314.         and     edx,0FFFFFFF0H
  315.         mov     edi,81H                 ; DOS command buffer es:edi
  316.         sub     ecx,ecx
  317.         mov     cl,es:[edi-1]           ; get length of command
  318.         cld                             ; set direction forward
  319.         mov     al,' '
  320.         rep     scasb
  321.         lea     esi,-1[edi]
  322.         mov     edi,edx
  323.         mov     bx,es
  324.         mov     dx,ds
  325.         mov     ds,bx
  326.         mov     es,dx                   ; es:edi is destination
  327.         je      noparm
  328.         inc     ecx
  329.         rep     movsb
  330. noparm: sub     al,al
  331.         stosb                           ; store NULLCHAR
  332.         mov     al,0                    ; assume no pgm name
  333.         stosb                           ; . . .
  334.         dec     edi                     ; back up pointer 1
  335.         push    edi                     ; save pointer to pgm name
  336.         mov     ds,dx                   ; restore ds
  337.         push    ds                      ; save ds
  338.  
  339.         cmp     byte ptr  _Extender,1   ; if OS/386 or Rational
  340.         jg      short pharlap           ; then
  341.           mov   dx,PSP_SEG              ; - get PSP segment descriptor
  342.           mov   ds,dx                   ; - ... into ds
  343.           mov   dx,ds:[02ch]            ; - get environment segment into dx
  344.           jmp   short haveenv           ; else
  345. pharlap:mov   dx,ENV_SEG                ; - PharLap environment segment
  346. haveenv:                                ; endif
  347.         mov     es: _Envseg,dx          ; save segment of environment area
  348.         mov     ds,dx                   ; get segment addr of environment area
  349.         sub     ebp,ebp                 ; assume "no87" env. var. not present
  350.         sub     esi,esi                 ; offset 0
  351.         mov     es: _Envptr,esi         ; save offset of environment area
  352. L1:     mov     eax,[esi]               ; get first 4 characters
  353.         or      eax,20202020h           ; map to lower case
  354.         cmp     eax,'78on'              ; check for "no87"
  355.         jne     short L2                ; skip if not "no87"
  356.         cmp     byte ptr 4[esi],'='     ; make sure next char is "="
  357.         jne     short L2                ; no
  358.         inc     ebp                     ; - indicate "no87" was present
  359. L2:     cmp     byte ptr [esi],0        ; end of string ?
  360.         lodsb
  361.         jne     L2                      ; until end of string
  362.         cmp     byte ptr [esi],0        ; end of all strings ?
  363.         jne     L1                      ; if not, then skip next string
  364.         lodsb
  365.         inc     esi                     ; point to program name
  366.         inc     esi                     ; . . .
  367. ;
  368. ;       copy the program name into bottom of stack
  369. ;
  370. L3:     cmp     byte ptr [esi],0        ; end of pgm name ?
  371.         movsb                           ; copy a byte
  372.         jne     L3                      ; until end of pgm name
  373.         pop     ds                      ; restore ds
  374.         pop     esi                     ; restore address of pgm name
  375.         mov     ebx,esp                 ; end of stack in data segment
  376.  
  377.  
  378.         assume  ds:DGROUP
  379. if      ACAD
  380.  ifdef   EADI
  381.     mov    bp,1            ; force "no87" env. var as present
  382.  endif
  383. endif    ; ACAD
  384.         mov     __no87,bp               ; set state of "no87" environment var
  385.  
  386.         mov      _STACKLOW,edi          ; save low address of stack
  387.  
  388. if      ACAD
  389.  
  390. ifdef   PADI
  391.         add     ebx,4095                ; round top of stack up a page
  392.         shr     ebx,12                  ; get number of pages
  393.         push    ebx                     ; store for later use
  394.         push    ds
  395.         pop     es
  396.         mov     ah,4Ah                  ; set PADI memory size to smallest #
  397.         int     21h                     ;   of pages ecompassing top of stack
  398.  
  399.         mov     ebx,phys_adr            ; get phys addr of pg w/ packet buffer
  400.         mov     eax,250Ah
  401.         mov     ecx,1
  402.         int     21h                     ; map pg w/ pkt buf to end of new PADI
  403.                                         ;   memory block, above top of stack
  404.         mov     cbufadr,eax             ; store mapped offset as ptr to buf
  405.  
  406.         call    map_phys_mem            ; allow 3rd party a chance to map in
  407.                                         ;   phys mem (returns # of pgs mapped)
  408.         pop     ebx                     ; get # of pgs to top of stack
  409.         inc     ebx                     ; add 1 for page mapped to end of seg
  410.         add     ebx,eax                 ; add add'l pgs mapped by 3rd party
  411.         shl     ebx,12                  ; get bottom of heap, in bytes
  412.         mov     _dynend,ebx             ; set top of dynamic memory area
  413.         mov     _curbrk,ebx             ; set bottom of dynamic memory area
  414. else    ; PADI
  415.         add     ebx,4095                ; round it up a page
  416.         shr     ebx,12                  ; get number of pages
  417.         push    ebx                     ; store for later use
  418.         push    ds
  419.         pop     es
  420.         mov     ah,4Ah                  ; set memory size to smallest #
  421.         int     21h                     ;   of pages encompassing top of stack
  422.  
  423.         call    map_phys_mem            ; allow 3rd party a chance to map in
  424.                                         ;   phys mem (returns # of pgs mapped)
  425.         pop     ebx                     ; Get # of pgs to top of stack
  426.         add     ebx,eax                 ; If so, add it in
  427.         shl     ebx,12                  ; Get bottom of heap, in bytes
  428.         mov     _curbrk,ebx             ; set bottom of dynamic memory area
  429.         mov     _dynend,ebx             ; set top of dynamic memory area
  430. endif   ; PADI
  431.         ;mov    ????,min_mem            ; initial size of heap
  432. else    ; ACAD
  433.         mov      _dynend,ebx            ; set top of dynamic memory area
  434. endif   ; ACAD
  435.  
  436.         mov     ecx,offset DGROUP:_end  ; end of _BSS segment (start of STACK)
  437.         mov     edi,offset DGROUP:_edata; start of _BSS segment
  438.         sub     ecx,edi                 ; calc # of bytes in _BSS segment
  439.         mov     dl,cl                   ; save bottom 2 bits of count in edx
  440.         shr     ecx,2                   ; calc # of dwords
  441.         sub     eax,eax                 ; zero the _BSS segment
  442.         rep     stosd                   ; ...
  443.         mov     cl,dl                   ; get bottom 2 bits of count
  444.         and     cl,3                    ; ...
  445.         rep     stosb                   ; ...
  446.  
  447.         mov     eax,offset DGROUP:_end  ; cmd buffer pointed at by EAX
  448.         add     eax,0FH
  449.         and     al,0F0H
  450.     mov     _LpCmdLine,eax        ; save command line address
  451.     mov     _LpPgmName,esi        ; save program name address
  452.         call    __InitRtns        ; call initializer routines
  453.  
  454. if      ACAD
  455. ifndef  PADI
  456. Comment @
  457.         Take information from a structure in AutoCAD, pointed to by
  458.         info_sel:info_off, and store it for use by routines in the
  459.         program loaded by AutoCAD to which this module is linked.
  460.         @
  461.         movzx   eax,word ptr info_sel
  462.         push    eax
  463.         push    info_off
  464.         call    getinitinfo
  465.         add     esp,8
  466. endif
  467. endif
  468.  
  469.         push    es
  470.         mov     cl,3
  471.         mov     ax,2502h
  472.         int     21h
  473.         jc      noi3
  474.         mov     ax,es
  475.         verr    ax
  476.         jnz     noi3
  477.         cmp     ebx,8
  478.         jb      noi3
  479.         sub     ebx,8
  480.         mov     eax,es:[ebx]
  481.         cmp     eax,'DIVW'
  482.         jne     noi3
  483.         mov     eax,es:4[ebx]
  484.         cmp     eax,'!!OE'
  485.         jne     noi3
  486.         int     3
  487. noi3:   pop     es
  488.  
  489.     sub    ebp,ebp            ; ebp=0 indicates end of ebp chain
  490.         call    __CMain
  491. _cstart_ endp
  492.  
  493.  
  494. if      ACAD
  495. comment @
  496.         For applications which are called as a subroutine from AutoCAD
  497.         (namely AutoLISP), here is the ultimate exit point which returns
  498.         back to AutoCAD.
  499.         @
  500. ifdef   PADI
  501.         public   exit_to_acad
  502. exit_to_acad:
  503.         jmp   rtnaddr                   ; Return to AutoCAD
  504. endif
  505.  
  506.  
  507. ;       Where we want attempted program exits to go:
  508. ifdef   ADS
  509. child_exit    equ    adsi_child_exit     ; Adhere to ADS naming convention
  510. endif
  511.               extrn  child_exit:near
  512. endif   ; ACAD
  513.  
  514.  
  515. ;       don't touch AL in __exit_, it has the return code
  516.  
  517.  
  518.  __exit  proc near
  519.  
  520.         jmp     short   ok
  521.  
  522.         public   __exit_with_msg
  523.  
  524. ; input: EAX - pointer to message to print
  525. ;        EDX - exit code
  526.  
  527.  __exit_with_msg:
  528.         push    edx                     ; save return code
  529.         push    eax                     ; save address of msg
  530.         mov     edx,offset ConsoleName
  531.         mov     ax,03d01h               ; write-only access to screen
  532.         int     021h
  533.         mov     bx,ax                   ; get file handle
  534.         pop     edx                     ; restore address of msg
  535.         mov     esi,edx                 ; get address of msg
  536.         cld                             ; make sure direction forward
  537. L4:     lodsb                           ; get char
  538.         cmp     al,0                    ; end of string?
  539.         jne     L4                      ; no
  540.         mov     ecx,esi                 ; calc length of string
  541.         sub     ecx,edx                 ; . . .
  542.         dec     ecx                     ; . . .
  543.         mov     ah,040h                 ; write out the string
  544.         int     021h                    ; . . .
  545.         pop     eax                     ; restore return code
  546. ok:
  547.  
  548.         push    eax                     ; save return code
  549.     call    __FiniRtns        ; call finalizer routines
  550.         pop     eax                     ; restore return code
  551.  
  552. if      ACAD
  553.         jmp     child_exit              ; do something more appropriate
  554. else    ; ACAD
  555.         mov     ah,04cH                 ; DOS call to exit with return code
  556.         int     021h                    ; back to DOS
  557. endif   ; ACAD
  558.  
  559.  __exit  endp
  560.  
  561.  
  562. __null_FPE_rtn proc near
  563.         ret                             ; return
  564. __null_FPE_rtn endp
  565.  
  566.         public  __GETDS
  567. __GETDS proc    near
  568.         mov     ds,cs:my_ds             ; load saved DS value
  569.         ret
  570. __GETDS endp
  571.  
  572. _TEXT   ends
  573.  
  574.         end     _cstart_
  575.