1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 #include <dos.h>
21 #include <errno.h>
22 #include <io.h>
23 #include <stdio.h>
24 #include <conio.h>
25 #include <stdarg.h>
26 #include <mem.h>
27 #include <ctype.h>
28 #include "rt_def.h"
29 #include "rt_str.h"
30 #include "rt_error.h"
31 #include "rt_menu.h"
32 #include "isr.h"
33 #include "w_wad.h"
34 #include "z_zone.h"
35 #include "rt_vid.h"
36 #include "rt_util.h"
37 #include "modexlib.h"
38 //MED
39 #include "memcheck.h"
40 
41 
42 //*****************************************************************************
43 //
44 //                          HARD ERROR ROUTINES
45 //
46 //****************************************************************************
47 
48 #define WINDOWUX           7
49 #define WINDOWUY           76
50 #define WINDOWLX           138
51 #define WINDOWLY           158
52 
53 #define MESSAGEBOXCOLOR    166
54 
55 
56 #define DISKERROR          0x4000         // bit 15 (of deverr)
57 #define IGNOREAVAILABLE    0x1000         // bit 13   (bit 14 isn't used)
58 #define RETRYAVAILABLE     0x800          // bit 12
59 #define FAILAVAILABLE      0x400          // bit 11
60 #define LOCATION           0x300          // bit 10 and 9
61 #define READWRITEERROR     0x80           // bit 8
62 #define DRIVEOFERROR       0x0F           // low-order byte
63 
64 #define DIVISIONINT                0x00
65 
66 // Globals
67 
68 boolean DivisionError = false;
69 
70 // Statics
71 
72 
73 static char ErrorCodes[13][25] =
74 {
75    "Write-protected disk\0",
76    "Unknown unit\0",
77    "Drive not ready\0",
78    "Unknown command\0",
79    "CRC error in data\0",
80    "Bad drive struct length\0",
81    "Seek error\0",
82    "Unknown media type\0",
83    "Sector not found\0",
84    "Printer out of paper\0",
85    "Write fault\0",
86    "Read fault\0",
87    "General failure\0"
88 };
89 
90 static char Drives[7][3] =
91 {
92    "A\0",
93    "B\0",
94    "C\0",
95    "D\0",
96    "E\0",
97    "F\0",
98    "G\0"
99 };
100 
101 static char Locations[4][11] =
102 {
103    "MS-DOS\0",
104    "FAT\0",
105    "Directory\0",
106    "Data area\0"
107 };
108 
109 static char ReadWrite[2][6] =
110 {
111    "Read\0",
112    "Write\0"
113 };
114 
115 static boolean ErrorHandlerStarted=false;
116 void (__interrupt __far *olddivisr) () = NULL;
117 
118 //******************************************************************************
119 //
120 // UL_UserMessage ()
121 //
122 //******************************************************************************
123 
UL_UserMessage(int x,int y,char * str,...)124 void UL_UserMessage (int x, int y, char *str, ...)
125 {
126    va_list strptr;
127    char buf[128];
128    int width, height;
129 
130    memset (&buf[0], 0, sizeof (buf));
131    va_start (strptr, str);
132    vsprintf (&buf[0], str, strptr);
133    va_end (strptr);
134 
135 	if ( *(byte *)0x449 == 0x13)
136       {
137       CurrentFont = tinyfont;
138 
139       WindowW=160;
140       WindowH=100;
141       WindowX=80;
142       WindowY=50;
143 
144       US_MeasureStr (&width, &height, &buf[0]);
145 
146       width  += (CurrentFont->width[1] << 1);
147       height += (CurrentFont->height << 1);
148 
149       VL_Bar (x, y, WindowW-2, WindowH, MESSAGEBOXCOLOR);
150 
151       PrintX = x+CurrentFont->width[1];
152       PrintY = y+CurrentFont->height;
153 
154       US_CPrint (&buf[0]);
155 
156       displayofs=bufferofs;
157 
158       OUTP(CRTC_INDEX, CRTC_STARTHIGH);
159       OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
160 
161 
162       bufferofs += screensize;
163       if (bufferofs > page3start)
164          bufferofs = page1start;
165       }
166    else
167       printf("%s\n",&buf[0]);
168 }
169 
170 //****************************************************************************
171 //
172 // UL_GeneralError ()
173 //
174 //****************************************************************************
175 
UL_GeneralError(int code)176 int UL_GeneralError (int code)
177 {
178    boolean done = false;
179    int retval = 0;
180 
181    UL_UserMessage (80, 50, "Device Error!\n%s.\n \n(A)bort  (R)etry\n",
182                    ErrorCodes[code]);
183 
184    if (KeyboardStarted==true)
185       {
186       while (!done)
187       {
188          if (Keyboard[sc_A])
189          {
190             retval = 1;
191             done = true;
192 
193             while (Keyboard[sc_A])
194                ;
195          }
196          else
197             if (Keyboard[sc_R])
198             {
199                retval = 0;
200                done = true;
201 
202                while (Keyboard[sc_R])
203                   ;
204             }
205       }
206       }
207    else
208       {
209       while (!done)
210       {
211          if (kbhit())
212          {
213             char ch;
214 
215             ch=toupper(getch());
216             if (ch=='A')
217                {
218                retval = 1;
219                done = true;
220                }
221             else if (ch=='R')
222                {
223                retval = 0;
224                done = true;
225                }
226          }
227       }
228       }
229 
230 
231    return (retval);
232 }
233 
234 
235 //****************************************************************************
236 //
237 // UL_DriveError ()
238 //
239 //****************************************************************************
240 
UL_DriveError(int code,int location,int rwerror,int whichdrive)241 int UL_DriveError (int code, int location, int rwerror, int whichdrive)
242 {
243    boolean done = false;
244    int retval   = 0;
245 
246    UL_UserMessage (80, 50,
247                   "Drive Error!\n%s.\nOn drive %s.\nLocation: %s.\n%s error.\n(A)bort  (R)etry\n",
248                     ErrorCodes[code], Drives[whichdrive],
249                     Locations[location], ReadWrite[rwerror]);
250 
251    if (KeyboardStarted==true)
252       {
253       while (!done)
254       {
255          if (Keyboard[sc_A])
256          {
257             retval = 1;
258             done = true;
259 
260             while (Keyboard[sc_A])
261                ;
262          }
263          else
264             if (Keyboard[sc_R])
265             {
266                retval = 0;
267                done = true;
268 
269                while (Keyboard[sc_R])
270                   ;
271             }
272       }
273       }
274    else
275       {
276       while (!done)
277       {
278          if (kbhit())
279          {
280             char ch;
281 
282             ch=toupper(getch());
283             if (ch=='A')
284                {
285                retval = 1;
286                done = true;
287                }
288             else if (ch=='R')
289                {
290                retval = 0;
291                done = true;
292                }
293          }
294       }
295       }
296 
297    return (retval);
298 }
299 
300 
301 //****************************************************************************
302 //
303 //	UL_harderr ()
304 //
305 //****************************************************************************
306 
UL_harderr(unsigned deverr,unsigned errcode,unsigned far * devhdr)307 int __far UL_harderr (unsigned deverr, unsigned errcode, unsigned far *devhdr)
308 {
309    int DiskError      = 0;    // Indicates if it was a disk error
310    int IgnoreAvail    = 0;    // if "ignore" response is available
311    int RetryAvail     = 0;    // if "retry" response is available
312    int FailAvail      = 0;    // if "fail" response is available
313    byte ErrorLocation = 0;    // Location of error
314    byte RWerror       = 0;    // Read/Write error (0 == read, 1 == write)
315    byte whichDrive    = 0;    // Drive the error is on (0 == A, 1 == B, ...)
316    int action;
317 
318    unsigned temp;
319    temp = *devhdr;
320 
321   // Check errors
322    DiskError     = (deverr & DISKERROR);
323    IgnoreAvail   = (deverr & IGNOREAVAILABLE);
324    RetryAvail    = (deverr & RETRYAVAILABLE);
325    FailAvail     = (deverr & FAILAVAILABLE);
326    ErrorLocation = ((deverr & LOCATION) >> 8);
327    RWerror       = (deverr & READWRITEERROR);
328 
329    if (DiskError == 0)
330       action = UL_GeneralError (errcode);
331    else
332       action = UL_DriveError (errcode, ErrorLocation, RWerror, whichDrive);
333 
334    if (action)
335       Error ("USER BREAK : ROTT aborted.\n");
336    return (_HARDERR_RETRY);
337 }
338 
339 
340 //****************************************************************************
341 //
342 //	UL_DivisionISR ()
343 //
344 //****************************************************************************
345 
346 extern byte * colormap;
347 
UL_DivisionISR(void)348 void __interrupt __far UL_DivisionISR ( void )
349 {
350 // acknowledge the interrupt
351 
352    SetBorderColor (*(colormap+(((100-10)>>2)<<8)+160));
353    DivisionError = true;
354    OUTP (0x20, 0x20);
355 }
356 
357 
358 //****************************************************************************
359 //
360 //	UL_ErrorStartup ()
361 //
362 //****************************************************************************
363 
UL_ErrorStartup(void)364 void UL_ErrorStartup ( void )
365 {
366    if (ErrorHandlerStarted==true)
367       return;
368    ErrorHandlerStarted=true;
369    _harderr (UL_harderr);     // Install hard error handler
370    UL_StartupDivisionByZero();
371 }
372 
373 //****************************************************************************
374 //
375 //	UL_ErrorShutdown ()
376 //
377 //****************************************************************************
378 
UL_ErrorShutdown(void)379 void UL_ErrorShutdown ( void )
380 {
381    if (ErrorHandlerStarted==false)
382       return;
383    ErrorHandlerStarted=false;
384    UL_ShutdownDivisionByZero();
385 }
386 
387 
388 /*
389 ===============
390 =
391 = UL_StartupDivisionByZero
392 =
393 ===============
394 */
395 
UL_StartupDivisionByZero(void)396 void UL_StartupDivisionByZero ( void )
397 {
398 	olddivisr = _dos_getvect(DIVISIONINT);
399 	_dos_setvect (DIVISIONINT, UL_DivisionISR);
400 }
401 
402 /*
403 ===============
404 =
405 = UL_ShutdownDivisionByZero
406 =
407 ===============
408 */
409 
UL_ShutdownDivisionByZero(void)410 void UL_ShutdownDivisionByZero ( void )
411 {
412 	_dos_setvect (DIVISIONINT, olddivisr);
413 }
414 
415