holland@mips.csc.ti.com (Fred Hollander) (11/04/88)
I would like to patch the Alert trap and I've been having a hard time finding documentation that spells out the procedure on patches. I understand the basic idea: save the existing trap address, set the trap address to point to your patch, call the old trap, return. What's missing is how to install the patch in the first place. I don't know anything about a PTCH resource. How do I install the code permanently in the System heap? Here's a first pass at trying to update the trap dispatch table. The trap address for SysBeep seems to have changed while in LSC (by re-executing GetTrapAddress), but after exiting, the trap address reverts back to the original address. #define trapSysBeep 0xA9C8 long oldTrapAddress; newBeep (ignore) int ignore; { asm{ move.l oldTrapAddress,A1 jsr (A1) rts } } main () { oldTrapAddress = GetTrapAddress (trapSysBeep); SetTrapAddress (newBeep, trapSysBeep); } If someone could send me an example, preferrably in LSC, I'd sure appreciate it. Thanks, Fred Hollander Computer Science Center Texas Instruments, Inc. holland%ti-csl@csnet-rela The above statements are my own and not representative of Texas Instruments.
bob@eecs.nwu.edu (Bob Hablutzel) (11/05/88)
You don't want to mess with a PTCH resource. Rather, you want to write an INIT file, put it in the system folder, and let the system execute the INIT at startup time. An INIT is basically a resource containing code. It takes no parameters, and the entry point is at the start of the resource. I find it's easiest to write these beasts in Assembler, but there is usually some means of writing them in high level languages. Read the start manager chapter of IM V. I think everything is covered in that chapter. Bob Hablutzel BOB@NUACC.ACNS.NWU.EDU
ech@poseidon.ATT.COM (Edward C Horvath) (11/07/88)
From article <10050042@eecs.nwu.edu>, by bob@eecs.nwu.edu (Bob Hablutzel):
> You don't want to mess with a PTCH resource...
No, he wants to know how to OVERRIDE or REPLACE a system trap, right?
The straight answer is:
- Use GetTrapAddress to get the address of the trap handler.
- Use SetTrapAddress to replace that one with your own.
Note that your own trap handler has to be in a locked-down chunk of code in
order for that to be viable. There are a couple of choices for INIT code:
- allocate a block (NewPtr) in the System heap. Install your code there.
- reduce the value in BufPtr (the effective top of memory) by the size of
the permanent block you want, and put your stuff there. There's no simple
way to release that memory later, so you own it 'til reboot.
=Ned Horvath=
holland@mips.csc.ti.com (Fred Hollander) (11/09/88)
Thanks to those who responded to my request for help. I finally got something to work. Here it is in case anybody else would like to use it. Build a code resource, type INIT, with the System and Locked attributes. There's a bit of a kludge in there because, unless I'm mistaken, the standard header provided by LightSpeed C trashes A0 beyond recovery. I modified the header (in ResEdit) by putting an extra instruction to push registers A0-A2 on the stack. An alternative would be to store the globals' base address and skip the header or write a custom header. Does anyone have the standard header? What else does it do besides put the entry point into A0? Fred Hollander Computer Science Center Texas Instruments, Inc. holland%ti-csl@csnet-rela The above statements are my own and not representative of Texas Instruments. The code below is my own and not representative of Texas Instruments. #include <SetUpA4.h> #define trapSysBeep 0xA9C8 long oldTrapAddress; Handle trapHandle; char installed = false; void main () { /* Manually put this (48E7 00E0) in the header at 0x000C so that it is called before AO is trashed! Change 0x0000 from 600E to 600A to point to this move. (May be easier to write a custom header.) asm{ movem.l A0-A2,-(A7) } */ RememberA0 (); SetUpA4 (); if (installed) { /* Put your stuff here */ asm{ move.l oldTrapAddress,A3 } RestoreA4 (); asm{ movem.l (A7)+,A0-A2 } asm{ jmp (A3) } } else { asm{ move.l A4,A0 _RecoverHandle move.l A0,trapHandle } DetachResource (trapHandle); HLock (trapHandle); oldTrapAddress = GetTrapAddress (trapSysBeep); SetTrapAddress ((long) *trapHandle, trapSysBeep); installed = true; RestoreA4 (); asm{ movem.l (A7)+,A0-A2 } } }