#include <windows.h>
#include <signal.h>
#include <stdlib.h>
static int *_xceptblkptr;

short _basefpmask = 0x1332 ;

short _clear87(void)
{
	short work ;
	asm fnstsw	[work ];
	asm fnclex
	return work ;
}
void _control87(int mask1, int mask2)
{
	short work ;
	asm fstcw [work];
	mask1 &= mask2;
	mask2 = ~mask2;
	asm fwait
	work &= mask2;
	work = mask1 |= work ;
	asm fldcw [work]
}

void PASCAL __llfpinit(void)
{
	asm finit ;
	_control87(_basefpmask,0x1fff) ;
}
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:
			break ;
		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 = TRUE ;

	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);
ExitProcess(1) ;
	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 ;
}
main()
{
   DWORD xcept[2] ;
   DWORD written ;
   HANDLE h ;
   asm int3

   __llfpinit() ;
   __xceptinit(&xcept[0]) ;
   
   h = GetStdHandle(STD_OUTPUT_HANDLE) ;

   WriteFile(h,"hello dave\n",11,&written,0) ;

   __xceptrundown() ;
   ExitProcess(0) ;
}