Memory Manager - IIgs Toolbox Ref. Information Index Housekeeping Routines MMBootInit MMStartUp MMShutDown MMVersion MMReset MMStatus Memory Allocation Routines NewHandle ReAllocHandle RestoreHandle DisposeHandle DisposeAll PurgeHandle PurgeAll Block and Free Space Information Routines FindHandle CheckHandle GetHandleSize SetHandleSize CompactMem FreeMem MaxBlock TotalMem RealFreeMem Handle Attribute Routines HLock HLockAll HUnlock HUnlockAll SetPurge SetPurgeAll SetHandleID Out-of-Memory Queue Routines AddToOOMQueue RemoveFromOOMQueue Memory-Copy Routines BlockMove PtrToHand HandToPtr HandToHand Constants Error Codes _________________________________________________________________ $0102 MMBootInit Initializes the Memory Manager; called only by the Tool Locator when the Memory Manager is loaded. Warning An application must never make this call. Parameters There are no input or output parameters. Errors None C You shouldn't call this function. _________________________________________________________________ $0202 MMStartUp Starts up the Memory Manager; you must call this before using any other Memory Manager calls. This function returns your application's master user ID. You can actually call this function any time you need to know your application's user ID, although it would save space and time to call it once and save the value. If your application is running under ProDOS 8 or DOS 3.3 and this call is issued from outside a Memory Manager-managed block of memory, you'll get an error. Use the Miscellaneous Tool Set's GetNewID call to obtain a user ID, then use NewHandle to allocate the memory your application resides in before requesting more memory. Parameters Input: wordspace Word -- Space for result Output: userID Word -- Application's master user ID Errors None C extern pascal Word MMStartUp(void) _________________________________________________________________ $0302 MMShutDown Shuts down the Memory Manager; if you called MMStartUp, you must call this before your program exits. You only need to call this function once (if you used MMStartUp lots of times to get your user ID, you still only call MMShutDown once). You should also dispose of any handles you've allocated before calling this function; even though they'll go away automatically, it's poor programming practice to not do so. Parameters Input: userID Word -- User ID of the application to shut down Errors None C extern pascal void MMShutDown(Word userID) _________________________________________________________________ $0402 MMVersion Returns the version number of the Memory Manager. Parameters Input: wordspace Word -- Space for result Output: versionInfo Word -- Version number of the Memory Manager. Errors None C extern pascal Word MMVersion(void) _________________________________________________________________ $0502 MMReset Resets the Memory Manager. The Tool Locator calls this when the system is reset; you should never issue this call. Warning An application must never make this call. Parameters There are no input or output parameters. Errors $0201 memErr Unable to reset. C You shouldn't call this function. _________________________________________________________________ $0602 MMStatus Indicates whether or not the Memory Manager is active. Parameters Input: wordspace Word -- Space for result Output: status Word -- TRUE if the Memory Manager is active, FALSE if not. Errors None C extern pascal Word MemoryStatus(void) _________________________________________________________________ $0C02 AddToOOMQueue Adds a new entry into the out-of-memory queue. The input pointer should point to the routine's header block. See page 36-2 of the Apple IIgs Toolbox Reference, Volume 3 for more detailed information on how the out-of-memory queue works and how to write an out-of-memory queue function. Parameters Input: headerPtr Long -- Pointer to out-of-memory routine's header Errors $0381 invalidTag Invalid signature in routine header C extern pascal void AddToOOMQueue(Pointer headerPtr) _________________________________________________________________ $2B02 BlockMove Copies the specified number of bytes from a source location to a given destination. This works even if the two memory buffers overlap or cross bank boundaries. Note: BlockMove doesn't verify that the addresses or memory ranges are legal; it just performs the copy. Parameters Input: sourcePtr Long -- Pointer to first byte of source buffer destPtr Long -- Pointer to first byte of destination buffer count Long -- Number of bytes to copy Errors None C extern pascal void BlockMove(Pointer sourcePtr, Pointer destPtr, LongWord count) _________________________________________________________________ $1E02 CheckHandle Checks to see if the given handle is valid; if it's invalid, an error occurs, otherwise, this function returns 0. Parameters Input: theHandle Long -- Handle to verify Errors $0206 handleErr Invalid handle. C extern pascal void CheckHandle(Handle theHandle) _________________________________________________________________ $1F02 CompactMem Compacts memory space. Does nothing during interrupts. Parameters There are no input or output parameters. Errors None C extern pascal void CompactMem(void) _________________________________________________________________ $1102 DisposeAll Discards all the handles and memory blocks belonging to the specified user ID. Your application must discard of all its memory before it calls MMShutDown; however, if you used the unmodified master user ID to allocate your memory, you'll have to do it handle by handle using DisposeHandle, since DisposeAll will also dispose of the memory in which your application is running, which would be very bad. Parameters Input: userID Word -- User ID whose handles will be deallocated Errors $207 idErr Invalid user ID. C extern pascal void DisposeAll(Word userID) _________________________________________________________________ $1002 DisposeHandle Deallocates the specified block and the handle that references it. The block is discarded regardless of its lock status or purge level. Parameters Input: theHandle Long -- Handle to deallocate Errors $206 handleErr Invalid handle. C extern pascal void DisposeHandle(Handle theHandle) _________________________________________________________________ $1A02 FindHandle Returns the handle of the memory block that contains a given address. If the address isn't in any handle, NIL is returned. Keep in mind that if the handle returned isn't locked, it could move later. Parameters Input: longspace Long -- Space for result locationPtr Long -- Pointer whose handle will be returned Output: theHandle Long -- Handle to the block containing locationPtr; NIL if not found Errors None C extern pascal Handle FindHandle(Pointer locationPtr) _________________________________________________________________ $1B02 FreeMem Returns the total number of free bytes of memory in the system, not including memory that could be freed by purging. However, because of memory fragmentation, you may not be able to allocate a block of memory as large as the value returned by this function. To find out the maximum block size that can be allocated, use the MaxBlock function instead. Parameters Input: longspace Long -- Space for result Output: freeSize Long -- Total number of free bytes Errors None C extern pascal LongWord FreeMem(void) _________________________________________________________________ $1802 GetHandleSize Returns the size of the specified memory block in bytes. Parameters Input: longspace Long -- Space for result theHandle Long -- Handle of the block whose size is to be returned Output: blockSize Long -- Size of block in bytes. Errors $0206 handleErr Invalid handle. C extern pascal LongWord GetHandleSize(Handle theHandle) _________________________________________________________________ $2A02 HandToHand Copies the specified number of bytes from a source location to a given destination. This works even if the two memory buffers overlap or cross bank boundaries. Where BlockMove uses pointers to specify the source and destination, HandToHand users handles. Note: HandToHand doesn't verify that the addresses or memory ranges are legal; it just performs the copy. Parameters Input: sourceHandle Long -- Handle of source buffer destHandle Long -- Handle of destination buffer count Long -- Number of bytes to copy Errors $0202 emptyErr Illegal operation on an empty handle. $0206 handleErr Invalid handle. C extern pascal void HandToHand(Handle sourceHandle, Handle destHandle, LongWord count) _________________________________________________________________ $2902 HandToPtr Copies the specified number of bytes from a source location to a given destination. This works even if the two memory buffers overlap or cross bank boundaries. Where BlockMove uses pointers to specify the source and destination, HandToPtr uses a handle to specify the source and a pointer to specify the destination. Note: HandToPtr doesn't verify that the addresses or memory ranges are legal; it just performs the copy. Parameters Input: sourceHandle Long -- Handle of source buffer destPtr Long -- Pointer to the first byte of the destination buffer count Long -- Number of bytes to copy Errors $0202 emptyErr Illegal operation on an empty handle. $0206 handleErr Invalid handle. C extern pascal void HandToPtr(Handle sourceHandle, Pointer destPtr, LongWord count) _________________________________________________________________ $2002 HLock Locks the specified handle so that it won't be moved or purged. To lock a block quickly from assembly language, use the following Apple-approved method: lda #$0004 lda [theHandle],y ora #AttrLocked sta [theHandle],y Parameters Input: theHandle Long -- Handle to lock Errors $0206 handleErr Invalid handle. C extern pascal void HLock(Handle theHandle) _________________________________________________________________ $2102 HLockAll Locks all the memory blocks owned by a specified user ID. Locked blocks won't be moved or purged during compaction. Parameters Input: userID Word -- User ID whose handles will be locked Errors $0207 idErr Invalid user ID. C extern pascal void HLockAll(Word userID) _________________________________________________________________ $2202 HUnlock Unlocks the specified handle so that it can be moved or purged. To unlock a block quickly from assembly language, use the following Apple-approved method: lda #$0004 lda [theHandle],y and #$7FFF sta [theHandle],y Parameters Input: theHandle Long -- Handle to unlock Errors $0206 handleErr Invalid handle. C extern pascal void HUnlock(Handle theHandle) _________________________________________________________________ $2302 HUnlockAll Unlocks all the memory blocks owned by a specified user ID. Unlocked blocks can be moved or purged during compaction. Parameters Input: userID Word -- User ID whose handles will be unlocked Errors $0207 idErr Invalid user ID. C extern pascal void HUnlockAll(Word userID) _________________________________________________________________ $1C02 MaxBlock Returns the size of the largest contiguous block of memory, not counting memory that can be freed by purging or compacting. Parameters Input: longspace Long -- Space for result Output: blockSize Long -- Size in bytes of the largest block of free memory Errors None C extern pascal LongWord MaxBlock(void) _________________________________________________________________ $0902 NewHandle Creates a new block of memory and returns the handle to the new block. The userID parameter is used to mark the owner of the block. The ID can be specified as any of the following: * A new ID obtained by modifying the audID field of the master user ID. * The master user ID returned by the MMStartUp call. * A new ID created by calling the GetNewID call in the Miscellaneous Tool Set. See page 12-10 of the Apple IIgs Toolbox Reference, Volume 1 for more information on user IDs. This information will be available online soon. The block's location and attributes are determined by the attributes parameter, as described below. locationPtr is used to specify the starting address of the block in memory if and only if the attributes specify a fixed address or bank; otherwise, this parameter is ignored. If you create a 0-byte block, the handle returned is empty. Parameters Input: longspace Long -- Space for result blockSize Long -- Size of block to create in bytes userID Word -- User ID to assign to the block attributes Word -- User Atribute flags (see below) locationPtr Long -- Pointer to first byte of block to allocate Output: theHandle Long -- Handle of new block Errors $0201 memErr Unable to allocate block. $0204 lockErr Illegal operation on a locked or immovable block. $0207 idErr Invalid user ID. C extern pascal Handle NewHandle(LongWord blockSize, Word userID, Word attributes, Pointer locationPtr) attributes bit 15: attrLocked 1 = Block is temporarily locked down and can't be moved or purged; 0 = Block may be moved or purged bit 14: attrFixed 1 = Block is permanently fixed-location; 0 = Block may move while unlocked bits 13-10: Reserved; set to 0. bits 9-8: attrPurge 11 = Purge level 3 10 = Purge level 2 01 = Purge level 1 00 = don't purge bits 7-5: Reserved; set to 0. bit 4: attrNoCross 1 = May not cross bank boundaries; 0 = May cross bank boundaries bit 3: attrNoSpec 1 = May not use special memory; 0 = May use special memory bit 2: attrPage 1 = Block must be page aligned; 0 = Doesn't have to be page aligned bit 1: attrAddr 1 = Block must stay at fixed address; 0 = Doesn't have to stay at fixed address bit 0: attrBank 1 = Block must stay in fixed bank; 0 = Doesn't have to stay in fixed bank Curious about the difference between attrFixed and attrAddr? The attrFixed attribute means that the block must stay at its initial position in memory permanently. The attrAddr attribute is more restrictive: it means that not only must the block remain at a fixed address, but it must remain at the address specified by locationPtr. _________________________________________________________________ $2802 PtrToHand Copies the specified number of bytes from a source location to a given destination. This works even if the two memory buffers overlap or cross bank boundaries. Where BlockMove uses pointers to specify the source and destination, PtrToHand uses a handle to specify the source and a pointer to specify the destination. Note: PtrToHand doesn't verify that the addresses or memory ranges are legal; it just performs the copy. Parameters Input: sourcePtr Long -- Pointer to the first byte of the source buffer destHandle Long -- Handle to the destination buffer count Long -- Number of bytes to copy Errors $0202 emptyErr Illegal operation on an empty handle. $0206 handleErr Invalid handle. C extern pascal void PtrToHand(Pointer sourcePtr, Handle destHandle, LongWord count) _________________________________________________________________ $1302 PurgeAll Purges all the unlocked, purgeable blocks for the given user ID. You'll get an error if there were any unpurgeable (and/or locked) blocks with the specified user ID, but all the purgeable blocks will have been purged. Parameters Input: userID Word -- User ID whose blocks will be purged Errors $0204 lockErr Illegal operation on a locked or fixed block. $0205 purgeErr Can't purge an unpurgeable block. $0207 idErr Invalid user ID. C extern pascal void PurgeAll(Word userID) _________________________________________________________________ $1202 PurgeHandle Purges the specified handle if it is both purgeable and unlocked. The handle still exists after this call, but is empty. Parameters Input: theHandle Long -- Handle whose block is to be purged Errors $0204 lockErr Illegal operation on a locked or fixed block. $0205 purgeErr Can't purge an unpurgeable block. $0206 handleErr Invalid handle. C extern pascal void PurgeHandle(Handle theHandle) _________________________________________________________________ $2F02 RealFreeMem Returns the number of bytes in memory that would be free after purging all purgeable blocks. This is a more accurate means of determining how much memory is free than the FreeMem call. To determine the size of the largest block you can allocate (without purging or compacting memory), use the MaxBlock call. There is no built-in mechanism for determining the maximum block available if purging and compacting were done; you'll have to actually call CompactMem before calling MaxBlock. Parameters Input: longspace Long -- Space for result Output: freeSize Long -- Number of free bytes in memory Errors None C extern pascal LongWord RealFreeMem(void) _________________________________________________________________ $0A02 ReAllocHandle Reallocates a purged block using new attributes. The userID parameter is used to mark the owner of the block. The ID can be specified as any of the following: * A new ID obtained by modifying the audID field of the master user ID. * The master user ID returned by the MMStartUp call. * A new ID created by calling the GetNewID call in the Miscellaneous Tool Set. See page 12-10 of the Apple IIgs Toolbox Reference, Volume 1 for more information on user IDs. This information will be available online soon. See NewHandle for information on the attributes argument. The block's location and attributes are determined by the attributes parameter, as described below. locationPtr is used to specify the starting address of the block in memory if and only if the attributes specify a fixed address or bank; otherwise, this parameter is ignored. If you create a 0-byte block, the handle returned is empty. Parameters Input: blockSize Long -- Size of block to create in bytes userID Word -- User ID to assign to the block attributes Word -- User Atribute flags (see below) locationPtr Long -- Pointer to first byte of block to allocate theHandle Long -- Handle to reallocate Errors $0201 memErr Unable to allocate block. $0203 notEmptyErr Can't reallocate a non-empty handle. $0204 lockErr Illegal operation on a locked or immovable block. $0206 handleErr Invalid handle. $0207 idErr Invalid user ID. C extern pascal void ReAllocHandle(LongWord blockSize, Word userID, Word attributes, Pointer locationPtr, Handle theHandle) _________________________________________________________________ $0D02 RemoveFromOOMQueue Removes the specified out-of-memory routine from the out-of-memory queue. Parameters Input: headerPtr Long -- Pointer to out-of-memory routine's header Errors $0380 notInList The routine isn't in the queue. $0381 invalidTag Invalid signature in routine header C extern pascal void RemoveFromOOMQueue(Pointer headerPtr) _________________________________________________________________ $0B02 RestoreHandle Reallocates a purged block with the same attributes, size, and user ID it had before it was purged. The block can't have had either the fixed address or fixed bank attributes. The data that was in the handle is gone forever, though.afk Parameters Input: theHandle Long -- Handle to be reallocated Errors $0201 memErr Unable to allocate block. $0203 notEmptyErr Can't reallocate a non-empty handle. $0206 handleErr Invalid handle. $0208 attrErr Can't reallocate handles with the fixed address or fixed bank attributes. C extern pascal void RestoreHandle(Handle theHandle) _________________________________________________________________ $3002 SetHandleID Allows you to determine (and change, if you want to) the user ID of a specific handle. To determine the user ID of a handle without changing anything, pass the value $0000 for the newID parameter. The previous ID is returned without altering the existing user ID. This function is especially useful for cases in which you need to keep a chunk of memory (such as a code resource) in memory after the main body of your program has gone away. A temporary init or control panel might use this, for instance. Use GetNewID to create a new user ID, then call SetHandleID on the block that needs to stay around to change it to an ID that the System Loader won't unload when your init or control panel is shut down. System 6.0 Parameters Input: wordspace Word -- Space for result newID Word -- New ID to assign the handle (0 if you don't want to change it) theHandle Long -- Handle whose ID is toe set and/or returned Input: oldID Word -- The previous user ID of the handle Errors None C extern pascal Word SetHandleID(Word newID, Handle theHandle) _________________________________________________________________ $1902 SetHandleSize Sets the size of the specified handle to a new size, which can be either larger or smaller than the original size. If there's not enough room for the new size (if the block is being made larger), the Memory Manager may compact memory and/or purge blocks of memory. Before calling SetHandleSize, you should unlock the block so it can be moved if necessary to satisfy the request (see HUnlock). If you specify a new size of 0 bytes, the handle becomes empty. Parameters Input: newSize Long -- New size of the block in bytes theHandle Long -- Handle of the block to be resized Errors $0201 memErr Unable to allocate block. $0202 emptyErr Can't resize an empty block. $0204 lockErr Illegal operation on a locked or immovable block. $0206 handleErr Invalid handle. C extern pascal void SetHandleSize(LongWord newSize, Handle theHandle) _________________________________________________________________ $2402 SetPurge Changes the purge level of the specified memory block. The purge level occupies two bits of the block's attributes flags, and determines the purging priority for the block. Possible values for the purge flags are: 3 Most purgeable (only the System Loader can use this value) 2 Next most purgeable 1 Least purgeable (but still purgeable) 0 Not purgeable Parameters Input: newPurgeLevel Word -- New purge level (use bits 0 and 1 only; all others must be 0) theHandle Long -- Handle of the block whose purge level is to change Errors $0206 handleErr Invalid handle. C extern pascal void SetPurge(Word newPurgeLevel, Handle theHandle) _________________________________________________________________ $2502 SetPurgeAll Changes the purge level for all memory blocks with the specified user ID. The purge level occupies two bits of the block's attributes flags, and determines the purging priority for the block. Possible values for the purge flags are: 3 Most purgeable (only the System Loader can use this value) 2 Next most purgeable 1 Least purgeable (but still purgeable) 0 Not purgeable Parameters Input: newPurgeLevel Word -- New purge level (use bits 0 and 1 only; all others must be 0) userID Word -- User ID of the blocks whose purge level is to change Errors $0207 idErr Invalid user ID. C extern pascal void SetPurgeAll(Word newPurgeLevel, Word userID) _________________________________________________________________ $1D02 TotalMem Returns the total amount of memory, in bytes, in the currently-running Apple IIgs. Parameters Input: longspace Long -- Space for result Output: totalSize Long -- Size in bytes of all of memory Errors None C extern pascal LongWord TotalMem(void) _________________________________________________________________ Memory Manager Constants Name Value Description Attribute bits attrNoPurge $0000 Not purgeable. attrBank $0001 Fixed bank. attrAddr $0002 Fixed address. attrPage $0004 Page-aligned. attrNoSpec $0008 May not use special memory. attrNoCross $0010 May not cross bank boundaries. attrPurge1 $0100 Purge level 1. attrPurge2 $0200 Purge level 2. attrPurge3 $0300 Purge level 3. attrPurge $0300 Test or set both purge bits. attrHandle $1000 Block of handles (Memory Manager only) attrSystem $2000 System handle (Memory Manager only) attrFixed $4000 Block fixed in memory. attrLocked $8000 Block locked in memory. Memory Manager Error Codes Code Name Description $0201 memErr Unable to allocate block. $0202 emptyErr Illegal operation on an empty handle. $0203 notEmptyErr Illegal operation on a non-empty handle. $0204 lockErr Illegal operation on a locked or fixed block. $0205 purgeErr Can't purge an unpurgeable block. $0206 handleErr Invalid handle. $0207 idErr Invalid user ID. $0208 attrErr Illegal operation with the given attributes. ______________________________________________________________________ This text file is freely available public domain information. As such...It may be duplicated or reprinted, in whole or in part, without the express written permission of anybody.