#include <windows.h>
#include <signal.h>
#include <stdlib.h>

static int *_xceptblkptr;

static int PASCAL _xceptionhandle(PEXCEPTION_RECORD er, void *frame,
			PCONTEXT context, void *dispatchercontext)
{

	int signum = -1,rv = 0;
	switch(er->ExceptionCode) {
		case EXCEPTION_ACCESS_VIOLATION:
		case EXCEPTION_DATATYPE_MISALIGNMENT:
		case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
			signum = SIGSEGV;
			break ;
		case EXCEPTION_PRIV_INSTRUCTION:
			signum = SIGILL;
			break ;
		case EXCEPTION_BREAKPOINT:
		case EXCEPTION_SINGLE_STEP:
			return EXCEPTION_CONTINUABLE ;
		case EXCEPTION_FLT_DENORMAL_OPERAND:
		case EXCEPTION_FLT_DIVIDE_BY_ZERO:
		case EXCEPTION_FLT_INEXACT_RESULT:
		case EXCEPTION_FLT_INVALID_OPERATION:
		case EXCEPTION_FLT_OVERFLOW:
		case EXCEPTION_FLT_STACK_CHECK:
		case EXCEPTION_FLT_UNDERFLOW:
			signum = SIGFPE ;
			break ;
		case EXCEPTION_INT_DIVIDE_BY_ZERO:
			break ;
		case EXCEPTION_INT_OVERFLOW:
			break ;
		case EXCEPTION_NONCONTINUABLE_EXCEPTION:
		case EXCEPTION_INVALID_DISPOSITION:
			break ;
		case EXCEPTION_STACK_OVERFLOW:
			break ;
	}
	if (signum != -1)
		rv = !raise(signum);

	if (!rv) {
		EXCEPTION_POINTERS xx;
		xx.ExceptionRecord = er ;
		xx.ContextRecord = context ;
		return UnhandledExceptionFilter(&xx) ;
	} else
		return EXCEPTION_CONTINUABLE ;
}
static BOOL PASCAL ControlCHandler(DWORD type)
{
	raise(SIGBREAK) ;
		exit(0xff);
	return TRUE ;
}
void PASCAL __xceptinit(int *block)
{
	_xceptblkptr = block ;
	asm mov eax,[block]
  asm mov [eax+4],offset _xceptionhandle
	asm mov	ecx,fs:[0]
	asm mov [eax],ecx
	asm mov fs:[0],eax
	SetConsoleCtrlHandler(ControlCHandler,1);
}
void PASCAL __xceptrundown(void)
{
	asm mov eax,[_xceptblkptr]
	asm cmp eax,fs:[0]
  asm jnz nounset
	asm mov eax,[eax]
	asm mov fs:[0],eax
nounset:
	SetConsoleCtrlHandler(ControlCHandler,0);
	return ;
}