summaryrefslogtreecommitdiff
path: root/v2.0/source/CTRLC.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/CTRLC.ASM')
-rw-r--r--v2.0/source/CTRLC.ASM468
1 files changed, 468 insertions, 0 deletions
diff --git a/v2.0/source/CTRLC.ASM b/v2.0/source/CTRLC.ASM
new file mode 100644
index 0000000..054903d
--- /dev/null
+++ b/v2.0/source/CTRLC.ASM
@@ -0,0 +1,468 @@
1;
2; ^C status routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17 i_need DevIOBuf,BYTE
18 i_need DidCTRLC,BYTE
19 i_need INDOS,BYTE
20 i_need DSKSTCOM,BYTE
21 i_need DSKSTCALL,BYTE
22 i_need DSKSTST,WORD
23 i_need BCON,DWORD
24 i_need DSKCHRET,BYTE
25 i_need DSKSTCNT,WORD
26 i_need IDLEINT,BYTE
27 i_need CONSWAP,BYTE
28 i_need user_SS,WORD
29 i_need user_SP,WORD
30 i_need ERRORMODE,BYTE
31 i_need ConC_spSave,WORD
32 i_need Exit_type,BYTE
33 i_need PFLAG,BYTE
34 i_need ExitHold,DWORD
35 i_need WPErr,BYTE
36 i_need ReadOp,BYTE
37 i_need CONTSTK,WORD
38 i_need Exit_Code,WORD
39 i_need CurrentPDB,WORD
40 i_need DIVMES,BYTE
41 i_need DivMesLen,BYTE
42
43SUBTTL Checks for ^C in CON I/O
44PAGE
45ASSUME DS:NOTHING,ES:NOTHING
46
47 procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in
48 CMP BYTE PTR [INDOS],1
49 retnz ; Do NOTHING
50 PUSH CX
51 PUSH ES
52 PUSH BX
53 PUSH DS
54 PUSH SI
55 PUSH CS
56 POP ES
57 PUSH CS
58 POP DS
59ASSUME DS:DOSGROUP
60 XOR CX,CX
61 MOV BYTE PTR [DSKSTCOM],DEVRDND
62 MOV BYTE PTR [DSKSTCALL],DRDNDHL
63 MOV [DSKSTST],CX
64 MOV BX,OFFSET DOSGROUP:DSKSTCALL
65 LDS SI,[BCON]
66ASSUME DS:NOTHING
67 invoke DEVIOCALL2
68 TEST [DSKSTST],STBUI
69 JNZ ZRET ; No characters available
70 MOV AL,BYTE PTR [DSKCHRET]
71DSK1:
72 CMP AL,"C"-"@"
73 JNZ RET36
74 MOV BYTE PTR [DSKSTCOM],DEVRD
75 MOV BYTE PTR [DSKSTCALL],DRDWRHL
76 MOV BYTE PTR [DSKCHRET],CL
77 MOV [DSKSTST],CX
78 INC CX
79 MOV [DSKSTCNT],CX
80 invoke DEVIOCALL2 ; Eat the ^C
81 POP SI
82 POP DS
83 POP BX ; Clean stack
84 POP ES
85 POP CX
86 JMP SHORT CNTCHAND
87
88ZRET:
89 XOR AL,AL ; Set zero
90RET36:
91 POP SI
92 POP DS
93 POP BX
94 POP ES
95 POP CX
96 return
97
98NOSTOP:
99 CMP AL,"P"-"@"
100 JZ INCHK
101
102 IF NOT TOGLPRN
103 CMP AL,"N"-"@"
104 JZ INCHK
105 ENDIF
106
107 CMP AL,"C"-"@"
108 JZ INCHK
109 return
110DSKSTATCHK ENDP
111
112 procedure SPOOLINT,NEAR
113 PUSHF
114 CMP BYTE PTR [IDLEINT],0
115 JZ POPFRET
116 CMP BYTE PTR [ERRORMODE],0
117 JNZ POPFRET ;No spool ints in error mode
118 INT int_spooler
119POPFRET:
120 POPF
121RET18: return
122SPOOLINT ENDP
123
124 procedure STATCHK,NEAR
125
126 invoke DSKSTATCHK ; Allows ^C to be detected under
127 ; input redirection
128 PUSH BX
129 XOR BX,BX
130 invoke GET_IO_FCB
131 POP BX
132 JC RET18
133 MOV AH,1
134 invoke IOFUNC
135 JZ SPOOLINT
136 CMP AL,'S'-'@'
137 JNZ NOSTOP
138 XOR AH,AH
139 invoke IOFUNC ; Eat Cntrl-S
140 JMP SHORT PAUSOSTRT
141PRINTOFF:
142PRINTON:
143 NOT BYTE PTR [PFLAG]
144 return
145
146PAUSOLP:
147 CALL SPOOLINT
148PAUSOSTRT:
149 MOV AH,1
150 invoke IOFUNC
151 JZ PAUSOLP
152INCHK:
153 PUSH BX
154 XOR BX,BX
155 invoke GET_IO_FCB
156 POP BX
157 JC RET18
158 XOR AH,AH
159 invoke IOFUNC
160 CMP AL,'P'-'@'
161 JZ PRINTON
162 IF NOT TOGLPRN
163 CMP AL,'N'-'@'
164 JZ PRINTOFF
165 ENDIF
166 CMP AL,'C'-'@'
167 retnz
168STATCHK ENDP
169
170 procedure CNTCHAND,NEAR
171; Ctrl-C handler.
172; "^C" and CR/LF is printed. Then the user registers are restored and
173; the user CTRL-C handler is executed. At this point the top of the stack
174; has 1) the interrupt return address should the user CTRL-C handler wish
175; to allow processing to continue; 2) the original interrupt return address
176; to the code that performed the function call in the first place. If
177; the user CTRL-C handler wishes to continue, it must leave all registers
178; unchanged and RET (not IRET) with carry CLEAR. If carry is SET then
179; an terminate system call is simulated.
180 MOV AL,3 ; Display "^C"
181 invoke BUFOUT
182 invoke CRLF
183 PUSH SS
184 POP DS
185ASSUME DS:DOSGROUP
186 CMP BYTE PTR [CONSWAP],0
187 JZ NOSWAP
188 invoke SWAPBACK
189NOSWAP:
190 CLI ; Prepare to play with stack
191 MOV SP,[user_SP]
192 MOV SS,[user_SS] ; User stack now restored
193ASSUME SS:NOTHING
194 invoke restore_world ; User registers now restored
195ASSUME DS:NOTHING
196 MOV BYTE PTR [INDOS],0 ; Go to known state
197 MOV BYTE PTR [ERRORMODE],0
198 MOV [ConC_spsave],SP ; save his SP
199 INT int_ctrl_c ; Execute user Ctrl-C handler
200 MOV [user_SS],AX ; save the AX
201 PUSHF ; and the flags (maybe new call)
202 POP AX
203 CMP SP,[ConC_spsave]
204 JNZ ctrlc_try_new ; new syscall maybe?
205ctrlc_repeat:
206 MOV AX,[user_SS] ; no...
207 transfer COMMAND ; Repeat command otherwise
208
209ctrlc_try_new:
210 SUB [ConC_spsave],2 ; Are there flags on the stack?
211 CMP SP,[ConC_spsave]
212 JZ ctrlc_new ; yes, new system call
213
214ctrlc_abort:
215 MOV AX,(EXIT SHL 8) + 0
216 MOV BYTE PTR [DidCTRLC],0FFh
217
218 transfer COMMAND ; give up by faking $EXIT
219
220ctrlc_new:
221 PUSH AX
222 POPF
223 POP [user_SS]
224 JNC ctrlc_repeat ; repeat operation
225 JMP ctrlc_abort ; indicate ^ced
226
227CNTCHAND ENDP
228
229SUBTTL DIVISION OVERFLOW INTERRUPT
230PAGE
231; Default handler for division overflow trap
232 procedure DIVOV,NEAR
233ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
234 MOV SI,OFFSET DOSGROUP:DIVMES
235 CALL RealDivOv
236 JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow
237DIVOV ENDP
238
239;
240; RealDivOv: perform actual divide overflow stuff.
241; Inputs: none
242; Outputs: message to BCON
243;
244 procedure RealDivOv,NEAR ; Do divide overflow and clock process
245
246 PUSH CS ; get ES addressability
247 POP ES
248
249 PUSH CS ; get DS addressability
250 POP DS
251ASSUME DS:DOSGROUP
252
253 MOV BYTE PTR [DskStCom],DevWrt
254 MOV BYTE PTR [DskStCall],DRdWrHL
255 MOV [DskSTST],0
256 MOV BL,[DivMesLen]
257 XOR BH,BH
258 MOV [DskStCnt],BX
259 MOV BX,OFFSET DOSGROUP:DskStCall
260 MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU)
261 LDS SI,[BCON]
262ASSUME DS:NOTHING
263 invoke DEVIOCALL2
264 MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf
265 MOV [DskStCnt],1
266 return
267RealDivOv ENDP
268
269SUBTTL CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER
270PAGE
271 procedure CHARHARD,NEAR
272ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
273
274; Character device error handler
275; Same function as HARDERR
276
277 MOV WORD PTR [EXITHOLD+2],ES
278 MOV WORD PTR [EXITHOLD],BP
279 PUSH SI
280 AND DI,STECODE
281 MOV BP,DS ;Device pointer is BP:SI
282 CALL FATALC
283 POP SI
284 return
285CHARHARD ENDP
286
287 procedure HardErr,NEAR
288ASSUME DS:NOTHING,ES:NOTHING
289
290; Hard disk error handler. Entry conditions:
291; DS:BX = Original disk transfer address
292; DX = Original logical sector number
293; CX = Number of sectors to go (first one gave the error)
294; AX = Hardware error code
295; DI = Original sector transfer count
296; ES:BP = Base of drive parameters
297; [READOP] = 0 for read, 1 for write
298 ;
299 XCHG AX,DI ; Error code in DI, count in AX
300 AND DI,STECODE ; And off status bits
301 CMP DI,WRECODE ; Write Protect Error?
302 JNZ NOSETWRPERR
303 PUSH AX
304 MOV AL,ES:[BP.dpb_drive]
305 MOV BYTE PTR [WPERR],AL ; Flag drive with WP error
306 POP AX
307NOSETWRPERR:
308 SUB AX,CX ; Number of sectors successfully transferred
309 ADD DX,AX ; First sector number to retry
310 PUSH DX
311 MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred
312 POP DX
313 ADD BX,AX ; First address for retry
314 XOR AH,AH ; Flag disk section in error
315 CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area?
316 JB ERRINT
317 INC AH ; Flag for FAT
318 CMP DX,ES:[BP.dpb_dir_sector] ; In FAT?
319 JB ERRINT
320 INC AH
321 CMP DX,ES:[BP.dpb_first_sector] ; In directory?
322 JB ERRINT
323 INC AH ; Must be in data area
324ERRINT:
325 SHL AH,1 ; Make room for read/write bit
326 OR AH,BYTE PTR [READOP]
327 entry FATAL
328 MOV AL,ES:[BP.dpb_drive] ; Get drive number
329 entry FATAL1
330 MOV WORD PTR [EXITHOLD+2],ES
331 MOV WORD PTR [EXITHOLD],BP ; The only things we preserve
332 LES SI,ES:[BP.dpb_driver_addr]
333 MOV BP,ES ; BP:SI points to the device involved
334FATALC:
335 CMP BYTE PTR [ERRORMODE],0
336 JNZ SETIGN ; No INT 24s if already INT 24
337 MOV [CONTSTK],SP
338 PUSH SS
339 POP ES
340ASSUME ES:DOSGROUP
341 CLI ; Prepare to play with stack
342 INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress
343 DEC BYTE PTR [INDOS] ; INT 24 handler might not return
344 MOV SS,[user_SS]
345ASSUME SS:NOTHING
346 MOV SP,ES:[user_SP] ; User stack pointer restored
347 INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES
348 MOV ES:[user_SP],SP ; restore our stack
349 MOV ES:[user_SS],SS
350 MOV SP,ES
351 MOV SS,SP
352ASSUME SS:DOSGROUP
353 MOV SP,[CONTSTK]
354 INC BYTE PTR [INDOS] ; Back in the DOS
355 MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24
356 STI
357IGNRET:
358 LES BP,[EXITHOLD]
359ASSUME ES:NOTHING
360 CMP AL,2
361 JZ error_abort
362 MOV BYTE PTR [WPERR],-1 ;Forget about WP error
363 return
364
365SETIGN:
366 XOR AL,AL ;Flag ignore
367 JMP SHORT IGNRET
368
369error_abort:
370 PUSH SS
371 POP DS
372ASSUME DS:DOSGROUP
373 CMP BYTE PTR [CONSWAP],0
374 JZ NOSWAP2
375 invoke SWAPBACK
376NOSWAP2:
377 MOV BYTE PTR [exit_Type],Exit_hard_error
378 MOV DS,[CurrentPDB]
379ASSUME DS:NOTHING
380
381;
382; reset_environment checks the DS value against the CurrentPDB. If they
383; are different, then an old-style return is performed. If they are
384; the same, then we release jfns and restore to parent. We still use
385; the PDB at DS:0 as the source of the terminate addresses.
386;
387; output: none.
388;
389 entry reset_environment
390 ASSUME DS:NOTHING,ES:NOTHING
391 PUSH DS ; save PDB of process
392
393 MOV AL,int_Terminate
394 invoke $Get_interrupt_vector ; and who to go to
395 MOV WORD PTR [EXITHOLD+2],ES ; save return address
396 MOV WORD PTR [EXITHOLD],BX
397
398 MOV BX,[CurrentPDB] ; get current process
399 MOV DS,BX ;
400 MOV AX,DS:[PDB_Parent_PID] ; get parent to return to
401 POP CX
402;
403; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB
404; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not
405; Exit_keep_process
406;
407 CMP AX,BX
408 JZ reset_return ; parentPDB = CurrentPDB
409 CMP BX,CX
410 JNZ reset_return ; CurrentPDB <> ThisPDB
411 PUSH AX ; save parent
412 CMP BYTE PTR [exit_type],Exit_keep_process
413 JZ reset_to_parent ; keeping this process
414
415 invoke arena_free_process
416
417 ; reset environment at [CurrentPDB]; close those handles
418 MOV CX,FilPerProc
419
420reset_free_jfn:
421 MOV BX,CX
422 PUSH CX
423 DEC BX ; get jfn
424 invoke $CLOSE ; close it, ignore return
425 POP CX
426 LOOP reset_free_jfn ; and do 'em all
427
428reset_to_parent:
429 POP [CurrentPDB] ; set up process as parent
430
431reset_return: ; come here for normal return
432 PUSH CS
433 POP DS
434 ASSUME DS:DOSGROUP
435 MOV AL,-1
436 invoke FLUSHBUF ; make sure that everything is clean
437
438 CLI
439 MOV BYTE PTR [INDOS],0 ;Go to known state
440 MOV BYTE PTR [WPERR],-1 ;Forget about WP error
441;
442; Snake into multitasking... Get stack from CurrentPDB person
443;
444 MOV DS,[CurrentPDB]
445 ASSUME DS:NOTHING
446 MOV SS,WORD PTR DS:[PDB_user_stack+2]
447 MOV SP,WORD PTR DS:[PDB_user_stack]
448
449 ASSUME SS:NOTHING
450 invoke restore_world
451 ASSUME ES:NOTHING
452 POP AX ; suck off CS:IP of interrupt...
453 POP AX
454 POP AX
455 MOV AX,0F202h ; STI
456 PUSH AX
457 PUSH WORD PTR [EXITHOLD+2]
458 PUSH WORD PTR [EXITHOLD]
459 STI
460 IRET ; Long return back to user terminate address
461HardErr ENDP
462
463 ASSUME SS:DOSGROUP
464
465do_ext
466
467CODE ENDS
468 END