Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uwm.edu!uakari.primate.wisc.edu!nic.MR.NET!shamash!pwp From: pwp@shamash.cdc.com ( HOUFAC) Newsgroups: comp.sys.mac.programmer Subject: Re: Patching a trap question Summary: Here's a little Pascal code. Message-ID: <14108@shamash.cdc.com> Date: 27 Sep 89 03:55:22 GMT References: <6582@hubcap.clemson.edu> Reply-To: pwp@shamash.UUCP (Pete Poorman) Organization: Control Data Corp., Houston, Texas Lines: 68 In article <6582@hubcap.clemson.edu> mikeoro@hubcap.clemson.edu (Michael K O'Rourke) writes: >how can i get it to jump to my routine first and then let my routine decide >whether or not to pass the event or whatever on to the old routine that was >originally pointed to by the trap? Now please keep in mind that i know >absolutely no assembly language. Is it possible to do this in C or Pascal? >The responses that i got last time said that assembly was the only way. I haven't used this technique in an actual trap patch, but it ought to work for any stack-based trap. It lets you call the routine that is pointed to by a procPtr. The trick is to define a procedure with the same calling sequence as the trap, but with one additional parameter. This parameter is of type procPtr. The body of the procedure consists of inline code to pop this last parameter from the stack and "JSR" to it. In your patch code, you'd simply pass all the parameters to this routine, with the address of the original trap code as the final parameter. Of course, this may cause trouble for traps that are already patched. (See Scott Knaster's book, "How to Write Macintosh Software", appendix B, for details of the problem.) For that case, you're probably better off with Murat Konar's technique of cleaning up the stack and "JMP"ing to the original address. Sample code follows. --Pete Poorman pwp@shamash.cdc.com -------------------------------------------------------------- program testcall; uses AddOneUnit; var i: INTEGER; AddOnePtr: procPtr; procedure callAddOne (var i: integer; addr: procPtr); inline $205F, { MOVE.L (SP)+,A0 } $4E90; { JSR (A0) } begin writeln('In main program...'); i := 0; CallAddOne(I, @AddOne); if i = 1 then WriteLn('It Worked!') else writeln('It failed, how sad...'); end. -------------------------------------------------------------- unit AddOneUnit; interface procedure AddOne (var i: integer); implementation procedure AddOne (var i: integer); begin writeln('Hi there from AddOne!'); i := i + 1; end; end.