|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.