Annotation of os2sdk/startup/os2/crt0.asm, revision 1.1.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.