2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Alert.Hook for AROS
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>
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. */
45 const struct Resident Alerthook_resident
__attribute__((section(".text"))) =
48 (struct Resident
*)&Alerthook_resident
,
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
))
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).
85 mystrcpy(STRPTR dest
, STRPTR src
, LONG len
)
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
108 ULONG
*location_zero
= (void *)0;
113 if(SysBase
->LastAlert
[0] != -1)
115 struct IntuitionBase
*IntuitionBase
;
117 UBYTE buffer
[256], *buf
, *tname
;
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);
127 buf
= mystrcpy(buf
, recov
, -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];
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
;
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 */
152 RawDoFmt(errstring
, &SysBase
->LastAlert
[0], (void *)putChProc
, &buf
);
154 buf
= getGuruString(SysBase
->LastAlert
[0], &buf
[-1]);
157 /* This rather strange contraption will centre the string. */
158 *((UBYTE
*)tname
) = (82 - (buf
- tname
)) << 2;
160 IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",0);
164 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
165 TimedDisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38, 500);
167 DisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38);
169 CloseLibrary((struct Library
*)IntuitionBase
);
172 SysBase
->LastAlert
[0] = -1;
175 SysBase
->LastAlert
[0] = old
;
176 SysBase
->LastAlert
[1] = 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
))
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 " },
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 " },
240 /* This takes in 0x35 as well... */
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
[] =
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)
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 */
581 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
584 buf
= getString(buf
, alertnum
, stringlist
[subsys
]);
586 buf
= mystrcpy(buf
, "unknown error", -1);
592 static const char Alerthook_end
= 1;