Annotation of os2sdk/startup/os2/crt0.asm, revision 1.1

1.1     ! root        1:        page    ,132
        !             2:        TITLE   crt0 - OS/2 C start up routine
        !             3: ;***
        !             4: ;5crt0.asm - OS/2 C start up routine
        !             5: ;
        !             6: ;      Copyright (c) 1986-1987, Microsoft Corporation, All Rights Reserved
        !             7: ;
        !             8: ;Purpose:
        !             9: ;      How startup works in a few words -
        !            10: ;
        !            11: ;      The startup and termination is performed by a few modules
        !            12: ;
        !            13: ;              5crt0.asm       OS/2 specific init/term
        !            14: ;              5crt0msg.asm    OS/2 error messages
        !            15: ;              5crt0dat.asm    remainder of shared OS/2 init/term
        !            16: ;
        !            17: ;      *************  IMPORTANT  *****************************************
        !            18: ;
        !            19: ;      If the user reassembles this module, he will need to link using the
        !            20: ;      /DOSSEG switch or run the the DOSSEG.EXE program on 5crt0.obj, i.e.
        !            21: ;
        !            22: ;              dosseg 5crt0.obj
        !            23: ;
        !            24: ;      See the C documentation for more information about the /DOSSEG switch.
        !            25: ;
        !            26: ;      All assembler modules must be assembled with the /mx switch, i.e.
        !            27: ;
        !            28: ;              masm 5crt0/mx;
        !            29: ;
        !            30: ;*******************************************************************************
        !            31: 
        !            32: 
        !            33: ?DF=   1                       ; this is special for c startup
        !            34: include        version.inc
        !            35: .xlist
        !            36: include        cmacros.inc
        !            37: include        msdos.inc
        !            38: include        brkctl.inc
        !            39: .list
        !            40: 
        !            41:        page
        !            42: ;===========================================================================
        !            43: ;
        !            44: ;      Segment definitions
        !            45: ;
        !            46: ;      The segment order is essentially the same as in XENIX.
        !            47: ;      This module is edited after assembly to contain a dosseg comment
        !            48: ;      record for the linker.
        !            49: ;
        !            50: ;===========================================================================
        !            51: 
        !            52: createSeg _TEXT, code, word,   public, CODE,   <>
        !            53: createSeg C_ETEXT,etext, word, public, ENDCODE,<>
        !            54: 
        !            55: createSeg _DATA, data, word,   public, DATA,   DGROUP
        !            56: createSeg STACK, stack,        para,   stack,  STACK,  DGROUP
        !            57: 
        !            58: defGrp DGROUP                  ; define DGROUP
        !            59: 
        !            60: codeOFFSET equ offset _TEXT:
        !            61: dataOFFSET equ offset DGROUP:
        !            62: 
        !            63: page
        !            64: 
        !            65: public __acrtused              ; trick to force in startup
        !            66:        __acrtused = 9876h      ; funny value not easily matched in SYMDEB
        !            67: 
        !            68: extrn  __acrtmsg:abs           ; trick to pull in startup messages
        !            69: 
        !            70: 
        !            71: sBegin stack
        !            72: assumes        ds,data
        !            73:        db      2048 dup (?)    ; default stack size
        !            74: sEnd
        !            75: 
        !            76: page
        !            77: 
        !            78: sBegin data
        !            79: 
        !            80: extrn  _edata:byte             ; end of data (start of bss)
        !            81: extrn  _end:byte               ; end of bss (start of stack)
        !            82: 
        !            83: externW        __argc
        !            84: externDP __argv
        !            85: externDP environ
        !            86: externB _osfile
        !            87: externB _osmajor               ; Major and Minor versions of OS/2
        !            88: externB _osmode                ; real/protected mode flag
        !            89: 
        !            90: ;      these are used by DOS C memory management (not used in Windows)
        !            91: 
        !            92: ;*
        !            93: ;*     The following (_acmdln and _aenvseg) must be in this order!
        !            94: ;*
        !            95: globalW        _acmdln,0               ; Offset of command line string in env
        !            96: globalW        _aenvseg,0              ; Selector of Environment segment
        !            97: 
        !            98: globalW        _asizds,0               ; DS size (in bytes)
        !            99: globalW        _atopsp,0               ; top of stack (heap bottom)
        !           100: globalW        _aexit_rtn,<codeoffset __exit> ; NEAR pointer
        !           101: 
        !           102: labelW <PUBLIC,_abrktb>        ; segment table for brkctl
        !           103:        dw      ?
        !           104:        dw      DGROUP
        !           105:        db      (MAXSEG_PM-1) * (size segrec) dup (?)
        !           106: 
        !           107: labelW <PUBLIC,_abrktbe>
        !           108: globalW        _abrkp,<dataoffset _abrktb>
        !           109: 
        !           110: 
        !           111: ;      special C environment string
        !           112: 
        !           113: labelB <PUBLIC,_acfinfo>
        !           114: cfile  db      '_C_FILE_INFO'
        !           115: cfilex db      '=',0
        !           116: cfileln        =       cfilex-cfile+1
        !           117: 
        !           118: sEnd
        !           119: 
        !           120:        page
        !           121: 
        !           122: 
        !           123: externP        _cinit                  ; run-time initializers
        !           124: 
        !           125: externP        _NMSG_WRITE             ; pascal - write error message to stdout
        !           126: externP        _FF_MSGBANNER           ; pascal - C/FORTRAN error message banner
        !           127: 
        !           128: externP        _setargv                ; process command line arguments
        !           129: externP        _setenvp                ; process environment
        !           130: externP        _nullcheck              ; check for null assignment
        !           131: 
        !           132: externP        main                    ; C main program
        !           133: externP        exit                    ; exit ( code )
        !           134: 
        !           135: if     sizeC
        !           136: extrn  __exit:far              ; _exit ( code) (cmacros name conflict)
        !           137: else
        !           138: extrn  __exit:near
        !           139: endif
        !           140: 
        !           141:        extrn   DOSGETVERSION:far
        !           142:        extrn   DOSGETMACHINEMODE:far
        !           143: 
        !           144: sBegin code
        !           145: assumes        cs,code
        !           146: 
        !           147: page
        !           148: ;***
        !           149: ;_astart - start of all C programs
        !           150: ;
        !           151: ;Purpose:
        !           152: ;      Startup routine to initialize C run-time environment.
        !           153: ;
        !           154: ;Entry:
        !           155: ;      OS/2 Start-Up Conditions:
        !           156: ;
        !           157: ;      DS      = Automatic Data Segment
        !           158: ;      SS:SP   = Stack Segment and Initial Stack Pointer
        !           159: ;      ES      = 0000
        !           160: ;      AX      = Selector of Environment Segment
        !           161: ;      BX      = Offset of Command Line in Environment Segment
        !           162: ;      CX      = Size of Automatic Data Segment (CX=0 means 65536 bytes)
        !           163: ;      BP      = 0000
        !           164: ;
        !           165: ;Exit:
        !           166: ;      Exits to OS/2 via exit().
        !           167: ;
        !           168: ;Uses:
        !           169: ;
        !           170: ;Exceptions:
        !           171: ;
        !           172: ;*******************************************************************************
        !           173: 
        !           174: labelNP        <PUBLIC,_astart>        ; start address of all "C" programs
        !           175: ;
        !           176: ;
        !           177:        cld                     ; set direction flag (up)
        !           178:        mov     [_atopsp],sp    ; Top of Stack Region
        !           179:        mov     [_abrktb].sz,sp ; top DS free location
        !           180:        mov     [_abrktb].sg,ds ; DGROUP segment
        !           181:        dec     cx
        !           182:        mov     [_asizds],cx    ; Size of Global Data Segment
        !           183:        mov     [_aenvseg],ax   ; Handle of Environment Segment
        !           184:        mov     [_acmdln],bx    ; Offset of Command Line String
        !           185: ;
        !           186: ;      get OS/2 version
        !           187: ;
        !           188:        push    ax
        !           189:        mov     ax,sp
        !           190: 
        !           191:        push    ss
        !           192:        push    ax              ; address for version
        !           193:        call    DOSGETVERSION
        !           194:        pop     ax
        !           195:        xchg    ah,al           ; swap bytes
        !           196:        mov     word ptr [_osmajor],ax
        !           197: ;
        !           198: ; Get real/protected mode flag
        !           199: ;
        !           200:        mov     ax,dataOFFSET _osmode
        !           201:        push    ds
        !           202:        push    ax
        !           203:        call    DOSGETMACHINEMODE
        !           204: 
        !           205: ifdef IBMC20
        !           206: ;
        !           207: ;     zero data areas (_BSS and c_common)
        !           208: ;
        !           209:        push    ss
        !           210:        pop     es
        !           211:        assumes es,data
        !           212:        mov     di,dataOFFSET _edata ; beginning of bss area
        !           213:        mov     cx,dataOFFSET _end ; end of bss area
        !           214:        sub     cx,di
        !           215:        xor     ax,ax
        !           216:        rep     stosb           ; zero bss
        !           217: endif
        !           218: 
        !           219: ;****
        !           220: ;*     C_FILE_INFO must be processed before _cinit() is called
        !           221: ;*     because _cinit() checks handles 0-2 for device/pipe.
        !           222: ;****
        !           223: 
        !           224: ;      fix up files inherited from child using _C_FILE_INFO
        !           225: 
        !           226:        call    inherit
        !           227: 
        !           228: ;      do necessary initialization BEFORE command line processing!
        !           229: 
        !           230:        call    _cinit          ; shared by OS/2 and Windows
        !           231: 
        !           232: ;      process command line and environment
        !           233: 
        !           234:        call    _setargv        ; crack command line
        !           235:        call    _setenvp        ; crack environment
        !           236: 
        !           237: ;      call main and exit
        !           238: 
        !           239: if     sizeD
        !           240:        push    word ptr [environ+2] ; the environment is not always in DS
        !           241: endif
        !           242:        push    word ptr [environ]
        !           243: 
        !           244: if     sizeD
        !           245:        push    word ptr [__argv+2] ; the arguments are not always in DS
        !           246: endif
        !           247:        push    word ptr [__argv]
        !           248: 
        !           249:        push    [__argc]        ; argument count
        !           250: 
        !           251:        call    main            ; main ( argc , argv , envp )
        !           252: 
        !           253: ; use whatever is in ax after returning here from the main program
        !           254: 
        !           255:        push    ax
        !           256:        call    exit            ; exit (AX)
        !           257:                                ;   _exit will call terminators
        !           258: 
        !           259: page
        !           260: ;***
        !           261: ;_amsg_exit, _cintDIV - Fast exit fatal errors
        !           262: ;
        !           263: ;Purpose:
        !           264: ;      Exit the program with error code of 255 and appropriate error
        !           265: ;      message.  cintDIV is used for integer divide by zero, amsg_exit
        !           266: ;      is for other run time errors.
        !           267: ;
        !           268: ;Entry:
        !           269: ;      AX      = error message number (amsg_exit only).
        !           270: ;
        !           271: ;Exit:
        !           272: ;      calls exit() [cintDIV] or indirect through _aexit_rtn [amsg_exit].
        !           273: ;
        !           274: ;Uses:
        !           275: ;
        !           276: ;Exceptions:
        !           277: ;
        !           278: ;*******************************************************************************
        !           279: 
        !           280: labelNP        <PUBLIC,_cintDIV>
        !           281: 
        !           282: ifndef IBMC20
        !           283:        assumes ds,nothing
        !           284:        assumes ss,data
        !           285: endif ; IBMC20
        !           286: 
        !           287: ;      _NMSG_WRITE will reestablish ds = DGROUP
        !           288: 
        !           289:        mov     ax,3            ; Integer divide by zero interrupt
        !           290:        mov     [_aexit_rtn],codeoffset _exit ; call high-level exit()
        !           291:                                ; to cause file buffer flushing
        !           292: 
        !           293: labelNP        <PUBLIC,_amsg_exit>
        !           294:        push    ax              ; message number for _NMSG_WRITE
        !           295:        call    _FF_MSGBANNER   ; run-time error message banner
        !           296:        call    _NMSG_WRITE     ; write error message to stdout
        !           297: 
        !           298:        assumes ds,data
        !           299: 
        !           300:        mov     ax,255
        !           301:        push    ax
        !           302:        call    word ptr [_aexit_rtn] ; _exit(255) ordinarily
        !           303:                                ; (or exit(255) for div by 0)
        !           304:                                ; NEAR routine pointer
        !           305: 
        !           306: page
        !           307: ;***
        !           308: ;inherit - process C_FILE_INFO variable from the environment
        !           309: ;
        !           310: ;Purpose:
        !           311: ;      locates and interprets the "C_FILE_INFO" environment variable.
        !           312: ;      The value of this variable is written into the "_osfile" array.
        !           313: ;      This routine recognizes both DOS and OS/2 formats:
        !           314: ;
        !           315: ;      DOS:    ";C_FILE_INFO" + count byte "N" + "N" data bytes + "\0"
        !           316: ;
        !           317: ;              where each data byte is written directly into _osfile
        !           318: ;              except that 0xFF represents 0
        !           319: ;
        !           320: ;      OS/2:   "_C_FILE_INFO=<AA><BB><CC><DD>" + "\0"
        !           321: ;
        !           322: ;              In this case the variable is a null-terminated string
        !           323: ;              (a well-formed environment variable) where each pair
        !           324: ;              of successive letters form one byte in _osfile.
        !           325: ;              The letters are in the range "A" through "P", representing
        !           326: ;              0 through 15.  The first letter of each pair is the more
        !           327: ;              significant 4 bits of the result.
        !           328: ;
        !           329: ;Entry:
        !           330: ;
        !           331: ;Exit:
        !           332: ;
        !           333: ;Uses:
        !           334: ;      AX, BX, CX, DX, SI, DI, ES
        !           335: ;
        !           336: ;Exceptions:
        !           337: ;
        !           338: ;*******************************************************************************
        !           339: 
        !           340: inherit proc   near
        !           341:        mov     bx,cfileln
        !           342:        cmp     [_osmode],0
        !           343:        jne     not_fapi
        !           344: ;
        !           345: ;      Set up real-mode version of ;C_FILE_INFO
        !           346: ;
        !           347:        mov     [cfile],';'     ; change _C_FILE_INFO= to ;C_FILE_INFO
        !           348:        mov     [cfilex],0
        !           349:        dec     bx              ; length is one less
        !           350: not_fapi:
        !           351:        xor     di,di
        !           352:        mov     es,[_aenvseg]   ; ES:DI points to environment strings
        !           353:        mov     cx,07FFFh       ; environment max = 32K
        !           354:        cmp     byte ptr es:[di],0
        !           355:        jne     cfilp
        !           356:        inc     di              ; first environment string is null
        !           357: cfilp:
        !           358:        cmp     byte ptr es:[di],0 ; check for end of environment
        !           359:        je      nocfi           ;   yes - not found
        !           360:        mov     si,dataOFFSET cfile
        !           361:        mov     dx,cx           ; DX has count of bytes left in environment
        !           362:        mov     cx,bx           ; BX=cfileln
        !           363:        repe    cmpsb           ; compare for '_C_FILE_INFO='/';C_FILE_INFO'
        !           364:        mov     cx,dx           ; environment max = 32K
        !           365:        je      gotcfi          ;   yes - now do something with it
        !           366:        xor     ax,ax
        !           367:        repne   scasb           ; search for end of current string
        !           368:        je      cfilp           ; keep searching
        !           369: ;
        !           370:        jmp     short nocfi     ;   no 00 !!! - assume end of env.
        !           371: ;
        !           372: ;      found _C_FILE_INFO, so transfer handle info into _osfile
        !           373: ;
        !           374: gotcfi:
        !           375:        push    es
        !           376:        push    ds
        !           377: 
        !           378:        pop     es              ; es = DGROUP
        !           379:        mov     si,di           ; si = startup of _osfile info
        !           380:        pop     ds              ; ds = env. segment
        !           381:        assumes es,data
        !           382:        assumes ds,nothing
        !           383: 
        !           384:        mov     di,dataOFFSET _osfile ; di = _osfile block
        !           385: 
        !           386:        cmp     bx,cfileln
        !           387:        jne     real_cfi
        !           388: ;
        !           389: ; Prot-mode _C_FILE_INFO:
        !           390: ;      Read in pairs of characters, expected to be ['A'..'P'].
        !           391: ;      Each pair represents one byte in the _osfile array.
        !           392: ;      A null is the normal terminator for the string.
        !           393: ;
        !           394:        mov     cl,4
        !           395: 
        !           396: osfile_lp:
        !           397:        lodsb                   ; get next byte (more significant 4 bits)
        !           398:        sub     al,'A'
        !           399:        jb      nocfi           ; string should terminate with a null
        !           400:        shl     al,cl
        !           401:        xchg    dx,ax           ; save in DL
        !           402: 
        !           403:        lodsb                   ; get next byte (less significant 4 bits)
        !           404:        sub     al,'A'
        !           405:        jb      nocfi
        !           406:        or      al,dl           ; this assumes that AL is in range
        !           407:        stosb
        !           408:        jmp     short osfile_lp
        !           409: ;
        !           410: ; Real-mode C_FILE_INFO
        !           411: ;
        !           412: real_cfi:
        !           413:        lodsb                   ; must be less than 20
        !           414:        cbw
        !           415:        xchg    cx,ax           ; cx = number of entries
        !           416: 
        !           417: osflp:
        !           418:        lodsb                   ; get next byte
        !           419:        inc     al
        !           420:        jz      saveit          ; was FF - save as 00
        !           421:        dec     ax              ; restore al
        !           422: saveit:
        !           423:        stosb
        !           424:        loop    osflp           ; transfer next character
        !           425: 
        !           426: ;------
        !           427: 
        !           428: nocfi:
        !           429:        push    ss
        !           430:        pop     ds              ; ds = DGROUP
        !           431:        assumes ds,data
        !           432: 
        !           433:        ret
        !           434: inherit endp
        !           435: 
        !           436: sEnd
        !           437:        end     _astart         ; start address

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.