RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

The Buffer Manager


Introduction and Overview

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.

Vectors

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.

  • InsV - inserts a byte in a buffer
  • RemV - removes a byte from a buffer
  • CnpV - counts the number of entries or spaces in a buffer, or purges the contents of a buffer
Events

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.

  • Event_OutputEmpty - issued when the last character is removed from a buffer
  • Event_InputFull - generated when a character or block is inserted and it failed
Service calls

The service call Service_BufferStarting has been added to allow modules which wish to register buffers with the buffer manager to do so. For more details of this service call see Service_BufferStarting (Service Call &6F).

UpCalls

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.

  • OS_UpCall 8 - issued when data is inserted into the buffer causing the free space to fall below the specified threshold
  • OS_UpCall 9 - issued when the free space in the buffer becomes greater than the current threshold.

Service Calls


Service_BufferStarting
(Service Call &6F)

Notifies modules that the buffer manager is starting

On entry

R1 = &6F (reason code)

On exit

All registers preserved

Use

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.

SWI calls


Buffer_Create
(SWI &42940)

Claims an area of memory from the RMA and registers it as a buffer

On entry

R0 = buffer's flags word:

bit 0: 0 => buffer is dormant, and wake up routine should be called when data enters it
bit 1: 1 => Event_OutputEmpty should be generated for this buffer
bit 2: 1 => Event_InputFull should be generated for this buffer
bit 3: 1 => UpCalls should be issued when this buffer's free space threshold is crossed
bits 4 - 31 reserved (should be set to 0 on creation)
R1 = size of buffer to be created
R2 = handle to be assigned to buffer (-1 => get buffer manager to generate handle)

On exit

R0 = buffer handle

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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 0 is set if the buffer is not dormant, and its wake up routine (see the chapter entitled The wake up routine) has been called.
Bit 1 is set if Event_OutputEmpty should be generated for this buffer.
Bit 2 is set if Event_InputFull should be generated for this buffer.
Bit 3 is 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.

Related SWIs

Buffer_Remove, Buffer_Register, Buffer_LinkDevice

Related vectors

None


Buffer_Remove
(SWI &42941)

Deregisters a buffer and frees its memory

On entry

R0 = handle of buffer to be removed

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

Buffer_Create, Buffer_Deregister, Buffer_LinkDevice

Related vectors

None


Buffer_Register
(SWI &42942)

Registers an area of memory as a buffer

On entry

R0 = buffer's flags word:

bit 0: 0 => buffer is dormant, and wake up routine should be called when data enters it
bit 1: 1 => Event_OutputEmpty should be generated for this buffer
bit 2: 1 => Event_InputFull should be generated for this buffer
bit 3: 1 => UpCalls should be issued when this buffer's free space threshold is crossed
bits 4 - 31 reserved (should be set to 0 on registration)
R1 = pointer to start of memory for buffer
R2 = pointer to byte following end of buffer
R3 = handle to be assigned to buffer (-1 => get buffer manager to generate handle)

On exit

R0 = buffer handle

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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 0 is set if the buffer is not dormant, and its wake up routine (see the chapter entitled The wake up routine) has been called.
Bit 1 is set if Event_OutputEmpty should be generated for this buffer.
Bit 2 is set if Event_InputFull should be generated for this buffer.
Bit 3 is 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.

Related SWIs

Buffer_Create, Buffer_Deregister, Buffer_LinkDevice

Related vectors

None


Buffer_Deregister
(SWI &42943)

Deregisters a buffer

On entry

R0 = handle of buffer to be deregistered

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

Buffer_Remove, Buffer_Register, Buffer_LinkDevice

Related vectors

None


Buffer_ModifyFlags
(SWI &42944)

Modifies a buffer's flags word

On entry

R0 = handle of buffer to be modified
R1 = EOR mask
R2 = AND mask

On exit

R1 = old value
R2 = new value

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call modifies a buffer's flags word (see earlier) 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).

Related SWIs

Buffer_LinkDevice

Related vectors

None


Buffer_LinkDevice
(SWI &42945)

Links a set of routines to the specified buffer

On entry

R0 = buffer handle
R1 = pointer to routine to call when data enters the dormant buffer (0 => none)
R2 = pointer to routine to call when owner of buffer is to change (0 => cannot be changed)
R3 = private word to be passed to above routines
R4 = pointer to workspace for above routines

On exit

R0 - R4 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call links a set of routines to the specified buffer.

The routines are called with the same entry conditions. The processor may be in any mode and interrupt state. The registers are as follows:

On entry

R0 = buffer handle
R8 = private word (as specified in R3)
R12 = pointer to workspace for routine (as specified in R4)

Such 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.

The wake up routine

R1 contains a pointer to a routine to be called when data enters the buffer and it is currently marked 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.

If this pointer (ie R1) is zero, the buffer manager does not attempt to call a wake up routine for the specified buffer.

The owner change routine

R2 contains a pointer to a routine to be called whenever the owner of the buffer is about to change. This occurs:

  • when an attempt is made to remove or deregister the buffer by calling Buffer_Remove or Buffer_Deregister respectively
  • when an attempt is made to link to the buffer by another call of this SWI for the same buffer
  • when an attempt is made to kill the buffer manager.

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.

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.

Related SWIs

Buffer_Remove, Buffer_Deregister, Buffer_ModifyFlags, Buffer_UnlinkDevice

Related vectors

None


Buffer_UnlinkDevice
(SWI &42946)

Unlinks a set of routines from the specified buffer

On entry

R0 = buffer handle

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

Buffer_LinkDevice

Related vectors

None


Buffer_GetInfo
(SWI &42947)

Returns data about the buffer

On entry

R0 = buffer handle

On exit

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

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

None

Related vectors

None


Buffer_Threshold
(SWI &42948)

Sets or reads the warning threshold of the buffer

On entry

R0 = buffer handle
R1 = threshold (0 = none, -1 to read)

On exit

R1 = previous value

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

Buffer_Create, Buffer_Register

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015