Subject: Re: Where are the handles?? Hmmm....
From: David A Lyons <[email-masked]>
Date: Mon, 23 Aug 1993 20:57:57 GMT
Newsgroups: comp.sys.apple2.programmer

In article <[email-masked]> Bright Software,
[email-masked] writes:
> Is that possible somehow???? I think NiftyList got such a function, and
> SuperConvert, too...how did they do that???

Nifty List looks at $E1/1600 to find the first handle.  (That is,
$E1/1600 points to the first master pointer record.  A handle is the
address of a master pointer record.)

Each master pointer record starts with a pointer to the memory block. 
Then there is a word of attributes.  There are actually 14 more bytes: 
ID word, size (long), previous handle (long), next handle (long) [prev
and next may not be in that order, I didn't look].

The handles are linked together in address order.

The above information is not officially documented anywhere, but certain
utilities (like Nifty List) obviously need it.

Dave Lyons, [email-masked]
Mr Tangent

My opinions are my own, not Apple's.
Path: news.weeg.uiowa.edu!news.uiowa.edu!hobbes.physics.uiowa.edu!math.ohio-state.edu!howland.reston.ans.net!spool.mu.edu!news.clark.edu!netnews.nwnet.net!news.uoregon.edu!cie.uoregon.edu!nparker
From: [email-masked] (Neil Parker)
Newsgroups: comp.sys.apple2.programmer
Subject: Re: Where are the handles?? Hmmm....
Date: 24 Aug 1993 09:48:43 GMT
Organization: The Universal Society for the Prevention of Reality
Lines: 47
Message-ID: <[email-masked]>
References: <[email-masked]>
NNTP-Posting-Host: cie.uoregon.edu

In article <[email-masked]> [email-masked]
(Bright Software) writes:
>I was and am wondering how one can build a complete list of memory blocks. I
>need to know the absolute addresses and the IDs of these blocks (and perhaps
>the handles)...
> 
>Is that possible somehow???? I think NiftyList got such a function, and
>SuperConvert, too...how did they do that???

Yes, it's possible.  It's not documented, but there are enough things that
depend on it (the Memory Peeker CDA, the Memory Mangler CDA, Nifty List,
etc.) that it's not likely to be changed.

The Memory Manager keeps three lists of handles--the Used List (where all
the handles currently in use reside), the Purge List (which is the limbo
where handles go after you call PurgeHandle), and the Free List (where dead
handles go after you kill them with DisposeHandle).

The pointer the first element of the Used List is at $E1/1600 (4 bytes),
the pointer to the Purge List is at $E1/1604, and the pointer to the Free
List is at $E1/1608.  Each list is a doubly-linked list whose elements have
the following structure:

     struct Handle {
          Pointer Addr;        /* Master pointer to block of memory */
          Word Attr;           /* Handle attributes */
          Word ID;             /* UserID of handle's owner */
          long Size;           /* Length (in bytes) of block */
          struct Handle *Prev; /* Pointer to previous handle structure */
          struct Handle *Next; /* Pointer to next handle structure */
     };

The first element of the list has its Prev pointer set to NIL, and the last
element of the list has its Next pointer set to NIL.

The Memory Manager keeps the Used List sorted in order of increasing Addr.
This makes it possible to find unallocated blocks of memory by walking the
Used List and comparing curHandle.Addr+curHandle.Size to
curHandle.Next->Addr...if they don't match, then you've found a "hole"--the
memory from the current handle's Addr+Size to the next handle's Addr is
free.

               - Neil Parker
--
Neil Parker                 No cute ASCII art...no cute quote...no cute
[email-masked]     disclaimer...no deposit, no return...
[email-masked]   (This space intentionally left blank:           )