Annotation of os2sdk/startup/os2/crt0dat.asm, revision 1.1.1.1

1.1       root        1:        TITLE   crt0dat - OS/2 C run-time initialization/termination
                      2: ;***
                      3: ;5crt0dat.asm - OS/2 C run-time initialization/termination routines
                      4: ;
                      5: ;      Copyright (c) 1986-1987, Microsoft Corporation, All Rights Reserved
                      6: ;
                      7: ;Purpose:
                      8: ;      This module contains the routines _cinit, exit, and _exit
                      9: ;      for C run-time startup and termination.  _cinit and exit
                     10: ;      are called from the _astart code in 5crt0.asm.
                     11: ;
                     12: ;*******************************************************************************
                     13: 
                     14: _NFILE_        =       40              ; Maximum number of file handles
                     15: 
                     16: ?DF    =       1               ;; tell cmacros.inc we want to define our own segments
                     17: 
                     18: include        version.inc
                     19: .xlist
                     20: include        cmacros.inc
                     21: include        msdos.inc
                     22: .list
                     23: 
                     24: createSeg _TEXT, code, word,   public, CODE,   <>
                     25: createSeg CDATA, cdata,        word,   common, DATA,   DGROUP
                     26: createSeg _DATA, data, word,   public, DATA,   DGROUP
                     27: 
                     28: createSeg XIB, xibseg, word,   public, DATA,   DGROUP
                     29: createSeg XI,  xiseg,  word,   public, DATA,   DGROUP ; init's
                     30: createSeg XIE, xieseg, word,   public, DATA,   DGROUP
                     31: 
                     32: createSeg XOB, xobseg, word,   public, BSS,    DGROUP
                     33: createSeg XO,  xoseg,  word,   public, BSS,    DGROUP ; onexit table
                     34: createSeg XOE, xoeseg, word,   public, BSS,    DGROUP
                     35: 
                     36: createSeg XPB, xpbseg, word,   public, DATA,   DGROUP
                     37: createSeg XP,  xpseg,  word,   public, DATA,   DGROUP ; preterm's
                     38: createSeg XPE, xpeseg, word,   public, DATA,   DGROUP
                     39: 
                     40: createSeg XCB, xcbseg, word,   public, DATA,   DGROUP
                     41: createSeg XC,  xcseg,  word,   public, DATA,   DGROUP ; term's
                     42: createSeg XCE, xceseg, word,   public, DATA,   DGROUP
                     43: 
                     44: defGrp DGROUP                  ;; define DGROUP
                     45: 
                     46: codeOFFSET equ offset _TEXT:
                     47: dataOFFSET equ offset DGROUP:
                     48: 
                     49: page
                     50: 
                     51: sBegin xibseg
                     52: xibegin        label   byte
                     53: sEnd   xibseg
                     54: 
                     55: sBegin xieseg
                     56: xiend  label   byte
                     57: sEnd   xieseg
                     58: 
                     59: sBegin xobseg
                     60: xontab label   byte            ; start of onexit table
                     61: sEnd   xobseg
                     62: 
                     63: sBegin xoeseg
                     64: xonend label   byte
                     65: sEnd   xoeseg
                     66: 
                     67: sBegin xpbseg
                     68: xpbegin        label   byte            ; end of onexit table
                     69: sEnd   xpbseg
                     70: 
                     71: sBegin xpeseg
                     72: xpend  label   byte
                     73: sEnd   xpeseg
                     74: 
                     75: 
                     76: sBegin xcbseg
                     77: xcbegin        label   byte
                     78: sEnd   xcbseg
                     79: 
                     80: sBegin xceseg
                     81: xcend  label   byte
                     82: sEnd   xceseg
                     83: 
                     84: 
                     85: 
                     86: sBegin cdata                   ; floating point setup segment
                     87: assumes        ds,data
                     88: 
                     89:        dw      0               ; force segment to be at least 0's
                     90: labelD <PUBLIC,_fpinit>        ; public for signal
                     91: fpmath dd      1 dup (?)       ; linking trick for fp
                     92: fpdata dd      1 dup (?)
                     93: fpsignal dd    1 dup (?)       ; fp signal message
                     94: 
                     95: externW        _aenvseg                ; Selector of Environment segment
                     96: sEnd
                     97: 
                     98: sBegin data
                     99: assumes        ds,data
                    100: 
                    101: globalQ        _fac,0                  ; floating accumulator
                    102: globalW        errno,0                 ; initial error code
                    103: globalW        _umaskval,0             ; initial umask value
                    104: 
                    105: ;================= following must be in this order
                    106: 
                    107: labelW <PUBLIC,_osversion>
                    108: labelB <PUBLIC,_dosvermajor>
                    109: globalB        _osmajor,0
                    110: labelB <PUBLIC,_dosverminor>
                    111: globalB        _osminor,0
                    112: 
                    113: ;================= above must be in this order
                    114: 
                    115: labelB <PUBLIC,_dosmode>
                    116: globalB        _osmode,0
                    117: 
                    118: labelW <PUBLIC,_oserr>
                    119: globalW        _doserrno,0             ; initial DOS error code
                    120: 
                    121: globalW        _nfile,_NFILE_          ; maximum number of file handle
                    122: 
                    123: labelB <PUBLIC,_osfile>
                    124:        db      3 dup (FOPEN+FTEXT) ; stdin, stdout, stderr
                    125:        db      _NFILE_-3 dup (0) ; the other 17 handles
                    126: 
                    127: labelB <PUBLIC,_pipe>
                    128:        db      _NFILE_ dup (0AH) ; peek-ahead buffers for pipes
                    129: 
                    130: 
                    131: globalW        __argc,0
                    132: globalDP __argv,0
                    133: globalDP environ,0             ; environment pointer
                    134: globalD        _pgmptr,0               ; far pointer to program name
                    135: globalW        _child,0                ; flag that child program is executing
                    136:                                ; needed by signal code in real mode
                    137: 
                    138: sEnd   data
                    139: 
                    140: page
                    141: 
                    142: extrn  DOSCLOSE:far            ; DOS Function Call
                    143: extrn  DOSQHANDTYPE:far        ; DOS Function Call
                    144: extrn  DOSSETVEC:far           ; DOS Function Call
                    145: extrn  DOSEXIT:far             ; DOS Function Call
                    146: 
                    147: 
                    148: sBegin code
                    149: assumes        cs,code
                    150: 
                    151: if     sizeC
                    152: global proc    far
                    153: endif
                    154: 
                    155: externNP _fptrap
                    156: externP        _cintDIV
                    157: externP        _nullcheck
                    158: 
                    159: page
                    160: ;***
                    161: ;_cinit - C initialization
                    162: ;
                    163: ;Purpose:
                    164: ;      This routine performs the shared DOS and Windows initialization.
                    165: ;      The following order of initialization must be preserved -
                    166: ;
                    167: ;      1.      Check for devices for file handles 0 - 2
                    168: ;      2.      Integer divide interrupt vector setup
                    169: ;      3.      Floating point initialization
                    170: ;      4.      General C initializer routines
                    171: ;
                    172: ;Entry:
                    173: ;
                    174: ;Exit:
                    175: ;
                    176: ;Uses:
                    177: ;
                    178: ;Exceptions:
                    179: ;
                    180: ;*******************************************************************************
                    181: 
                    182: cProc  _cinit,<PUBLIC>,<>
                    183: 
                    184: cBegin nogen                   ; no local frame to set up
                    185: assumes        ds,data
                    186: assumes        ss,data
                    187: 
                    188: ;      1.      Check for devices for file handles 0 - 2
                    189: 
                    190:        mov     bx,2
                    191: 
                    192:        push    dx              ; space for device driver attribute
                    193:        mov     dx,sp
                    194: devloop:
                    195:        and     _osfile[bx],not (FDEV or FPIPE)
                    196:                                ; Assume this handle is not a device or pipe
                    197:        push    ax              ; space for isdevice flag
                    198:        mov     ax,sp
                    199:        push    bx              ; handle
                    200:        push    ss
                    201:        push    ax              ; address for isdevice flag
                    202:        push    ss
                    203:        push    dx              ; address for device driver attribute
                    204:        call    DOSQHANDTYPE
                    205: 
                    206:        pop     ax              ; get isdevice flag
                    207:        cmp     ax,IS_DEV       ; is the handle a device ?
                    208:        jz      dev             ; yes - set FDEV bit
                    209:        cmp     ax,IS_PIPE      ; is the handle a pipe ?
                    210:        jnz     notdev          ; no - it is a file
                    211:        or      _osfile[bx],FPIPE ; yes - set both FDEV and FPIPE
                    212: dev:
                    213:        or      _osfile[bx],FDEV ; set FDEV bit
                    214: notdev:
                    215:        dec     bx
                    216:        jns     devloop
                    217: 
                    218:        pop     dx              ; clean up stack
                    219: 
                    220: ;      2.      Integer divide interrupt vector setup
                    221: 
                    222:        xor     ax,ax
                    223: 
                    224:        push    ax
                    225:        push    ax              ; space for previous handler (returned)
                    226:        mov     bx,sp
                    227: 
                    228:        push    ax              ; zero means divide by 0 exception
                    229: 
                    230:        mov     dx,offset _TEXT:__cintDIV
                    231:        push    cs
                    232:        push    dx              ; address of divide exception handler
                    233: 
                    234:        push    ss
                    235:        push    bx              ; address of address for prev. handler
                    236: 
                    237:        call    DOSSETVEC
                    238:        pop     ax              ; clean-up stack
                    239:        pop     ax              ; (ignore return value)
                    240: 
                    241: ;      3.      Floating point initialization
                    242: 
                    243:        mov     cx,word ptr [fpmath+2]
                    244:        jcxz    nofloat_i
                    245: 
                    246:        mov     si,[_aenvseg]   ; environment segment
                    247:        lds     ax,[fpdata]     ; get task data area
                    248:        assumes ds,nothing
                    249:        mov     dx,ds           ;   into dx:ax
                    250:        xor     bx,bx           ; (si) = environment segment
                    251:        call    [fpmath]        ; fpmath(0) - init
                    252:        jnc     fpok
                    253: 
                    254:        push    ss              ; restore ds from ss
                    255:        pop     ds
                    256:        jmp     _fptrap         ; issue "Floating point not loaded"
                    257:                                ; error and abort
                    258: 
                    259: fpok:
                    260:        lds     ax,[fpsignal]   ; get signal address
                    261:        assumes ds,nothing
                    262:        mov     dx,ds
                    263:        mov     bx,3
                    264:        call    [fpmath]        ; fpmath(3) - set signal address
                    265:        push    ss
                    266:        pop     ds
                    267:        assumes ds,data
                    268: 
                    269: nofloat_i:
                    270: 
                    271: ;      4.      General C initializer routines
                    272: 
                    273:        mov     si,dataOFFSET xibegin
                    274:        mov     di,dataOFFSET xiend
                    275:        call    initterm        ; call the initializers
                    276: 
                    277:        ret
                    278: cEnd   nogen
                    279: 
                    280: page
                    281: ;***
                    282: ;exit(status), _exit(status) - C termination
                    283: ;
                    284: ;Purpose:
                    285: ;      The termination sequence is more complicated due to the multiple
                    286: ;      entry points - exit(code) and _exit(code).  The _exit() routine
                    287: ;      is a quick exit routine that does not do certain C exit functions
                    288: ;      like stdio buffer flushing and onexit processing.
                    289: ;
                    290: ;      exit (status):
                    291: ;
                    292: ;      1.      call runtime preterminators
                    293: ;
                    294: ;      _exit (status):
                    295: ;
                    296: ;      2.      perform C terminators
                    297: ;      3.      close all open files
                    298: ;      4.      perform _nullcheck() for null pointer assignment
                    299: ;      5.      terminate floating point
                    300: ;      6.      terminate with return code to DOS
                    301: ;
                    302: ;Entry:
                    303: ;      int status - exit status (0-255)
                    304: ;
                    305: ;Exit:
                    306: ;      Routine exits to DOS.
                    307: ;
                    308: ;Uses:
                    309: ;
                    310: ;Exceptions:
                    311: ;
                    312: ;*******************************************************************************
                    313: 
                    314: public _exit
                    315: _exit:
                    316: cProc  dummy1,<>,<>
                    317: 
                    318: parmw  status
                    319: 
                    320: cBegin
                    321: assumes        ds,data
                    322: assumes        ss,data
                    323: 
                    324: ;      1.      call runtime preterminators
                    325: ;              - onexit processing
                    326: ;              - flushall
                    327: ;              - rmtmp
                    328: 
                    329:        mov     si,dataOFFSET xontab ; beginning of onexit table
                    330:        mov     di,dataOFFSET xonend ; end of onexit table
                    331:        call    initterm
                    332: 
                    333:        mov     si,dataOFFSET xpbegin ; beginning of pre-terminators
                    334:        mov     di,dataOFFSET xpend ; end of pre-terminators
                    335:        call    initterm
                    336: 
                    337:        jmp     short exiting   ; jump into _exit
                    338: 
                    339: cend   nogen
                    340: 
                    341: public __exit
                    342: __exit:
                    343: cProc  dummy2,<>,<>
                    344: 
                    345: parmw  status
                    346: 
                    347: cBegin
                    348: assumes        ds,data
                    349: assumes        ss,data
                    350: 
                    351: exiting:
                    352: 
                    353: ;      2.      perform C terminators
                    354: 
                    355:        mov     si,dataOFFSET xcbegin
                    356:        mov     di,dataOFFSET xcend
                    357:        call    initterm
                    358: 
                    359: 
                    360: ;      3.      close all files (except pre-opened handles 0-2)
                    361: 
                    362:        mov     cx,_NFILE_-3
                    363:        mov     bx,3            ; close handles that are not pre-opened
                    364: 
                    365: closeloop:
                    366:        test    _osfile[bx],FOPEN
                    367:        jz      notopen
                    368: 
                    369:        push    bx
                    370:        call    DOSCLOSE
                    371: 
                    372: notopen:
                    373:        inc     bx
                    374:        loop    closeloop
                    375: 
                    376: ;      4.      perform _nullcheck() for null pointer assignment
                    377: 
                    378:        call    _nullcheck      ; perform null check (ignore return)
                    379:        or      ax,ax           ; zero if no null pointer asmt. detected
                    380:        jz      startclose
                    381:        cmp     status,0        ; zero if no other error has occurred
                    382:        jnz     startclose
                    383:        mov     status,255      ; nonzero status to indicate an
                    384:                                ; null-pointer-assignment error
                    385: startclose:
                    386: 
                    387: ;      5.      terminate floating point
                    388: 
                    389:        call    _ctermsub       ; fast cleanup
                    390: 
                    391: ;      6.      return to the DOS
                    392: 
                    393:        mov     ax,1            ; terminate all threads of this process
                    394:        push    ax
                    395:        mov     al,byte ptr [status] ; get return value (low 8 bits)
                    396:        push    ax
                    397:        call    DOSEXIT         ; exit with return code
                    398: 
                    399: cEnd   nogen
                    400: 
                    401: if     sizeC
                    402: global endp
                    403: endif
                    404: 
                    405: page
                    406: ;***
                    407: ;_ctermsub - What does this do?
                    408: ;
                    409: ;Purpose:
                    410: ;      UNDONE: What does this entry point do?
                    411: ;
                    412: ;Entry:
                    413: ;
                    414: ;Exit:
                    415: ;
                    416: ;Uses:
                    417: ;
                    418: ;Exceptions:
                    419: ;
                    420: ;*******************************************************************************
                    421: 
                    422: labelNP        <PUBLIC,_ctermsub>
                    423: 
                    424: ;      5.      terminate floating point
                    425: 
                    426:        mov     cx,word ptr [fpmath+2] ; test for floating point
                    427:        jcxz    nofloat_t       ;   no
                    428: 
                    429:        mov     bx,2            ;   yes - cleanup
                    430:        call    [fpmath]
                    431: 
                    432: nofloat_t:
                    433: 
                    434:        ret
                    435: 
                    436: page
                    437: ;***
                    438: ;initterm - do all the initializers and terminators
                    439: ;
                    440: ;Purpose:
                    441: ;      The initializers and terminators may be written in C
                    442: ;      so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
                    443: ;      We go through them in reverse order for onexit.
                    444: ;
                    445: ;Entry:
                    446: ;      SI      = start of procedure list
                    447: ;      DI      = end of procedure list
                    448: ;
                    449: ;Exit:
                    450: ;
                    451: ;Uses:
                    452: ;
                    453: ;Exceptions:
                    454: ;
                    455: ;*******************************************************************************
                    456: 
                    457: initterm:
                    458:        cmp     si,di           ; are we done?
                    459:        jae     itdone          ;   yes - no more
                    460: 
                    461: if     sizeC
                    462:        sub     di,4
                    463:        mov     ax,[di]
                    464:        or      ax,[di+2]
                    465:        jz      initterm        ; skip null procedures
                    466:        call    dword ptr [di]
                    467: else
                    468:        dec     di
                    469:        dec     di
                    470:        mov     cx,[di]
                    471:        jcxz    initterm        ; skip null procedures
                    472:        call    cx
                    473: endif
                    474:        jmp     initterm        ; keep looping
                    475: 
                    476: itdone:
                    477:        ret
                    478: 
                    479: sEnd
                    480: 
                    481:        end

unix.superglobalmegacorp.com

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