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