[comp.sys.mac.programmer] Bufptr vs. System Heap

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