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