home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!olivea!apple!goofy!mumbo.apple.com!gallant.apple.com!seuss.apple.com!user
- From: absurd@apple.apple.com (Tim Dierks, software saboteur)
- Newsgroups: comp.sys.mac.programmer
- Subject: Re: Need BOOK that explains how to write an INIT
- Message-ID: <absurd-030193145416@seuss.apple.com>
- Date: 4 Jan 93 00:29:13 GMT
- References: <1992Dec21.113758.1944@random.ccs.northeastern.edu>
- Sender: news@gallant.apple.com
- Followup-To: comp.sys.mac.programmer
- Distribution: comp.sys.mac.programmer
- Organization: MacDTS Marauders
- Lines: 109
-
- In article <1992Dec21.113758.1944@random.ccs.northeastern.edu>,
- chuck@ccs.northeastern.edu (Chuck Wells) wrote:
- >
- > I have quite a few Mac programming books, but none that explain the art of
- > INIT writing. Can anyone recommend such a book?
- >
- > Specifically, the init I am currently hoping to write just has to:
- > 1) Modify some files when I restart the computer
- > 2) Modify some files when I shutdown the computer
- > If I can do those things with an INIT, that will keep me happy for now. Later,
- > I'll need to be able to: tell what keys the user is pressing, no matter what
- > application he is in, yet still allow the user to get those keypress events
- > to the applications.
- >
- > Any book recommendations? A while ago, Tim Dierks posted a long message on
- > how to write an INIT, but since I don't know how to patch traps, I was a bit
- > confused. Thanks for any help.
-
- Well, as far as I know, there isn't a book specifically on
- writing INITs, (although I'm currently toying with the idea of writing
- one);
- however, I believe a couple of books may have passing examples on doing it.
- Here's some info you might find helpful on traps and patching them:
-
- A lot (as in virtually all) of the Mac relies on the toolbox and
- operating system, a collection of routines which are used by virtually
- all Mac programs. The code for these routines is shared by all the
- applications on a Mac; it is loaded by the system and made available to
- the routines. The problem is how to link up the code loaded by the
- system with the code in the application so the application can easily
- call the system routines reliably. Because code on the Mac can be loaded
- into any RAM address, and the ROMs on different Macs vary greatly, you
- can't just have a single address for each routine which the application
- can jump to; you need some kind of flexible mechanism to dispatch
- the application's requests to the appropriate system code. This
- mechanism is the a-trap dispatcher.
- The 68000 series of processors use a 16 bit instruction set; any
- processor instruction can be specified in one 16-bit word (which may
- be followed by more data specifying the operands). For convenience
- and simplicity, information about the instruction is encoded into the
- bit pattern of the hex value that specifies it. For example, any
- 68000 instruction which begins with the hex digit $D is some variety
- of an ADD instruction. Some of the binary patterns were reserved
- for later expansion; for example, any instruction intended for the
- floating-point co-processor bgins with the hex digit $F. Similarly,
- any instruction beginning with the hex digit $A is unassigned; if
- the processor encounters one, it stops what it is doing and calls
- a routine to deal with this problem; as far as it is concerned, you've
- just executed an illegal instruction. On the Mac, the routine which
- deals with this problem is the trap dispatcher; it looks at the
- instruction which caused the problem and matches it up with a routine
- in the system software. It then jumps to this routine, which
- returns to the application after it has completed its work.
- Because these instructions begin with the hex digit $A and because
- they act like a trap door, interrupting the program's flow and taking
- it elsewhere, we call these instructions A-traps.
- Let's look at a concrete example. Let's say I'm writing a program
- and I want to call PaintRect; I insert the following line into my
- application:
-
- PaintRect(&myRect);
-
- This results in the compiler placing the following assembly code
- in my program:
-
- Assembly code Machine code
-
- PEA -$0008(A6) 486E FFF8
- _PaintRect A8A2
-
- (Note the hex machine code translation on the left). First, we put the
- address of the rectangle I want to paint on the stack, then we
- have one of these mysterious A-traps. When the processor is bipping
- along and hits this A-trap, it is mystified. Unlike $486E (the PEA
- instruction), there isn't any processor instruction specified by $A8A1;
- the the processor doesn't know how to handle it in hardware, so it
- calls a software routine to deal with it. This software routine is
- the trap dispatcher; it looks at what instruction you're trying to
- execute (in this case $A8A1) and looks in a table it has to find
- the routine that matches up with this trap. In this case, the
- table holds the address $4082C48C, which is where the code for
- _PaintRect sits in the ROM on my machine. The trap dispatcher then
- cleans up the stack and jumps to this routine; the end result is
- that to the system software, it looks like the application called
- it directly in the same way any routine linked in with the application
- would be. When the system code is done, it returns to the code that
- called the A-trap, in this case my application; to the application,
- it all looks just like as if it had called a routine linked in in a
- more traditional manner.
- OK, that covers the basic facts behind the dispatcher. You can
- patch traps by replacing the address of the system supplied routine
- with the address of a routine of your own; the routines
- GetTrapAddress and SetTrapAddress manipulate the trap table.
- Basically, you can then intercept the calls the application makes;
- rather than the system software getting called when the application
- uses an a-trap, you will get control, allowing you to do your own
- nefarious acts. It's your responsibility to pass control on to the
- system software when you're done, so you need to use GetTrapAddress
- to get the address of the trap before you patch it and remember that
- address; when you're done doing your stuff, you can jump to this
- address to allow the system code to do what the application is asking.
-
- Well, I'm getting tired and I want to go home and play pinball, so
- I'm going to leave this there. I've still got the previous post
- I wrote on this, which discusses a specific question and details a
- lot of how to pick which trap to patch; mail me if you want a copy.
-
- Tim Dierks
- MacDTS, but I speak for myself
-