COMMENT ~
    This file is part of SUPPL - the supplemental library for DOS
    Copyright (C) 1996-2000 Steffen Kaiser

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
~
COMMENT ~
   $Id: CB_CATCH.ASM 2.2 1999/12/13 02:23:45 ska Exp ska $
   $Locker: ska $	$Name:  $	$State: Exp $

	^Break signal catcher.	(companion of ctrlbrk())
	It will spawn the function in __fct_cbreak:WORD.
	If this value is NULL or this function returns != 0, the
	^Break signal is ignored; otherwise, the program is terminated
	with exit(3).

	Micro-C only.

ob(ject): _cbreak_catcher_
su(bsystem): portable
ty(pe): L
sy(nopsis): void interrupt _cbreak_catcher(void)
im: _fct_cbreak
sh(ort description): ^Break catcher
he(ader files): 
lo(ng description): Installed by ctrlbrk() to catch ^Break interrupts
	raised by DOS.\par
	If the global variable \tok{_fct_cbreak} is zero, ^Break's are
	simply ignored. Otherwise, the varible points to a callback function,
	which is invoked.\newline
	If the callback function returns \em{non-zero}, the ^Break is ignored.
	Otherwise, the program is terminated.
pr(erequistes): 
va(lue): none
re(lated to): ctrlbrk
se(condary subsystems): 
xr(ef): 
im(port): 
fi(le): cb_catch.asm
in(itialized by): ctrlbrk
wa(rning): 
bu(gs): Because of incomaptiblies between MS DOS and other DOS variants, the
	program is not terminated by DOS, but using the exit() function. See
	the source code for more details and how to change this behaviour.\par
	This also probably implies the \em{MAJOR BUG}, when this ^Break
	catcher is activated from a child process. Because this function
	calls the \tok{exit()} function of the parent to actually terminate
	the child. \em{Ooops}.

~
DGRP GROUP DSEG,BSEG
DSEG SEGMENT BYTE PUBLIC 'IDATA'
DSEG ENDS
BSEG SEGMENT BYTE PUBLIC 'UDATA'
BSEG ENDS
CSEG SEGMENT BYTE PUBLIC 'CODE'
 ASSUME CS:CSEG, DS:DGRP, SS:DGRP
 EXTRN ?eq:NEAR,?ne:NEAR,?lt:NEAR,?le:NEAR,?gt:NEAR
 EXTRN ?ge:NEAR,?ult:NEAR,?ule:NEAR,?ugt:NEAR,?uge:NEAR
 EXTRN ?not:NEAR,?switch:NEAR,?temp:WORD
CSEG ENDS
DSEG SEGMENT
 EXTRN __fct_cbreak: WORD
DSEG ENDS
CSEG SEGMENT
 EXTRN _exit:NEAR
	PUBLIC __cbreak_catcher
__cbreak_catcher:
		push bx
		push cx
		push dx
		push di
		push si
		push ds
		push es
		push bp
		push ax
		mov ax, ss			; /* under Micro-C always SS == DS */
		mov ds, ax
		mov ax, __fct_cbreak
		or ax, ax
		je cbreak1_catcher
		call ax
		or ax, ax			; /* continue with program? */
		jne cbreak1_catcher
		; /* terminate the program, that's a bit of a problem, because */
		; /* MS built in some interesting stuff to make their DOS */
		; /* incompatible with DR DOS and Novell DOS. Therefore we don't */
		; /* let DOS terminate our program, but we terminate it ourselves */
		; /* with the exit code 3. That won't inform the caller, that */
		; /* we terminated because of ^C and probably leads to misinterpretation */
		; /* of the exit code. */
		; /* To let DOS terminate the program, change: */
		; /*	 1) in this branch: only set the Carry flag (stc). */
		; /*	 2) Replace the iret by retf (NOT retf 2!). */

		mov ax, 3
		push ax
		call _exit

cbreak1_catcher:
		pop ax
		pop bp
		pop es
		pop ds
		pop si
		pop di
		pop dx
		pop cx
		pop bx
		iret				; /* continue with the program */
CSEG ENDS
END
