home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
editors
/
tde150.arj
/
CRITERR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-01
|
8KB
|
218 lines
/*
* Instead of the Abort, Retry, Ignore thing, let's try to handle critical
* errors within tde. Give the user some indication of the critical error
* and then find out what the user wants to do.
*
* This is a very simple critical error handler. It's not much better than
* Abort, Retry, Ignore, but at least the program will probably not terminate
* with unsaved work.
*
* IMPORTANT: This is a replacement for the standard DOS critical error
* handler. Since DOS is not re-entrant, do not call any functions that,
* directly or indirectly, call DOS functions. We are in some DOS function
* when a critical error occurs. Using BIOS and direct hardware I/O
* functions, however, is allowed.
*
* New editor name: tde, the Thomson-Davis Editor.
* Author: Frank Davis
* Date: June 5, 1991, version 1.0
* Date: July 29, 1991, version 1.1
* Date: October 5, 1991, version 1.2
* Date: January 20, 1992, version 1.3
* Date: February 17, 1992, version 1.4
* Date: April 1, 1992, version 1.5
*
* This code is released into the public domain, Frank Davis.
* You may distribute it freely.
*/
#include "tdestr.h"
#include "common.h"
#include "tdefunc.h"
#include "criterr.h"
/*
* Save the area of the screen that will display the Critical
* Error info. CEH_WIDTH and CEH_HEIGHT are the dimensions of critical
* error screen in criterr.h. CEH_OFFSET is the offset into the screen
* refresh buffer. Let the compiler calculate the offset, 'cause the offset
* don't change anyway.
*/
#define CEH_ROW 5
#define CEH_COL 6
#define CEH_WIDTH 69
#define CEH_HEIGHT 15
#define CEH_OFFSET ((CEH_ROW * 160) + (CEH_COL * 2))
/*
* buffer for ceh info screen. make this an int array because we
* need to save character and attribute.
*/
int ceh_buffer[CEH_HEIGHT][CEH_WIDTH];
/*
* Name: crit_err_handler
* Purpose: Show user something is wrong and get a response
* Date: April 1, 1992
*/
int far crit_err_handler( void )
{
int rc;
int c;
save_area( (void far *)ceh_buffer );
show_error_screen( CEH_ROW, CEH_COL );
xygoto( 60, 17 );
c = getkey( );
while (c != 'Q' && c != 'q' && c != 'R' && c != 'r')
c = getkey( );
switch ( c ) {
case 'Q':
case 'q':
rc = FAIL;
break;
case 'R':
case 'r':
rc = RETRY;
break;
}
restore_area( (void far *)ceh_buffer );
return( rc );
}
/*
* Name: show_error_screen
* Purpose: Display error screen in window
* Date: April 1, 1992
* Passed: row: line to display ceh screen
* col: column to begin display ceh screen
*/
void show_error_screen( int row, int col )
{
char **p;
for (p=criterr_screen; *p != NULL; p++, row++)
s_output( *p, row, col, g_display.help_color );
s_output( error_code[ceh.code], 8, 23, g_display.help_color );
s_output( operation[ceh.rw], 9, 23, g_display.help_color );
if (ceh.dattr == 0)
c_output( ceh.drive + 'a', 23, 10, g_display.help_color );
else
s_output( "N/A", 10, 23, g_display.help_color );
s_output( ext_err[ceh.extended], 11, 23, g_display.help_color );
s_output( error_class[ceh.class], 12, 23, g_display.help_color );
s_output( locus[ceh.locus], 13, 23, g_display.help_color );
s_output( device_type[ceh.dattr], 14, 23, g_display.help_color );
if (ceh.dattr == 0)
s_output( "N/A", 15, 23, g_display.help_color );
else
s_output( ceh.dname, 15, 23, g_display.help_color );
}
/*
* Name: save_area
* Purpose: save a region of the screen
* Date: April 1, 1992
* Passed: dest: pointer to buffer for contents of screen under ceh
* Notes: use an assembly routine to save the area. we could have used
* a C library function instead of assembly, but the "rep movsw"
* instruction is really easy to use. this function does not check
* for snow. the source is the screen and the destination is the
* buffer.
*/
void save_area( void far *dest )
{
void far *source;
/*
* put the address of the display adapter in a local stack variable.
*/
source = (void far *)g_display.display_address;
_asm {
push ds ; save ds and any register vars
push si
push di
mov dx, CEH_HEIGHT ; save height in dx (num of rows)
mov di, WORD PTR dest ; load OFFSET of destination
mov ax, WORD PTR dest+2 ; load SEGMENT of destination
mov es, ax ; es:di == destination
mov si, WORD PTR source ; load OFFSET of source
mov ax, WORD PTR source+2 ; load SEGMENT of source
mov ds, ax ; ds:si == source
add si, CEH_OFFSET ; add offset into display screen
ALIGN 2
top:
cmp dx, 0 ; any more rows left?
jbe getout ; if not, we're done
mov cx, CEH_WIDTH ; load count register
mov bx, si ; save videomem location
rep movsw ; copy from screen area to buffer
mov si, bx ; get back videomem location
add si, 160 ; make videomem point to next line
dec dx ; ready for another row
jmp SHORT top
getout:
pop di
pop si
pop ds
}
}
/*
* Name: restore_area
* Purpose: restore a region of the screen
* Date: April 1, 1992
* Passed: source: pointer to buffer for contents of screen under ceh
* Notes: use an assembly routine to restore the area. this function
* does not check for snow. the source is the buffer and
* the destination is the screen.
*/
void restore_area( void far *source )
{
void far *dest;
/*
* put the address of the display adapter in a local stack variable.
*/
dest = (void far *)g_display.display_address;
_asm {
push ds ; save ds and any register vars
push si
push di
mov dx, CEH_HEIGHT ; save height in dx (num of rows)
mov di, WORD PTR dest ; load OFFSET of destination
mov ax, WORD PTR dest+2 ; load SEGMENT of destination
mov es, ax ; es:di == destination
add di, CEH_OFFSET ; add offset into display screen
mov si, WORD PTR source ; load OFFSET of source
mov ax, WORD PTR source+2 ; load SEGMENT of source
mov ds, ax ; ds:si == source
ALIGN 2
top:
cmp dx, 0 ; any more rows left?
jbe getout ; if not, we're done
mov cx, CEH_WIDTH ; load count register, number of words
mov bx, di ; save videomem location
rep movsw ; copy from buffer to screen area
mov di, bx ; get back videomem location
add di, 160 ; make videomem point to next line
dec dx ; ready for another row
jmp SHORT top
getout:
pop di
pop si
pop ds
}
}