Channel processes

A project log for IO881

An I/O Processor for 8-bit systems

JulianJulian 09/03/2018 at 14:300 Comments

Each channel can have a total of up to 3 processes associated with it.  (There's a limit of 32 active processes imposed due to the register file organization, so not every channel can have that many, but that should be fine -- most applications I've looked at only need 1 or 2). Each of these processes has a different role, and this is reflected in slightly different behaviour of the PULL and YIELD instructions.

In all cases the processes are started by a byte of data being added to the processor task FIFO and reaching the front of the queue. This byte is them returned from a PULL instruction. If a PULL is executed while the process is not the target of the front queue entry the process is suspended and the relevant process is started. The byte is stored in the target register operand of the instruction (which may be either A or B). 

All processes in a channel share the same 4KiB segment of memory.  Each process has separate registers, except for the P2 and P3 registers which are shared between all processes in a channel and can be used as pointers to shared data structures or counters (e.g. to implement a circular buffer or a stack).

The input handling process receives input from an external source (eg being passed from an associated device, sent from another channel, the result of DMA requests performed by any of the channel processes, and so on). There are several ways it can pass on data: it can store the data in the channel's memory, send it directly to a recipient port, or use the YIELD instruction to send it on to either the output process (if one exists) or to the channel output (otherwise).

The output process is invoked at channel startup, every time the channel output value is received by the destination, and every time the input process is suspended while there is no output value available at present. It can also be invoked explicitly by the input process.  If invoked explicitly, PULL stores the value passed to YIELD; otherwise the value stored is not currently defined (but will likely either be 00 or FF).

The request process is invoked by external control (e.g. a service request line from a device or a specific output port from the host computer to request it) or explicitly using the PUT instruction (which will be described in detail in a later log).  Its purpose is to perform operations that do not relate to handling incoming or outgoing data, e.g. setting up DMA load requests to generate data, configuring device settings, etc.  It may call YIELD, in which case the bytes passed to it are sent to the input process (if one exists), or the output process (if there is no input process but there is an output process), or are stored directly in the channel output (otherwise).

If a process sends data to the channel output when there is already a value stored there, it overwrites the existing value.  A process may reasonably expect that there isn't a value present if it is connected to a hardware device and that device is always able to accept incoming data quickly; otherwise it would usually be best to store data locally and use the automatically invoked output process to refresh the output value when necessary.