Merging NList MCC 0.119 into the main branch.
[AROS.git] / rom / alerthook / alerthook.c
blobfa1207fb3b13ef62bbfd30407294507a2489e3a3
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Alert.Hook for AROS
6 Lang: english
7 */
9 #define DEBUG 0
10 #include <aros/debug.h>
11 #include <aros/config.h>
12 #include <exec/types.h>
13 #include <exec/resident.h>
14 #include <exec/alerts.h>
15 #include <exec/tasks.h>
16 #include <exec/execbase.h>
17 #include <intuition/intuitionbase.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <aros/system.h>
21 #include <aros/libcall.h>
22 #include <aros/asmcall.h>
24 struct Errors
26 ULONG number;
27 STRPTR string;
30 static const UBYTE Alerthook_name[];
31 static const UBYTE Alerthook_version[];
32 static AROS_UFP3(ULONG, Alerthook_init,
33 AROS_UFPA(void *, dummy1, D0),
34 AROS_UFPA(BPTR, dummy2, A0),
35 AROS_UFPA(struct ExecBase *, SysBase, A6)
38 STRPTR getGuruString(ULONG, STRPTR);
40 extern void Alerthook_end(void);
42 const struct Resident Alerthook_resident =
44 RTC_MATCHWORD,
45 (struct Resident *)&Alerthook_resident,
46 (APTR)&Alerthook_end,
47 RTF_COLDSTART,
48 41,
49 NT_UNKNOWN,
50 -45,
51 (UBYTE *)Alerthook_name,
52 (UBYTE *)&Alerthook_version[6],
53 (APTR)&Alerthook_init,
56 static const UBYTE Alerthook_name[] = "alert.hook\r\n";
57 static const UBYTE Alerthook_version[] = "$VER: alert.hook 41.8 " ADATE;
58 static UBYTE *const nomem = "\x38\x0f" "Not Enough Memory! ";
59 static UBYTE *const sfail = "\x38\x0f" "Software Failure! ";
60 static UBYTE *const recov = "\x38\x0f" "Recoverable Alert! ";
61 static UBYTE *const mouse = "\x01\x50\x0f" "Press mouse button to continue.";
62 static UBYTE *const fmtstring = "\xa8\x2a" "Task: %08lx - ";
63 static UBYTE *const errstring = "\x1e" "Error %04x %04x - ";
64 static UBYTE *const tasknotfound = "--task not found--";
66 /* This is the callback for RawDoFmt() */
67 AROS_UFH2(void, putChProc,
68 AROS_UFHA(UBYTE, chr, D0),
69 AROS_UFHA(STRPTR *, buf, A3))
71 AROS_LIBFUNC_INIT
73 **buf = chr;
74 *buf += 1;
76 AROS_LIBFUNC_EXIT
79 /* This function copies a string, but also returns a pointer to the
80 '\0' at the end of the string. This way I can concat the strings
81 which have '\0' in them for other reasons.
83 Note len == -1 is equivalent to strcpy(dest,src).
85 static STRPTR
86 mystrcpy(STRPTR dest, STRPTR src, LONG len)
88 while(len && *src)
90 *dest++ = *src++;
91 len--;
93 *dest++ = 0;
94 return dest;
97 static AROS_UFH3(ULONG, Alerthook_init,
98 AROS_UFHA(void *, dummy1, D0),
99 AROS_UFHA(BPTR, dummy2, A0),
100 AROS_UFHA(struct ExecBase *, SysBase, A6)
103 AROS_LIBFUNC_INIT
105 #if (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
107 Clear memory location zero (a cookie for the delayed guru after reset).
108 Some machines will keep putting a guru up during every reset if I don't
109 do this here.
111 ULONG *location_zero = (void *)0;
113 *location_zero = 0;
114 #endif
116 D(bug("AlertHook: *******************\n"));
117 if(SysBase->LastAlert[0] != -1)
119 struct IntuitionBase *IntuitionBase;
120 struct Task *task;
121 UBYTE buffer[256], *buf, *tname;
123 D(bug("alert.hook: LastAlert[0] = 0x%lx\n", SysBase->LastAlert[0]));
125 buffer[0] = 0;
126 buf = &buffer[1];
128 if(SysBase->LastAlert[0] & AG_NoMemory)
129 buf = mystrcpy(buf, nomem, -1);
130 else if(SysBase->LastAlert[0] & AT_DeadEnd)
131 buf = mystrcpy(buf, sfail, -1);
132 else
133 buf = mystrcpy(buf, recov, -1);
135 *buf++ = 1;
137 buf = mystrcpy(buf, mouse, -1);
138 *buf++ = 1; *buf++ = 0;
140 /* Find out the task name. The node type must be correct. */
141 task = (struct Task *)SysBase->LastAlert[1];
142 if( (
143 (task->tc_Node.ln_Type == NT_TASK)
144 || (task->tc_Node.ln_Type == NT_PROCESS)
146 && (task->tc_Node.ln_Name != NULL)
148 tname = task->tc_Node.ln_Name;
149 else
150 tname = tasknotfound;
152 RawDoFmt(fmtstring, &SysBase->LastAlert[1], (void *)putChProc, &buf);
153 buf = mystrcpy(buf - 1, tname, 30);
154 *buf++ = 1; *buf++ = 0;
156 /* Use this variable to hold the current address */
157 tname = buf++;
158 RawDoFmt(errstring, &SysBase->LastAlert[0], (void *)putChProc, &buf);
160 buf = getGuruString(SysBase->LastAlert[0], &buf[-1]);
161 *buf++ = 0;
163 /* This rather strange contraption will centre the string. */
164 *((UBYTE *)tname) = (82 - (buf - tname)) << 2;
166 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
168 if(IntuitionBase)
170 if(IntuitionBase->LibNode.lib_Version >= 39)
171 TimedDisplayAlert(SysBase->LastAlert[0] & AT_DeadEnd, buffer, 0x38, 500);
172 else
173 DisplayAlert(SysBase->LastAlert[0] & AT_DeadEnd, buffer, 0x38);
175 CloseLibrary((struct Library *)IntuitionBase);
176 } else {
177 D(bug("alert.hook: No intuition, dumping message\n"));
178 D(bug("alert.hook: %s\n", buffer));
181 SysBase->LastAlert[0] = -1;
183 #if 0
184 SysBase->LastAlert[0] = old;
185 SysBase->LastAlert[1] = NULL;
186 #endif
187 return FALSE;
189 AROS_LIBFUNC_EXIT
192 /* Get a string from an array of type Errors. */
193 STRPTR getString(STRPTR buffer, ULONG alertnum, const struct Errors *errs)
195 while((errs->number) && (errs->number != alertnum))
197 errs++;
199 return mystrcpy(buffer, errs->string, -1);
202 static const struct Errors cpustrings[] =
204 { ACPU_BusErr, "Hardware bus fault/address error" },
205 { ACPU_AddressErr, "Illegal address access (odd)" },
206 { ACPU_InstErr, "Illegal instruction" },
207 { ACPU_DivZero, "Division by zero" },
208 { ACPU_CHK, "CHK instruction error" },
209 { ACPU_TRAPV, "TRAPV instruction error" },
210 { ACPU_PrivErr, "Priviledge violation error" },
211 { ACPU_Trace, "Trace error" },
212 { ACPU_LineA, "Line 1010 (A) E mulator error" },
213 { ACPU_LineF, "Line 1111 (F) Emulator/Coprocessor error" },
214 { ACPU_Format, "Stack frame format error" },
215 { ACPU_Spurious, "Spurious interrupt error" },
216 { 0, "Unknown CPU error" }
219 static const struct Errors subsystems[] =
221 { 0x01, "exec.library " },
222 { 0x02, "graphics.library " },
223 { 0x03, "layers.library " },
224 { 0x04, "intuition.library " },
225 { 0x05, "math.library " },
226 { 0x07, "dos.library " },
227 { 0x08, "ramlib " },
228 { 0x09, "icon.library " },
229 { 0x0a, "expansion.library " },
230 { 0x0b, "diskfont.library " },
231 { 0x10, "audio.device " },
232 { 0x11, "console.device " },
233 { 0x12, "gameport.device " },
234 { 0x13, "keyboard.device " },
235 { 0x14, "trackdisk.device " },
236 { 0x15, "timer.device " },
237 { 0x20, "cia.resource " },
238 { 0x21, "disk.resource " },
239 { 0x22, "misc.resource " },
240 { 0x30, "bootstrap " },
241 { 0x31, "workbench " },
242 { 0x32, "diskcopy " },
243 { 0x33, "gadtools " },
244 { 0x34, "utility " },
246 { 0x40, "aros " },
247 { 0x41, "oop " },
248 { 0x42, "hidd " },
250 /* This takes in 0x35 as well... */
251 { 0x00, "unknown " }
254 static const struct Errors types[] =
256 { 0x01, "no memory for " },
257 { 0x02, "could not make library " },
258 { 0x03, "could not open library " },
259 { 0x04, "could not open device " },
260 { 0x05, "could not open resource " },
261 { 0x06, "IO error with " },
262 { 0x07, "no signal for/from " },
263 { 0x08, "bad parameter for/from " },
264 { 0x09, "close library error with " },
265 { 0x0a, "close device error with " },
266 { 0x0b, "process creating failure with " },
267 { 0x00, "unknown problem with "}
270 static const struct Errors execstrings[] =
272 { AN_ExcptVect, "MC68k Exception vector checksum" },
273 { AN_BaseChkSum, "ExecBase checksum" },
274 { AN_LibChkSum, "Library checksum failure" },
275 { AN_MemCorrupt, "Corrupt memory list detected" },
276 { AN_IntrMem, "No memory for interrupt servers" },
277 { AN_InitAPtr, "(obs) InitStruct of an APTR" },
278 { AN_SemCorrupt, "Semaphore in an illegal state" },
279 { AN_FreeTwice, "Memory freed twice" },
280 { AN_BogusExcpt, "Illegal mc68k exception taken" },
281 { AN_IOUsedTwice, "Attempt to reuse active IORequest" },
282 { AN_MemoryInsane, "Sanity check on memory list failed" },
283 { AN_IOAfterClose, "Attempt to use IORequest after close" },
284 { AN_StackProbe, "Stack extends out of range" },
285 { AN_BadFreeAddr, "Memory header not located" },
286 { AN_BadSemaphore, "Attempt to use the old message semaphore" },
287 { 0, "unknown exec.library error" }
290 static const struct Errors gfxstrings[] =
292 { AN_GfxNoMem, "Graphics out of memory" },
293 { AN_GfxNoMemMspc, "No memory to allocate MonitorSpec" },
294 { AN_LongFrame, "No memory for long frame" },
295 { AN_ShortFrame, "No memory for short frame" },
296 { AN_TextTmpRas, "Mo memory for TmpRas" },
297 { AN_BltBitMap, "No memory for BltBitMap" },
298 { AN_RegionMemory, "No memory for Region" },
299 { AN_MakeVPort, "No memory for MakeVPort" },
300 { AN_GfxNewError, "Error in GfxNew()" },
301 { AN_GfxFreeError, "Error in GfxFree()" },
302 { AN_GfxNoLCM, "Emergency memory not available" },
303 { AN_ObsoleteFont, "Unsupported font description used" },
304 { 0, "unknown graphics.library error" }
307 static const struct Errors unknownstrings[] =
309 { 0, "unknown error" }
312 static const struct Errors layersstrings[] =
314 { AN_LayersNoMem, "layers: no memory" },
315 { 0, "unknown layers.library error" }
318 static const struct Errors intuistrings[] =
320 { AN_GadgetType, "intuition: unknown gadget type" },
321 { AN_CreatePort, "intuition couldn't create port, no memory" },
322 { AN_ItemAlloc, "no memory for menu item" },
323 { AN_SubAlloc, "no memory for menu subitem" },
324 { AN_PlaneAlloc, "no memory for bitplane" },
325 { AN_ItemBoxTop, "top of item box < RelZero" },
326 { AN_OpenScreen, "no memory for OpenScreen()" },
327 { AN_OpenScrnRast, "no memory for OpenScreen() raster" },
328 { AN_SysScrnType, "unknown type of system screen" },
329 { AN_AddSWGadget, "add SW gadgets, no memory" },
330 { AN_OpenWindow, "no memory for OpenWindow()" },
331 { AN_BadState, "bad state return entering intuition" },
332 { AN_BadMessage, "bad message received by IDCMP" },
333 { AN_WeirdEcho, "weird echo causing incomprehension" },
334 { AN_NoConsole, "couldn't open the console.device" },
335 { AN_NoISem, "intuition skipped obtaining a semaphore" },
336 { AN_ISemOrder, "intuition got a semaphore in wrong order" },
337 { 0, "unknown intuition.library error" }
340 static const struct Errors mathstrings[] =
342 { 0, "unknown math library error" }
345 static const struct Errors dosstrings[] =
347 { AN_StartMem, "no memory at startup" },
348 { AN_EndTask, "EndTask did not end task" },
349 { AN_QPktFail, "QPkt failure" },
350 { AN_AsyncPkt, "unexpected DOS packet received" },
351 { AN_FreeVec, "freevec failed" },
352 { AN_DiskBlkSeq, "disk block sequence error" },
353 { AN_BitMap, "disk bitmap corrupt" },
354 { AN_KeyFree, "disk key already free" },
355 { AN_BadChkSum, "disk checksum bad" },
356 { AN_DiskError, "disk error" },
357 { AN_KeyRange, "disk key out of range" },
358 { AN_BadOverlay, "bad overlay" },
359 { AN_BadInitFunc, "invalid initialization packet for cli/shell" },
360 { AN_FileReclosed, "filehandle closed more than once" },
361 { 0, "unknown dos.library error" }
364 static const struct Errors ramlibstrings[] =
366 { AN_BadSegList, "bad library seglist" },
367 { 0, "unknown ramlib/lddemon error" }
370 static const struct Errors iconstrings[] =
372 { 0, "unknown icon.library error" }
375 static const struct Errors expanstrings[] =
377 { AN_BadExpansionFree, "expansion freeing region already freed"},
378 { 0, "unknown expansion.library error" }
381 static const struct Errors utilitystrings[] =
383 {0, "unknown utility.library error" }
386 static const struct Errors keymapstrings[] =
388 {0, "unknown keymap error" }
391 static const struct Errors dfontstrings[] =
393 { 0, "unknown diskfont.library error" }
396 static const struct Errors audiostrings[] =
398 { 0, "unknown audio.device error" }
401 static const struct Errors consolestrings[] =
403 { AN_NoWindow, "can't open initial console window" },
404 { 0, "unknown console.device error" }
407 static const struct Errors gameportstrings[] =
409 { 0, "unknown gameport.device error" }
412 static const struct Errors keyboardstrings[] =
414 { 0, "unknown keyboard.device error" }
417 static const struct Errors trackdiskstrings[] =
419 { AN_TDCalibSeek, "trackdisk calibrate seek error" },
420 { 0, "unknown trackdisk.device error" }
423 static const struct Errors timerstrings[] =
425 { AN_TMBadReq, "bad timer request" },
426 { AN_TMBadSupply, "bad timer powersupply frequency" },
427 { 0, "unknown timer.device error" }
430 static const struct Errors ciastrings[] =
432 { 0, "unknown cia resource error" }
435 static const struct Errors diskstrings[] =
437 { AN_DRHasDisk, "get disk unit, already has disk" },
438 { AN_DRIntNoAct,"disk interrupt, no active unit" },
439 { 0, "unknown disk.resource error" }
442 static const struct Errors miscstrings[] =
444 { 0, "unknown misc.resource error" }
447 static const struct Errors bootstrings[] =
449 { AN_BootError, "boot code returned an error" },
450 { 0, "unknown bootstrap error" }
453 static const struct Errors workbenchstrings[] =
455 { AN_NoFonts, "no fonts for workbench" },
456 { AN_WBBadStartupMsg1, "bad startup message 1 for workbench" },
457 { AN_WBBadStartupMsg2, "bad startup message 2 for workbench" },
458 { AN_WBBadIOMsg, "bad IO message for workbench" },
459 { AN_WBReLayoutToolMenu, "error with layout on tools menu" },
460 { 0, "unknown workbench error" }
463 static const struct Errors diskcopystrings[] =
465 {0, "unknown diskcopy error" }
468 static const struct Errors gadtoolsstrings[] =
470 {0, "unknown gadtools.library error" }
473 static const struct Errors arosstrings[] =
475 {0, "unknown aros.library error" }
478 static const struct Errors oopstrings[] =
480 {0, "unknown oop.library error" }
483 static const struct Errors hiddstrings[] =
485 {0, "unknown Hidd system error" }
488 static const struct Errors *const stringlist[] =
490 /* 0x00 */
491 unknownstrings,
492 execstrings,
493 gfxstrings,
494 layersstrings,
495 intuistrings,
496 mathstrings,
497 unknownstrings,
498 dosstrings,
499 ramlibstrings,
500 iconstrings,
501 expanstrings,
502 dfontstrings,
503 utilitystrings,
504 keymapstrings,
505 unknownstrings,
506 unknownstrings,
508 /* 0x10 */
509 audiostrings,
510 consolestrings,
511 gameportstrings,
512 keyboardstrings,
513 trackdiskstrings,
514 timerstrings,
515 unknownstrings,
516 unknownstrings,
517 unknownstrings,
518 unknownstrings,
519 unknownstrings,
520 unknownstrings,
521 unknownstrings,
522 unknownstrings,
523 unknownstrings,
524 unknownstrings,
526 /* 0x20 */
527 ciastrings,
528 diskstrings,
529 miscstrings,
530 unknownstrings,
531 unknownstrings,
532 unknownstrings,
533 unknownstrings,
534 unknownstrings,
535 unknownstrings,
536 unknownstrings,
537 unknownstrings,
538 unknownstrings,
539 unknownstrings,
540 unknownstrings,
541 unknownstrings,
542 unknownstrings,
544 /* 0x30 */
545 bootstrings,
546 workbenchstrings,
547 diskcopystrings,
548 gadtoolsstrings,
549 unknownstrings,
550 unknownstrings,
551 unknownstrings,
552 unknownstrings,
553 unknownstrings,
554 unknownstrings,
555 unknownstrings,
556 unknownstrings,
557 unknownstrings,
558 unknownstrings,
559 unknownstrings,
560 unknownstrings,
562 /* 0x40 */
563 arosstrings,
564 oopstrings,
565 hiddstrings
568 /* Decode the alert number, and try and work out what string to get */
569 STRPTR getGuruString(ULONG alertnum, STRPTR buf)
571 /* Is this a CPU alert? */
572 if((alertnum & 0x7f008000) == 0)
574 /* Yes */
575 buf = getString(buf, alertnum, cpustrings);
577 /* Is this a General alert */
578 else if((alertnum & 0x8000) == 0x8000)
580 UBYTE type = (alertnum & 0x00FF0000) >> 16;
581 UWORD obj = (alertnum & 0x7fff);
582 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
584 buf = getString(buf, obj, subsystems);
585 buf = getString(&buf[-1], type, types);
586 buf = getString(&buf[-1], subsys, subsystems);
588 /* This must be a specific alert */
589 else
591 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
593 if(subsys < 0x80)
594 buf = getString(buf, alertnum, stringlist[subsys]);
595 else
596 buf = mystrcpy(buf, "unknown error", -1);
599 return buf;