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