home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
TC4OS22.ZIP
/
C0.ASM
next >
Wrap
Assembly Source File
|
1989-02-24
|
15KB
|
417 lines
PAGE 66,132
.286
;-----------------------------------------------------------------
; C.ASM - Start Up Code for Turbo C 2.0 under OS/2 |
; <For the LARGE Memory Model Only - No Floating Point> |
; <HardCoded Stack for convenience; recompile as needed> |
;-----------------------------------------------------------------
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT PARA PUBLIC 'DATA'
_DATA ENDS
;_CVTSEG SEGMENT WORD PUBLIC 'DATA'
;_CVTSEG ENDS
;_SCNSEG SEGMENT WORD PUBLIC 'DATA'
;_SCNSEG ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_BSSEND SEGMENT BYTE PUBLIC 'STACK'
_BSSEND ENDS
_STACK SEGMENT STACK 'STACK'
DB 2560 DUP('S')
_STACK ENDS
DGROUP GROUP _DATA, _BSS, _BSSEND
ASSUME CS:_TEXT, DS:DGROUP
STDERR equ 2
EXTRN _main : FAR
EXTRN DOSGETVERSION : FAR
EXTRN DosExit : FAR
EXTRN DosWrite : FAR
EXTRN DosAllocSeg : FAR
PUBLIC __exit, _abort, _reload_ds
PUBLIC __RealCvtVector, __ScanTodVector
;PUBLIC __setargv
;------------------------------------------------------
; Start of Code |
;------------------------------------------------------
;
; OS/2 Startup Conventions:
;
; CS:IP - Program Entry Point
; SS:SP - Top of Stack
; DX - Stack Size
; DS - Auto Data Segment
; ES - 0000
; CX - Length of Data Segment (0 = 65536 bytes)
; AX - Environment Segment Selector
; BX - Command-Line Offset in Environment Segment
; BP - 0000
;
_TEXT SEGMENT
STARTX PROC NEAR
mov __8087, -1 ; No 8087 support
mov __envseg,ax ; SEGMENT of environment
mov __cmdline,bx ; Offset of Command line string
push ax ; Get OS/2 Version
mov ax,sp ; Return Info Version
push ss ; onto the stack
push ax ; (SS:SP)
call DOSGETVERSION ; Get the OS/2 Version #
pop ax ; retrieve it from the stack
xchg ah,al ; and save it
mov Word Ptr __version,ax
; Calc size of environment
les di, Dword Ptr __envLng
mov ax, di
mov bx, ax
mov cx, 07FFFh ; Max size = 32k
NextVar: repnz scasb ; Find Terminating NULL
jcxz _abort ; No NULL == bad environment
inc bx ; BX = # environment variables
cmp es:[di], al
jne NextVar ; Next variable ...
or ch, 10000000b
neg cx
mov __envLng, cx ; Save Environment size
mov cx, 2
shl bx, cl
add bx, 16
and bx, not 15
mov __envSize, bx ; Save Environment Variables Nb.
call near ptr __setargv
call near ptr __setenvp
; Clear un-initialized data
mov ax,DGROUP
mov es, ax
xor ax, ax
mov di, offset DGROUP:_bdata
mov cx, offset DGROUP:_edata
sub cx, di
rep stosb
; ExitCode = main(argc,argv,envp);
push word ptr _environ+2
push word ptr _environ
push word ptr __argv+2
push word ptr __argv
push __argc
call _main
; Flush and close streams and files
__exit PROC FAR
mov ax,DGROUP
mov ds,ax
; Exit to OS/2
mov cx,1
push cx
xor ax,ax
mov al,[bp+4]
call far ptr DosExit
__exit ENDP
STARTX ENDP
;-----------------------------------------------------------------
_abort PROC FAR
push ds
mov ax,STDERR
mov cx,AbortMsgL
lds si,Dword Ptr __cnt
les di,Dword Ptr AbortMsg
push ax ; handle
push di ; Offset of msg
push es ; Segment of msg
push cx ; Length of msg
push si ; Offset of o/p char cnt
push ds ; Segment of o/p char cnt
call far ptr DosWrite
pop ds
mov ax, 3
push ax
call __exit ; _exit(3);
_abort ENDP
;-----------------------------------------------------------------
_reload_ds PROC FAR ; Though not used by the
mov ax,DGROUP ; start-up code, some TC
mov ds,ax ; run-times access this rtn
ret
_reload_ds ENDP
;-----------------------------------------------------------------
__setargv PROC NEAR
;*-----------------------------------------------------*
;* Setup the argument string array (char *argv[]) *
;*-----------------------------------------------------*
pop ProcRet ; Save return address
cld ; moves go forward
mov es, __envseg ; Environment Segment
mov si, __cmdline ; ES: SI = Command Line address
mov bp, es ; Save for later use
sub sp, 2 ; Reserve SS:FFFF as unused
mov cx,07fh ; max size of cmd line
mov di,si ; point to start of pgm name
xor ax,ax ; scan for NULL
repnz scasb ; Find NULL at end of pgm name
jcxz NoPgmName ; No NULL found - abort pgm
push cx ; save pgm name length
mov dx, di ; Ptr to start of parms
cmp Byte Ptr Es:[di],0 ; is next byte also NULL?
je NoCmdLn ; Yes, skip space replacement
dec di ; point at NULL again
mov Byte Ptr Es:[di],' ' ; & replace w/ space
NoCmdLn: repnz scasb ; Find NULL at end of cmd line
NoPgmName: jcxz BadPgmName ; Not found - abort pgm
xor cl, 07fh ; CX = Total cmd line size
mov bx,cx ; save in bx
pop cx ;
xor cx,07fh ; length of pgm name
mov ax, bx ; = total parm length rq'd
sub bx,cx ; subtract from parm length
inc ax ; Round up
and ax, not 1 ; " "
mov di, sp ; di = amt of space on stack
sub di, ax ; is there enough space?
jb BadPgmName ; no, abort program
mov sp, di ; SS:DI = Save Area Address
; Copy ProgName to the stack
mov ax, es ; DS = ES
mov ds, ax
mov ax, ss ; ES = SS
mov es, ax
push cx
rep movsb
xor al, al
stosb ; ASCIIZ string
; Process Command Line.
mov ds, bp
xchg si, dx ; DS: SI = Command Line address
xchg bx, cx ; CX = length of parms
mov ax, bx
mov dx, ax ; AX = BX = DX = 0
inc bx ; BX = No of arguments (at least 1)
ParseChar: call NextChar
ja NotQuote ; Not a quote and there are more
ParmChar: jb BuildArgv ; Command line is empty now
call NextChar
ja ParmChar ; Not a quote and there are more
NotQuote: cmp al, ' '
je EndArg ; Space is an argument separator
cmp al, 13
je EndArg ; \r is an argument separator
cmp al, 9
jne ParseChar ; \t is an argument separator
EndArg: xor al, al ; Space and TAB are argument separators
jmp short ParseChar
; Character test function used in SetArgs
; On entry AL holds the previous character
; On exit AL holds the next character
; ZF on if the next character is quote (") and AL = 0
; CF on if end of command line and AL = 0
NextChar PROC NEAR
or ax, ax
jz NxtCh0
inc dx ; DX = Actual length of CmdLine
stosb
or al, al
jnz NxtCh0
inc bx ; BX = Number of parameters
NxtCh0: xchg ah, al
xor al, al
stc
jcxz NxtCh2 ; End of command line --> CF ON
lodsb
dec cx
sub al, '"'
jz NxtCh2 ; Quote found --> AL = 0 and ZF ON
add al, '"'
cmp al,'\'
jne NxtCh1 ; It is not a \
cmp byte ptr ds:[si], '"'
jne NxtCh1 ; Only " is transparent after \
lodsb
NxtCh1: or si, si ; Be sure both CF & ZF are OFF
NxtCh2: ret
NextChar ENDP
; Invalid program name
BadPgmName:
jmp _abort ; Something wrong with cmd line
; Now, build the argv array
BuildArgv:
mov ax, DGROUP
mov ds, ax ; restore DS
pop cx ; Restore length of pgm name
add cx, dx ; Calc total space needed for parms
mov __argc, bx ; bx = argument count
inc bx ; add 1 for terminating NULL argument
add bx, bx ; multiply by 4 to compute space
add bx, bx ; required for pointers (4 bytes per)
mov si, sp ;
mov bp, sp
sub bp, bx ; Is there room left for the ptrs?
jb BadPgmName ; no, abort the pgm
mov sp, bp ; SS:BP = argv array address
mov word ptr __argv, bp
mov word ptr __argv+2, ss
SetArg: jcxz LastArg ; last arg; get out
mov [bp], si ; Set argv[n]
mov [bp+2], ss
add bp, 4 ; and point to location for next
CopyArg: lods byte ptr ss:[si]
or al, al ; and copy argument into the
loopnz CopyArg ; stack space reserved for it
jz SetArg
LastArg: xor ax, ax ; add terminating NULL pointer
mov [bp], ax ; as last argument
mov [bp+2], ax
mov dx, ProcRet
jmp dx
__setargv ENDP
;-----------------------------------------------------------------
__setenvp PROC NEAR
;*-----------------------------------------------------*
;* Setup the environment. Since we only allow the *
;* LARGE memory model, we don't have to worry about *
;* creating a copy in our own data segment. *
;*-----------------------------------------------------*
push __envSize ; # bytes needed
mov ax, SEG _environ ; pointer
push ax ; to
mov ax, OFFSET _environ+2 ; addr of
push ax ; new environ
push 1 ; New segment is shareable
call DosAllocSeg ; Allocate Memory
or ax,ax ; OK?
jz BldEnv ; No - no memory; abort
jmp _abort
BldEnv: mov es, __envseg ; ES = Original environment
push ds ; Save DS
mov ds,Word Ptr _environ+2 ; DS = New environment
xor di, di ; ES:DI = start of environ
xor ax, ax
xor bx, bx ; Offset into new environ
mov cx, -1
BldEnv0: mov [bx], di ; store 1st parm
mov [bx+2], es ;
add bx, 4 ; adjust for next pointer
repnz scasb ; find next parm
cmp es:[di], al ; end of environ?
jne BldEnv0 ; Build next pointer
mov [bx], ax ; NULL Ptr to terminate
mov [bx+2], ax
pop ds ; restore correct DS
ret
__setenvp ENDP
_TEXT ENDS
_DATA SEGMENT
AbortMsg db 'Abnormal program termination', 13, 10
AbortMsgL equ $ - AbortMsg
__argc dw 0 ; # args in cmd line
__argv dd 0 ; ptr to array of argv[]'s
_environ dd 0 ; address of our environment
PUBLIC _environ
__envLng dw 0 ; offset of environment
__envseg dw 0 ; data segment of environment
__envSize dw 0 ; size of environment
__version label word ; os/2 version #'s
__osmajor db 0
__osminor db 0
_errno dw 0 ; used by library routines only
__8087 dw 0 ; 8087 support yes or no
__cnt dw 0 ; offset of cmd line in environ
__cmdline dw 0
;;__heapbase dd 0 ; lowest heap position
;;__brklvl dd 0 ;
;;__heaptop dd 0 ; highest heap location
ProcRet dw ? ; for psuedo RET's
_DATA ENDS
_CVTSEG SEGMENT
__RealCvtVector label word
_CVTSEG ENDS
_SCNSEG SEGMENT
__ScanTodVector label word
_SCNSEG ENDS
_BSS SEGMENT
_bdata label byte
_BSS ENDS
_BSSEND SEGMENT
_edata label byte
_BSSEND ENDS
END STARTX