file : /dsgn/tranpdsgn.text date : 18-Mar-1982 kb This document describes the Transporter "Physical" Driver for Concept. The Physical driver has two (2) main functions : 1) "strobe in" transporter commands 2) handle Transporter generated interrupts Part of handling Transporter interrupts involves maintaining the Transporter Interrupt Service Table. The SVS Unitstatus mechanism is the driver interface for the user. ****** Transporter Interrupt Service Table ****** This table has 5 entries, one for each Receive Socket and one more for the Current Command. Entries have the form : type byte = -128..127; bytes = array [0..9999] of byte; Pbytes = ^bytes; record BitFlags : integer; ResultPointer : Pbytes; ProcedurePointer : Pbytes; BufferPointer : Pbytes; A4SaveArea : longint; ---> for SVS A5SaveAres : longint; ---> Pascal end; The first entry is the Current Command entry. It is used for any request which expects an interrupt response. The entry is marked used when it is filled in and marked unused when it's interrupt occurs and before the user routine, if any, is called. The last 4 entries correspond to the 4 Receive Sockets on the Transporter. They are used only when a user is expecting two (2) interrupts. It specifies the user service routine for the second interrupt. Field descriptions : 1) BitFlags => This field contains 16 bit flags controlling the useage of the entry. The following flags are defined : a) EntryInUse - if set means the entry is currently waiting for an interrupt. it is an active entry. if clear means entry not being used, inactive. 2) ResultPointer => points to the byte result code from the Transporter. significant states are : $FF = no interrupt yet $FE = performed receive command, if Current Command entry then call it's corresponding Procedure, if one exists (see ProcedurePointer description). <$FE = result code response for completed command. Get a value in this range for Command and Socket interrupts. When ResultPointer points at this value then call the entry's corresponding Procedure, if one exists. 3) ProcedurePointer => points to the procedure to call when this entries interrupt occurs. If the user passes a Procedure pointer parameter equal to Nil (0) then the interrupt is expected but there is no procedure to call. For this case, the ProcedurePointer field is Nil (0). 4) BufferPointer => points to the receive buffer for this socket. It is only used by the receive socket entries 1-4. 5) A4SaveArea and A5SaveArea => these hold the 68000 A4 and A5 register values for the Procedure to be called when this entry's interrupt occurs. They are acquired when the entry is filled in. They are assumed to be the same as the Procedure which called the driver to setup the table. Therefore, any SVS Pascal procedure which uses this driver must call the driver to setup the table entry from a global level procedure at least. Furthermore, the user Procedure called when the entry's interrupt occurs must be in the same program and also be a global procedure to that program. Upon receipt of an interrupt the interrupt handler will scan the active entries looking for one whose ResultPointer points at a byte which is less than $FE for the Receive Socket entries and less than $FF for the Current Command entry. When the valid entry with a Ready Result byte is found then the interrupt handler calls the Procedure pointed at by the entry's ProcedurePointer, if it is not Nil (0). If it is Nil (0) the Procedure is not called. Before the call, registers A4 and A5 are set to the entry's A4 and A5 save area values. The the ResultPointer and BufferPointer variables are passed as parameters to the user service routine via the stack using the SVS Pascal parameter passing conventions. Finally, the 68000 interrupts are enabled. Next, the user service routine is called. User service routines must make a standard return to the driver. Calling interface is : Procedure Done(ResultPointer, BufferPointer : Pbytes); Whether or not a Procedure is called always mark the entry not in use by clearing the EntryInUse flag. If a Procedure is called, the flag must be cleared before calling the user service routine and re-enabling interrupts. The interrupt handler must reset the Omninet (Transporter) interrupt first thing done in order not to lose a successive Omninet interrupt. ****** Interface for Transporter Physical Driver ****** The Pascal defined Unitstatus call is as follows : UnitStatus (Unit#,ParameterBlock,function code); The function code specifies 4 different Transporter calls. The meaning of the ParameterBlock depends on which call is made. The first is when the function code equals $FFFF. This code specifies no interrupt call to the user is wanted for this command and that no interrupt is expected. The ParameterBlock's address is the address to strobe into the Transporter. Therefore, strobe in the buffer address. No entry in the table is used and no entry is changed. The second is when it equals 5. This is a command with a single interrupt and no Receive socket is used. The ParameterBlock is 12 bytes long and has the following form : record CommandAddress : Pbytes; ResultPointer : Pbytes; ProcedurePointer : Pbytes; end; This call uses the Current Command entry only. Therefore, place the ResultPointer and the ProcedurePointer in the Current Command table entry (the first entry). Assign the entry's BufferPointer to Nil (0). The CommandAddress is strobed into the Transporter. The third is when the function code equals 6. This is a two (2) interrupt command. It uses the Current Command entry and 1 of the socket entries. The ParameterBlock is 22 bytes long and has the form : record CommandAddress : Pbytes; ResultPointer : Pbytes; Procedure1Pointer : Pbytes: SocketNumber : integer; BufferPointer : Pbytes; Procedure2Pointer : Pbytes; The CommandAddress is strobed into the Transporter. The ResultPointer is placed in both the Current Command entry and the Receive Socket entry specified by the SocketNumber. Procedure1Pointer is the pointer to the Current Command's user service routine. It is placed in the ProcedurePointer field of the Current Command entry of the table. SocketNumber is an integer from 1 to 4, inclusive specifying which Receive Socket entry is to be used. The BufferPointer is placed in the Receive Socket's entry's BufferPointer field. It is passed to the user's service routine for that entry when called. The Current Command entry's BufferPointer field is cleared to Nil (0). Procedure2Pointer is a pointer to the Receive Socket's entry's user service routine. It is placed in the Receive Socket's entry's ProcedurePointer field. Either Procedure address may be zero. If it is then an interrupt is expected for this entry, however, no user service routine exists for the interrupt handler to call. The last type is when the function code equals 0,1,2,3, or 4. These mean to clear the entry in the Transporter Interrupt Service Table designated by the function code. In other words, clear the EntryInUse flag for the entry indexed by the function code. For every call made to setup a table entry, the driver must check the EntryInUse flag. If it is set, the entry is in use waiting for an interrupt, then this call to the driver is in Error. Return to the user an IORESULT error code specifying Entry In Use Error. Also, do NOT change the table. The End