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