|
|
Microsoft OS/2 SDK 12-15-1987
page ,132 TITLE crt0 - OS/2 C start up routine ;*** ;5crt0.asm - OS/2 C start up routine ; ; Copyright (c) 1986-1987, Microsoft Corporation, All Rights Reserved ; ;Purpose: ; How startup works in a few words - ; ; The startup and termination is performed by a few modules ; ; 5crt0.asm OS/2 specific init/term ; 5crt0msg.asm OS/2 error messages ; 5crt0dat.asm remainder of shared OS/2 init/term ; ; ************* IMPORTANT ***************************************** ; ; If the user reassembles this module, he will need to link using the ; /DOSSEG switch or run the the DOSSEG.EXE program on 5crt0.obj, i.e. ; ; dosseg 5crt0.obj ; ; See the C documentation for more information about the /DOSSEG switch. ; ; All assembler modules must be assembled with the /mx switch, i.e. ; ; masm 5crt0/mx; ; ;******************************************************************************* ?DF= 1 ; this is special for c startup include version.inc .xlist include cmacros.inc include msdos.inc include brkctl.inc .list page ;=========================================================================== ; ; Segment definitions ; ; The segment order is essentially the same as in XENIX. ; This module is edited after assembly to contain a dosseg comment ; record for the linker. ; ;=========================================================================== createSeg _TEXT, code, word, public, CODE, <> createSeg C_ETEXT,etext, word, public, ENDCODE,<> createSeg _DATA, data, word, public, DATA, DGROUP createSeg STACK, stack, para, stack, STACK, DGROUP defGrp DGROUP ; define DGROUP codeOFFSET equ offset _TEXT: dataOFFSET equ offset DGROUP: page public __acrtused ; trick to force in startup __acrtused = 9876h ; funny value not easily matched in SYMDEB extrn __acrtmsg:abs ; trick to pull in startup messages sBegin stack assumes ds,data db 2048 dup (?) ; default stack size sEnd page sBegin data extrn _edata:byte ; end of data (start of bss) extrn _end:byte ; end of bss (start of stack) externW __argc externDP __argv externDP environ externB _osfile externB _osmajor ; Major and Minor versions of OS/2 externB _osmode ; real/protected mode flag ; these are used by DOS C memory management (not used in Windows) ;* ;* The following (_acmdln and _aenvseg) must be in this order! ;* globalW _acmdln,0 ; Offset of command line string in env globalW _aenvseg,0 ; Selector of Environment segment globalW _asizds,0 ; DS size (in bytes) globalW _atopsp,0 ; top of stack (heap bottom) globalW _aexit_rtn,<codeoffset __exit> ; NEAR pointer labelW <PUBLIC,_abrktb> ; segment table for brkctl dw ? dw DGROUP db (MAXSEG_PM-1) * (size segrec) dup (?) labelW <PUBLIC,_abrktbe> globalW _abrkp,<dataoffset _abrktb> ; special C environment string labelB <PUBLIC,_acfinfo> cfile db '_C_FILE_INFO' cfilex db '=',0 cfileln = cfilex-cfile+1 sEnd page externP _cinit ; run-time initializers externP _NMSG_WRITE ; pascal - write error message to stdout externP _FF_MSGBANNER ; pascal - C/FORTRAN error message banner externP _setargv ; process command line arguments externP _setenvp ; process environment externP _nullcheck ; check for null assignment externP main ; C main program externP exit ; exit ( code ) if sizeC extrn __exit:far ; _exit ( code) (cmacros name conflict) else extrn __exit:near endif extrn DOSGETVERSION:far extrn DOSGETMACHINEMODE:far sBegin code assumes cs,code page ;*** ;_astart - start of all C programs ; ;Purpose: ; Startup routine to initialize C run-time environment. ; ;Entry: ; OS/2 Start-Up Conditions: ; ; DS = Automatic Data Segment ; SS:SP = Stack Segment and Initial Stack Pointer ; ES = 0000 ; AX = Selector of Environment Segment ; BX = Offset of Command Line in Environment Segment ; CX = Size of Automatic Data Segment (CX=0 means 65536 bytes) ; BP = 0000 ; ;Exit: ; Exits to OS/2 via exit(). ; ;Uses: ; ;Exceptions: ; ;******************************************************************************* labelNP <PUBLIC,_astart> ; start address of all "C" programs ; ; cld ; set direction flag (up) mov [_atopsp],sp ; Top of Stack Region mov [_abrktb].sz,sp ; top DS free location mov [_abrktb].sg,ds ; DGROUP segment dec cx mov [_asizds],cx ; Size of Global Data Segment mov [_aenvseg],ax ; Handle of Environment Segment mov [_acmdln],bx ; Offset of Command Line String ; ; get OS/2 version ; push ax mov ax,sp push ss push ax ; address for version call DOSGETVERSION pop ax xchg ah,al ; swap bytes mov word ptr [_osmajor],ax ; ; Get real/protected mode flag ; mov ax,dataOFFSET _osmode push ds push ax call DOSGETMACHINEMODE ifdef IBMC20 ; ; zero data areas (_BSS and c_common) ; push ss pop es assumes es,data mov di,dataOFFSET _edata ; beginning of bss area mov cx,dataOFFSET _end ; end of bss area sub cx,di xor ax,ax rep stosb ; zero bss endif ;**** ;* C_FILE_INFO must be processed before _cinit() is called ;* because _cinit() checks handles 0-2 for device/pipe. ;**** ; fix up files inherited from child using _C_FILE_INFO call inherit ; do necessary initialization BEFORE command line processing! call _cinit ; shared by OS/2 and Windows ; process command line and environment call _setargv ; crack command line call _setenvp ; crack environment ; call main and exit if sizeD push word ptr [environ+2] ; the environment is not always in DS endif push word ptr [environ] if sizeD push word ptr [__argv+2] ; the arguments are not always in DS endif push word ptr [__argv] push [__argc] ; argument count call main ; main ( argc , argv , envp ) ; use whatever is in ax after returning here from the main program push ax call exit ; exit (AX) ; _exit will call terminators page ;*** ;_amsg_exit, _cintDIV - Fast exit fatal errors ; ;Purpose: ; Exit the program with error code of 255 and appropriate error ; message. cintDIV is used for integer divide by zero, amsg_exit ; is for other run time errors. ; ;Entry: ; AX = error message number (amsg_exit only). ; ;Exit: ; calls exit() [cintDIV] or indirect through _aexit_rtn [amsg_exit]. ; ;Uses: ; ;Exceptions: ; ;******************************************************************************* labelNP <PUBLIC,_cintDIV> ifndef IBMC20 assumes ds,nothing assumes ss,data endif ; IBMC20 ; _NMSG_WRITE will reestablish ds = DGROUP mov ax,3 ; Integer divide by zero interrupt mov [_aexit_rtn],codeoffset _exit ; call high-level exit() ; to cause file buffer flushing labelNP <PUBLIC,_amsg_exit> push ax ; message number for _NMSG_WRITE call _FF_MSGBANNER ; run-time error message banner call _NMSG_WRITE ; write error message to stdout assumes ds,data mov ax,255 push ax call word ptr [_aexit_rtn] ; _exit(255) ordinarily ; (or exit(255) for div by 0) ; NEAR routine pointer page ;*** ;inherit - process C_FILE_INFO variable from the environment ; ;Purpose: ; locates and interprets the "C_FILE_INFO" environment variable. ; The value of this variable is written into the "_osfile" array. ; This routine recognizes both DOS and OS/2 formats: ; ; DOS: ";C_FILE_INFO" + count byte "N" + "N" data bytes + "\0" ; ; where each data byte is written directly into _osfile ; except that 0xFF represents 0 ; ; OS/2: "_C_FILE_INFO=<AA><BB><CC><DD>" + "\0" ; ; In this case the variable is a null-terminated string ; (a well-formed environment variable) where each pair ; of successive letters form one byte in _osfile. ; The letters are in the range "A" through "P", representing ; 0 through 15. The first letter of each pair is the more ; significant 4 bits of the result. ; ;Entry: ; ;Exit: ; ;Uses: ; AX, BX, CX, DX, SI, DI, ES ; ;Exceptions: ; ;******************************************************************************* inherit proc near mov bx,cfileln cmp [_osmode],0 jne not_fapi ; ; Set up real-mode version of ;C_FILE_INFO ; mov [cfile],';' ; change _C_FILE_INFO= to ;C_FILE_INFO mov [cfilex],0 dec bx ; length is one less not_fapi: xor di,di mov es,[_aenvseg] ; ES:DI points to environment strings mov cx,07FFFh ; environment max = 32K cmp byte ptr es:[di],0 jne cfilp inc di ; first environment string is null cfilp: cmp byte ptr es:[di],0 ; check for end of environment je nocfi ; yes - not found mov si,dataOFFSET cfile mov dx,cx ; DX has count of bytes left in environment mov cx,bx ; BX=cfileln repe cmpsb ; compare for '_C_FILE_INFO='/';C_FILE_INFO' mov cx,dx ; environment max = 32K je gotcfi ; yes - now do something with it xor ax,ax repne scasb ; search for end of current string je cfilp ; keep searching ; jmp short nocfi ; no 00 !!! - assume end of env. ; ; found _C_FILE_INFO, so transfer handle info into _osfile ; gotcfi: push es push ds pop es ; es = DGROUP mov si,di ; si = startup of _osfile info pop ds ; ds = env. segment assumes es,data assumes ds,nothing mov di,dataOFFSET _osfile ; di = _osfile block cmp bx,cfileln jne real_cfi ; ; Prot-mode _C_FILE_INFO: ; Read in pairs of characters, expected to be ['A'..'P']. ; Each pair represents one byte in the _osfile array. ; A null is the normal terminator for the string. ; mov cl,4 osfile_lp: lodsb ; get next byte (more significant 4 bits) sub al,'A' jb nocfi ; string should terminate with a null shl al,cl xchg dx,ax ; save in DL lodsb ; get next byte (less significant 4 bits) sub al,'A' jb nocfi or al,dl ; this assumes that AL is in range stosb jmp short osfile_lp ; ; Real-mode C_FILE_INFO ; real_cfi: lodsb ; must be less than 20 cbw xchg cx,ax ; cx = number of entries osflp: lodsb ; get next byte inc al jz saveit ; was FF - save as 00 dec ax ; restore al saveit: stosb loop osflp ; transfer next character ;------ nocfi: push ss pop ds ; ds = DGROUP assumes ds,data ret inherit endp sEnd end _astart ; start address
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.