imp@crayview.msi.umn.edu (Chuck Lukaszewski) (12/31/88)
A couple of people have asked what technique they ought to use to install procedures that are retained across application launches. The two most common methods are to put the code into the system heap, or to put it in high memory above BufPtr. Both approaches are (currently) sanctioned by Apple. The choice you make depends on three attributes of you code: function, lifetime and size. #1 Function: I haven't checked to see if Tim Maroney is right about retrace tasks having to be in the system heap, but it sounds reasonable. This would be a good example of where the function of the code limits location. I have written a lot of routines that sit above BufPtr and never had difficulties. If there are other functions that must be in the system heap, perhaps others could comment... #2 Lifetime: Space allocated by moving BufPtr is gone *permanently*. This is primarily because you can never guarantee that your installation procedure will be the last one to move BufPtr, therefore precluding any reconstruction of the memory setup. By contrast, the system heap is designed to be changed and reconfigured. I think that if your code is always supposed to be present and #1 doesn't affect you, then put it above BufPtr and let other people use the System Heap. #3 Size: If you still can't make up your mind, take a look at what percentage of the system heap your procedure will occupy. Remember that not everyone is running the same system version and that you may have less heap to work with than under 6.0.2. At the risk of starting a war of opinion, I would say that any routine using more than 5% of the system heap better get put in high memory if #1 doesn't preclude it. And 5% of the smallest system heap in the last several system releases is a LOT of instructions... As long as we're on the topic, I have two interesting comments about BufPtr. First, if you're going to do a Macintosh emulator, it is best to write your startup code in such a way that the block of code comprising the emulator looks like a BIG init that gets installed above BufPtr. This is how MacWorks Plus installs itself. Using this solution is desirable because otherwise you have to put the emulator code outside of the 'range' of memory that is the 'Macintosh'. And, because of nonstandard environment checks (see my earlier tirades) you always have to worry that some application is going to come along and fiddle with your bits. Why hide the emulator somewhere else when Apple already has a straightforward way to install permanent code on startup? Second, it is possible to move BufPtr below the halfway point in memory, even though IM says not to. Let's say you're approach to writing a RAM disk gets its memory on startup from BufPtr, and the selected disk size requires that BufPtr be cut by more than 50%. There are three reasons this is a problem: 1. StackTop is set to MemTop/2 during startup 2. Boot blocks are loaded at MemTop/2 3. The stack will obviously have to be moved, and so LINKED frames won't come back to the right place. I have a little piece of code that solves these problems. Here's the logic: 1. How much RAM do I need? If it won't put me below MemTop/2, just move BufPtr and go on. ELSE 2. Move BufPtr anyway. Subtract $500 for bootblocks and AND with $FFFFFF000 to get new StackTop. 3. Copy bootblocks to above new StackTop. 4. Copy stack to below new StackTop. 5. Set A7 to (New StackTop - (MemTop / 2 - Old A7)) 6. Set A6 to New StackTop 7. Then I do these instructions (written for System Software 5.3 so I don't know if its current anymore though the ROM should handle boot anyway): MOVE.L D2,A6 ;Step 6 above SUBA.L #$408,A6 MOVE.L D2,(A6) ;Fix first stack frame MOVE.L A6,$40(SP) ;Fix second stack frame MOVE.L A6,$B8(SP) ;Fix third stack frame 8. Continue with life Hope that's helpful to somebody. ______________________________________________________________________________ Chuck Lukaszewski imp@crayview.msi.umn.edu 612 789 0931