415 lines
9.1 KiB
C
Executable File
415 lines
9.1 KiB
C
Executable File
/*
|
|
Copyright (C) 1994-1995 Apogee Software, Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
#include <dos.h>
|
|
#include <errno.h>
|
|
#include <io.h>
|
|
#include <stdio.h>
|
|
#include <conio.h>
|
|
#include <stdarg.h>
|
|
#include <mem.h>
|
|
#include <ctype.h>
|
|
#include "rt_def.h"
|
|
#include "rt_str.h"
|
|
#include "rt_error.h"
|
|
#include "rt_menu.h"
|
|
#include "isr.h"
|
|
#include "w_wad.h"
|
|
#include "z_zone.h"
|
|
#include "rt_vid.h"
|
|
#include "rt_util.h"
|
|
#include "modexlib.h"
|
|
//MED
|
|
#include "memcheck.h"
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// HARD ERROR ROUTINES
|
|
//
|
|
//****************************************************************************
|
|
|
|
#define WINDOWUX 7
|
|
#define WINDOWUY 76
|
|
#define WINDOWLX 138
|
|
#define WINDOWLY 158
|
|
|
|
#define MESSAGEBOXCOLOR 166
|
|
|
|
|
|
#define DISKERROR 0x4000 // bit 15 (of deverr)
|
|
#define IGNOREAVAILABLE 0x1000 // bit 13 (bit 14 isn't used)
|
|
#define RETRYAVAILABLE 0x800 // bit 12
|
|
#define FAILAVAILABLE 0x400 // bit 11
|
|
#define LOCATION 0x300 // bit 10 and 9
|
|
#define READWRITEERROR 0x80 // bit 8
|
|
#define DRIVEOFERROR 0x0F // low-order byte
|
|
|
|
#define DIVISIONINT 0x00
|
|
|
|
// Globals
|
|
|
|
boolean DivisionError = false;
|
|
|
|
// Statics
|
|
|
|
|
|
static char ErrorCodes[13][25] =
|
|
{
|
|
"Write-protected disk\0",
|
|
"Unknown unit\0",
|
|
"Drive not ready\0",
|
|
"Unknown command\0",
|
|
"CRC error in data\0",
|
|
"Bad drive struct length\0",
|
|
"Seek error\0",
|
|
"Unknown media type\0",
|
|
"Sector not found\0",
|
|
"Printer out of paper\0",
|
|
"Write fault\0",
|
|
"Read fault\0",
|
|
"General failure\0"
|
|
};
|
|
|
|
static char Drives[7][3] =
|
|
{
|
|
"A\0",
|
|
"B\0",
|
|
"C\0",
|
|
"D\0",
|
|
"E\0",
|
|
"F\0",
|
|
"G\0"
|
|
};
|
|
|
|
static char Locations[4][11] =
|
|
{
|
|
"MS-DOS\0",
|
|
"FAT\0",
|
|
"Directory\0",
|
|
"Data area\0"
|
|
};
|
|
|
|
static char ReadWrite[2][6] =
|
|
{
|
|
"Read\0",
|
|
"Write\0"
|
|
};
|
|
|
|
static boolean ErrorHandlerStarted=false;
|
|
void (__interrupt __far *olddivisr) () = NULL;
|
|
|
|
//******************************************************************************
|
|
//
|
|
// UL_UserMessage ()
|
|
//
|
|
//******************************************************************************
|
|
|
|
void UL_UserMessage (int x, int y, char *str, ...) __attribute__((format(printf,3,4)))
|
|
{
|
|
va_list strptr;
|
|
char buf[128];
|
|
int width, height;
|
|
|
|
memset (&buf[0], 0, sizeof (buf));
|
|
va_start (strptr, str);
|
|
vsprintf (&buf[0], str, strptr);
|
|
va_end (strptr);
|
|
|
|
if ( *(byte *)0x449 == 0x13)
|
|
{
|
|
CurrentFont = tinyfont;
|
|
|
|
WindowW=160;
|
|
WindowH=100;
|
|
WindowX=80;
|
|
WindowY=50;
|
|
|
|
US_MeasureStr (&width, &height, &buf[0]);
|
|
|
|
width += (CurrentFont->width[1] << 1);
|
|
height += (CurrentFont->height << 1);
|
|
|
|
VL_Bar (x, y, WindowW-2, WindowH, MESSAGEBOXCOLOR);
|
|
|
|
PrintX = x+CurrentFont->width[1];
|
|
PrintY = y+CurrentFont->height;
|
|
|
|
US_CPrint (&buf[0]);
|
|
|
|
displayofs=bufferofs;
|
|
|
|
OUTP(CRTC_INDEX, CRTC_STARTHIGH);
|
|
OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
|
|
|
|
|
|
bufferofs += screensize;
|
|
if (bufferofs > page3start)
|
|
bufferofs = page1start;
|
|
}
|
|
else
|
|
printf("%s\n",&buf[0]);
|
|
}
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_GeneralError ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
int UL_GeneralError (int code)
|
|
{
|
|
boolean done = false;
|
|
int retval = 0;
|
|
|
|
UL_UserMessage (80, 50, "Device Error!\n%s.\n \n(A)bort (R)etry\n",
|
|
ErrorCodes[code]);
|
|
|
|
if (KeyboardStarted==true)
|
|
{
|
|
while (!done)
|
|
{
|
|
if (Keyboard[sc_A])
|
|
{
|
|
retval = 1;
|
|
done = true;
|
|
|
|
while (Keyboard[sc_A])
|
|
;
|
|
}
|
|
else
|
|
if (Keyboard[sc_R])
|
|
{
|
|
retval = 0;
|
|
done = true;
|
|
|
|
while (Keyboard[sc_R])
|
|
;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (!done)
|
|
{
|
|
if (kbhit())
|
|
{
|
|
char ch;
|
|
|
|
ch=toupper(getch());
|
|
if (ch=='A')
|
|
{
|
|
retval = 1;
|
|
done = true;
|
|
}
|
|
else if (ch=='R')
|
|
{
|
|
retval = 0;
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return (retval);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_DriveError ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
int UL_DriveError (int code, int location, int rwerror, int whichdrive)
|
|
{
|
|
boolean done = false;
|
|
int retval = 0;
|
|
|
|
UL_UserMessage (80, 50,
|
|
"Drive Error!\n%s.\nOn drive %s.\nLocation: %s.\n%s error.\n(A)bort (R)etry\n",
|
|
ErrorCodes[code], Drives[whichdrive],
|
|
Locations[location], ReadWrite[rwerror]);
|
|
|
|
if (KeyboardStarted==true)
|
|
{
|
|
while (!done)
|
|
{
|
|
if (Keyboard[sc_A])
|
|
{
|
|
retval = 1;
|
|
done = true;
|
|
|
|
while (Keyboard[sc_A])
|
|
;
|
|
}
|
|
else
|
|
if (Keyboard[sc_R])
|
|
{
|
|
retval = 0;
|
|
done = true;
|
|
|
|
while (Keyboard[sc_R])
|
|
;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (!done)
|
|
{
|
|
if (kbhit())
|
|
{
|
|
char ch;
|
|
|
|
ch=toupper(getch());
|
|
if (ch=='A')
|
|
{
|
|
retval = 1;
|
|
done = true;
|
|
}
|
|
else if (ch=='R')
|
|
{
|
|
retval = 0;
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (retval);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_harderr ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
int __far UL_harderr (unsigned deverr, unsigned errcode, unsigned far *devhdr)
|
|
{
|
|
int DiskError = 0; // Indicates if it was a disk error
|
|
int IgnoreAvail = 0; // if "ignore" response is available
|
|
int RetryAvail = 0; // if "retry" response is available
|
|
int FailAvail = 0; // if "fail" response is available
|
|
byte ErrorLocation = 0; // Location of error
|
|
byte RWerror = 0; // Read/Write error (0 == read, 1 == write)
|
|
byte whichDrive = 0; // Drive the error is on (0 == A, 1 == B, ...)
|
|
int action;
|
|
|
|
unsigned temp;
|
|
temp = *devhdr;
|
|
|
|
// Check errors
|
|
DiskError = (deverr & DISKERROR);
|
|
IgnoreAvail = (deverr & IGNOREAVAILABLE);
|
|
RetryAvail = (deverr & RETRYAVAILABLE);
|
|
FailAvail = (deverr & FAILAVAILABLE);
|
|
ErrorLocation = ((deverr & LOCATION) >> 8);
|
|
RWerror = (deverr & READWRITEERROR);
|
|
|
|
if (DiskError == 0)
|
|
action = UL_GeneralError (errcode);
|
|
else
|
|
action = UL_DriveError (errcode, ErrorLocation, RWerror, whichDrive);
|
|
|
|
if (action)
|
|
Error ("USER BREAK : ROTT aborted.\n");
|
|
return (_HARDERR_RETRY);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_DivisionISR ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
extern byte * colormap;
|
|
|
|
void __interrupt __far UL_DivisionISR ( void )
|
|
{
|
|
// acknowledge the interrupt
|
|
|
|
SetBorderColor (*(colormap+(((100-10)>>2)<<8)+160));
|
|
DivisionError = true;
|
|
OUTP (0x20, 0x20);
|
|
}
|
|
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_ErrorStartup ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
void UL_ErrorStartup ( void )
|
|
{
|
|
if (ErrorHandlerStarted==true)
|
|
return;
|
|
ErrorHandlerStarted=true;
|
|
_harderr (UL_harderr); // Install hard error handler
|
|
UL_StartupDivisionByZero();
|
|
}
|
|
|
|
//****************************************************************************
|
|
//
|
|
// UL_ErrorShutdown ()
|
|
//
|
|
//****************************************************************************
|
|
|
|
void UL_ErrorShutdown ( void )
|
|
{
|
|
if (ErrorHandlerStarted==false)
|
|
return;
|
|
ErrorHandlerStarted=false;
|
|
UL_ShutdownDivisionByZero();
|
|
}
|
|
|
|
|
|
/*
|
|
===============
|
|
=
|
|
= UL_StartupDivisionByZero
|
|
=
|
|
===============
|
|
*/
|
|
|
|
void UL_StartupDivisionByZero ( void )
|
|
{
|
|
olddivisr = _dos_getvect(DIVISIONINT);
|
|
_dos_setvect (DIVISIONINT, UL_DivisionISR);
|
|
}
|
|
|
|
/*
|
|
===============
|
|
=
|
|
= UL_ShutdownDivisionByZero
|
|
=
|
|
===============
|
|
*/
|
|
|
|
void UL_ShutdownDivisionByZero ( void )
|
|
{
|
|
_dos_setvect (DIVISIONINT, olddivisr);
|
|
}
|
|
|