home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
vile-src.zip
/
vile-8.1
/
djhandl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-28
|
4KB
|
156 lines
/*
* control-c and critical error handlers for DJGPP environment
*
* control-c code based exactly on the equivalent handler
* for control-break in the go32 libraries
* critical error handling from Bob Babcock.
*
* $Header: /usr/build/vile/vile/RCS/djhandl.c,v 1.6 1998/04/28 10:19:54 tom Exp $
*
*
*/
#include <stdlib.h>
#include <go32.h>
#include <dpmi.h>
#include <dos.h>
#include <stdio.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
static _go32_dpmi_registers regs;
static volatile unsigned long ctrl_c_count = 0;
static int ctrl_c_hooked = 0;
static _go32_dpmi_seginfo old_vector;
static _go32_dpmi_seginfo new_vector;
unsigned long was_ctrl_c_hit();
void want_ctrl_c(int yes); /* auto-yes if call above function */
static void ctrl_c_isr(_go32_dpmi_registers *regs)
{
ctrl_c_count ++;
}
unsigned long was_ctrl_c_hit()
{
unsigned long cnt;
want_ctrl_c(1);
cnt = ctrl_c_count;
ctrl_c_count = 0;
return cnt;
}
void want_ctrl_c(int yes)
{
if (yes)
{
if (ctrl_c_hooked)
return;
_go32_dpmi_get_real_mode_interrupt_vector(0x23, &old_vector);
new_vector.pm_offset = (int)ctrl_c_isr;
_go32_dpmi_allocate_real_mode_callback_iret(&new_vector, ®s);
_go32_dpmi_set_real_mode_interrupt_vector(0x23, &new_vector);
ctrl_c_count = 0;
ctrl_c_hooked = 1;
}
else
{
if (!ctrl_c_hooked)
return;
_go32_dpmi_set_real_mode_interrupt_vector(0x23, &old_vector);
_go32_dpmi_free_real_mode_callback(&new_vector);
ctrl_c_count = 0;
ctrl_c_hooked = 0;
}
}
/* hardgcc - critical error handler for gcc
*/
int hard_error_occurred = FALSE;
static char handler[16] =
{
0x81, 0xe7, 0x7f, 0, /* and di,7f */
0x47, /* inc di */
0x2e, 0x89, 0x3e, 0xe, 0, /* mov cs:[0eh],di */
0xb8, 3, 0, /* mov ax,3 */
0xcf, /* iret */
0,0 /* storage for error code */
};
static int handler_installed = FALSE;
static _go32_dpmi_seginfo new_handler_info, old_handler_info;
/* clear_hard_error - clear any indication of a critical error
*/
void clear_hard_error(void)
{
short zero = 0;
if(handler_installed)
dosmemput(&zero, 2, new_handler_info.rm_segment * 16 + 14);
hard_error_occurred = 0;
return;
}
/* install the real-mode critical error handler
*/
void hard_error_catch_setup(void)
{
/* On first call, allocate some DOS memory and copy the handler into it
*/
if(!handler_installed) {
handler_installed = TRUE;
new_handler_info.size = old_handler_info.size = 1;
if (_go32_dpmi_allocate_dos_memory(&new_handler_info) != 0) {
fprintf(stderr,"Couldn't allocate handler memory\n");
exit(1);
}
dosmemput(handler, 16, new_handler_info.rm_segment * 16);
#ifdef XDEBUG
sprintf(Tempbuf, "Handler at segment %x", new_handler_info.rm_segment);
error_msg(Tempbuf, 0);
#endif
}
_go32_dpmi_get_real_mode_interrupt_vector(0x24, &old_handler_info);
_go32_dpmi_set_real_mode_interrupt_vector(0x24, &new_handler_info);
clear_hard_error();
return;
}
/* switch back to old critical error handler
*/
void hard_error_teardown(void)
{
if(handler_installed)
_go32_dpmi_set_real_mode_interrupt_vector(0x24, &old_handler_info);
return;
}
/* test_hard_err - test whether a critical error has occurred and return
error code (0 if none or handler never installed).
*/
int did_hard_error_occur(void)
{
short error_code;
if(handler_installed)
{
dosmemget(new_handler_info.rm_segment * 16 + 14, 2, &error_code);
#ifdef XDEBUG
if(error_code)
{
sprintf(Tempbuf,"Critical error code is %d", error_code);
error_msg(Tempbuf,0);
}
#endif
return(error_code);
}
return(0);
}