- Resident packet handlers can now be used.
[cake.git] / rom / alerthook / alerthook.c
blob912f3c3be0ca2d34b79d543ef2be08de810d3a2d
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 #include <aros/config.h>
10 #include <exec/types.h>
11 #include <exec/resident.h>
12 #include <exec/alerts.h>
13 #include <exec/tasks.h>
14 #include <exec/execbase.h>
15 #include <intuition/intuitionbase.h>
16 #include <proto/exec.h>
17 #include <proto/intuition.h>
18 #include <aros/system.h>
19 #include <aros/libcall.h>
20 #include <aros/asmcall.h>
22 struct Errors
24 ULONG number;
25 STRPTR string;
28 static const UBYTE Alerthook_name[];
29 static const UBYTE Alerthook_version[];
30 AROS_UFP3(ULONG, AROS_SLIB_ENTRY(init,Alerthook),
31 AROS_UFPA(void *, dummy1, D0),
32 AROS_UFPA(BPTR, dummy2, A0),
33 AROS_UFPA(struct ExecBase *, SysBase, A6)
35 static const char Alerthook_end;
37 STRPTR getGuruString(ULONG, STRPTR);
39 int Alerthook_entry(void)
41 /* If the hook was executed by accident return error code. */
42 return -1;
45 const struct Resident Alerthook_resident __attribute__((section(".text"))) =
47 RTC_MATCHWORD,
48 (struct Resident *)&Alerthook_resident,
49 (APTR)&Alerthook_end,
50 RTF_COLDSTART,
51 41,
52 NT_UNKNOWN,
53 -55,
54 (UBYTE *)Alerthook_name,
55 (UBYTE *)&Alerthook_version[6],
56 (APTR)&AROS_SLIB_ENTRY(init,Alerthook)
59 static const UBYTE Alerthook_name[] = "alert.hook\r\n";
60 static const UBYTE Alerthook_version[] = "$VER: alert.hook 41.8 (6.3.2001)";
61 static UBYTE *const nomem = "\x38\x0f" "Not Enough Memory! ";
62 static UBYTE *const sfail = "\x38\x0f" "Software Failure! ";
63 static UBYTE *const recov = "\x38\x0f" "Recoverable Alert! ";
64 static UBYTE *const mouse = "\x01\x50\x0f" "Press mouse button to continue.";
65 static UBYTE *const fmtstring = "\xa8\x2a" "Task: %08lx - ";
66 static UBYTE *const errstring = "\x1e" "Error %04x %04x - ";
67 static UBYTE *const tasknotfound = "--task not found--";
69 /* This is the callback for RawDoFmt() */
70 AROS_UFH2(void, putChProc,
71 AROS_UFHA(UBYTE, chr, D0),
72 AROS_UFHA(STRPTR *, buf, A3))
74 **buf = chr;
75 *buf += 1;
78 /* This function copies a string, but also returns a pointer to the
79 '\0' at the end of the string. This way I can concat the strings
80 which have '\0' in them for other reasons.
82 Note len == -1 is equivalent to strcpy(dest,src).
84 static STRPTR
85 mystrcpy(STRPTR dest, STRPTR src, LONG len)
87 while(len && *src)
89 *dest++ = *src++;
90 len--;
92 *dest++ = 0;
93 return dest;
96 AROS_UFH3(ULONG, AROS_SLIB_ENTRY(init,Alerthook),
97 AROS_UFHA(void *, dummy1, D0),
98 AROS_UFHA(BPTR, dummy2, A0),
99 AROS_UFHA(struct ExecBase *, SysBase, A6)
102 #if (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
104 Clear memory location zero (a cookie for the delayed guru after reset).
105 Some machines will keep putting a guru up during every reset if I don't
106 do this here.
108 ULONG *location_zero = (void *)0;
110 *location_zero = 0;
111 #endif
113 if(SysBase->LastAlert[0] != -1)
115 struct IntuitionBase *IntuitionBase;
116 struct Task *task;
117 UBYTE buffer[256], *buf, *tname;
119 buffer[0] = 0;
120 buf = &buffer[1];
122 if(SysBase->LastAlert[0] & AG_NoMemory)
123 buf = mystrcpy(buf, nomem, -1);
124 else if(SysBase->LastAlert[0] & AT_DeadEnd)
125 buf = mystrcpy(buf, sfail, -1);
126 else
127 buf = mystrcpy(buf, recov, -1);
129 *buf++ = 1;
131 buf = mystrcpy(buf, mouse, -1);
132 *buf++ = 1; *buf++ = 0;
134 /* Find out the task name. The node type must be correct. */
135 task = (struct Task *)SysBase->LastAlert[1];
136 if( (
137 (task->tc_Node.ln_Type == NT_TASK)
138 || (task->tc_Node.ln_Type == NT_PROCESS)
140 && (task->tc_Node.ln_Name != NULL)
142 tname = task->tc_Node.ln_Name;
143 else
144 tname = tasknotfound;
146 RawDoFmt(fmtstring, &SysBase->LastAlert[1], (void *)putChProc, &buf);
147 buf = mystrcpy(buf - 1, tname, 30);
148 *buf++ = 1; *buf++ = 0;
150 /* Use this variable to hold the current address */
151 tname = buf++;
152 RawDoFmt(errstring, &SysBase->LastAlert[0], (void *)putChProc, &buf);
154 buf = getGuruString(SysBase->LastAlert[0], &buf[-1]);
155 *buf++ = 0;
157 /* This rather strange contraption will centre the string. */
158 *((UBYTE *)tname) = (82 - (buf - tname)) << 2;
160 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
162 if(IntuitionBase)
164 if(IntuitionBase->LibNode.lib_Version >= 39)
165 TimedDisplayAlert(SysBase->LastAlert[0] & AT_DeadEnd, buffer, 0x38, 500);
166 else
167 DisplayAlert(SysBase->LastAlert[0] & AT_DeadEnd, buffer, 0x38);
169 CloseLibrary((struct Library *)IntuitionBase);
172 SysBase->LastAlert[0] = -1;
174 #if 0
175 SysBase->LastAlert[0] = old;
176 SysBase->LastAlert[1] = NULL;
177 #endif
178 return NULL;
182 /* Get a string from an array of type Errors. */
183 STRPTR getString(STRPTR buffer, ULONG alertnum, const struct Errors *errs)
185 while((errs->number) && (errs->number != alertnum))
187 errs++;
189 return mystrcpy(buffer, errs->string, -1);
192 static const struct Errors cpustrings[] =
194 { ACPU_BusErr, "Hardware bus fault/address error" },
195 { ACPU_AddressErr, "Illegal address access (odd)" },
196 { ACPU_InstErr, "Illegal instruction" },
197 { ACPU_DivZero, "Division by zero" },
198 { ACPU_CHK, "CHK instruction error" },
199 { ACPU_TRAPV, "TRAPV instruction error" },
200 { ACPU_PrivErr, "Priviledge violation error" },
201 { ACPU_Trace, "Trace error" },
202 { ACPU_LineA, "Line 1010 (A) E mulator error" },
203 { ACPU_LineF, "Line 1111 (F) Emulator/Coprocessor error" },
204 { ACPU_Format, "Stack frame format error" },
205 { ACPU_Spurious, "Spurious interrupt error" },
206 { 0, "Unknown CPU error" }
209 static const struct Errors subsystems[] =
211 { 0x01, "exec.library " },
212 { 0x02, "graphics.library " },
213 { 0x03, "layers.library " },
214 { 0x04, "intuition.library " },
215 { 0x05, "math.library " },
216 { 0x07, "dos.library " },
217 { 0x08, "ramlib " },
218 { 0x09, "icon.library " },
219 { 0x0a, "expansion.library " },
220 { 0x0b, "diskfont.library " },
221 { 0x10, "audio.device " },
222 { 0x11, "console.device " },
223 { 0x12, "gameport.device " },
224 { 0x13, "keyboard.device " },
225 { 0x14, "trackdisk.device " },
226 { 0x15, "timer.device " },
227 { 0x20, "cia.resource " },
228 { 0x21, "disk.resource " },
229 { 0x22, "misc.resource " },
230 { 0x30, "bootstrap " },
231 { 0x31, "workbench " },
232 { 0x32, "diskcopy " },
233 { 0x33, "gadtools " },
234 { 0x34, "utility " },
236 { 0x40, "aros " },
237 { 0x41, "oop " },
238 { 0x42, "hidd " },
240 /* This takes in 0x35 as well... */
241 { 0x00, "unknown " }
244 static const struct Errors types[] =
246 { 0x01, "no memory for " },
247 { 0x02, "could not make library " },
248 { 0x03, "could not open library " },
249 { 0x04, "could not open device " },
250 { 0x05, "could not open resource " },
251 { 0x06, "IO error with " },
252 { 0x07, "no signal for/from " },
253 { 0x08, "bad parameter for/from " },
254 { 0x09, "close library error with " },
255 { 0x0a, "close device error with " },
256 { 0x0b, "process creating failure with " },
257 { 0x00, "unknown problem with "}
260 static const struct Errors execstrings[] =
262 { AN_ExcptVect, "MC68k Exception vector checksum" },
263 { AN_BaseChkSum, "ExecBase checksum" },
264 { AN_LibChkSum, "Library checksum failure" },
265 { AN_MemCorrupt, "Corrupt memory list detected" },
266 { AN_IntrMem, "No memory for interrupt servers" },
267 { AN_InitAPtr, "(obs) InitStruct of an APTR" },
268 { AN_SemCorrupt, "Semaphore in an illegal state" },
269 { AN_FreeTwice, "Memory freed twice" },
270 { AN_BogusExcpt, "Illegal mc68k exception taken" },
271 { AN_IOUsedTwice, "Attempt to reuse active IORequest" },
272 { AN_MemoryInsane, "Sanity check on memory list failed" },
273 { AN_IOAfterClose, "Attempt to use IORequest after close" },
274 { AN_StackProbe, "Stack extends out of range" },
275 { AN_BadFreeAddr, "Memory header not located" },
276 { AN_BadSemaphore, "Attempt to use the old message semaphore" },
277 { 0, "unknown exec.library error" }
280 static const struct Errors gfxstrings[] =
282 { AN_GfxNoMem, "Graphics out of memory" },
283 { AN_GfxNoMemMspc, "No memory to allocate MonitorSpec" },
284 { AN_LongFrame, "No memory for long frame" },
285 { AN_ShortFrame, "No memory for short frame" },
286 { AN_TextTmpRas, "Mo memory for TmpRas" },
287 { AN_BltBitMap, "No memory for BltBitMap" },
288 { AN_RegionMemory, "No memory for Region" },
289 { AN_MakeVPort, "No memory for MakeVPort" },
290 { AN_GfxNewError, "Error in GfxNew()" },
291 { AN_GfxFreeError, "Error in GfxFree()" },
292 { AN_GfxNoLCM, "Emergency memory not available" },
293 { AN_ObsoleteFont, "Unsupported font description used" },
294 { 0, "unknown graphics.library error" }
297 static const struct Errors unknownstrings[] =
299 { 0, "unknown error" }
302 static const struct Errors layersstrings[] =
304 { AN_LayersNoMem, "layers: no memory" },
305 { 0, "unknown layers.library error" }
308 static const struct Errors intuistrings[] =
310 { AN_GadgetType, "intuition: unknown gadget type" },
311 { AN_CreatePort, "intuition couldn't create port, no memory" },
312 { AN_ItemAlloc, "no memory for menu item" },
313 { AN_SubAlloc, "no memory for menu subitem" },
314 { AN_PlaneAlloc, "no memory for bitplane" },
315 { AN_ItemBoxTop, "top of item box < RelZero" },
316 { AN_OpenScreen, "no memory for OpenScreen()" },
317 { AN_OpenScrnRast, "no memory for OpenScreen() raster" },
318 { AN_SysScrnType, "unknown type of system screen" },
319 { AN_AddSWGadget, "add SW gadgets, no memory" },
320 { AN_OpenWindow, "no memory for OpenWindow()" },
321 { AN_BadState, "bad state return entering intuition" },
322 { AN_BadMessage, "bad message received by IDCMP" },
323 { AN_WeirdEcho, "weird echo causing incomprehension" },
324 { AN_NoConsole, "couldn't open the console.device" },
325 { AN_NoISem, "intuition skipped obtaining a semaphore" },
326 { AN_ISemOrder, "intuition got a semaphore in wrong order" },
327 { 0, "unknown intuition.library error" }
330 static const struct Errors mathstrings[] =
332 { 0, "unknown math library error" }
335 static const struct Errors dosstrings[] =
337 { AN_StartMem, "no memory at startup" },
338 { AN_EndTask, "EndTask did not end task" },
339 { AN_QPktFail, "QPkt failure" },
340 { AN_AsyncPkt, "unexpected DOS packet received" },
341 { AN_FreeVec, "freevec failed" },
342 { AN_DiskBlkSeq, "disk block sequence error" },
343 { AN_BitMap, "disk bitmap corrupt" },
344 { AN_KeyFree, "disk key already free" },
345 { AN_BadChkSum, "disk checksum bad" },
346 { AN_DiskError, "disk error" },
347 { AN_KeyRange, "disk key out of range" },
348 { AN_BadOverlay, "bad overlay" },
349 { AN_BadInitFunc, "invalid initialization packet for cli/shell" },
350 { AN_FileReclosed, "filehandle closed more than once" },
351 { 0, "unknown dos.library error" }
354 static const struct Errors ramlibstrings[] =
356 { AN_BadSegList, "bad library seglist" },
357 { 0, "unknown ramlib/lddemon error" }
360 static const struct Errors iconstrings[] =
362 { 0, "unknown icon.library error" }
365 static const struct Errors expanstrings[] =
367 { AN_BadExpansionFree, "expansion freeing region already freed"},
368 { 0, "unknown expansion.library error" }
371 static const struct Errors utilitystrings[] =
373 {0, "unknown utility.library error" }
376 static const struct Errors keymapstrings[] =
378 {0, "unknown keymap error" }
381 static const struct Errors dfontstrings[] =
383 { 0, "unknown diskfont.library error" }
386 static const struct Errors audiostrings[] =
388 { 0, "unknown audio.device error" }
391 static const struct Errors consolestrings[] =
393 { AN_NoWindow, "can't open initial console window" },
394 { 0, "unknown console.device error" }
397 static const struct Errors gameportstrings[] =
399 { 0, "unknown gameport.device error" }
402 static const struct Errors keyboardstrings[] =
404 { 0, "unknown keyboard.device error" }
407 static const struct Errors trackdiskstrings[] =
409 { AN_TDCalibSeek, "trackdisk calibrate seek error" },
410 { 0, "unknown trackdisk.device error" }
413 static const struct Errors timerstrings[] =
415 { AN_TMBadReq, "bad timer request" },
416 { AN_TMBadSupply, "bad timer powersupply frequency" },
417 { 0, "unknown timer.device error" }
420 static const struct Errors ciastrings[] =
422 { 0, "unknown cia resource error" }
425 static const struct Errors diskstrings[] =
427 { AN_DRHasDisk, "get disk unit, already has disk" },
428 { AN_DRIntNoAct,"disk interrupt, no active unit" },
429 { 0, "unknown disk.resource error" }
432 static const struct Errors miscstrings[] =
434 { 0, "unknown misc.resource error" }
437 static const struct Errors bootstrings[] =
439 { AN_BootError, "boot code returned an error" },
440 { 0, "unknown bootstrap error" }
443 static const struct Errors workbenchstrings[] =
445 { AN_NoFonts, "no fonts for workbench" },
446 { AN_WBBadStartupMsg1, "bad startup message 1 for workbench" },
447 { AN_WBBadStartupMsg2, "bad startup message 2 for workbench" },
448 { AN_WBBadIOMsg, "bad IO message for workbench" },
449 { AN_WBReLayoutToolMenu, "error with layout on tools menu" },
450 { 0, "unknown workbench error" }
453 static const struct Errors diskcopystrings[] =
455 {0, "unknown diskcopy error" }
458 static const struct Errors gadtoolsstrings[] =
460 {0, "unknown gadtools.library error" }
463 static const struct Errors arosstrings[] =
465 {0, "unknown aros.library error" }
468 static const struct Errors oopstrings[] =
470 {0, "unknown oop.library error" }
473 static const struct Errors hiddstrings[] =
475 {0, "unknown Hidd system error" }
478 static const struct Errors *const stringlist[] =
480 /* 0x00 */
481 unknownstrings,
482 execstrings,
483 gfxstrings,
484 layersstrings,
485 intuistrings,
486 mathstrings,
487 unknownstrings,
488 dosstrings,
489 ramlibstrings,
490 iconstrings,
491 expanstrings,
492 dfontstrings,
493 utilitystrings,
494 keymapstrings,
495 unknownstrings,
496 unknownstrings,
498 /* 0x10 */
499 audiostrings,
500 consolestrings,
501 gameportstrings,
502 keyboardstrings,
503 trackdiskstrings,
504 timerstrings,
505 unknownstrings,
506 unknownstrings,
507 unknownstrings,
508 unknownstrings,
509 unknownstrings,
510 unknownstrings,
511 unknownstrings,
512 unknownstrings,
513 unknownstrings,
514 unknownstrings,
516 /* 0x20 */
517 ciastrings,
518 diskstrings,
519 miscstrings,
520 unknownstrings,
521 unknownstrings,
522 unknownstrings,
523 unknownstrings,
524 unknownstrings,
525 unknownstrings,
526 unknownstrings,
527 unknownstrings,
528 unknownstrings,
529 unknownstrings,
530 unknownstrings,
531 unknownstrings,
532 unknownstrings,
534 /* 0x30 */
535 bootstrings,
536 workbenchstrings,
537 diskcopystrings,
538 gadtoolsstrings,
539 unknownstrings,
540 unknownstrings,
541 unknownstrings,
542 unknownstrings,
543 unknownstrings,
544 unknownstrings,
545 unknownstrings,
546 unknownstrings,
547 unknownstrings,
548 unknownstrings,
549 unknownstrings,
550 unknownstrings,
552 /* 0x40 */
553 arosstrings,
554 oopstrings,
555 hiddstrings
558 /* Decode the alert number, and try and work out what string to get */
559 STRPTR getGuruString(ULONG alertnum, STRPTR buf)
561 /* Is this a CPU alert? */
562 if((alertnum & 0x7f008000) == 0)
564 /* Yes */
565 buf = getString(buf, alertnum, cpustrings);
567 /* Is this a General alert */
568 else if((alertnum & 0x8000) == 0x8000)
570 UBYTE type = (alertnum & 0x00FF0000) >> 16;
571 UWORD obj = (alertnum & 0x7fff);
572 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
574 buf = getString(buf, obj, subsystems);
575 buf = getString(&buf[-1], type, types);
576 buf = getString(&buf[-1], subsys, subsystems);
578 /* This must be a specific alert */
579 else
581 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
583 if(subsys < 0x80)
584 buf = getString(buf, alertnum, stringlist[subsys]);
585 else
586 buf = mystrcpy(buf, "unknown error", -1);
589 return buf;
592 static const char Alerthook_end = 1;