/*****************************************************************************
* Module to trap ctrl-brk/hardware error and handle them gracefully.	     *
* Note the usage of GraphGen.c module is assumed.			     *
*									     *
* Written by:  Gershon Elber			IBM PC Ver 1.0,	Jan. 1989    *
*****************************************************************************/

#include <stdio.h>
#include <dos.h>
#include <setjmp.h>
#include "Ctrl-Brk.h"

static void far *OldCtrlBrk;  /* Save here old int 1bh to be able to restore */
static int WasCtrlBrkSetUp = FALSE;   /* TRUE if SetUpCtrlBrk rtn was called */
int WasCtrlBrk;

static void interrupt TrapCtrlBrk(void);
static int TrapCtrlC(void);

/*****************************************************************************
* Routine TrapCtrlBrk gain control if Control break was typed:		     *
*****************************************************************************/
static void interrupt TrapCtrlBrk(void)
{
    WasCtrlBrk = TRUE;
}

/*****************************************************************************
* Routine TrapCtrlC gain control if Control C was typed (DOS level):	     *
*****************************************************************************/
static int TrapCtrlC(void)
{
    WasCtrlBrk = TRUE;

    return -1;						 /* Resume execution */
}

/*****************************************************************************
* Routine SetUpCtrlBrk must be called once by main program:		     *
*****************************************************************************/
void SetUpCtrlBrk(void)
{
    if (WasCtrlBrkSetUp) return;		/* No need to to it twice! */

    OldCtrlBrk = getvect(BIOS_CTRL_BRK);
    setvect(BIOS_CTRL_BRK, TrapCtrlBrk);

    ctrlbrk(TrapCtrlC);

    WasCtrlBrkSetUp = TRUE;
}

/*****************************************************************************
* Routine RestoreCtrlBrk must be called before the program quit:	     *
*****************************************************************************/
void RestoreCtrlBrk(void)
{
    if (WasCtrlBrkSetUp)
	setvect(BIOS_CTRL_BRK, (void interrupt (*)()) OldCtrlBrk);

    WasCtrlBrkSetUp = FALSE;
}

/*****************************************************************************
* Routine TrapHardWareError gain control if hardware fails - int 24.	     *
*****************************************************************************/
static int TrapHardWareError(int errval, int ax, int bp, int si)
{
    return IGNORE;
}

/*****************************************************************************
* Routine SetUpHardError must be called once by main program:		     *
* harderr set interrupt vector 0x024 to point to TrapHardWareError.	     *
*****************************************************************************/ 
void SetUpHardErr(void)
{
    harderr(TrapHardWareError);
}
