Annotation of os2sdk/startup/dos/crt0dat.asm, revision 1.1

1.1     ! root        1:        page    ,132
        !             2:        TITLE   crt0dat - DOS and Windows shared startup and termination
        !             3: ;***
        !             4: ;crt0dat.asm - DOS and Windows shared startup and termination
        !             5: ;
        !             6: ;      Copyright (c) 1985-1987, Microsoft Corporation.  All rights reserved.
        !             7: ;
        !             8: ;Purpose:
        !             9: ;      Shared startup and termination.
        !            10: ;
        !            11: ;*******************************************************************************
        !            12: 
        !            13: _NFILE_        =       20              ; Maximum number of file handles
        !            14: 
        !            15: ?DF    =       1               ;; tell cmacros.inc we want to define our own segments
        !            16: 
        !            17: include        version.inc
        !            18: .xlist
        !            19: ifdef  _QC                     ;[8] Move these includes out of version.inc
        !            20: include        \sl\qc\src\include\kernel.inc   ;[8]
        !            21: include \sl\qc\src\include\kmac.inc    ;[8]
        !            22: endif  ;_QC                    ;[8]
        !            23: 
        !            24: include        cmacros.inc
        !            25: include        msdos.inc
        !            26: .list
        !            27: 
        !            28: ifdef  _QC
        !            29: BEGINT equ     34h             ;First EM.LIB interrupt vector.
        !            30: NUMVEC equ     11              ;Uses 11 actual vectors.
        !            31: endif  ;_QC
        !            32: 
        !            33: createSeg _TEXT, code, word,   public, CODE,   <>
        !            34: createSeg CDATA, cdata,        word,   common, DATA,   DGROUP
        !            35: createSeg _DATA, data, word,   public, DATA,   DGROUP
        !            36: 
        !            37: ifndef IBMC20
        !            38: createSeg XIFB,        xifbseg, word,  public, DATA,   DGROUP
        !            39: createSeg XIF, xifseg, word,   public, DATA,   DGROUP ; far init's
        !            40: createSeg XIFE,        xifeseg, word,  public, DATA,   DGROUP
        !            41: endif  ;IBMC20
        !            42: 
        !            43: createSeg XIB, xibseg, word,   public, DATA,   DGROUP
        !            44: createSeg XI,  xiseg,  word,   public, DATA,   DGROUP ; init's
        !            45: createSeg XIE, xieseg, word,   public, DATA,   DGROUP
        !            46: 
        !            47: createSeg XOB, xobseg, word,   public, BSS,    DGROUP
        !            48: createSeg XO,  xoseg,  word,   public, BSS,    DGROUP ; onexit table
        !            49: createSeg XOE, xoeseg, word,   public, BSS,    DGROUP
        !            50: 
        !            51: createSeg XPB, xpbseg, word,   public, DATA,   DGROUP
        !            52: createSeg XP,  xpseg,  word,   public, DATA,   DGROUP ; preterm's
        !            53: createSeg XPE, xpeseg, word,   public, DATA,   DGROUP
        !            54: 
        !            55: createSeg XCB, xcbseg, word,   public, DATA,   DGROUP
        !            56: createSeg XC,  xcseg,  word,   public, DATA,   DGROUP ; term's
        !            57: createSeg XCE, xceseg, word,   public, DATA,   DGROUP
        !            58: 
        !            59: ifndef IBMC20
        !            60: createSeg XCFB,        xcfbseg, word,  public, DATA,   DGROUP
        !            61: createSeg XCF, xcfseg, word,   public, DATA,   DGROUP ; far term's
        !            62: createSeg XCFE,        xcfeseg, word,  public, DATA,   DGROUP
        !            63: endif  ;IBMC20
        !            64: 
        !            65: defGrp DGROUP                  ;; define DGROUP
        !            66: 
        !            67: codeOFFSET equ offset _TEXT:
        !            68: dataOFFSET equ offset DGROUP:
        !            69: 
        !            70: page
        !            71: ifndef IBMC20
        !            72: sBegin xifbseg
        !            73: xifbegin label byte
        !            74: sEnd   xifbseg
        !            75: 
        !            76: sBegin xifeseg
        !            77: xifend label   byte
        !            78: sEnd   xifeseg
        !            79: endif  ;IBMC20
        !            80: 
        !            81: sBegin xibseg
        !            82: xibegin        label   byte
        !            83: sEnd   xibseg
        !            84: 
        !            85: sBegin xieseg
        !            86: xiend  label   byte
        !            87: sEnd   xieseg
        !            88: 
        !            89: sBegin xobseg
        !            90: xontab label   byte            ; start of onexit table
        !            91: sEnd   xobseg
        !            92: 
        !            93: sBegin xoeseg
        !            94: xonend label   byte
        !            95: sEnd   xoeseg
        !            96: 
        !            97: sBegin xpbseg
        !            98: xpbegin        label   byte            ; end of onexit table
        !            99: sEnd   xpbseg
        !           100: 
        !           101: sBegin xpeseg
        !           102: xpend  label   byte
        !           103: sEnd   xpeseg
        !           104: 
        !           105: sBegin xcbseg
        !           106: xcbegin        label   byte
        !           107: sEnd   xcbseg
        !           108: 
        !           109: sBegin xceseg
        !           110: xcend  label   byte
        !           111: sEnd   xceseg
        !           112: 
        !           113: ifndef IBMC20
        !           114: sBegin xcfbseg
        !           115: xcfbegin label byte
        !           116: sEnd   xifbseg
        !           117: 
        !           118: sBegin xcfeseg
        !           119: xcfend label   byte
        !           120: sEnd   xcfeseg
        !           121: endif  ;IBMC20
        !           122: 
        !           123: ifdef _QC
        !           124:        extrn   $Exec_Shell:FAR
        !           125:        extrn   $Terminate_QC:FAR       ;[5] exit point for shell exits
        !           126:        extrn   __fpsignal:FAR
        !           127:        extrn   $EmulInit:FAR           ;[6]
        !           128:        extrn   $EmulTerm:FAR           ;[6]
        !           129: endif  ;_QC
        !           130: 
        !           131: sBegin cdata                   ; floating point setup segment
        !           132: assumes        ds,data
        !           133: 
        !           134:        dw      0               ; force segment to be at least 0's
        !           135: labelD <PUBLIC,_fpinit>        ; public for signal
        !           136: fpmath dd      1 dup (?)       ; linking trick for fp
        !           137: fpdata dd      1 dup (?)
        !           138: ifdef  _QC
        !           139: fpsignal dd    __fpsignal      ; fp signal message
        !           140: else   ;_QC
        !           141: fpsignal dd    1 dup (?)       ; fp signal message
        !           142: endif  ;_QC
        !           143: 
        !           144: ifdef  _QC                     ;[5]
        !           145: staticB        shellexit,0             ;[5] marker for special exit for shell
        !           146: endif  ;_QC                    ;[5]
        !           147: 
        !           148: sEnd
        !           149: 
        !           150: ifdef  _QC
        !           151: externP        _Break_error
        !           152: endif  ;_QC
        !           153: 
        !           154: sBegin data
        !           155: assumes        ds,data
        !           156: 
        !           157: ;      special C environment string
        !           158: 
        !           159:        labelB  <PUBLIC,_acfinfo>
        !           160:        cfile   db      ';C_FILE_INFO'
        !           161:        cfilex  db      0
        !           162:        cfileln =       cfilex-cfile
        !           163: 
        !           164: ifdef  _QC
        !           165: globalD                _abrkvec,0              ;[4]break interrupt vector
        !           166: endif  ;_QC
        !           167: 
        !           168: globalD        _aintdiv,0              ; divide error interrupt vector save
        !           169: 
        !           170: globalQ        _fac,0                  ; floating accumulator
        !           171: globalW        errno,0                 ; initial error code
        !           172: globalW        _umaskval,0             ; initial umask value
        !           173: 
        !           174: ;=============== following must be in this order
        !           175: 
        !           176: globalW        _pspadr,0               ; psp:0 (far * to PSP segment)
        !           177: globalW        _psp,0                  ; psp:0 (paragraph #)
        !           178: 
        !           179: ;=============== above must be in this order
        !           180: 
        !           181: ;=============== following must be in this order
        !           182: 
        !           183: labelW <PUBLIC,_osversion>
        !           184: labelB <PUBLIC,_dosvermajor>
        !           185: globalB        _osmajor,0
        !           186: labelB <PUBLIC,_dosverminor>
        !           187: globalB        _osminor,0
        !           188: 
        !           189: ;=============== above must be in this order
        !           190: 
        !           191: 
        !           192: globalB        _osmode,0               ; 0 = real mode
        !           193: 
        !           194: labelW <PUBLIC,_oserr>
        !           195: globalW        _doserrno,0             ; initial DOS error code
        !           196: 
        !           197: globalW        _nfile,_NFILE_          ; maximum number of file handles
        !           198: 
        !           199: labelB <PUBLIC,_osfile>
        !           200:        db      3 dup (FOPEN+FTEXT) ; stdin, stdout, stderr
        !           201:        db      2 dup (FOPEN)   ; stdaux, stdprn
        !           202:        db      _NFILE_-5 dup (0) ; the other 15 handles
        !           203: 
        !           204: 
        !           205: globalW        __argc,0
        !           206: globalDP __argv,0
        !           207: globalDP environ,0             ; environment pointer
        !           208: 
        !           209: labelD <PUBLIC,_pgmptr>        ; pointer to program name
        !           210:        dw      dataOFFSET dos2nam,DGROUP
        !           211: dos2nam        db      'C',0           ; dummy argv[0] for DOS 2.X
        !           212: 
        !           213: 
        !           214: ; signal related common data
        !           215: 
        !           216: globalW        _child,0                ; flag used to handle signals from child process
        !           217: 
        !           218: ifndef _QC                     ;[XX] we don't do overlays
        !           219: ifndef IBMC20
        !           220: ;Overlay related data
        !           221: 
        !           222: globalB _ovlflag,0     ;Overlay flag (0 = no overlays)
        !           223: globalB        _intno,0        ;Overlay interrupt value (e.g., 3F)
        !           224: globalD _ovlvec,0      ;Address of original overlay handler
        !           225: endif
        !           226: endif  ;_QC                    ;[XX] we don't do overlays
        !           227: 
        !           228: ifdef   _QC
        !           229: con    db      'CON',0
        !           230: _fpsave        dd      NUMVEC dup (0)
        !           231: endif  ;_QC
        !           232: 
        !           233: ifdef _QC                      ;[1]
        !           234: ; DWORD pointer for runtime errors.  Routines calling amsg_exit set this
        !           235: ; to their 'best guess' for the CS:IP where the error occurred.  amsg_exit
        !           236: ; then uses this information to set up information for return to the shell.
        !           237: ; [1]
        !           238: 
        !           239: globalD        _QCrtcsip, 0    ;[1]
        !           240: endif  ;_QC            ;[1]
        !           241: 
        !           242: sEnd   data
        !           243: 
        !           244: page
        !           245: sBegin code
        !           246: assumes        cs,code
        !           247: 
        !           248: if     sizeC
        !           249: global proc    far
        !           250: endif
        !           251: 
        !           252: ifndef _QC                             ;[X] fptrap has vanished
        !           253: externNP _fptrap
        !           254: endif  ;_QC                            ;[X]
        !           255: externP        _cintDIV
        !           256: externP        _nullcheck
        !           257: 
        !           258: ifdef  _QC                             ;[10]
        !           259: extrn  $F_PSP:WORD                     ;[10]
        !           260: endif  ;ifdef _QC                      ;[10]
        !           261: 
        !           262: page
        !           263: ;***
        !           264: ;_cinit - C initialization
        !           265: ;
        !           266: ;Purpose:
        !           267: ;      This routine performs the shared DOS and Windows initialization.
        !           268: ;      The following order of initialization must be preserved -
        !           269: ;
        !           270: ;      1.      Integer divide interrupt vector setup
        !           271: ;      2.      Floating point initialization
        !           272: ;      3.      Copy ;C_FILE_INFO into _osfile
        !           273: ;      4.      Check for devices for file handles 0 - 4
        !           274: ;      5.      General C initializer routines
        !           275: ;
        !           276: ;Entry:
        !           277: ;
        !           278: ;Exit:
        !           279: ;
        !           280: ;Uses:
        !           281: ;
        !           282: ;Exceptions:
        !           283: ;
        !           284: ;*******************************************************************************
        !           285: 
        !           286: cProc  _cinit,<PUBLIC>,<>
        !           287: 
        !           288: cBegin nogen                   ; no local frame to set up
        !           289: assumes        ds,data
        !           290: assumes        ss,data
        !           291: 
        !           292: ;      Store DOS major/minor version number
        !           293: ;      This is done in crt0dat.asm rather than in crt0.asm for Windows' sake.
        !           294: ;
        !           295: 
        !           296:        callos  VERSION
        !           297:        mov     [_osversion],ax
        !           298: 
        !           299: ;      1.      Integer divide interrupt vector setup
        !           300: 
        !           301:        mov     ax,DOS_getvector shl 8 + 0
        !           302:        callos                  ; save divide error interrupt
        !           303:        mov     word ptr [_aintdiv],bx
        !           304:        mov     word ptr [_aintdiv+2],es
        !           305: 
        !           306:        push    cs
        !           307:        pop     ds
        !           308:        assumes ds,nothing
        !           309:        mov     ax,DOS_setvector shl 8 + 0
        !           310:        mov     dx,codeOFFSET _cintDIV
        !           311:        callos                  ; set divide error interrupt
        !           312:        push    ss
        !           313:        pop     ds
        !           314:        assumes ds,data
        !           315: 
        !           316: 
        !           317: ifdef  _QC
        !           318: ;      1a. BREAK interrupt vector setup.
        !           319: 
        !           320:        INT21   3523h                   ;[4]Get vector via MSDOS.
        !           321: 
        !           322:        mov     Word Ptr [__abrkvec],bx ;[4]save vector offset
        !           323:        mov     Word Ptr [__abrkvec+2],es ;[4]save vector segment
        !           324: 
        !           325:        push    cs                      ;[4]
        !           326:        pop     ds                      ;[4]
        !           327:        mov     es,$F_PSP               ;[10]get QC PSP for flags
        !           328:        test    es:[PSP_KERNEL_FLGS],PSP_KF_SHELL ;[10]test if in SHELL
        !           329:        mov     dx,codeOFFSET intret    ;[10]set DS:DX to int-return pointer
        !           330:        JNZ     cinit_shell             ;[10]if SHELL, then jump
        !           331:        mov     dx,codeOFFSET __Break_error ;[4]
        !           332: cinit_shell:                           ;[10]
        !           333:        INT21   2523h                   ;[4]Set up new break vector
        !           334: 
        !           335:        push    ss                      ;[4]
        !           336:        pop     ds                      ;[4]
        !           337: endif  ;_QC
        !           338: 
        !           339: ;      2.      Floating point initialization
        !           340: 
        !           341: ifndef _QC
        !           342:        mov     cx,word ptr [fpmath+2]
        !           343:        jcxz    nofloat_i
        !           344: 
        !           345:        mov     es,[_psp]       ; psp segment
        !           346:        mov     si,es:[DOS_ENVP] ; environment segment
        !           347:        lds     ax,[fpdata]     ; get task data area
        !           348:        assumes ds,nothing
        !           349:        mov     dx,ds           ;   into dx:ax
        !           350:        xor     bx,bx           ; (si) = environment segment
        !           351:        call    [fpmath]        ; fpmath(0) - init
        !           352:        jnc     fpok
        !           353: 
        !           354:        push    ss              ; restore ds from ss
        !           355:        pop     ds
        !           356:        jmp     _fptrap         ; issue "Floating point not loaded"
        !           357:                                ; error and abort
        !           358: 
        !           359: fpok:
        !           360:        lds     ax,[fpsignal]   ; get signal address
        !           361:        assumes ds,nothing
        !           362:        mov     dx,ds
        !           363:        mov     bx,3
        !           364:        call    [fpmath]        ; fpmath(3) - set signal address
        !           365:        push    ss
        !           366:        pop     ds
        !           367:        assumes ds,data
        !           368: 
        !           369: nofloat_i:
        !           370: else   ;_QC
        !           371: ;      cCall   $EmulInit,<addr of __fpinit>    ;[9]
        !           372:        push    ds                              ;[9]
        !           373:        mov     ax,dataOffset _fpinit           ;[9]
        !           374:        push    ax                              ;[9]
        !           375:        call    $EmulInit                       ;[6]
        !           376: endif  ;_QC
        !           377: 
        !           378: ;      3.      Copy ;C_FILE_INFO into _osfile
        !           379: 
        !           380: ;      fix up files inherited from child using ;C_FILE_INFO
        !           381: 
        !           382:        mov     es,[_psp]       ; es = PSP
        !           383:        mov     cx,word ptr es:[DOS_envp] ; es = user's environment
        !           384:        jcxz    nocfi           ;   no environment !!!
        !           385:        mov     es,cx
        !           386:        xor     di,di           ; start at 0
        !           387: 
        !           388: cfilp:
        !           389:        cmp     byte ptr es:[di],0 ; check for end of environment
        !           390:        je      nocfi           ;   yes - not found
        !           391:        mov     cx,cfileln
        !           392:        mov     si,dataOFFSET cfile
        !           393:        repe    cmpsb           ; compare for ';C_FILE_INFO'
        !           394:        je      gotcfi          ;   yes - now do something with it
        !           395:        mov     cx,07FFFh       ; environment max = 32K
        !           396:        xor     ax,ax
        !           397:        repne   scasb           ; search for end of current string
        !           398:        jne     nocfi           ;   no 00 !!! - assume end of env.
        !           399:        jmp     cfilp           ; keep searching
        !           400: 
        !           401: ;      found ;C_FILE_INFO and transfer info into _osfile
        !           402: 
        !           403: gotcfi:
        !           404:        push    es
        !           405:        push    ds
        !           406:        pop     es              ; es = DGROUP
        !           407:        pop     ds              ; ds = env. segment
        !           408:        assumes ds,nothing
        !           409:        assumes es,data
        !           410:        mov     si,di           ; si = startup of _osfile info
        !           411:        mov     di,dataOFFSET _osfile ; di = _osfile block
        !           412: 
        !           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:        push    ss
        !           427:        pop     ds              ; ds = DGROUP
        !           428:        assumes ds,data
        !           429: nocfi:
        !           430: 
        !           431: 
        !           432: ;      4.      Check for devices for file handles 0 - 4
        !           433: ;
        !           434: ;              Clear the FDEV bit (which might be inherited from C_FILE_INFO)
        !           435: ;              and then call DOS to see if it really is a device or not
        !           436: ;
        !           437:        mov     bx,4
        !           438: 
        !           439: devloop:
        !           440:        and     _osfile[bx],not FDEV ; clear FDEV bit on principal
        !           441: 
        !           442:        mov     ax,DOS_ioctl shl 8 + 0 ; issue ioctl(0) to get dev info
        !           443:        callos
        !           444:        jc      notdev
        !           445: 
        !           446:        test    dl,80h          ; is it a device ?
        !           447:        jz      notdev          ;   no
        !           448:        or      _osfile[bx],FDEV ;   yes - set FDEV bit
        !           449: 
        !           450: notdev:
        !           451:        dec     bx
        !           452:        jns     devloop
        !           453: 
        !           454: ;      5.      General C initializer routines
        !           455: 
        !           456: ifndef IBMC20
        !           457:        mov     si,dataOFFSET xifbegin
        !           458:        mov     di,dataOFFSET xifend
        !           459: if     sizeC
        !           460:        call    initterm        ; call the far initializers
        !           461: else
        !           462:        call    farinitterm     ; call the far initializers
        !           463: endif
        !           464: 
        !           465: ifdef   _QC                                    ;[2]
        !           466:        mov     bx,24                           ;[2] offset in table
        !           467:        mov     si,PSP_UL_TERM_OFF              ;[7] QLB initializers
        !           468:        call    ulibinitterm                    ;[2] execute far C initializers
        !           469: 
        !           470:        mov     bx,24                           ;[7] offset in table
        !           471:        mov     si,PSP_EXE_TRM_OFF              ;[7] .exe initializers
        !           472:        call    ulibinitterm                    ;[7] execute far C initializers
        !           473: endif  ;_QC                                    ;[2]
        !           474: endif  ;IBMC20
        !           475: 
        !           476:        mov     si,dataOFFSET xibegin
        !           477:        mov     di,dataOFFSET xiend
        !           478:        call    initterm        ; call the initializers
        !           479: 
        !           480: ifdef _QC                                      ;[2]
        !           481:        mov     bx,0                            ;[2] offset in table
        !           482:        mov     si,PSP_UL_TERM_OFF              ;[7] User Lib initializers
        !           483:        call    ulibinitterm                    ;[2] execute C initializers
        !           484: 
        !           485:        mov     bx,0                            ;[7] offset in table
        !           486:        mov     si,PSP_EXE_TRM_OFF              ;[7] .exe initializers
        !           487:        call    ulibinitterm                    ;[7] execute far C initializers
        !           488: endif  ;_QC                                    ;[2]
        !           489: 
        !           490:        ret
        !           491: cEnd   nogen
        !           492: 
        !           493: page
        !           494: ;***
        !           495: ;exit(status), _exit(status) - C termination
        !           496: ;
        !           497: ;Purpose:
        !           498: ;      The termination sequence is more complicated due to the multiple
        !           499: ;      entry points - exit(code) and _exit(code).  The _exit() routine
        !           500: ;      is a quick exit routine that does not do certain C exit functions
        !           501: ;      like stdio buffer flushing and onexit processing.
        !           502: ;
        !           503: ;      exit (status):
        !           504: ;
        !           505: ;      1.      call runtime preterminators
        !           506: ;
        !           507: ;      _exit (status):
        !           508: ;
        !           509: ;      2.      perform C terminators
        !           510: ;      3.      perform _nullcheck() for null pointer assignment
        !           511: ;      4.      close all open files
        !           512: ;      5.      terminate floating point
        !           513: ;      6.      reset divide by zero interrupt vector
        !           514: ;      7.      restore int 3F handler
        !           515: ;      8.      terminate with return code to DOS
        !           516: ;
        !           517: ;Entry:
        !           518: ;      int status - exit status
        !           519: ;
        !           520: ;Exit:
        !           521: ;      returns to DOS.
        !           522: ;
        !           523: ;Uses:
        !           524: ;
        !           525: ;Exceptions:
        !           526: ;
        !           527: ;*******************************************************************************
        !           528: 
        !           529: public _exit
        !           530: _exit:
        !           531: cProc  dummy1,<>,<>
        !           532: 
        !           533: parmw  status
        !           534: 
        !           535: cBegin
        !           536: assumes        ds,data
        !           537: assumes        ss,data
        !           538: 
        !           539: ;      1.      call runtime preterminators
        !           540: ;              - onexit processing
        !           541: ;              - flushall
        !           542: ;              - rmtmp
        !           543: 
        !           544:        mov     si,dataOFFSET xontab ; beginning of onexit table
        !           545:        mov     di,dataOFFSET xonend ; end of onexit table
        !           546:        call    initterm
        !           547: 
        !           548:        mov     si,dataOFFSET xpbegin ; beginning of pre-terminators
        !           549:        mov     di,dataOFFSET xpend ; end of pre-terminators
        !           550:        call    initterm
        !           551: 
        !           552: ifdef  _QC                             ;[2]
        !           553:        ; [2] call the preterminators for the user library.
        !           554: 
        !           555:        mov     bx,8                            ;[2] offset in table
        !           556:        mov     si,PSP_UL_TERM_OFF              ;[7] User Lib initializers
        !           557:        call    ulibinitterm                    ;[2] execute C terminators
        !           558: 
        !           559:        mov     bx,8                            ;[7] offset in table
        !           560:        mov     si,PSP_EXE_TRM_OFF              ;[7] .exe initializers
        !           561:        call    ulibinitterm                    ;[7] execute far C initializers
        !           562: endif  ;_QC                                    ;[2]    
        !           563: 
        !           564:        jmp     short exiting   ; jump into _exit
        !           565: 
        !           566: cend   nogen
        !           567: 
        !           568: ifdef  _QC                             ;[5]
        !           569: 
        !           570: public __shell_exit                    ;[5]
        !           571: __shell_exit:                          ;[5]
        !           572: 
        !           573: cProc  dummy3,<>,<>                    ;[5]
        !           574: parmw  status                          ;[5]    
        !           575: 
        !           576: cBegin                                 ;[5]
        !           577:        mov     [shellexit],1           ;[5] mark as a shell exit
        !           578:        jmp     short exiting           ;[5] jump into _exit
        !           579: cEnd   nogen                           ;[5]
        !           580: 
        !           581: public __qcexit                        ;[11]
        !           582: __qcexit:                              ;[11]
        !           583: 
        !           584: cproc  dummy4,<>,<>                    ;[11]
        !           585: parmw  status                          ;[11]
        !           586: 
        !           587: cBegin                                 ;[11]
        !           588:        jmp     short   startclose      ;[11]
        !           589: cEnd   nogen                           ;[11]
        !           590: endif  ;_QC                            ;[5]
        !           591: 
        !           592: public __exit
        !           593: __exit:
        !           594: cProc  dummy2,<>,<>
        !           595: 
        !           596: parmw  status
        !           597: 
        !           598: cBegin
        !           599: assumes        ds,data
        !           600: assumes        ss,data
        !           601: 
        !           602: exiting:
        !           603: 
        !           604: ;      2.      perform C terminators
        !           605: 
        !           606:        mov     si,dataOFFSET xcbegin
        !           607:        mov     di,dataOFFSET xcend
        !           608:        call    initterm        ; call the terminators
        !           609: 
        !           610: ifdef  _QC                             ;[2]
        !           611:        ; [2] call the terminators for the user library.
        !           612: 
        !           613:        mov     bx,16                           ;[2] offset in table
        !           614:        mov     si,PSP_UL_TERM_OFF              ;[7] User Lib initializers
        !           615:        call    ulibinitterm                    ;[2] execute C terminators
        !           616: 
        !           617:        mov     bx,16                           ;[7] offset in table
        !           618:        mov     si,PSP_EXE_TRM_OFF              ;[7] .exe initializers
        !           619:        call    ulibinitterm                    ;[7] execute far C initializers
        !           620: endif  ;_QC                                    ;[2]
        !           621: 
        !           622: ifndef IBMC20
        !           623:        mov     si,dataOFFSET xcfbegin
        !           624:        mov     di,dataOFFSET xcfend
        !           625: if     sizeC
        !           626:        call    initterm        ; call the far terminators
        !           627: else
        !           628:        call    farinitterm     ; call the far terminators
        !           629: endif
        !           630: 
        !           631: ifdef  _QC                             ;[2]
        !           632:        ; [2] call the terminators for the user library.
        !           633: 
        !           634:        mov     bx,32                           ;[2] offset in table
        !           635:        mov     si,PSP_UL_TERM_OFF              ;[7] User Lib initializers
        !           636:        call    ulibinitterm                    ;[2] execute far terminators
        !           637: 
        !           638:        mov     bx,32                           ;[7] offset in table
        !           639:        mov     si,PSP_EXE_TRM_OFF              ;[7] .exe initializers
        !           640:        call    ulibinitterm                    ;[7] execute far C initializers
        !           641: endif  ;_QC                                    ;[2]
        !           642: 
        !           643: endif  ;IBMC20
        !           644: 
        !           645: ;      3.      perform _nullcheck() for null pointer assignment
        !           646: 
        !           647:        call    _nullcheck      ; check data in NULL data segment at DS:0
        !           648:        or      ax,ax           ; zero if no null ptr assignment detected
        !           649:        jz      startclose
        !           650:        cmp     status,0        ; zero if no other error has occurred
        !           651:        jnz     startclose
        !           652:        mov     status,255      ; nonzero status to indicate an
        !           653:                                ; null-pointer-assignment error
        !           654: startclose:
        !           655: 
        !           656: ;      4.      close all files (except pre-opened handles 0-4)
        !           657: 
        !           658: ifdef  _QC
        !           659: 
        !           660: ;
        !           661: ; M00BUG -- Can't assume that devices 0, 1, 2, 3, and 4 are DEVICE only.
        !           662: ;
        !           663: 
        !           664:        mov     cx,_NFILE                                               ;[ 1]
        !           665:        xor     bx,bx                                                   ;[ 1]
        !           666:                                                                        ;[ 1]
        !           667: closeloop:                                                             ;[ 1]
        !           668:        cmp     bx,5                                                    ;[ 1]
        !           669:        jae     closeit                 ;Unless > 4, which must close.  ;[ 1]
        !           670:                                                                        ;[ 1]
        !           671:        test    [__osfile+bx],FDEV                                      ;[ 1]
        !           672:        jz      openit                  ;Must open devices 0 -> 4.      ;[ 1]
        !           673:                                                                        ;[ 1]
        !           674:        test    [__osfile+bx],FOPEN                                     ;[ 1]
        !           675:        jnz     cycle_files             ;DEVICE's should stay open.     ;[ 1]
        !           676:                                                                        ;[ 1]
        !           677: openit:                                                                        ;[ 1]
        !           678:        mov     dx,dataOFFSET con       ;Ugly brute force method.       ;[ 1]
        !           679:        mov     ax,3D02h                                                ;[ 1]
        !           680:        int     21h                                                     ;[ 1]
        !           681:                                                                        ;[ 1]
        !           682:        jmp     short cycle_files                                       ;[ 1]
        !           683:                                                                        ;[ 1]
        !           684: closeit:                                                               ;[ 1]
        !           685:        test    [__osfile+bx],FOPEN                                     ;[ 1]
        !           686:        jz      cycle_files                                             ;[ 1]
        !           687:                                                                        ;[ 1]
        !           688:        INT21   3Eh                     ;MSDOS close file.              ;[ 1]
        !           689:                                                                        ;[ 1]
        !           690: cycle_files:                                                           ;[ 1]
        !           691:        inc     bx
        !           692:        loop    closeloop
        !           693: 
        !           694: else   ;_QC
        !           695:        mov     cx,_NFILE_-5
        !           696:        mov     bx,5            ; close handles that are not pre-opened
        !           697: 
        !           698: closeloop:
        !           699:        test    _osfile[bx],FOPEN
        !           700:        jz      notopen
        !           701: 
        !           702:        callos  close
        !           703: 
        !           704: notopen:
        !           705:        inc     bx
        !           706:        loop    closeloop
        !           707: endif  ;_QC
        !           708: 
        !           709: ;      5.      terminate floating point
        !           710: ;      6.      reset divide by zero interrupt vector
        !           711: ;      7.      restore int 3F handler
        !           712: 
        !           713:        call    _ctermsub       ; fast cleanup
        !           714: 
        !           715: ifdef   _QC
        !           716: ;      8.      return to SHELL.
        !           717: 
        !           718:        cmp     [shellexit],1
        !           719:        je      exit_sh1
        !           720: 
        !           721:        mov     ax,[status]
        !           722:        jmp     Far Ptr $Exec_Shell
        !           723: 
        !           724: exit_sh1:
        !           725:        mov     ax,[status]
        !           726:        jmp     Far Ptr $Terminate_QC
        !           727: 
        !           728: ;[10]  Interrupt return for control-break routine while in SHELL.
        !           729: 
        !           730: intret:                                ;[10]
        !           731:        IRET                    ;[10]immediate return while in termination
        !           732: 
        !           733: else   ;_QC
        !           734: ;      8.      return to the DOS
        !           735: 
        !           736:        mov     ax,status       ; get return value
        !           737:        callos  terminate       ; exit with al = return code
        !           738: endif  ;_QC
        !           739: 
        !           740: cEnd   nogen
        !           741: 
        !           742: if     sizeC
        !           743: global endp
        !           744: endif
        !           745: 
        !           746: page
        !           747: ;***
        !           748: ;_ctermsub - more C termination code
        !           749: ;
        !           750: ;Purpose:
        !           751: ;      This routine 
        !           752: ;              (1) performs floating-point termination
        !           753: ;              (2) resets the divide by zero interrupt vector
        !           754: ;              (3) restore int 3F handler
        !           755: ;
        !           756: ;Entry:
        !           757: ;
        !           758: ;Exit:
        !           759: ;
        !           760: ;Uses:
        !           761: ;      AX,BX,CX,DX.
        !           762: ;
        !           763: ;Exceptions:
        !           764: ;
        !           765: ;*******************************************************************************
        !           766: 
        !           767: labelNP        <PUBLIC,_ctermsub>
        !           768: 
        !           769: ;      5.      terminate floating point
        !           770: ifndef _QC
        !           771:        mov     cx,word ptr [fpmath+2] ; test for floating point
        !           772:        jcxz    nofloat_t       ;   no
        !           773: 
        !           774:        mov     bx,2            ;   yes - cleanup
        !           775:        call    [fpmath]
        !           776: 
        !           777: nofloat_t:
        !           778: else   ;_QC                    ;[6]
        !           779:        call    $EmulTerm       ;[6] clean up floating point
        !           780: endif  ;_QC                    ;[6]
        !           781: 
        !           782: ;      6.      reset divide by zero interrupt vector
        !           783: 
        !           784:        push    ds
        !           785:        lds     dx,[_aintdiv]   ; ds:dx = restore vector
        !           786:        mov     ax,DOS_setvector shl 8 + 0
        !           787:        callos                  ; set divide error interrupt
        !           788:        pop     ds
        !           789: 
        !           790: ifdef  _QC
        !           791: ;      6a.     reset Control break interrupt vector
        !           792: 
        !           793:        push    ds                      ;[4]
        !           794:        lds     dx,[__abrkvec]          ;[4]Original BREAK vector.
        !           795:        INT21   2523h                   ;[4]
        !           796:        pop     ds                      ;[4]
        !           797: endif  ;_QC
        !           798: 
        !           799: ifndef _QC                             ;[XX]  We don't have overlays
        !           800: ifndef IBMC20
        !           801: ;      7.      restore overlay interrupt vector
        !           802:        
        !           803:        cmp     byte ptr [_ovlflag],0   ; Overlays in use ??
        !           804:        jz      done_ovlvec             ; if 0, don't restore overlay vector
        !           805:        push    ds                      ; save ds
        !           806:        mov     al,byte ptr [_intno]    ; overlay interrupt number
        !           807:        lds     dx,dword ptr [_ovlvec]  ; original ovl interrupt vector
        !           808:        callos  setvector               ; restore the overlay vector
        !           809:        pop     ds                      ; restore ds
        !           810: done_ovlvec:
        !           811: endif
        !           812: endif  ; _QC                           ;[XX]
        !           813:        ret
        !           814: 
        !           815: 
        !           816: page
        !           817: ;***
        !           818: ;initterm - do a set of initializers or terminators
        !           819: ;
        !           820: ;Purpose:
        !           821: ;      The initializors and terminators may be written in C
        !           822: ;      so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
        !           823: ;      We go through them in reverse order for onexit.
        !           824: ;
        !           825: ;Entry:
        !           826: ;      SI      = start of procedure list
        !           827: ;      DI      = end of procedure list
        !           828: ;
        !           829: ;Exit:
        !           830: ;
        !           831: ;Uses:
        !           832: ;
        !           833: ;Exceptions:
        !           834: ;
        !           835: ;*******************************************************************************
        !           836: 
        !           837: initterm:
        !           838:        cmp     si,di           ; are we done?
        !           839:        jae     itdone          ;   yes - no more
        !           840: 
        !           841: if     sizeC
        !           842:        sub     di,4
        !           843:        mov     ax,[di]
        !           844:        or      ax,[di+2]
        !           845:        jz      initterm        ; skip null procedures
        !           846:        call    dword ptr [di]
        !           847: else
        !           848:        dec     di
        !           849:        dec     di
        !           850:        mov     cx,[di]
        !           851:        jcxz    initterm        ; skip null procedures
        !           852:        call    cx
        !           853: endif
        !           854:        jmp     initterm        ; keep looping
        !           855: 
        !           856: itdone:
        !           857:        ret
        !           858: 
        !           859: page
        !           860: ifndef IBMC20
        !           861: ife    sizeC                   ; S/C models only
        !           862: ;***
        !           863: ;farinitterm - do a set of far initializers or terminators
        !           864: ;
        !           865: ;Purpose:
        !           866: ;      The initializors and terminators may be written in C
        !           867: ;      so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
        !           868: ;      We go through them in reverse order for onexit.
        !           869: ;
        !           870: ;Entry:
        !           871: ;      SI      = start of procedure list
        !           872: ;      DI      = end of procedure list
        !           873: ;
        !           874: ;Exit:
        !           875: ;
        !           876: ;Uses:
        !           877: ;
        !           878: ;Exceptions:
        !           879: ;
        !           880: ;*******************************************************************************
        !           881: 
        !           882: farinitterm:
        !           883:        cmp     si,di           ; are we done?
        !           884:        jae     faritdone       ;   yes - no more
        !           885: 
        !           886:        sub     di,4
        !           887:        mov     ax,[di]
        !           888:        or      ax,[di+2]
        !           889:        jz      farinitterm     ; skip null procedures
        !           890:        call    dword ptr [di]
        !           891:        jmp     farinitterm     ; keep looping
        !           892: 
        !           893: faritdone:
        !           894:        ret
        !           895: endif  ;sizeC
        !           896: endif  ;IBMC20
        !           897:        
        !           898: 
        !           899: ifdef  _QC                             ;[2]
        !           900: ;***
        !           901: ; ulibinitterm - do a set of far initializers or terminators
        !           902: ;
        !           903: ;Purpose:
        !           904: ;      The initializors and terminators may be written in C
        !           905: ;      so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
        !           906: ;      We go through them in reverse order for onexit.
        !           907: ;
        !           908: ;Entry:
        !           909: ;      BX = Offset in User Library Init table to use
        !           910: ;
        !           911: ;Exit:
        !           912: ;
        !           913: ;Uses:
        !           914: ;      SI, DI, CX, AX, ES
        !           915: ;
        !           916: ;Exceptions:
        !           917: ;
        !           918: ;*******************************************************************************
        !           919: 
        !           920: ulibinitterm:                                  ;[2]
        !           921:        push    ds                              ;[2] save DGROUP
        !           922:        cmp     [shellexit],1                   ;[7]
        !           923:        je      skipfarterm                     ;[7] shell does not do this initializations
        !           924: 
        !           925:        mov     ds,[_psp]                       ;[2] get pointer to PSP
        !           926:        lds     si,dword ptr ds:[si]            ;[7] load user library far terminator table address
        !           927:        mov     cx,ds                           ;[2] verify that the table exists
        !           928:        or      cx,si                           ;[2]
        !           929:        jz      skipfarterm                     ;[2] NO? then skip over initialization code
        !           930:        les     di,ds:[si+bx]+4                 ;[2] Get end of far terminator list
        !           931:                                                ;[2] Compute offset of list from DGROUP
        !           932:        mov     ax,es                           ;[2]    ax = list segment
        !           933:        pop     cx                              ;[2]    cx = DGROUP segment
        !           934:        push    cx                              ;[2]
        !           935:        sub     ax,cx                           ;[2]    difference
        !           936:        mov     cl,4                            ;[2]
        !           937:        shl     ax,cl                           ;[2]    shift up
        !           938:        add     di,ax                           ;[2]
        !           939:        les     si,ds:[si+bx]                   ;[2] Get end of far terminator list
        !           940:                                                ;[2] Compute offset of list from DGROUP
        !           941:        mov     ax,es                           ;[2]    ax = list segment
        !           942:        pop     cx                              ;[2]    cx = DGROUP segment
        !           943:        push    cx                              ;[2]
        !           944:        sub     ax,cx                           ;[2]    difference
        !           945:        mov     cl,4                            ;[2]
        !           946:        shl     ax,cl                           ;[2]    shift up
        !           947:        add     si,ax                           ;[2]
        !           948:        pop     ds                              ;[2] Restore DGROUP
        !           949:        push    ds                              ;[2]
        !           950:        call    initterm                        ;[2] Execute the list of far terminators
        !           951: 
        !           952: skipfarterm:                                   ;[2]
        !           953:        pop     ds                              ;[2] restore dgroup
        !           954:        ret                                     ;[2]
        !           955: endif  ;_QC                                    ;[2]
        !           956: 
        !           957: sEnd
        !           958:        end

unix.superglobalmegacorp.com

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