home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / TC4OS22.ZIP / C0.ASM next >
Assembly Source File  |  1989-02-24  |  15KB  |  417 lines

  1.         PAGE    66,132
  2.         .286
  3. ;-----------------------------------------------------------------
  4. ;     C.ASM - Start Up Code for Turbo C 2.0 under OS/2           |
  5. ;     <For the LARGE Memory Model Only - No Floating Point>      |
  6. ;     <HardCoded Stack for convenience; recompile as needed>     |
  7. ;-----------------------------------------------------------------
  8.  
  9. _TEXT   SEGMENT BYTE PUBLIC 'CODE'
  10. _TEXT   ENDS
  11.  
  12. _DATA   SEGMENT PARA PUBLIC 'DATA'
  13. _DATA   ENDS
  14.  
  15. ;_CVTSEG SEGMENT WORD PUBLIC 'DATA'
  16. ;_CVTSEG ENDS
  17.  
  18. ;_SCNSEG SEGMENT WORD PUBLIC 'DATA'
  19. ;_SCNSEG ENDS
  20.  
  21. _BSS    SEGMENT WORD PUBLIC 'BSS'
  22. _BSS    ENDS
  23.  
  24. _BSSEND SEGMENT BYTE PUBLIC 'STACK'
  25. _BSSEND ENDS
  26.  
  27. _STACK  SEGMENT STACK 'STACK'
  28.         DB 2560 DUP('S')
  29. _STACK  ENDS
  30.  
  31. DGROUP  GROUP   _DATA, _BSS, _BSSEND
  32.  
  33.         ASSUME  CS:_TEXT, DS:DGROUP
  34.  
  35. STDERR equ 2
  36.  
  37. EXTRN _main         : FAR
  38. EXTRN DOSGETVERSION : FAR
  39. EXTRN DosExit       : FAR
  40. EXTRN DosWrite      : FAR
  41. EXTRN DosAllocSeg   : FAR
  42.  
  43. PUBLIC __exit, _abort, _reload_ds
  44. PUBLIC __RealCvtVector, __ScanTodVector
  45. ;PUBLIC __setargv
  46.  
  47.  
  48. ;------------------------------------------------------
  49. ; Start of Code                                       |
  50. ;------------------------------------------------------
  51. ;
  52. ; OS/2 Startup Conventions:
  53. ;
  54. ;     CS:IP  -  Program Entry Point
  55. ;     SS:SP  -  Top of Stack
  56. ;        DX  -  Stack Size
  57. ;        DS  -  Auto Data Segment
  58. ;        ES  -  0000
  59. ;        CX  -  Length of Data Segment (0 = 65536 bytes)
  60. ;        AX  -  Environment Segment Selector
  61. ;        BX  -  Command-Line Offset in Environment Segment
  62. ;        BP  -  0000
  63. ;
  64. _TEXT   SEGMENT
  65.  
  66. STARTX    PROC    NEAR
  67.           mov     __8087, -1            ; No 8087 support
  68.           mov     __envseg,ax           ; SEGMENT of environment
  69.           mov     __cmdline,bx          ; Offset of Command line string
  70.  
  71.           push    ax                    ; Get OS/2 Version
  72.           mov     ax,sp                 ; Return Info Version
  73.           push    ss                    ;  onto the stack
  74.           push    ax                    ; (SS:SP)
  75.           call    DOSGETVERSION         ; Get the OS/2 Version #
  76.           pop     ax                    ; retrieve it from the stack
  77.           xchg    ah,al                 ; and save it
  78.           mov     Word Ptr __version,ax
  79.  
  80. ; Calc size of environment
  81.  
  82.           les     di, Dword Ptr __envLng
  83.           mov     ax, di
  84.           mov     bx, ax
  85.           mov     cx, 07FFFh            ; Max size = 32k
  86.  
  87. NextVar:  repnz   scasb           ; Find Terminating NULL
  88.           jcxz    _abort          ; No NULL == bad environment
  89.           inc     bx              ; BX = # environment variables
  90.           cmp     es:[di], al
  91.           jne     NextVar         ; Next variable ...
  92.           or      ch, 10000000b
  93.           neg     cx
  94.           mov     __envLng, cx     ; Save Environment size
  95.           mov     cx, 2
  96.           shl     bx, cl
  97.           add     bx, 16
  98.           and     bx, not 15
  99.           mov     __envSize, bx   ; Save Environment Variables Nb.
  100.  
  101.           call    near ptr __setargv
  102.           call    near ptr __setenvp
  103.  
  104. ;       Clear un-initialized data
  105.  
  106.           mov     ax,DGROUP
  107.           mov     es, ax
  108.           xor     ax, ax
  109.           mov     di, offset DGROUP:_bdata
  110.           mov     cx, offset DGROUP:_edata
  111.           sub     cx, di
  112.           rep     stosb
  113.  
  114. ;       ExitCode = main(argc,argv,envp);
  115.  
  116.           push    word ptr _environ+2
  117.           push    word ptr _environ
  118.           push    word ptr __argv+2
  119.           push    word ptr __argv
  120.           push    __argc
  121.           call    _main
  122.  
  123. ;       Flush and close streams and files
  124.  
  125. __exit    PROC FAR
  126.           mov     ax,DGROUP
  127.           mov     ds,ax
  128.  
  129. ;       Exit to OS/2
  130.  
  131.           mov     cx,1
  132.           push    cx
  133.           xor     ax,ax
  134.           mov     al,[bp+4]
  135.           call far ptr DosExit
  136. __exit    ENDP
  137. STARTX    ENDP
  138.  
  139. ;-----------------------------------------------------------------
  140.  
  141. _abort    PROC    FAR
  142.           push    ds
  143.           mov     ax,STDERR
  144.           mov     cx,AbortMsgL
  145.           lds     si,Dword Ptr __cnt
  146.           les     di,Dword Ptr AbortMsg
  147.           push    ax                     ; handle
  148.           push    di                     ; Offset of msg
  149.           push    es                     ; Segment of msg
  150.           push    cx                     ; Length of msg
  151.           push    si                     ; Offset of o/p char cnt
  152.           push    ds                     ; Segment of o/p char cnt
  153.           call    far ptr DosWrite
  154.           pop     ds
  155.  
  156.           mov     ax, 3
  157.           push    ax
  158.           call    __exit                 ; _exit(3);
  159. _abort    ENDP
  160.  
  161. ;-----------------------------------------------------------------
  162.  
  163. _reload_ds      PROC    FAR             ; Though not used by the
  164.                 mov     ax,DGROUP       ; start-up code, some TC
  165.                 mov     ds,ax           ; run-times access this rtn
  166.                 ret
  167. _reload_ds      ENDP
  168.  
  169. ;-----------------------------------------------------------------
  170.  
  171. __setargv PROC NEAR
  172.  
  173. ;*-----------------------------------------------------*
  174. ;* Setup the argument string array (char *argv[])      *
  175. ;*-----------------------------------------------------*
  176.  
  177.           pop     ProcRet               ; Save return address
  178.           cld                           ; moves go forward
  179.  
  180.           mov     es, __envseg          ; Environment Segment
  181.           mov     si, __cmdline         ; ES: SI = Command Line address
  182.           mov     bp, es                ; Save for later use
  183.           sub     sp, 2                 ; Reserve SS:FFFF as unused
  184.  
  185.           mov     cx,07fh               ; max size of cmd line
  186.           mov     di,si                 ; point to start of pgm name
  187.           xor     ax,ax                 ; scan for NULL
  188.           repnz   scasb                 ; Find NULL at end of pgm name
  189.           jcxz    NoPgmName             ; No NULL found - abort pgm
  190.           push    cx                    ; save pgm name length
  191.           mov     dx, di                ; Ptr to start of parms
  192.           cmp     Byte Ptr Es:[di],0    ; is next byte also NULL?
  193.           je      NoCmdLn               ; Yes, skip space replacement
  194.           dec     di                    ; point at NULL again
  195.           mov     Byte Ptr Es:[di],' '  ; & replace w/ space
  196.  
  197. NoCmdLn:  repnz   scasb                 ; Find NULL at end of cmd line
  198.  
  199. NoPgmName: jcxz   BadPgmName            ; Not found - abort pgm
  200.           xor     cl, 07fh              ; CX = Total cmd line size
  201.           mov     bx,cx                 ; save in bx
  202.           pop     cx                    ;
  203.           xor     cx,07fh               ; length of pgm name
  204.  
  205.           mov     ax, bx                ; = total parm length rq'd
  206.           sub     bx,cx                 ; subtract from parm length
  207.           inc     ax                    ; Round up
  208.           and     ax, not 1             ; "      "
  209.           mov     di, sp                ; di = amt of space on stack
  210.           sub     di, ax                ; is there enough space?
  211.           jb      BadPgmName            ; no, abort program
  212.           mov     sp, di                ; SS:DI = Save Area Address
  213.  
  214. ;       Copy ProgName to the stack
  215.  
  216.           mov     ax, es                ; DS = ES
  217.           mov     ds, ax
  218.           mov     ax, ss                ; ES = SS
  219.           mov     es, ax
  220.           push    cx
  221.           rep     movsb
  222.           xor     al, al
  223.           stosb                         ; ASCIIZ string
  224.  
  225. ;       Process Command Line.
  226.           mov     ds, bp
  227.           xchg    si, dx          ; DS: SI = Command Line address
  228.           xchg    bx, cx          ; CX = length of parms
  229.           mov     ax, bx
  230.           mov     dx, ax          ; AX = BX = DX = 0
  231.           inc     bx              ; BX = No of arguments (at least 1)
  232.  
  233. ParseChar: call    NextChar
  234.           ja      NotQuote        ; Not a quote and there are more
  235.  
  236. ParmChar: jb      BuildArgv       ; Command line is empty now
  237.           call    NextChar
  238.           ja      ParmChar        ; Not a quote and there are more
  239.  
  240. NotQuote: cmp     al, ' '
  241.           je      EndArg          ; Space is an argument separator
  242.           cmp     al, 13
  243.           je      EndArg          ; \r    is an argument separator
  244.           cmp     al, 9
  245.           jne     ParseChar       ; \t    is an argument separator
  246.  
  247. EndArg:   xor     al, al          ; Space and TAB are argument separators
  248.           jmp     short ParseChar
  249.  
  250. ;   Character test function used in SetArgs
  251. ;        On entry AL holds the previous character
  252. ;        On exit  AL holds the next character
  253. ;               ZF on if the next character is quote (") and AL = 0
  254. ;               CF on if end of command line and AL = 0
  255.  
  256. NextChar  PROC    NEAR
  257.           or      ax, ax
  258.           jz      NxtCh0
  259.           inc     dx              ; DX = Actual length of CmdLine
  260.           stosb
  261.           or      al, al
  262.           jnz     NxtCh0
  263.           inc     bx              ; BX = Number of parameters
  264.  
  265. NxtCh0:   xchg    ah, al
  266.           xor     al, al
  267.           stc
  268.           jcxz    NxtCh2          ; End of command line --> CF ON
  269.           lodsb
  270.           dec     cx
  271.           sub     al, '"'
  272.           jz      NxtCh2          ; Quote found --> AL = 0 and ZF ON
  273.           add     al, '"'
  274.           cmp     al,'\'
  275.           jne     NxtCh1          ; It is not a \
  276.           cmp     byte ptr ds:[si], '"'
  277.           jne     NxtCh1          ; Only " is transparent after \
  278.           lodsb
  279.  
  280. NxtCh1:   or      si, si          ; Be sure both CF & ZF are OFF
  281.  
  282. NxtCh2:   ret
  283.  
  284. NextChar  ENDP
  285.  
  286. ;       Invalid program name
  287.  
  288. BadPgmName:
  289.           jmp     _abort          ; Something wrong with cmd line
  290.  
  291. ;       Now, build the argv array
  292.  
  293. BuildArgv:
  294.           mov     ax, DGROUP
  295.           mov     ds, ax          ; restore DS
  296.           pop     cx              ; Restore length of pgm name
  297.           add     cx, dx          ; Calc total space needed for parms
  298.           mov     __argc, bx      ; bx = argument count
  299.           inc     bx              ; add 1 for terminating NULL argument
  300.           add     bx, bx          ; multiply by 4 to compute space
  301.           add     bx, bx          ; required for pointers (4 bytes per)
  302.           mov     si, sp          ;
  303.           mov     bp, sp
  304.           sub     bp, bx          ; Is there room left for the ptrs?
  305.           jb      BadPgmName      ; no, abort the pgm
  306.           mov     sp, bp          ; SS:BP = argv array address
  307.           mov     word ptr __argv, bp
  308.           mov     word ptr __argv+2, ss
  309.  
  310. SetArg:   jcxz    LastArg         ; last arg; get out
  311.           mov     [bp], si        ; Set argv[n]
  312.           mov     [bp+2], ss
  313.           add     bp, 4           ; and point to location for next
  314.  
  315. CopyArg:  lods    byte ptr ss:[si]
  316.           or      al, al          ; and copy argument into the
  317.           loopnz  CopyArg         ; stack space reserved for it
  318.           jz      SetArg
  319.  
  320. LastArg:  xor     ax, ax         ; add terminating NULL pointer
  321.           mov     [bp], ax       ; as last argument
  322.           mov     [bp+2], ax
  323.           mov     dx, ProcRet
  324.           jmp     dx
  325. __setargv ENDP
  326.  
  327. ;-----------------------------------------------------------------
  328.  
  329. __setenvp PROC NEAR
  330.  
  331. ;*-----------------------------------------------------*
  332. ;* Setup the environment.  Since we only allow the     *
  333. ;* LARGE memory model, we don't have to worry about    *
  334. ;* creating a copy in our own data segment.            *
  335. ;*-----------------------------------------------------*
  336.  
  337.           push    __envSize             ; # bytes needed
  338.           mov     ax, SEG _environ      ; pointer
  339.           push    ax                    ;    to
  340.           mov     ax, OFFSET _environ+2 ;      addr of
  341.           push    ax                    ;         new environ
  342.           push    1                     ; New segment is shareable
  343.           call    DosAllocSeg           ; Allocate Memory
  344.           or      ax,ax                 ; OK?
  345.           jz      BldEnv                ; No - no memory;  abort
  346.           jmp     _abort
  347.  
  348. BldEnv:   mov     es, __envseg          ; ES = Original environment
  349.           push    ds                    ; Save DS
  350.           mov     ds,Word Ptr _environ+2 ; DS = New environment
  351.           xor     di, di                ; ES:DI = start of environ
  352.           xor     ax, ax
  353.           xor     bx, bx                ; Offset into new environ
  354.           mov     cx, -1
  355.  
  356. BldEnv0:  mov     [bx], di              ; store 1st parm
  357.           mov     [bx+2], es            ;
  358.           add     bx, 4                 ; adjust for next pointer
  359.           repnz   scasb                 ; find next parm
  360.           cmp     es:[di], al           ; end of environ?
  361.           jne     BldEnv0               ; Build next pointer
  362.           mov     [bx], ax              ; NULL Ptr to terminate
  363.           mov     [bx+2], ax
  364.           pop     ds                    ; restore correct DS
  365.           ret
  366. __setenvp ENDP
  367.  
  368.  
  369. _TEXT   ENDS
  370.  
  371. _DATA   SEGMENT
  372.  
  373. AbortMsg        db      'Abnormal program termination', 13, 10
  374. AbortMsgL       equ     $ - AbortMsg
  375.  
  376. __argc           dw 0                   ; # args in cmd line
  377. __argv           dd 0                   ; ptr to array of argv[]'s
  378. _environ         dd 0                   ; address of our environment
  379. PUBLIC _environ
  380. __envLng         dw 0                   ; offset of environment
  381. __envseg         dw 0                   ; data segment of environment
  382. __envSize        dw 0                   ; size of environment
  383.  
  384. __version        label word             ; os/2 version #'s
  385. __osmajor        db 0
  386. __osminor        db 0
  387.  
  388. _errno           dw 0                   ; used by library routines only
  389. __8087           dw 0                   ; 8087 support yes or no
  390. __cnt            dw 0                   ; offset of cmd line in environ
  391. __cmdline        dw 0
  392.  
  393. ;;__heapbase       dd 0                   ; lowest heap position
  394. ;;__brklvl         dd 0                   ;
  395. ;;__heaptop        dd 0                   ; highest heap location
  396.  
  397. ProcRet            dw      ?              ; for psuedo RET's
  398.  
  399. _DATA   ENDS
  400.  
  401. _CVTSEG SEGMENT
  402. __RealCvtVector label word
  403. _CVTSEG ENDS
  404.  
  405. _SCNSEG SEGMENT
  406. __ScanTodVector label word
  407. _SCNSEG ENDS
  408.  
  409. _BSS    SEGMENT
  410. _bdata  label   byte
  411. _BSS    ENDS
  412.  
  413. _BSSEND SEGMENT
  414. _edata  label   byte
  415. _BSSEND ENDS
  416.         END     STARTX
  417.