The buffer manager acts as a global buffer managing system, providing a set of calls for setting up a buffer, inserting and removing data from a buffer, and removing a buffer. The buffer manager extends the InsV, RemV and CnpV vector calls to provide access to these buffers and to allow block transfers.
The buffer manager is not available in RISC OS 2.
The buffer manager is used by DeviceFS to provide buffers for the various devices that can be accessed. A device may be linked to a buffer, and may supply routines to be called when data enters the buffer as well as a routine to be called when a buffer is removed (or a new device is attached).
When registering or creating a buffer you can force a specific buffer handle, or request that the buffer manager assign a unique handle. You should note that buffer handles are no longer stored as eight bit quantities.
Block transfers are signalled by setting bit 31 of the buffer handle. Anything you can do on a byte by byte basis you can also do to a block, such as examining the buffer contents.
A number of vectors, events, service calls and UpCalls have been extended or created to enable the buffer manager to function efficiently.
See also the chapter entitled Buffers.
The SWIs for the buffer manager module allow you to modify the actual buffer itself, but do not supply a way of inserting and removing data from these buffers. Extensions have been made to the following vectors to handle the inserting and removing of data from the buffers, and to allow block inserts. For more details of these vector calls see the chapter entitled Software vectors.
Because of the above changes to vectors, the following events have been extended so they can indicate that a block transfer occurred. For more details of these events see the chapter entitled Events.
The service call Service_BufferStarting has been added to allow modules which wish to register buffers with the buffer manager to do so.
UpCalls are used by the buffer manager to communicate with buffer owners. For more details of these UpCalls see the chapter entitled Communications within RISC OS.
| R1 | = | &6F (reason code) |
| R0-11 | preserved | |
This call is passed around modules after the buffer manager has been initialised or reset. Once modules have received this service call they can then register buffers with the buffer manager, and use the Buffer_... SWIs.
| R0 | = | buffer's flags word:
| |||||||||||||||||
| R1 | = | size of buffer to be created | |||||||||||||||||
| R2 | = | handle to be assigned to buffer (-1 to get buffer manager to generate handle) | |||||||||||||||||
| R0 | = | buffer handle |
This call claims an area of memory from the RMA and registers it as a buffer. If you register a buffer n bytes long, it can hold at most n - 1 bytes.
If R2 = -1 the buffer manager will attempt to find a unique handle; else the buffer manager will assign the specified handle to the buffer, after checking it is unique.
The buffer's flags word is used to indicate what should happen when data is being inserted and removed from the buffer:
| Bit(s) | Meaning | |
|---|---|---|
| 0 | Set if the buffer is not dormant, and its wake up routine (see the section entitled Buffer_WakeUp) has been called. | |
| 1 | Set if Event_OutputEmpty should be generated for this buffer. | |
| 2 | Set if Event_InputFull should be generated for this buffer. | |
| 3 | Set if UpCalls should be issued when this buffer's free space thresholds are crossed. | |
Bit 0 should be clear when calling this SWI. Bits 1 - 3 may have any value. The remaining bits are reserved, and should be clear when calling this SWI.
On exit R0 contains the buffer handle being used.
| R0 | = | handle of buffer to be removed |
| R0 | preserved | |
This call attempts to deregister the given buffer. If it succeeds, then any data held by the buffer will be purged, and any future access to the buffer via InsV, RemV and CnpV will be ignored; it will then attempt to free the memory that was claimed for that buffer.
You should only use this call for buffers created and registered using Buffer_Create. If you used Buffer_Register to register the buffer, you should instead call Buffer_Deregister to deregister it.
| R0 | = | buffer's flags word:
| ||||||||||||||||||||
| R1 | = | pointer to start of memory for buffer | ||||||||||||||||||||
| R2 | = | pointer to byte following end of buffer | ||||||||||||||||||||
| R3 | = | handle to be assigned to buffer (-1 to get buffer manager to generate handle) | ||||||||||||||||||||
| R0 | = | buffer handle |
This call registers an area of memory as a buffer. The routine accepts similar parameters to Buffer_Create, but instead of the call claiming the memory for you, you must already have done so yourself, and merely pass the buffer's start and end. If you register a buffer n bytes long, it can hold at most n - 1 bytes.
You should not put buffers in the application workspace, as this area of memory might be switched out when someone else tries to access the buffer. However, you can do this if your task will be the only one using the buffer, and it will only be accessed while your task is paged in.
If R3 = -1 the buffer manager will attempt to find a unique handle; else the buffer manager will assign the specified handle to the buffer, after checking it is unique.
The buffer's flags word is used to indicate what should happen when data is being inserted and removed from the buffer:
| Bit(s) | Meaning | |
|---|---|---|
| 0 | Set if the buffer is not dormant, and its wake up routine has been called. | |
| 1 | Set if Event_OutputEmpty should be generated for this buffer. | |
| 2 | Set if Event_InputFull should be generated for this buffer. | |
| 3 | Set if UpCalls should be issued when this buffer's free space thresholds are crossed. | |
Bit 0 should be clear when calling this SWI. Bits 1 - 3 may have any value. The remaining bits are reserved, and should be clear when calling this SWI.
On exit R0 contains the buffer handle being used.
| R0 | = | handle of buffer to be deregistered |
| R0 | preserved | |
This call attempts to deregister the given buffer. If it succeeds, then any data held by the buffer will be purged, and any future access to the buffer via InsV, RemV and CnpV will be ignored.
You should only use this call for buffers registered using Buffer_Register. If you used Buffer_Create to create and register the buffer, you should instead call Buffer_Remove to deregister it.
| R0 | = | handle of buffer to be modified |
| R1 | = | EOR mask |
| R2 | = | AND mask |
| R1 | = | old value |
| R2 | = | new value |
This call modifies a buffer's flags word by applying an AND mask, followed by an EOR mask. On exit it returns the old and new values of the flags word.
The new value is worked out as follows:
new = (old AND R2) EOR R1
You should not modify any reserved bits in the flags word when issuing this call (ie bits 4 - 31 should be set in R2 and clear in R1).
| R0 | = | buffer handle |
| R1 | = | pointer to routine to call when data enters the dormant buffer (or 0 for none) |
| R2 | = | pointer to routine to call when owner of buffer is about to change (or 0 if it cannot be changed) |
| R3 | = | private word to be passed to above routines |
| R4 | = | pointer to workspace for above routines |
| R0-4 | preserved | |
This call links a set of routines to the specified buffer.
The processor may be in any mode and interrupt state. The registers are as follows:
The registered routines routines are typically used to wake up devices attached to a previously dormant buffer so they can start processing data that has appeared, and to shutdown a device when another wishes to access its buffer. In particular, DeviceFS uses this mechanism.
R1 contains a pointer to a routine to be called when data enters the buffer and it is currently marked dormant. If this pointer is zero, the buffer manager does not attempt to call a wake up routine for the specified buffer.
R2 contains a pointer to a routine to be called whenever the owner of the buffer is about to change. If this pointer (ie R2) is zero, the buffer manager will always return an error if an attempt is made to change the buffer's owner. Changes of owner occur :
| R0 | = | buffer handle |
| R0 | preserved | |
This call unlinks all routines that were previously linked to the specified buffer by calling Buffer_LinkDevice. No warning is given of this (ie the buffer's change owner routine is not called), and any data that is currently stored within the buffer is purged.
You should only make this call if it was you that initially linked the routines; anyone else calling this SWI could confuse the system.
| R0 | = | buffer handle |
| R0 | = | buffer's flags word |
| R1 | = | pointer to start of buffer in memory |
| R2 | = | pointer to byte following end of buffer |
| R3 | = | offset within buffer of insertion point |
| R4 | = | offset within buffer of removal point |
| R5 | = | remaining free space in buffer |
| R6 | = | number of characters in buffer |
This call returns data about the buffer: its flags word, position in memory, the offsets within the buffer of its insertion and removal points, the amount of free space, and the number of characters in the buffer.
The insertion and removal points wrap around from the end of the buffer to the start, so you should not assume that the insertion point's offset will be greater than that of the removal point. Furthermore, you should not assume that the sum of R5 and R6 (the free space in the buffer and the number of characters in the buffer) will be the same as the size of the buffer.
| R0 | = | buffer handle |
| R1 | = | threshold (0 for none, or -1 to read) |
| R1 | = | previous value |
This call is used to set or read the warning threshold of the buffer. UpCalls are issued if bit 3 of the buffer's flags word is set, and the amount of free space in the buffer crosses this threshold value. For details of the UpCalls see the chapter entitled Communications within RISC OS.
| R0 | = | buffer handle |
| R8 | = | private word (as specified in R3) |
| R12 | = | pointer to workspace for routine (as specified in R4) |
| N | preserved | |
| C | preserved | |
| V | preserved | |
| Z | preserved | |
The 'wake up routine' is called when data enters the buffer and it is currently marked as dormant. Before calling this 'wake up' routine, the buffer manager first sets bit 0 in the buffer's flags word, marking it as no longer dormant. On exit from the wake up routine you must preserve the entire state of the processor: ie the register contents (including the PSR), the mode, and the state of IRQ and FIQ.
| R0 | = | buffer handle |
| R8 | = | private word (as specified in R3) |
| R12 | = | pointer to workspace for routine (as specified in R4) |
| N | preserved | |
| C | preserved | |
| V | set to return an error in R0 | |
| Z | preserved | |
The owner change routine is called :
On return from this 'owner change' routine you can return an error in the usual way (V set, R0 points to an error block) and thus halt the attempt to change the buffer's owner; you'll also - coincidentally - halt whatever caused the attempt. For example, this SWI may sometimes fail because the given buffer may already have an owner that is refusing to detach itself. If you don't return an error you must preserve the entire state of the processor: ie the register contents (including the PSR), the mode, and the state of IRQ and FIQ.
| Maintainer(s): | RISCOS Ltd <developer@riscos.com> | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| History: |
| ||||||||||||
| Disclaimer: |
Copyright © Pace Micro Technolgy plc, 2002. |