<<< Back Home >>>

BFACQ$ / BFRLS$ 2R1B -- Buffer Acquire & Release Package


The purpose of BFACQ$/BFRLS$ is to provide a simple, yet controlled means of managing user storage. Each element is a small (120 wds/70 wds), reentrant assembly language routine, using only registers X11, A0, and A1. For more extensive storage management, refer to STACK$ (which uses BFACQ$).

BFACQ$ handles the allocation of new buffers and, if necessary, the expansion of user memory. BFRLS$ processes the releasing of buffers back to the storage pool and storage back to the system. (The two elements are separate because a simple program might conceivably need only to acquire storage during its existence and thus not need BFRLS$.)

To acquire a buffer:

         LA,U      A0,packet-address
   Or:   LA        A0,(bdi,packet-address)    . buffer BDI on initial call
         LA,U      A1,buffer-length-desired   . [maximum = 131070]
         LMJ       X11,BFACQ$
                   (error return)
                   (normal return)

Load the length negative to have the buffer zeroed.

On a normal return, A1 will contain the address of the user's buffer. On an error return, A0 will contain one of the following status codes:

1 - Storage overflow

2 - Zero or invalid length requested

3 - Corrupted link encountered (address in upper half of A1. Tentative user buffer address in lower half)

07X - TCS error when releasing packet. When this occurs, 070 is added to what would have been the status code; so X is either 0, if the return would otherwise have been normal, or one of the other error codes.

To release a buffer:

         LA,U      A0,packet-address
         LA,U      A1,buffer-address . (Must have been previously acquired
                                       through BFACQ$ and the same control
                                       packet)
         LMJ       X11,BFRLS$
                   (error return)
                   (normal return)

On an error return, A0 will contain the status code:

4 - Release address out of bounds

5 - Corrupted link encountered (same as BFACQ$ error 3)

07X - TCS error when releasing packet (same as for BFACQ$).

After releasing a buffer, BFRLS$ will check the links before and after it and, if possible, combine it with the preceding or following buffer. Whenever BFACQ$ cannot satisfy a request from the highest available buffer, it will search back through any released buffers before trying to acquire more storage.

A third element and entry point, BFACQ$BIG, are provided to allow for requests of buffers larger than 131070. The call is the same as for BFACQ$, except that there is no option for zeroing the buffer. Furthermore, once acquired, this size buffer cannot be released using BFRLS$; it must exist for the life of the program. The call to BFACQ$BIG is not reentrant, as it saves and restores registers in its own dbank packet.

The two-word packet whose address is supplied in A0 initially has the following format, although it is later updated by the routines:

      |-----------------------------------------------------|
   -1 |          [Optional T$CELL word]                     |
      |-----------------------------------------------------|
    0 |  (TS)  | SPBITS | BFPMIN |       BFPLTH/A2MOD       |
      |-----------------------------------------------------|
    1 |         (BFCURR)         |          BFSTRT          |
      |-----------------------------------------------------|

where: 

0,,S1  - TS cell. If set to 040, making word negative, BFACQ$ will not use standard TS locking, but will instead expect a T$CELL word to be defined before word 0 of the packet, for use in test-and-set queuing (TS/C$TS). TSQRG$ registration, if needed, must be done by the caller.

SPBITS - Special flag bits:

Bit 0 - If set, round up all buffer request lengths to one less than the next power of 2.

BFPMIN - The minimum number of 64-word blocks to remain in reserve in the highest available buffer after satisfying a request through MCORE$. If 0, BFACQ$ will assume it only has a fixed amount of storage to work with, will do no MCORE$'s, and could get a storage overflow error if it exhausts the original storage pool.

BFPLTH - The initial length of the storage pool being managed (may be 0). Maximum = 131070. This cell is later used to save A2's modifier.

BFCURR - Must initially be 0. Will always hold the address of the current highest available buffer.

BFSTRT - Address of the storage pool to be managed by this control packet. If BFPMIN is non-zero, BFSTRT must be at the high end of the bank in which it resides; and may be expanded up to 262K. If the user program is banked, BFSTRT's bank must already be based when calling BFACQ$/BFRLS$. If the program's structure is other than a simple IBANK/DBANK, you may need to include the storage pool's BDI in H1 of A0. It is only needed for the initial call to BFACQ$.

The links and pointer words maintained by BFACQ$/BFRLS$ look like this, given a storage pool starting at address A and having its current highest buffer (BFCURR) at address D:

           |-------------------------------|
        A. |       0       | Length+1 of A |
           |-------------------------------|
           |          ( Buffer )           |
           |-------------------------------|
        B. |       A       | Length+1 of B |
           |-------------------------------|
           |          ( Buffer )           |
           |-------------------------------|
        C. |       B       | Length+1 of C |
           |-------------------------------|
           |          ( Buffer )           |
           |-------------------------------|
        D. |       C       |  BFPMIN*64+?  |
  [BFCURR] |-------------------------------|
           |          ( Buffer )           |
           |-------------------------------|

When a buffer is in use, its length is set negative. Note that the buffer length kept in a link word will be one greater than the user's request, so it can point to the next link word.