summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/CTRLC.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/CTRLC.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DOS/CTRLC.ASM')
-rw-r--r--v4.0/src/DOS/CTRLC.ASM771
1 files changed, 771 insertions, 0 deletions
diff --git a/v4.0/src/DOS/CTRLC.ASM b/v4.0/src/DOS/CTRLC.ASM
new file mode 100644
index 0000000..5a79e04
--- /dev/null
+++ b/v4.0/src/DOS/CTRLC.ASM
@@ -0,0 +1,771 @@
1; SCCSID = @(#)ctrlc.asm 1.4 85/08/16
2; Low level routines for detecting special characters on CON input,
3; the ^C exit/int code, the Hard error INT 24 code, the
4; process termination code, and the INT 0 divide overflow handler.
5;
6; FATAL
7; FATAL1
8; reset_environment
9; DSKSTATCHK
10; SPOOLINT
11; STATCHK
12; CNTCHAND
13; DIVOV
14; CHARHARD
15; HardErr
16;
17; Revision history:
18;
19; AN000 version 4.0 Jan 1988
20; A002 PTM -- dir >lpt3 hangs
21; A003 PTM 3957- fake version for IBMCAHE.COM
22
23;
24; get the appropriate segment definitions
25;
26.xlist
27include dosseg.asm
28
29CODE SEGMENT BYTE PUBLIC 'CODE'
30 ASSUME SS:DOSGROUP,CS:DOSGROUP
31
32.xcref
33INCLUDE DOSSYM.INC
34INCLUDE DEVSYM.INC
35include version.inc
36.cref
37.list
38
39 I_need SFN,WORD
40 I_NEED pJFN,DWORD
41 i_need DevIOBuf,BYTE
42 i_need DidCTRLC,BYTE
43 i_need INDOS,BYTE
44 i_need DSKSTCOM,BYTE
45 i_need DSKSTCALL,BYTE
46 i_need DSKSTST,WORD
47 i_need BCON,DWORD
48 i_need DSKCHRET,BYTE
49 i_need DSKSTCNT,WORD
50 i_need IDLEINT,BYTE
51 i_need CONSWAP,BYTE
52 i_need user_SS,WORD
53 i_need user_SP,WORD
54 i_need User_In_AX,WORD
55 i_need ERRORMODE,BYTE
56 i_need ConC_spsave,WORD
57 i_need Exit_type,BYTE
58 i_need PFLAG,BYTE
59 i_need ExitHold,DWORD
60 i_need WPErr,BYTE
61 i_need ReadOp,BYTE
62 i_need CONTSTK,WORD
63 i_need Exit_Code,WORD
64 i_need CurrentPDB,WORD
65 i_need DIVMES,BYTE
66 i_need DivMesLen,WORD
67 i_need ALLOWED,BYTE
68 i_need FAILERR,BYTE
69 i_need EXTERR,WORD
70 i_need ERR_TABLE_24,BYTE
71 I_need ErrMap24,BYTE
72 I_need ErrMap24End,BYTE
73 I_need fAborting,BYTE
74 I_need AUXStack,BYTE
75 I_need SCAN_FLAG,BYTE
76 I_need EXTOPEN_ON,BYTE ;AN000; DOS 4.0
77 I_need InterCon,BYTE ;AN000; DOS 4.0
78 I_need DOS34_FLAG,WORD ;AN000; DOS 4.0
79 I_need ACT_PAGE,WORD ;AN000; DOS 4.0
80 I_need Special_Version,WORD ;AN007; DOS 4.0
81if debug
82 I_need BugLev,WORD
83 I_need BugTyp,WORD
84include bugtyp.asm
85endif
86IF BUFFERFLAG
87 extrn restore_user_map:near
88ENDIF
89
90Break <Checks for ^C in CON I/O>
91
92ASSUME DS:NOTHING,ES:NOTHING
93
94 procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in
95 CMP BYTE PTR [INDOS],1
96 retnz ; Do NOTHING
97 PUSH CX
98 PUSH ES
99 PUSH BX
100 PUSH DS
101 PUSH SI
102 PUSH CS
103 POP ES
104 Context DS
105 DOSAssume CS,<DS>,"DskStatChk"
106 MOV BYTE PTR [DSKSTCOM],DEVRDND
107 MOV BYTE PTR [DSKSTCALL],DRDNDHL
108 MOV [DSKSTST],0
109 IF DBCS ;AN000;
110 MOV AL, [InterCon] ;AN000;get type of status read 2/13/KK
111 MOV BYTE PTR [DSKCHRET],AL ;AN000; load interim flag into packet
112 ENDIF ;AN000;
113 MOV BX,OFFSET DOSGROUP:DSKSTCALL
114 LDS SI,[BCON]
115ASSUME DS:NOTHING
116 invoke DEVIOCALL2
117 TEST [DSKSTST],STBUI
118 JZ GotCh ; No characters available
119 XOR AL,AL ; Set zero
120RET36:
121 POP SI
122 POP DS
123 POP BX
124 POP ES
125 POP CX
126 return
127
128GotCh:
129 MOV AL,BYTE PTR [DSKCHRET]
130DSK1:
131 CMP AL,"C"-"@"
132 JNZ RET36
133 MOV BYTE PTR [DSKSTCOM],DEVRD
134 MOV BYTE PTR [DSKSTCALL],DRDWRHL
135 MOV BYTE PTR [DSKCHRET],CL
136 MOV [DSKSTST],0
137 MOV [DSKSTCNT],1
138 invoke DEVIOCALL2 ; Eat the ^C
139 POP SI
140 POP DS
141 POP BX ; Clean stack
142 POP ES
143 POP CX
144 JMP CNTCHAND
145
146NOSTOP:
147 CMP AL,"P"-"@"
148 JNZ check_next
149 CMP BYTE PTR [SCAN_FLAG],0 ; ALT_Q ?
150 JZ INCHKJ ; no
151 return
152check_next:
153 IF NOT TOGLPRN
154 CMP AL,"N"-"@"
155 JZ INCHKJ
156 ENDIF
157
158 CMP AL,"C"-"@"
159 JZ INCHKJ
160check_end:
161 return
162
163INCHKJ:
164 JMP INCHK
165
166EndProc DSKSTATCHK
167
168;
169; SpoolInt - signal processes that the DOS is truly idle. We are allowed to
170; do this ONLY if we are working on a 1-12 system call AND if we are not in
171; the middle of an INT 24.
172;
173procedure SPOOLINT,NEAR
174 PUSHF
175 test IdleInt,-1
176 jz POPFRet
177 test ErrorMode,-1
178 jnz POPFRet
179;
180; Note that we are going to allow an external program to issue system calls
181; at this time. We MUST preserve IdleInt across this.
182;
183 PUSH WORD PTR IdleInt
184 INT int_spooler
185 POP WORD PTR IdleInt
186POPFRET:
187 POPF
188 return
189EndProc SPOOLINT
190
191 procedure STATCHK,NEAR
192
193 invoke DSKSTATCHK ; Allows ^C to be detected under
194 ; input redirection
195 PUSH BX
196 XOR BX,BX
197 invoke GET_IO_SFT
198 POP BX
199 retc
200 MOV AH,1
201 invoke IOFUNC
202 JZ SPOOLINT
203 CMP AL,"S"-"@"
204 JNZ NOSTOP
205
206 CMP BYTE PTR [SCAN_FLAG],0 ;AN000; ALT_R ?
207 JNZ check_end ;AN000; yes
208 XOR AH,AH
209 invoke IOFUNC ; Eat Cntrl-S
210 JMP SHORT PAUSOSTRT
211PRINTOFF:
212PRINTON:
213 NOT BYTE PTR [PFLAG]
214 PUSH BX
215 MOV BX,4
216 invoke GET_IO_SFT
217 POP BX
218 retc
219 PUSH ES
220 PUSH DI
221 PUSH DS
222 POP ES
223 MOV DI,SI ; ES:DI -> SFT
224 TEST ES:[DI.sf_flags],sf_net_spool
225 JZ NORM_PR ; Not redirected, echo is OK
226 Callinstall NetSpoolEchoCheck,MultNet,38,<AX>,<AX> ; See if allowed
227 JNC NORM_PR ; Echo is OK
228 MOV BYTE PTR [PFLAG],0 ; If not allowed, disable echo
229 Callinstall NetSpoolClose,MultNet,36,<AX>,<AX> ; and close
230 JMP SHORT RETP6
231
232NORM_PR:
233 CMP BYTE PTR [PFLAG],0
234 JNZ PRNOPN
235 invoke DEV_CLOSE_SFT
236 JMP SHORT RETP6
237
238PRNOPN:
239 invoke DEV_OPEN_SFT
240RETP6:
241 POP DI
242 POP ES
243 return
244
245PAUSOLP:
246 CALL SPOOLINT
247PAUSOSTRT:
248 MOV AH,1
249 invoke IOFUNC
250 JZ PAUSOLP
251INCHK:
252 PUSH BX
253 XOR BX,BX
254 invoke GET_IO_SFT
255 POP BX
256 retc
257 XOR AH,AH
258 invoke IOFUNC
259 CMP AL,"P"-"@"
260;;;;; 7/14/86 ALT_Q key fix
261
262 JZ PRINTON ; no! must be CTRL_P
263
264NOPRINT:
265;;;;; 7/14/86 ALT_Q key fix
266 IF NOT TOGLPRN
267 CMP AL,"N"-"@"
268 JZ PRINTOFF
269 ENDIF
270 CMP AL,"C"-"@"
271 retnz
272EndProc STATCHK
273
274 procedure CNTCHAND,NEAR
275; Ctrl-C handler.
276; "^C" and CR/LF is printed. Then the user registers are restored and the
277; user CTRL-C handler is executed. At this point the top of the stack has 1)
278; the interrupt return address should the user CTRL-C handler wish to allow
279; processing to continue; 2) the original interrupt return address to the code
280; that performed the function call in the first place. If the user CTRL-C
281; handler wishes to continue, it must leave all registers unchanged and RET
282; (not IRET) with carry CLEAR. If carry is SET then an terminate system call
283; is simulated.
284 TEST [DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; from RAWOUT
285 JNZ around_deadlock ;AN002;
286 MOV AL,3 ; Display "^C"
287 invoke BUFOUT
288 invoke CRLF
289around_deadlock: ;AN002;
290 Context DS
291 CMP BYTE PTR [CONSWAP],0
292 JZ NOSWAP
293 invoke SWAPBACK
294NOSWAP:
295 CLI ; Prepare to play with stack
296 MOV SS,[user_SS] ; User stack now restored
297ASSUME SS:NOTHING
298 MOV SP,[user_SP]
299 invoke restore_world ; User registers now restored
300ASSUME DS:NOTHING
301 MOV BYTE PTR [INDOS],0 ; Go to known state
302 MOV BYTE PTR [ERRORMODE],0
303 MOV [ConC_spsave],SP ; save his SP
304 CLC
305 INT int_ctrl_c ; Execute user Ctrl-C handler
306;
307; The user has returned to us. The circumstances we allow are:
308;
309; IRET We retry the operation by redispatching the system call
310; CLC/RETF POP the stack and retry
311; ... Exit the current process with ^C exit
312;
313; User's may RETURN to us and leave interrupts on. Turn 'em off just to be
314; sure
315;
316 CLI
317 MOV [user_IN_AX],ax ; save the AX
318 PUSHF ; and the flags (maybe new call)
319 POP AX
320;
321; See if the input stack is identical to the output stack
322;
323 CMP SP,[ConC_spsave]
324 JNZ ctrlc_try_new ; current SP not the same as saved SP
325;
326; Repeat the operation by redispatching the system call.
327;
328ctrlc_repeat:
329 MOV AX,User_In_AX
330 transfer COMMAND
331;
332; The current SP is NOT the same as the input SP. Presume that he RETF'd
333; leaving some flags on the stack and examine the input
334;
335ctrlc_try_new:
336 ADD SP,2 ; pop those flags
337 TEST AX,f_carry ; did he return with carry?
338 JZ Ctrlc_Repeat ; no carry set, just retry
339;
340; Well... time to abort the user. Signal a ^C exit and use the EXIT system
341; call..
342;
343ctrlc_abort:
344 MOV AX,(EXIT SHL 8) + 0
345 MOV DidCTRLC,-1
346 transfer COMMAND ; give up by faking $EXIT
347
348EndProc CNTCHAND
349
350Break <DIVISION OVERFLOW INTERRUPT>
351
352; Default handler for division overflow trap
353 procedure DIVOV,NEAR
354ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
355 MOV SI,OFFSET DOSGROUP:DIVMES
356 MOV BX,DivMesLen
357 MOV AX,CS
358 MOV SS,AX
359 MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts
360 CALL OutMes
361 JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow
362EndProc DIVOV
363
364;
365; OutMes: perform message output
366; Inputs: SS:SI points to message
367; BX has message length
368; Outputs: message to BCON
369;
370procedure OutMes,NEAR
371
372 Context ES ; get ES addressability
373 Context DS ; get DS addressability
374
375 MOV BYTE PTR [DskStCom],DevWrt
376 MOV BYTE PTR [DskStCall],DRdWrHL
377 MOV [DskSTST],0
378 MOV [DskStCnt],BX
379 MOV BX,OFFSET DOSGROUP:DskStCall
380 MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU)
381 LDS SI,[BCON]
382ASSUME DS:NOTHING
383 invoke DEVIOCALL2
384 MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf
385 MOV [DskStCnt],1
386 return
387EndProc OutMes
388
389Break <CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER>
390
391 procedure CHARHARD,NEAR
392ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
393
394; Character device error handler
395; Same function as HARDERR
396
397 OR AH,allowed_FAIL + allowed_IGNORE + allowed_RETRY
398 MOV Allowed,AH
399 MOV WORD PTR [EXITHOLD+2],ES
400 MOV WORD PTR [EXITHOLD],BP
401 PUSH SI
402 AND DI,STECODE
403 MOV BP,DS ; Device pointer is BP:SI
404 CALL FATALC
405 POP SI
406 return
407EndProc CHARHARD
408
409; Hard disk error handler. Entry conditions:
410; DS:BX = Original disk transfer address
411; DX = Original logical sector number
412; CX = Number of sectors to go (first one gave the error)
413; AX = Hardware error code
414; DI = Original sector transfer count
415; ES:BP = Base of drive parameters
416; [READOP] = 0 for read, 1 for write
417; [ALLOWED] Set with allowed responses to this error (other bits MUST BE 0)
418; Output:
419; [FAILERR] will be set if user responded FAIL
420
421 procedure HardErr,NEAR
422 ASSUME DS:NOTHING,ES:NOTHING
423
424 XCHG AX,DI ; Error code in DI, count in AX
425 AND DI,STECODE ; And off status bits
426 CMP DI,error_I24_write_protect ; Write Protect Error?
427 JNZ NOSETWRPERR
428 PUSH AX
429 MOV AL,ES:[BP.dpb_drive]
430 MOV BYTE PTR [WPERR],AL ; Flag drive with WP error
431 POP AX
432NOSETWRPERR:
433 SUB AX,CX ; Number of sectors successfully transferred
434 ADD DX,AX ; First sector number to retry
435 PUSH DX
436 MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred
437 POP DX
438 ADD BX,AX ; First address for retry
439 XOR AH,AH ; Flag disk section in error
440 CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area?
441 JB ERRINT
442 INC AH ; Flag for FAT
443 CMP DX,ES:[BP.dpb_dir_sector] ; In FAT?
444 JAE TESTDIR ; No
445 MOV ES:[BP.dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace
446 JMP SHORT ERRINT
447
448TESTDIR:
449 INC AH
450 CMP DX,ES:[BP.dpb_first_sector] ; In directory?
451 JB ERRINT
452 INC AH ; Must be in data area
453ERRINT:
454 SHL AH,1 ; Make room for read/write bit
455 OR AH,BYTE PTR [READOP] ; Set bit 0
456; If we have a write protect error when writing on a critical area on disk,
457; do not allow a retry as this may write out garbage on any subsequent disk.
458 ;test ah,1
459 ;jz Not_Crit
460 ;cmp ah,5
461 ;ja Not_Crit
462 ;and [ALLOWED],NOT Allowed_RETRY
463Not_Crit:
464 OR AH,[ALLOWED] ; Set the allowed_ bits
465 entry FATAL
466 MOV AL,ES:[BP.dpb_drive] ; Get drive number
467 entry FATAL1
468 MOV WORD PTR [EXITHOLD+2],ES
469 MOV WORD PTR [EXITHOLD],BP ; The only things we preserve
470 LES SI,ES:[BP.dpb_driver_addr]
471 MOV BP,ES ; BP:SI points to the device involved
472;
473; DI has the INT-24-style extended error. We now map the error code for this
474; into the normalized get extended error set by using the ErrMap24 table as an
475; translate table. Note that we translate ONLY the device returned codes and
476; leave all others beyond the look up table alone.
477;
478FATALC:
479 call SET_I24_EXTENDED_ERROR
480 CMP DI,error_I24_gen_failure
481 JBE GOT_RIGHT_CODE ; Error codes above gen_failure get
482 MOV DI,error_I24_gen_failure ; mapped to gen_failure. Real codes
483 ; Only come via GetExtendedError
484
485 entry NET_I24_ENTRY
486; Entry point used by REDIRector on Network I 24 errors.
487;
488; ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
489;
490; ALL I 24 regs set up. ALL Extended error info SET. ALLOWED Set.
491; EXITHOLD set for restore of ES:BP.
492
493GOT_RIGHT_CODE:
494 CMP BYTE PTR [ERRORMODE],0 ; No INT 24s if already INT 24
495 JZ NoSetFail
496 MOV AL,3
497 JMP FailRet
498NoSetFail:
499IF BUFFERFLAG
500 invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map
501ENDIF
502 MOV [CONTSTK],SP
503 Context ES
504 fmt TypINT24,LevLog,<"INT 24: AX = $x DI = $x\n">,<AX,DI>
505;
506; Wango!!! We may need to free some user state info... In particular, we
507; may have locked down a JFN for a user and he may NEVER return to us. Thus,
508; we need to free it here and then reallocate it when we come back.
509;
510 CMP SFN,-1
511 JZ NoFree
512 SaveReg <DS,SI>
513 LDS SI,pJFN
514 MOV BYTE PTR [SI],0FFH
515 RestoreReg <SI,DS>
516NoFree:
517 CLI ; Prepare to play with stack
518 INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress
519 DEC BYTE PTR [INDOS] ; INT 24 handler might not return
520;; Extneded Open hooks
521 TEST [DOS34_FLAG],Force_I24_Fail ;AN000;IFS. form IFS Call Back ;AN000;
522 JNZ faili24 ;AN000;IFS. ;AN000;
523 TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;IFS.I24 error disabled ;AN000;
524 JZ i24yes ;AN000;IFS.no ;AN000;
525faili24: ;AN000;
526 MOV AL,3 ;AN000;IFS.fake fail ;AN000;
527 JMP passi24 ;AN000;IFS.exit ;AN000;
528i24yes: ;AN000;
529
530;; Extended Open hooks
531 MOV SS,[user_SS]
532ASSUME SS:NOTHING
533 MOV SP,ES:[user_SP] ; User stack pointer restored
534 INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES
535 MOV ES:[user_SP],SP ; restore our stack
536 MOV ES:[user_SS],SS
537 MOV BP,ES
538 MOV SS,BP
539ASSUME SS:DOSGROUP
540passi24: ;AN000;
541 MOV SP,[CONTSTK]
542 INC BYTE PTR [INDOS] ; Back in the DOS
543 MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24
544 STI
545;; MOV [ACT_PAGE],-1 ;LB. invalidate DOS active page ;AN000;
546;; invoke SAVE_MAP ;LB. save user's EMS map ;AN000;
547 fmt TypINT24,LevLog,<"INT 24: User reply = $x\n">,<AX>
548FAILRET:
549 LES BP,[EXITHOLD]
550ASSUME ES:NOTHING
551;
552; Triage the user's reply.
553;
554 CMP AL,1
555 JB CheckIgnore ; 0 => ignore
556 JZ CheckRetry ; 1 => retry
557 CMP AL,3 ; 3 => fail
558 JNZ DoAbort ; 2, invalid => abort
559;
560; The reply was fail. See if we are allowed to fail.
561;
562 TEST [ALLOWED],allowed_FAIL ; Can we?
563 JZ DoAbort ; No, do abort
564DoFail:
565 MOV AL,3 ; just in case...
566 TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO. I24 error disabled
567 JNZ cleanup ;AN000;EO. no
568 INC [FAILERR] ; Tell everybody
569CleanUp:
570 MOV WpErr,-1
571 CMP SFN,-1
572 retz
573 SaveReg <DS,SI,AX>
574 MOV AX,SFN
575 LDS SI,pJFN
576 MOV [SI],AL
577 RestoreReg <AX,SI,DS>
578 return
579;
580; The reply was IGNORE. See if we are allowed to ignore.
581;
582CheckIgnore:
583 TEST [ALLOWED],allowed_IGNORE ; Can we?
584 JZ DoFail ; No, do fail
585 JMP CleanUp
586;
587; The reply was RETRY. See if we are allowed to retry.
588;
589CheckRetry:
590 TEST [ALLOWED],allowed_RETRY ; Can we?
591 JZ DoFail ; No, do fail
592 JMP CleanUp
593;
594; The reply was ABORT.
595;
596DoAbort:
597 Context DS
598 CMP BYTE PTR [CONSWAP],0
599 JZ NOSWAP2
600 invoke SWAPBACK
601NOSWAP2:
602;
603; See if we are to truly abort. If we are in the process of aborting, turn
604; this abort into a fail.
605;
606 TEST fAborting,-1
607 JNZ DoFail
608;
609; Set return code
610;
611 MOV BYTE PTR [exit_Type],Exit_hard_error
612 XOR AL,AL
613;
614; we are truly aborting the process. Go restore information from the PDB as
615; necessary.
616;
617 Transfer exit_inner
618;
619; reset_environment checks the DS value against the CurrentPDB. If they are
620; different, then an old-style return is performed. If they are the same,
621; then we release jfns and restore to parent. We still use the PDB at DS:0 as
622; the source of the terminate addresses.
623;
624; Some subtlety: We are about to issue a bunch of calls that *may* generate
625; INT 24s. We *cannot* allow the user to restart the abort process; we may
626; end up aborting the wrong process or turn a terminate/stay/resident into a
627; normal abort and leave interrupt handlers around. What we do is to set a
628; flag that will indicate that if any abort code is seen, we just continue the
629; operation. In essence, we dis-allow the abort response.
630;
631; output: none.
632;
633 entry reset_environment
634 ASSUME DS:NOTHING,ES:NOTHING
635
636 invoke Reset_Version ;AN007;MS. reset version number
637 PUSH DS ; save PDB of process
638
639;
640; There are no critical sections in force. Although we may enter here with
641; critical sections locked down, they are no longer relevant. We may safely
642; free all allocated resources.
643;
644 MOV AH,82h
645 INT int_IBM
646
647 MOV fAborting,-1 ; signal abort in progress
648
649 CallInstall NetResetEnvironment, multNet, 34 ;DOS 4.00 doesn't need it
650 ; Allow REDIR to clear some stuff
651 ; On process exit.
652 MOV AL,int_Terminate
653 invoke $Get_interrupt_vector ; and who to go to
654
655 POP CX ; get ThisPDB
656 SaveReg <ES,BX> ; save return address
657
658 MOV BX,[CurrentPDB] ; get currentPDB
659 MOV DS,BX
660 MOV AX,DS:[PDB_Parent_PID] ; get parentPDB
661
662;
663; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB
664; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not
665; Exit_keep_process
666;
667 CMP AX,BX
668 JZ reset_return ; parentPDB = CurrentPDB
669 CMP BX,CX
670 JNZ reset_return ; CurrentPDB <> ThisPDB
671 PUSH AX ; save parent
672 CMP BYTE PTR [exit_type],Exit_keep_process
673 JZ reset_to_parent ; keeping this process
674;
675; We are truly removing a process. Free all allocation blocks belonging to
676; this PDB
677;
678 invoke arena_free_process
679;
680; Kill off remainder of this process. Close file handles and signal to
681; relevant network folks that this process is dead. Remember that CurrentPDB
682; is STILL the current process!
683;
684 invoke DOS_ABORT
685
686reset_to_parent:
687 POP [CurrentPDB] ; set up process as parent
688
689reset_return: ; come here for normal return
690 PUSH CS
691 POP DS
692 ASSUME DS:DOSGROUP
693 MOV AL,-1
694;
695; make sure that everything is clean In this case ignore any errors, we cannot
696; "FAIL" the abort, the program being aborted is dead.
697;
698 EnterCrit critDisk
699 invoke FLUSHBUF
700 LeaveCrit critDisk
701;
702; Decrement open ref. count if we had done a virtual open earlier.
703;
704 invoke CHECK_VIRT_OPEN
705IF BUFFERFLAG
706 invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map
707ENDIF
708 CLI
709 MOV BYTE PTR [INDOS],0 ; Go to known state
710 MOV BYTE PTR [WPERR],-1 ; Forget about WP error
711 MOV fAborting,0 ; let aborts occur
712 POP WORD PTR ExitHold
713 POP WORD PTR ExitHold+2
714;
715; Snake into multitasking... Get stack from CurrentPDB person
716;
717 MOV DS,[CurrentPDB]
718 ASSUME DS:NOTHING
719 MOV SS,WORD PTR DS:[PDB_user_stack+2]
720 MOV SP,WORD PTR DS:[PDB_user_stack]
721
722 ASSUME SS:NOTHING
723 invoke restore_world
724 ASSUME ES:NOTHING
725 MOV User_SP,AX
726 POP AX ; suck off CS:IP of interrupt...
727 POP AX
728 POP AX
729 MOV AX,0F202h ; STI
730 PUSH AX
731 PUSH WORD PTR [EXITHOLD+2]
732 PUSH WORD PTR [EXITHOLD]
733 MOV AX,User_SP
734 IRET ; Long return back to user terminate address
735EndProc HardErr
736
737;
738; This routine handles extended error codes.
739; Input : DI = error code from device
740; Output: All EXTERR fields are set
741;
742Procedure SET_I24_EXTENDED_ERROR,NEAR
743 PUSH AX
744 MOV AX,OFFSET DOSGroup:ErrMap24End
745 SUB AX,OFFSET DOSGroup:ErrMap24
746;
747; AX is the index of the first unavailable error. Do not translate if
748; greater or equal to AX.
749;
750 CMP DI,AX
751 MOV AX,DI
752 JAE NoTrans
753 MOV AL,ErrMap24[DI]
754 XOR AH,AH
755NoTrans:
756 MOV [EXTERR],AX
757 POP AX
758;
759; Now Extended error is set correctly. Translate it to get correct error
760; locus class and recommended action.
761;
762 PUSH SI
763 MOV SI,OFFSET DOSGROUP:ERR_TABLE_24
764 invoke CAL_LK ; Set other extended error fields
765 POP SI
766 ret
767EndProc SET_I24_EXTENDED_ERROR
768
769CODE ENDS
770 END
771 \ No newline at end of file