Trailing-Edge
-
PDP-10 Archives
-
BB-P363B-SM_1985
-
mcb/drivers/dcp.b16
There are no other files named dcp.b16 in the archive.
module DCP ( ! DDCMP Protocol Processor
ident = 'X05180',
language (bliss16)
) =
begin
!
! COPYRIGHT (c) 1980, 1981, 1982
! DIGITAL EQUIPMENT CORPORATION
! Maynard, Massachusetts
!
! This software is furnished under a license and may be used
! and copied only in accordance with the terms of such license
! and with the inclusion of the above copyright notice. This
! software or any other copies thereof may not be provided or
! otherwise made available to any other person. No title to
! and ownership of the software is hereby transferred.
!
! The information in this software is subject to change
! without notice and should not be construed as a commitment
! by DIGITAL EQUIPMENT CORPORATION.
!
! DIGITAL assumes no responsibility for the use or reliability
! of its software on equipment which is not supplied by
! DIGITAL.
!
!++
!
! FACILITY: MCB DDCMP Protocol Driver
!
! ABSTRACT:
!
! This module contains the DDCMP protocol routines.
!
! ENVIRONMENT: MCB V3.2
!
! AUTHOR: Alan D. Peckham CREATION DATE: 1-Jul-81
!
! MODIFIED BY:
!
! Alan D. Peckham, 1-Jul-81: Version 5
! 01 - Rewritten in BLISS
! 02 - Rewrite driver control code to insure device stop requests
! are performed.
! 03 - Dot bug in CHANGE_PROTOCOL_STATE.
! Wrong event class for maintenance "load me" notification.
! Wrong event types for threshold notifications.
! 04 - Fix to insure that there is only one control CCB to driver
! at any one timer (confuses the KDP driver).
! 05 - The last fix did not catch all cases in SET_DEVICE.
! 06 - Do not set half duplex in maintenance.
! 07 - Fix REP timer bug in DCPXCP.
! 08 - Fix state reporting.
! 09 - Out-of-range acks should not dump a data message.
! 10 - Update to NM V3.0.0 .
! 11 - Remove 'counters zeroed' event in DCPNMX.
! 12 - Fix event number for MOP requested event.
! 13 - Get KDP parameters from PLL.
! 14 - De-commit half-duplex.
! 15 - Do not use select timer when in FDX maintenance mode.
! 16 - Poke KDP DEVTYPE in maintenance messages that need it.
! 17 - Handle change in NMX interface in DCPINI.
! 18 - Modify CTLSTR to return the CIRCUIT COST to XPT in C_PRM1.
!--
!
! INCLUDE FILES:
!
library 'MCBLIB';
library 'XPORTX';
library 'NMXLIB';
$SHOW (NONE)
require 'DLLLIB';
library 'DCPDAT';
!
! TABLE OF CONTENTS:
!
linkage
DCP_CCB_DB = jsr (register = 4, register = 5) :
nopreserve (0, 1, 2, 3, 4),
DCP_CCB_DB_STS = jsr (register = 4, register = 5, register = 3) :
nopreserve (0, 1, 2, 3, 4),
DCP_CCB = jsr (register = 4) :
nopreserve (0, 1, 2, 3),
DCP_CTR = jsr (register = 0),
DCP_DB = jsr (register = 5) :
nopreserve (0, 1, 2, 3, 4),
DCP_DB_N0 = jsr (register = 5) :
preserve (0),
DCP_DB_CCB = jsr (register = 5, register = 4) :
nopreserve (0, 1, 2, 3),
DCP_DB_CCB_N0 = jsr (register = 5, register = 4) :
preserve (0) nopreserve (3),
DCP_DB_CCBR = jsr (register = 5, register = 4) :
nopreserve (0, 1, 2, 3, 4),
DCP_DB_CCB_HDR = jsr (register = 5, register = 4; register = 4) :
nopreserve (0, 1, 2, 3),
DCP_DB_CTR_STS = jsr (register = 5, register = 0, register = 3) :
nopreserve (0, 1, 2, 3),
DCP_DB_STS = jsr (register = 5, register = 3) :
nopreserve (0, 1, 2, 3);
forward routine
BUILD_CONTROL_MESSAGE : DCP_DB,
BUILD_DATA_MESSAGE : DCP_DB_CCBR,
BUILD_MAINTENANCE_MESSAGE : DCP_DB_CCBR,
BUMP_8_BIT_COUNTER : DCP_CTR novalue,
CCPGET : MCB_DB_CCB novalue,
CCPSET : MCB_DB_CCB novalue,
CCPSTP : MCB_DB_CCB novalue,
CCPSTR : MCB_DB_CCB novalue,
CHANGE_PROTOCOL_STATE : DCP_DB novalue,
CKACK : DCP_DB,
CKREP : DCP_DB novalue,
CTLSTP : MCB_DB_CCB novalue,
CTLSTR : MCB_DB_CCB novalue,
DCPCCP : MCB_DB_CCB_MOD novalue,
DCPCTL : MCB_DB_CCB_MOD novalue,
DCPKCP : MCB_DB_CCB novalue,
DCPRCE : MCB_DB_CCB novalue,
DCPRCP : MCB_DB_CCB novalue,
DCPTIM : MCB_DB_CCB_MOD novalue,
DCPXCP : MCB_DB_CCB novalue,
DCPXME : MCB_DB_CCB_MOD novalue,
ENTER_MAINTENANCE : MCB_DB_CCB novalue,
HEADER_CCB : DCP_DB_CCB_HDR,
HEADER_FORMAT_ERROR : DCP_DB novalue,
IGNORE_MESSAGE : DCP_DB novalue,
INITIALIZE_LINK : MCB_DB_CCB novalue,
MESSAGE_LENGTH : DCP_CCB,
PROCESS_ACK_MESSAGE : DCP_DB novalue,
PROCESS_CONTROL_MESSAGE : DCP_DB_CCBR novalue,
PROCESS_DATA_MESSAGE : DCP_DB_CCBR novalue,
PROCESS_MAINTENANCE_MESSAGE : DCP_DB_CCBR novalue,
PROCESS_NAK_MESSAGE : DCP_DB novalue,
PROCESS_REP_MESSAGE : DCP_DB novalue,
PROCESS_SELECT_FLAG : DCP_DB novalue,
PROCESS_STACK_MESSAGE : DCP_DB novalue,
PROCESS_START_MESSAGE : DCP_DB novalue,
RECORD_DRIVER_ERROR : DCP_DB_CCB novalue,
RECORD_NAK_REASON : DCP_DB novalue,
RESYNCHRONIZE : DCP_DB novalue,
RETRANSMIT_UNACKED_MESSAGES : DCP_DB novalue,
RETURN_ACKED_MESSAGES : DCP_DB novalue,
SCHEDULE_PERSISTENT_AST : DCP_CCB_DB novalue,
SCHEDULE_RECEIVE : DCP_CCB_DB novalue,
SCHEDULE_STATE_AST : DCP_CCB_DB novalue,
SCHEDULE_TRANSIENT_AST : DCP_CCB_DB novalue,
SCHEDULE_TRANSMIT : DCP_CCB_DB_STS novalue,
SEND_DATA : DCP_DB novalue,
SEND_PERSISTENT_ERROR : DCP_DB_STS novalue,
SEND_STATE : DCP_DB novalue,
SEND_TRANSIENT_ERROR : DCP_DB_STS novalue,
SET_DEVICE : DCP_DB novalue,
SET_LINK : DCP_DB novalue,
STARCE : DCP_DB_CCBR novalue,
START_DEVICE : DCP_CCB_DB novalue,
STOP_DEVICE : DCP_CCB_DB novalue,
STOP_LINK : MCB_DB_CCB novalue,
SYNCHRONIZE : DCP_DB_CCB_N0 novalue,
TERMINATE_SELECTION_INTERVAL : DCP_DB novalue,
TEST_RECEIVE_THRESHOLD : DCP_DB_N0 novalue,
TEST_THRESHOLD : DCP_DB_CTR_STS novalue,
TEST_TRANSMIT_THRESHOLD : DCP_DB_N0 novalue,
TEST_SELECT_THRESHOLD : DCP_DB_N0 novalue,
TIMCCB : MCB_DB_CCB novalue,
TIMLTM : MCB_DB novalue,
TIMPWF : MCB_DB novalue,
TRANSMIT : MCB_DB_CCB novalue;
global bind routine
TSTTH = TEST_TRANSMIT_THRESHOLD : DCP_DB novalue;
!
! MACROS:
!
macro
$SIGNED (FLD0, FLD1, FLD2, FLD3) =
%if %null (FLD1)
%then
%fieldexpand (FLD0, 0),
%fieldexpand (FLD0, 1),
%fieldexpand (FLD0, 2)
%else
FLD0, FLD1, FLD2
%fi, 1 %;
macro
FLUSH_QUEUE (QUEUE, RETURN_CALL) =
while 1 eql 1 do
begin
local
_DCP_CCB : ref block field (C_FIELDS);
if not CMQRM$ (QUEUE, _DCP_CCB) then exitloop;
RETURN_CALL (._DCP_CCB %if not %null (%remaining) %then , %remaining %fi);
end %;
!
! EQUATED SYMBOLS:
!
literal
TRUE = 1 EQL 1,
FALSE = 1 EQL 0,
NO_OPERATION = 0;
literal
LCL = 0,
RMT = 1;
macro
C_HANDLE = %fieldexpand (C_LIN, 0), 0, %bpval, 0 %;
global literal
%name ('D.LEN') = D_LENGTH*%upval;
!
! OWN STORAGE:
!
external routine
$DSPCR : novalue;
$MCB_PROCESS (
NAME = DCP,
DLC_DISPATCH = TABLE$ ($DSPCR, FC_CCP,
(FC_CTL, DCPCTL),
(FC_XME, DCPXME),
(FC_RCE, DCPRCE),
(FC_TIM, DCPTIM),
(FC_XCP, DCPXCP),
(FC_RCP, DCPRCP),
(FC_KCP, DCPKCP),
(FC_CCP, DCPCCP)));
!
! EXTERNAL REFERENCES:
!
linkage
DDM_CCB = jsr (register = 4) : nopreserve (4);
external routine
DCPNM : DCP_DB_CCBR novalue,
TIMPIN : MCB_DB novalue;
external
MCB$GAW_PROCESS_DATA_BASE : vector [2],
MCB$GW_PROCESS_HANDLE;
bind
DB_BIAS = MCB$GAW_PROCESS_DATA_BASE [0];
macro
GET_DCP_DATA_BASE (NAME) =
%if %declared (NAME)
%then map NAME : ref
%else bind NAME = .MCB$GAW_PROCESS_DATA_BASE [1] :
%fi block field (D_FIELDS); %;
routine BUILD_CONTROL_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS),
PTR;
if (PTR = HEADER_CCB (DB [D_TIM], 0; CCB)) eqla 0 then return .PTR;
ch$wchar_a (CM_ENQ, PTR);
selectone TRUE of
set
[.DB [SS_SEND_STACK]] :
begin
DB [SS_SEND_STACK] = FALSE;
DB [SS_START_REP_TIMER] = TRUE;
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
ch$wchar_a (MT_STK, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (1, PTR);
if .DB [L_PROTOCOL] eql DP_DMC then SYNCHRONIZE (DB [D_TIM], .CCB);
end;
[.DB [SS_SEND_START]] :
begin
DB [SS_SEND_START] = FALSE;
DB [SS_START_REP_TIMER] = TRUE;
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
ch$wchar_a (MT_STR, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (1, PTR);
if .DB [L_PROTOCOL] eql DP_DMC then SYNCHRONIZE (DB [D_TIM], .CCB);
end;
[.DB [SS_SEND_NAK]] :
begin
DB [SS_SEND_NAK] = FALSE;
ch$wchar_a (MT_NAK, PTR);
ch$wchar_a (.DB [S_PENDING_NAK_REASON], PTR);
ch$wchar_a (.DB [S_R], PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (1, PTR);
SYNCHRONIZE (DB [D_TIM], .CCB);
end;
[.DB [SS_SEND_REP]] :
begin
DB [SS_SEND_REP] = FALSE;
ch$wchar_a (MT_REP, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (.DB [S_N], PTR);
ch$wchar_a (1, PTR);
SYNCHRONIZE (DB [D_TIM], .CCB);
end;
[.DB [SS_SEND_ACK]] :
begin
DB [SS_SEND_ACK] = FALSE;
ch$wchar_a (MT_ACK, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (.DB [S_R], PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (1, PTR);
if .DB [L_PROTOCOL] eql DP_DMC then SYNCHRONIZE (DB [D_TIM], .CCB);
end;
tes;
if .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] neqa 0
then
CCB [C_PRM4] = .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_LAST)];
$MCB_QUEUE_CCB (DB [L_PRE_TRANSMIT], .CCB);
DB [S_MOTD] = .DB [S_MOTD] + 1;
.PTR
end; !of routine BUILD_CONTROL_MESSAGE
routine BUILD_DATA_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
DCCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS),
CNT,
PTR;
if (PTR = HEADER_CCB (DB [D_TIM], .DCCB; CCB)) eqla 0 then return .PTR;
DB [SS_SEND_ACK] = FALSE;
DB [L_MESSAGES_AT_DRIVER] = .DB [L_MESSAGES_AT_DRIVER] + 1;
CNT = MESSAGE_LENGTH (.CCB);
if .DB [S_N] eqlu .DB [S_TM1]
then
begin
DB [S_N] = .DB [S_N] + 1;
COUNTER_ADD (DB, S_BYTES_TRANSMITTED, .CNT);
COUNTER_INCREMENT (DB, S_DATA_BLOCKS_TRANSMITTED);
end;
DB [S_TM1] = .DB [S_TM1] + 1;
ch$wchar_a (CM_SOH, PTR);
ch$wchar_a (.CNT <0, 8>, PTR);
ch$wchar_a (.CNT <8, 8>, PTR);
ch$wchar_a (.DB [S_R], PTR);
ch$wchar_a (.DB [S_TM1], PTR);
ch$wchar_a (1, PTR);
if .DB [L_PROTOCOL] eql DP_DMC then SYNCHRONIZE (DB [D_TIM], .CCB);
if .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] neqa 0
then
CCB [C_PRM4] = .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_LAST)];
$MCB_QUEUE_CCB (DB [L_PRE_TRANSMIT], .CCB);
DB [S_MOTD] = .DB [S_MOTD] + 1;
.PTR
end; !of routine BUILD_DATA_MESSAGE
routine BUILD_MAINTENANCE_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
DCCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS),
CNT,
PTR;
if (PTR = HEADER_CCB (DB [D_TIM], .DCCB; CCB)) eqla 0 then return .PTR;
DB [SS_SEND_SELECT] = TRUE;
DB [L_MESSAGES_AT_DRIVER] = .DB [L_MESSAGES_AT_DRIVER] + 1;
CNT = MESSAGE_LENGTH (.CCB);
ch$wchar_a (CM_DLE, PTR);
ch$wchar_a (.CNT <0, 8>, PTR);
ch$wchar_a (.CNT <8, 8>, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (0, PTR);
ch$wchar_a (1, PTR);
SYNCHRONIZE (DB [D_TIM], .CCB);
if .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] neqa 0
then
CCB [C_PRM4] = .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_LAST)];
$MCB_QUEUE_CCB (DB [L_PRE_TRANSMIT], .CCB);
DB [S_MOTD] = .DB [S_MOTD] + 1;
.PTR
end; !of routine BUILD_MAINTENANCE_MESSAGE
routine BUMP_8_BIT_COUNTER
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CTR : ref block)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CTR novalue =
!
! SIDE EFFECTS:
! None
!--
begin
CTR [0, 0, 8, 0] = .CTR [0, 0, 8, 0] + 1;
if .CTR [0, 0, 8, 0] eql 0
then
CTR [0, 0, 8, 0] = .CTR [0, 0, 8, 0] - 1;
end; !of routine BUMP_8_BIT_COUNTER
routine CCPGET
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [K_REGISTER] = .CCB [C_PRM1];
DB [D_REGISTER] = .CCB [C_PRM2];
DB [K_VECTOR] = .CCB [C_PRM3];
DB [K_PRIORITY] = .CCB [C_PRM4];
$MCB_RETURN_CCB (.CCB);
end; !of routine CCPGET
routine CCPSET
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
external routine
$DDSTR : DDM_CCB novalue;
$DDSTR (.CCB);
end; !of routine CCPSET
routine CCPSTP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
$MCB_RETURN_CCB (.CCB);
DB [SS_DEVICE_BEING_SET] = FALSE;
FLUSH_QUEUE (DB [S_WAITING_FOR_ACK],
%quote SCHEDULE_TRANSMIT, DB [D_TIM], DLL$_ABORTED);
FLUSH_QUEUE (DB [S_WAITING_FOR_TRANSMIT],
%quote SCHEDULE_TRANSMIT, DB [D_TIM], DLL$_ABORTED);
SET_DEVICE (DB [D_TIM]);
end; !of routine CCPSTP
routine CCPSTR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
$MCB_RETURN_CCB (.CCB);
DB [SS_DEVICE_BEING_SET] = FALSE;
DB [LS_STATION_ENABLED] = TRUE;
DB [SS_DEVICE_RUNNING] = TRUE;
SET_DEVICE (DB [D_TIM]);
end; !of routine CCPSTR
routine CHANGE_PROTOCOL_STATE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
STATE,
REASON)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if .DB [S_PROTOCOL_STATE] eql .STATE then return;
$NM_DLL_EVENT (.REASON, .DB [S_CIRCUIT_ENTITY],
PARAMETER_C_1 (0, DB [S_PROTOCOL_STATE]),
DB [S_PROTOCOL_STATE] = .STATE,
PARAMETER_C_1 (1, DB [S_PROTOCOL_STATE]));
SEND_STATE (DB [D_TIM]);
end; !of routine CHANGE_PROTOCOL_STATE
routine CKACK
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB =
!
! SIDE EFFECTS:
! None
!--
begin
field
NUM = [0, 0, 8, 0];
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
local
LAST_ACK : block [1] field (NUM),
NUM_ACKED : block [1] field (NUM),
NUM_SENT : block [1] field (NUM);
LAST_ACK = .DB [$SIGNED (S_A)];
NUM_ACKED = .HEADER [$SIGNED (H_RESP)];
if .LAST_ACK [NUM] eql .NUM_ACKED [NUM]
then
begin
if .LAST_ACK [NUM] eql .DB [S_N] then DB [S_TRANSMIT_THRESHOLD] = 7;
return TRUE
end;
NUM_ACKED = .NUM_ACKED - .LAST_ACK;
NUM_SENT = .DB [$SIGNED (S_N)];
NUM_SENT = .NUM_SENT - .LAST_ACK;
if .NUM_SENT [NUM] lssu .NUM_ACKED [NUM]
then
return FALSE;
DB [S_A] = .HEADER [H_RESP];
RETURN_ACKED_MESSAGES (DB [D_TIM]);
return TRUE
end; !of routine CKACK
routine CKREP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [SS_START_REP_TIMER] = FALSE;
DB [SS_TIMING_REP] = FALSE;
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
if
begin
field
NUM = [0, 0, 8, 0];
local
NUM_NOT_ACKED : block [1] field (NUM),
NUM_NOT_TRANSMITTED : block [1] field (NUM);
NUM_NOT_TRANSMITTED = .DB [$SIGNED (S_N)];
NUM_NOT_ACKED = .NUM_NOT_TRANSMITTED;
NUM_NOT_TRANSMITTED = .NUM_NOT_TRANSMITTED - .DB [$SIGNED (S_X)];
NUM_NOT_ACKED = .NUM_NOT_ACKED - .DB [$SIGNED (S_A)];
.NUM_NOT_ACKED [NUM] gtru .NUM_NOT_TRANSMITTED [NUM]
end
then
if .DB [L_DUPLEX] eql DL_FULL
then
begin
DB [SS_TIMING_REP] = TRUE;
DB [D_TIM] = .DB [L_RETRANSMIT_TIMER];
end
else
DB [SS_START_REP_TIMER] = TRUE;
end; !of routine CKREP
routine CTLSTP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [SS_NOTIFY_STATE] = FALSE;
DB [S_TRANSIENT_ERROR] = 0;
DB [S_PERSISTENT_ERROR] = 0;
DB [S_USER_HANDLE] = 0;
CCB [C_FNC] = FC_CCP;
CCB [C_STS] = DLL$_SUCCESS;
if .DB [D_USER_BUFFERS] eql 0
then
$MCB_SCHEDULE_CCB (.CCB)
else
DB [S_CONTROL_CCB] = .CCB;
end; !of routine CTLSTP
routine CTLSTR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
STATUS = TABLE$ (0, 0,
(SS_HALTED^1, DLL$_STATE_OFF),
(SS_ISTRT^1, DLL$_STATE_SYNCHRONIZING),
(SS_ASTRT^1, DLL$_STATE_SYNCHRONIZING),
(SS_RUNNING^1, DLL$_STATE_RUNNING),
(SS_MAINTENANCE^1, DLL$_STATE_MAINTENANCE)) : vector;
DB [S_USER_HANDLE] = .CCB [C_HANDLE];
if .CCB [C_PRM1] eql 0
then
CCB [C_PRM1] = .DB [S_CIRCUIT_COST];
CCB [C_STS] = .STATUS [.DB [S_PROTOCOL_STATE]];
CCB [C_FNC] = FC_CCP;
$MCB_SCHEDULE_CCB (.CCB);
end; !of routine CTLSTR
routine CURRENT_STATUS (DB) : LINKAGE_DB =
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
! DB = address of DCP data base.
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
! COMPLETION CODES:
! None
!
! SIDE EFFECTS:
! None
!--
begin
GET_DCP_DATA_BASE (DB)
literal
DLL_OFF = 0,
DLL_SYNCHRONIZING = 1,
DLL_RUNNING = 2,
DLL_MAINTENANCE = 3;
bind
STATUS = TABLE$ (0, 0,
(SS_HALTED^1, DLL_OFF),
(SS_ISTRT^1, DLL_SYNCHRONIZING),
(SS_ASTRT^1, DLL_SYNCHRONIZING),
(SS_RUNNING^1, DLL_RUNNING),
(SS_MAINTENANCE^1, DLL_MAINTENANCE)) : vector,
DLL_STATUS = TABLE$ (0, 0,
(DLL_OFF^1, DLL$_STATE_OFF),
(DLL_SYNCHRONIZING^1, DLL$_STATE_SYNCHRONIZING),
(DLL_RUNNING^1, DLL$_STATE_RUNNING),
(DLL_MAINTENANCE^1, DLL$_STATE_MAINTENANCE)) : vector;
if .DB [SS_NOTIFY_OFF]
then
begin
DB [SS_NOTIFY_OFF] = FALSE;
if .DB [D_REPORTED_STATE] eql DLL_OFF
then
DB [SS_NOTIFY_STATE] = FALSE;
return .DLL_STATUS [DB [D_REPORTED_STATE] = DLL_OFF];
end;
DB [SS_NOTIFY_STATE] = FALSE;
.DLL_STATUS [DB [D_REPORTED_STATE] = .STATUS [.DB [S_PROTOCOL_STATE]]]
end; !of routine CURRENT_STATUS
routine DCPCCP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS),
MODIFIER)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB_MOD novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, FD_TIM,
(FM_GET, CCPGET),
(FM_SET, CCPSET),
(FM_STR, CCPSTR),
(FM_STP, CCPSTP)),
(DB [D_TIM], .CCB),
MCB_DB_CCB);
end; !of routine DCPCCP
routine DCPCTL
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS),
MODIFIER)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB_MOD novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, 0,
(FM_NM, DCPNM),
(FM_STR, CTLSTR),
(FM_STP, CTLSTP)),
(DB [D_TIM], .CCB),
MCB_DB_CCB);
end; !of routine DCPCTL
routine DCPKCP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
$MCB_RETURN_CCB (.CCB);
DB [LS_RESYNCH_IN_PROGRESS] = FALSE;
end; !of routine DCPKCP
routine DCPRCE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
STARCE (DB [D_TIM], .CCB);
DB [D_USER_BUFFERS] = .DB [D_USER_BUFFERS] - 1;
if .DB [D_USER_BUFFERS] neq 0 then return;
if .DB [S_CONTROL_CCB] neqa 0
then
begin
$MCB_SCHEDULE_CCB (.DB [S_CONTROL_CCB]);
DB [S_CONTROL_CCB] = 0;
end;
end; !of routine DCPRCE
routine DCPRCP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
!
! Copy the header and adjust the buffer pointer
!
begin
map
HEADER : vector [H_LENGTH];
local
HDR_0, HDR_1, HDR_2;
begin
local
SAVE_MAP;
SMAP$ (SAVE_MAP);
MAP$ (.CCB [C_BIAS]);
begin
local
PTR : ref vector;
PTR = .CCB [C_ADDR];
HDR_0 = .PTR [0];
HDR_1 = .PTR [1];
HDR_2 = .PTR [2];
CCB [C_ADDR] = PTR = PTR [3];
CCB [C_CNT] = .CCB [C_CNT] - H_LENGTH*%upval;
end;
MAP$ (.SAVE_MAP);
end;
begin
local
PTR : ref vector;
PTR = HEADER [0];
PTR [0] = .HDR_0;
PTR [1] = .HDR_1;
PTR [2] = .HDR_2;
PTR = PTR [2]; %(force auto-increment)%
end;
end;
!
! Toss if we are re-synchronizing or halted
!
if .DB [LS_RESYNCH_IN_PROGRESS] or (.DB [S_PROTOCOL_STATE] eql SS_HALTED)
then
begin
STARCE (DB [D_TIM], .CCB);
return;
end;
if (.CCB [C_STS] geq 0) or (.CCB [C_STS] eql CE_DCR)
then
begin
selectone .HEADER [H_IDENTIFIER] of
set
[CM_ENQ] : PROCESS_CONTROL_MESSAGE (DB [D_TIM], .CCB);
[CM_SOH] : PROCESS_DATA_MESSAGE (DB [D_TIM], .CCB);
[CM_DLE] : PROCESS_MAINTENANCE_MESSAGE (DB [D_TIM], .CCB);
[otherwise] :
begin
HEADER_FORMAT_ERROR (DB [D_TIM]);
STARCE (DB [D_TIM], .CCB);
end;
tes;
end
else
begin
!
! There was an error in message reception -
! record where appropriate.
!
RECORD_DRIVER_ERROR (DB [D_TIM], .CCB);
STARCE (DB [D_TIM], .CCB);
end;
SEND_DATA (DB [D_TIM]);
end; !of routine DCPRCP
routine DCPTIM
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS),
MODIFIER)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB_MOD novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, FD_TIM,
(FM_LTM, TIMLTM),
(FM_PWF, TIMPWF),
(FM_PIN, TIMPIN),
(FM_CCB, TIMCCB)),
(DB [D_TIM], .CCB),
MCB_DB_CCB);
end; !of routine DCPTIM
routine DCPXCP
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
begin
map
HEADER : vector [H_LENGTH];
local
PTR : ref vector;
PTR = .CCB [C_ADDR];
HEADER [0] = .PTR [0];
HEADER [1] = .PTR [1];
HEADER [2] = .PTR [2];
PTR = PTR [2]; %(force auto-increment)%
end;
!
! If a data message, put it in the proper place
!
if .HEADER [H_IDENTIFIER] neq CM_ENQ
then
begin
DB [L_MESSAGES_AT_DRIVER] = .DB [L_MESSAGES_AT_DRIVER] - 1;
if .HEADER [H_IDENTIFIER] eql CM_SOH
then
begin
$MCB_QUEUE_CCB (DB [S_WAITING_FOR_ACK], .CCB [C_STK]);
RETURN_ACKED_MESSAGES (DB [D_TIM]);
end
else
SCHEDULE_TRANSMIT (.CCB [C_STK], DB [D_TIM], DLL$_SUCCESS);
end;
$MCB_RETURN_CCB (.CCB);
!
! One less message at the driver
!
DB [S_MOTD] = .DB [S_MOTD] - 1;
if .DB [S_MOTD] eql 0
then
if .DB [SS_RETRANSMIT] then RETRANSMIT_UNACKED_MESSAGES (DB [D_TIM]);
!
! If halted, then there is nothing else to do.
!
if .DB [S_PROTOCOL_STATE] eql SS_HALTED then return;
!
! Do post-transmit processing
!
selectone .HEADER [H_IDENTIFIER] of
set
[CM_ENQ] :
if .HEADER [H_TYPE] eql MT_REP
then
DB [SS_START_REP_TIMER] = TRUE;
[CM_SOH] :
begin
if
begin
field
NUM = [0, 0, 8, 0];
local
NUM_NOT_ACKED : block [1] field (NUM),
NUM_NOT_TRANSMITTED : block [1] field (NUM);
NUM_NOT_TRANSMITTED = .DB [$SIGNED (S_N)];
NUM_NOT_ACKED = .NUM_NOT_TRANSMITTED;
NUM_NOT_TRANSMITTED = .NUM_NOT_TRANSMITTED -
(DB [S_X] = .HEADER [$SIGNED (H_NUM)]);
NUM_NOT_ACKED = .NUM_NOT_ACKED - .DB [$SIGNED (S_A)];
.NUM_NOT_ACKED [NUM] gtru .NUM_NOT_TRANSMITTED [NUM]
end
then
begin
if not (.DB [SS_START_REP_TIMER] or .DB [SS_TIMING_REP])
then
DB [SS_START_REP_TIMER] = TRUE;
end
else
begin
DB [SS_START_REP_TIMER] = FALSE;
DB [SS_TIMING_REP] = FALSE;
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
end;
end;
tes;
!
! Start the rep timer if asked
!
if .DB [SS_START_REP_TIMER]
then
begin
DB [SS_START_REP_TIMER] = FALSE;
DB [SS_TIMING_REP] = TRUE;
if .DB [L_DUPLEX] eql DL_FULL
then DB [D_TIM] = .DB [L_RETRANSMIT_TIMER];
end;
!
! Process select flag if appropriate
!
if .DB [L_DUPLEX] neq DL_FULL
then
if .HEADER [H_SELECT]
then
begin
COUNTER_INCREMENT (DB, S_SELECTION_INTERVALS);
DB [D_TIM] = .DB [L_RETRANSMIT_TIMER];
end;
!
! Send more data
!
SEND_DATA (DB [D_TIM]);
end; !of routine DCPXCP
routine DCPXME
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS),
MODIFIER)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB_MOD novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DISPATCH$ (
.MODIFIER,
TABLE$ ($DSPCR, 0,
(DLL$K_ENTER_MAINTENANCE, ENTER_MAINTENANCE),
(DLL$K_INITIALIZE_LINK, INITIALIZE_LINK),
(DLL$K_STOP_LINK, STOP_LINK),
(DLL$K_TRANSMIT, TRANSMIT),
(DLL$K_TRANSMIT_AND_TIME, TRANSMIT)),
(DB [D_TIM], .CCB),
MCB_DB_CCB);
end; !of routine DCPXME
routine ENTER_MAINTENANCE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
SET_LINK (DB [D_TIM], SS_HALTED);
DB [DC_SET_REQUESTED_STATE] = TRUE;
DB [S_REQUESTED_STATE] = SS_MAINTENANCE;
SET_DEVICE (DB [D_TIM]);
CCB [C_FNC] = FC_XCP;
CCB [C_STS] = DLL$_SUCCESS;
$MCB_SCHEDULE_CCB (.CCB);
end; !of routine ENTER_MAINTENANCE
routine HEADER_CCB
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
STACK_CCB : ref block field (C_FIELDS);
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCB_HDR =
!
! SIDE EFFECTS:
! None
!--
begin
if not $MCB_GET_CCB (CCB) then return 0;
CCB [C_CHN] = CCB [C_STK] = .STACK_CCB;
CCB [C_HANDLE] = .DB [L_DRIVER_HANDLE];
CCB [C_PRM4] = 0;
CCB [C_CNT] = 6;
CCB [C_BIAS] = 0;
CCB [C_ADDR] = ch$ptr (CCB [C_PRM1])
end; !of routine HEADER_CCB
routine HEADER_FORMAT_ERROR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT] :
begin
DB [SS_SEND_START] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_ASTRT] :
begin
DB [SS_SEND_STACK] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_RUNNING] :
begin
DB [SS_SEND_NAK] = TRUE;
DB [S_PENDING_NAK_REASON] = RN_HFE;
DB [SS_SEND_ACK] = FALSE;
COUNTER_INCREMENT (DB, L_REMOTE_STATION_ERRORS);
COUNTER_INCREMENT (DB, LR_N17);
$NM_DLL_EVENT (6, .DB [S_CIRCUIT_ENTITY],
PARAMETER_HI (2, 6, DB [L_HEADER]));
end;
[inrange] :
NO_OPERATION;
tes;
end; !of routine HEADER_FORMAT_ERROR
routine IGNORE_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT] :
begin
DB [SS_SEND_START] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_ASTRT] :
begin
DB [SS_SEND_STACK] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[inrange] :
NO_OPERATION;
tes;
end; !of routine IGNORE_MESSAGE
routine INITIALIZE_LINK
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
SET_LINK (DB [D_TIM], SS_HALTED);
DB [DC_SET_REQUESTED_STATE] = TRUE;
DB [S_REQUESTED_STATE] = SS_RUNNING;
SET_DEVICE (DB [D_TIM]);
CCB [C_FNC] = FC_XCP;
CCB [C_STS] = DLL$_SUCCESS;
$MCB_SCHEDULE_CCB (.CCB);
end; !of routine INITIALIZE_LINK
routine MESSAGE_LENGTH
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB =
!
! SIDE EFFECTS:
! None
!--
begin
local
CNT;
CCB = .CCB [C_CHN];
CNT = 0;
do (CNT = .CNT + .CCB [C_CNT]) while (CCB = .CCB [C_CHN]) neqa 0;
.CNT
end; !of routine MESSAGE_LENGTH
routine PROCESS_ACK_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT] :
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_ASTRT] :
if .HEADER [H_RESP] eqlu 0
then
begin
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_RUNNING, 1);
DB [S_TRANSMIT_THRESHOLD] = 7;
DB [S_RECEIVE_THRESHOLD] = 7;
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
end
else
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_RUNNING] :
if CKACK (DB [D_TIM])
then
CKREP (DB [D_TIM])
else
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_MAINTENANCE] :
NO_OPERATION;
[inrange] :
return NO_OPERATION;
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_ACK_MESSAGE
routine PROCESS_CONTROL_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
CASE .HEADER [H_TYPE] from MT_LOW to MT_HIGH of
set
[MT_STR] : PROCESS_START_MESSAGE (DB [D_TIM]);
[MT_STK] : PROCESS_STACK_MESSAGE (DB [D_TIM]);
[MT_ACK] : PROCESS_ACK_MESSAGE (DB [D_TIM]);
[MT_NAK] : PROCESS_NAK_MESSAGE (DB [D_TIM]);
[MT_REP] : PROCESS_REP_MESSAGE (DB [D_TIM]);
[inrange, outrange] : HEADER_FORMAT_ERROR (DB [D_TIM]);
tes;
STARCE (DB [D_TIM], .CCB);
end; !of routine PROCESS_CONTROL_MESSAGE
routine PROCESS_DATA_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ASTRT] :
if .HEADER [H_RESP] eqlu 0
then
begin
if
begin
local
NEW_NUM;
NEW_NUM = .DB [S_R] + 1;
.HEADER [H_NUM] eql .NEW_NUM <0, 8>
end
then
begin
if .CCB [C_STS] geq 0
then
begin
DB [S_R] = .DB [S_R] + 1;
COUNTER_INCREMENT (DB, S_DATA_BLOCKS_RECEIVED);
COUNTER_ADD (DB, S_BYTES_RECEIVED, .CCB [C_CNT]);
DB [SS_SEND_ACK] = TRUE;
DB [SS_SEND_NAK] = FALSE;
DB [S_RECEIVE_THRESHOLD] = 7;
CCB [C_MOD] = DLL$K_DATA_RECEIVED;
SCHEDULE_RECEIVE (.CCB, DB [D_TIM], DLL$_SUCCESS);
end
else
begin
RECORD_DRIVER_ERROR (DB [D_TIM], .CCB);
STARCE (DB [D_TIM], .CCB);
end;
end
else
STARCE (DB [D_TIM], .CCB);
end
else
STARCE (DB [D_TIM], .CCB);
[SS_RUNNING] :
begin
if CKACK (DB [D_TIM])
then
CKREP (DB [D_TIM]);
if
begin
local
NEW_NUM;
NEW_NUM = .DB [S_R] + 1;
.HEADER [H_NUM] eql .NEW_NUM <0, 8>
end
then
begin
if .CCB [C_STS] geq 0
then
begin
DB [S_R] = .DB [S_R] + 1;
COUNTER_INCREMENT (DB, S_DATA_BLOCKS_RECEIVED);
COUNTER_ADD (DB, S_BYTES_RECEIVED, .CCB [C_CNT]);
DB [SS_SEND_ACK] = TRUE;
DB [SS_SEND_NAK] = FALSE;
DB [S_RECEIVE_THRESHOLD] = 7;
CCB [C_MOD] = DLL$K_DATA_RECEIVED;
SCHEDULE_RECEIVE (.CCB, DB [D_TIM], DLL$_SUCCESS);
end
else
begin
RECORD_DRIVER_ERROR (DB [D_TIM], .CCB);
STARCE (DB [D_TIM], .CCB);
end;
end
else
STARCE (DB [D_TIM], .CCB);
end;
[inrange] :
STARCE (DB [D_TIM], .CCB);
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_DATA_MESSAGE
routine PROCESS_MAINTENANCE_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
if .DB [L_PROTOCOL] eql DP_DMC
then
begin
HEADER [H_SELECT] = TRUE;
HEADER [H_QSYNC] = TRUE;
end;
if not .HEADER [H_SELECT]
then
HEADER_FORMAT_ERROR (DB [D_TIM]);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT, SS_RUNNING] :
begin
$NM_DLL_EVENT (96^6 + 13, .DB [S_CIRCUIT_ENTITY]);
SEND_PERSISTENT_ERROR (DB [D_TIM], DLL$_MAINTENANCE_RECEIVED);
SET_LINK (DB [D_TIM], DB [S_REQUESTED_STATE] = SS_HALTED);
SET_DEVICE (DB [D_TIM]);
STARCE (DB [D_TIM], .CCB);
end;
[SS_MAINTENANCE] :
begin
if .CCB [C_STS] geq 0
then
begin
DB [S_RECEIVE_THRESHOLD] = 7;
CCB [C_MOD] = DLL$K_MAINTENANCE_RECEIVED;
SCHEDULE_RECEIVE (.CCB, DB [D_TIM], DLL$_SUCCESS);
end
else
begin
COUNTER_INCREMENT (DB, L_MAINTENANCE_BCC_ERRORS);
STARCE (DB [D_TIM], .CCB);
end;
end;
[inrange] :
STARCE (DB [D_TIM], .CCB);
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_MAINTENANCE_MESSAGE
routine PROCESS_NAK_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT] :
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_RUNNING] :
if CKACK (DB [D_TIM])
then
begin
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
RECORD_NAK_REASON (DB [D_TIM]);
PROCESS_SELECT_FLAG (DB [D_TIM]);
end
else
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_MAINTENANCE] :
NO_OPERATION;
[inrange] :
return NO_OPERATION;
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_NAK_MESSAGE
routine PROCESS_REP_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT] :
return IGNORE_MESSAGE (DB [D_TIM]);
[SS_RUNNING] :
if .HEADER [H_NUM] nequ .DB [S_R]
then
begin
DB [SS_SEND_NAK] = TRUE;
DB [S_PENDING_NAK_REASON] = RN_REP;
DB [SS_SEND_ACK] = FALSE;
TEST_RECEIVE_THRESHOLD (DB [D_TIM]);
COUNTER_INCREMENT (DB, SI_N3);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_INBOUND);
end
else
begin
DB [SS_SEND_ACK] = TRUE;
DB [SS_SEND_NAK] = FALSE;
COUNTER_INCREMENT (DB, S_REMOTE_REPLY_TIMEOUTS);
end;
[SS_MAINTENANCE] :
NO_OPERATION;
[inrange] :
return NO_OPERATION;
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_REP_MESSAGE
routine PROCESS_SELECT_FLAG
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
if .DB [L_DUPLEX] neq DL_FULL
then
if .HEADER [H_SELECT]
then
begin
DB [D_TIM] = 0;
DB [S_SELECT_THRESHOLD] = 7;
TERMINATE_SELECTION_INTERVAL (DB [D_TIM]);
end
else
DB [D_TIM] = .DB [L_RETRANSMIT_TIMER];
end; !of routine PROCESS_SELECT_FLAG
routine PROCESS_STACK_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT] :
begin
if not .HEADER [H_SELECT]
then
return HEADER_FORMAT_ERROR (DB [D_TIM]);
DB [SS_SEND_ACK] = TRUE;
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_RUNNING, 0);
DB [S_TRANSMIT_THRESHOLD] = 7;
DB [S_RECEIVE_THRESHOLD] = 7;
end;
[SS_RUNNING] :
DB [SS_SEND_ACK] = TRUE;
[SS_MAINTENANCE] :
NO_OPERATION;
[inrange] :
return NO_OPERATION;
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_STACK_MESSAGE
routine PROCESS_START_MESSAGE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT] :
begin
if not .HEADER [H_SELECT]
then
return HEADER_FORMAT_ERROR (DB [D_TIM]);
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_ASTRT, 0);
DB [S_TRANSMIT_THRESHOLD] = 7;
DB [S_RECEIVE_THRESHOLD] = 7;
DB [SS_SEND_STACK] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_RUNNING] :
begin
SEND_PERSISTENT_ERROR (DB [D_TIM], DLL$_START_RECEIVED);
SET_LINK (DB [D_TIM], DB [S_REQUESTED_STATE] = SS_HALTED);
SET_DEVICE (DB [D_TIM]);
end;
[SS_MAINTENANCE] :
$NM_DLL_EVENT (2, .DB [S_CIRCUIT_ENTITY]);
[inrange] :
return NO_OPERATION;
tes;
PROCESS_SELECT_FLAG (DB [D_TIM]);
end; !of routine PROCESS_START_MESSAGE
routine RECORD_DRIVER_ERROR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
selectone .CCB [C_STS] of
set
[CE_DCR] :
if .DB [S_PROTOCOL_STATE] eql SS_RUNNING
then
begin
DB [S_PENDING_NAK_REASON] = RN_DBC;
COUNTER_INCREMENT (DB, SI_N2);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_INBOUND);
end
else
begin
COUNTER_INCREMENT (DB, LL_NNS);
COUNTER_INCREMENT (DB, L_LOCAL_STATION_ERRORS);
return;
end;
[CE_BUF] :
begin
DB [S_PENDING_NAK_REASON] = RN_BUF;
COUNTER_INCREMENT (DB, SL_N8);
COUNTER_INCREMENT (DB, S_LOCAL_BUFFER_ERRORS);
end;
[CE_ROV] :
begin
DB [S_PENDING_NAK_REASON] = RN_ROV;
COUNTER_INCREMENT (DB, LL_N9);
COUNTER_INCREMENT (DB, L_LOCAL_STATION_ERRORS);
end;
[CE_MTL] :
begin
external
MCB$GW_RDB_SIZE;
$NM_DLL_EVENT (9, .DB [S_CIRCUIT_ENTITY],
PARAMETER_DU_2 (8, MCB$GW_RDB_SIZE));
DB [S_PENDING_NAK_REASON] = RN_MTL;
COUNTER_INCREMENT (DB, SL_N16);
COUNTER_INCREMENT (DB, S_LOCAL_BUFFER_ERRORS);
end;
[CE_HFE] :
begin
DB [S_PENDING_NAK_REASON] = RN_HBC;
COUNTER_INCREMENT (DB, SI_N1);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_INBOUND);
end;
[otherwise] :
return;
tes;
DB [SS_SEND_NAK] = TRUE;
DB [SS_SEND_ACK] = FALSE;
TEST_RECEIVE_THRESHOLD (DB [D_TIM]);
SEND_DATA (DB [D_TIM]);
end; !of routine RECORD_DRIVER_ERROR
routine RECORD_NAK_REASON
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
bind
HEADER = DB [L_HEADER] : block [H_LENGTH] field (HDR_FIELDS);
selectone .HEADER [H_SUBTYPE] of
set
[RN_HBC] :
begin
COUNTER_INCREMENT (DB, SO_N1);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_OUTBOUND);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[RN_DBC] :
begin
COUNTER_INCREMENT (DB, SO_N2);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_OUTBOUND);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[RN_REP] :
begin
COUNTER_INCREMENT (DB, SO_N3);
COUNTER_INCREMENT (DB, S_DATA_ERRORS_OUTBOUND);
end;
[RN_BUF] :
begin
COUNTER_INCREMENT (DB, SR_N8);
COUNTER_INCREMENT (DB, S_REMOTE_BUFFER_ERRORS);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[RN_ROV] :
begin
COUNTER_INCREMENT (DB, LR_N9);
COUNTER_INCREMENT (DB, L_REMOTE_STATION_ERRORS);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[RN_MTL] :
begin
COUNTER_INCREMENT (DB, SR_N16);
COUNTER_INCREMENT (DB, S_REMOTE_BUFFER_ERRORS);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[RN_HFE] :
begin
COUNTER_INCREMENT (DB, LL_N17);
COUNTER_INCREMENT (DB, L_LOCAL_STATION_ERRORS);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[otherwise] :
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
tes;
if .HEADER [H_RESP] neq .DB [S_TM1]
then
begin
DB [SS_RETRANSMIT] = TRUE;
if .DB [S_MOTD] eql 0 then RETRANSMIT_UNACKED_MESSAGES (DB [D_TIM]);
end;
DB [SS_START_REP_TIMER] = FALSE;
DB [SS_TIMING_REP] = FALSE;
if .DB [L_DUPLEX] eql DL_FULL then DB [D_TIM] = 0;
end; !of routine RECORD_NAK_REASON
routine RESYNCHRONIZE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS);
external routine
$DDCRA : DDM_CCB novalue;
if .DB [LS_RESYNCH_IN_PROGRESS] then return;
if not $MCB_GET_CCB (CCB) then return;
DB [LS_RESYNCH_IN_PROGRESS] = TRUE;
CCB [C_HANDLE] = .DB [L_DRIVER_HANDLE];
$DDCRA (.CCB);
end; !of routine RESYNCHRONIZE
routine RETRANSMIT_UNACKED_MESSAGES
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [SS_RETRANSMIT] = FALSE;
if .DB [$SUB_FIELD (S_WAITING_FOR_ACK, LIST_FIRST)] neqa 0
then
begin
if (.DB [$SUB_FIELD (S_WAITING_FOR_ACK, LIST_LAST)] =
.DB [$SUB_FIELD (S_WAITING_FOR_TRANSMIT, LIST_FIRST)]) eqla 0
then
DB [$SUB_FIELD (S_WAITING_FOR_TRANSMIT, LIST_LAST)] = .DB [$SUB_FIELD (S_WAITING_FOR_ACK, LIST_LAST)];
DB [$SUB_FIELD (S_WAITING_FOR_TRANSMIT, LIST_FIRST)] = .DB [$SUB_FIELD (S_WAITING_FOR_ACK, LIST_FIRST)];
$MCB_INITIALIZE_QUEUE (DB [S_WAITING_FOR_ACK]);
end;
DB [S_TM1] = .DB [S_A];
end; !of routine RETRANSMIT_UNACKED_MESSAGES
routine RETURN_ACKED_MESSAGES
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
until .DB [S_AR] eql .DB [S_A] do
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (DB [S_WAITING_FOR_ACK], CCB) then return;
DB [S_AR] = .DB [S_AR] + 1;
DB [S_TRANSMIT_THRESHOLD] = 7;
SCHEDULE_TRANSMIT (.CCB, DB [D_TIM], DLL$_SUCCESS);
end;
end; !of routine RETURN_ACKED_MESSAGES
routine SCHEDULE_PERSISTENT_AST
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS), ! CCB to use for status nodification.
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
CCB [C_HANDLE] = .DB [S_USER_HANDLE];
CCB [C_FNC] = FC_AST;
CCB [C_MOD] = DLL$K_PERSISTENT_ERROR;
CCB [C_STS] = .DB [S_PERSISTENT_ERROR];
$MCB_SCHEDULE_CCB (.CCB);
DB [S_PERSISTENT_ERROR] = 0;
end; !of routine SCHEDULE_PERSISTENT_AST
routine SCHEDULE_RECEIVE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
CCB [C_HANDLE] = .DB [S_USER_HANDLE];
if .CCB [C_HANDLE] eqlu 0 then return STARCE (DB [D_TIM], .CCB);
DB [D_USER_BUFFERS] = .DB [D_USER_BUFFERS] + 1;
CCB [C_FNC] = FC_RCP;
CCB [C_STS] = DLL$_SUCCESS;
$MCB_SCHEDULE_CCB (.CCB);
end; !of routine SCHEDULE_RECEIVE
routine SCHEDULE_STATE_AST
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if not .DB [SS_NOTIFY_STATE] then return $MCB_RETURN_CCB (.CCB);
CCB [C_HANDLE] = .DB [S_USER_HANDLE];
CCB [C_FNC] = FC_AST;
CCB [C_MOD] = DLL$K_STATE;
CCB [C_STS] = CURRENT_STATUS (DB [D_TIM]);
$MCB_SCHEDULE_CCB (.CCB);
if .DB [SS_NOTIFY_STATE]
then
if $MCB_GET_CCB (CCB)
then
SCHEDULE_STATE_AST (.CCB, DB [D_TIM])
else
$MCB_REQUEST_CCB ();
end; !of routine SCHEDULE_STATE_AST
routine SCHEDULE_TRANSIENT_AST
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
CCB [C_HANDLE] = .DB [S_USER_HANDLE];
CCB [C_FNC] = FC_AST;
CCB [C_MOD] = DLL$K_TRANSIENT_ERROR;
CCB [C_STS] = .DB [S_TRANSIENT_ERROR];
$MCB_SCHEDULE_CCB (.CCB);
DB [S_TRANSIENT_ERROR] = 0;
end; !of routine SCHEDULE_TRANSIENT_AST
routine SCHEDULE_TRANSMIT
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS),
STATUS)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB_STS novalue =
!
! SIDE EFFECTS:
! None
!--
begin
CCB [C_FNC] = FC_XCP;
CCB [C_STS] = .STATUS;
$MCB_SCHEDULE_CCB (.CCB);
DB [D_USER_BUFFERS] = .DB [D_USER_BUFFERS] - 1;
if .DB [D_USER_BUFFERS] neq 0 then return;
if .DB [S_CONTROL_CCB] neqa 0
then
begin
$MCB_SCHEDULE_CCB (.DB [S_CONTROL_CCB]);
DB [S_CONTROL_CCB] = 0;
end;
end; !of routine SCHEDULE_TRANSMIT
routine SEND_DATA
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if .DB [D_CONTROL_FLAGS] neq 0 then return;
if .DB [L_MESSAGES_AT_DRIVER] gtru 0 then return;
if not .DB [LS_STATION_ENABLED] then return;
DB [L_BABBLE_COUNT] = .DB [S_MAXIMUM_TRANSMITS] %(4)%;
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT] :
begin
if not (.DB [SS_SEND_START] or .DB [SS_SEND_STACK]) then return;
if (BUILD_CONTROL_MESSAGE (DB [D_TIM]) eqla 0) then return;
end;
[SS_RUNNING] :
begin
label
BUILD_MESSAGES;
BUILD_MESSAGES : begin
while (.DB [SS_SEND_REP] or .DB [SS_SEND_NAK]) do
if (BUILD_CONTROL_MESSAGE (DB [D_TIM]) eqla 0) then leave BUILD_MESSAGES;
if not .DB [SS_RETRANSMIT]
then
while .DB [L_MESSAGES_AT_DRIVER] lss .DB [L_MAXIMUM_AT_DRIVER] do
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (DB [S_WAITING_FOR_TRANSMIT], CCB) then exitloop;
if (BUILD_DATA_MESSAGE (DB [D_TIM], .CCB) eqla 0)
then
begin
$MCB_STACK_CCB (DB [S_WAITING_FOR_TRANSMIT], .CCB);
leave BUILD_MESSAGES;
end;
if (DB [L_BABBLE_COUNT] = .DB [L_BABBLE_COUNT] - 1) eql 0 then exitloop;
end;
if .DB [SS_SEND_SELECT] and (.DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] eqla 0)
then
DB [SS_SEND_ACK] = TRUE;
if .DB [SS_SEND_ACK]
then
BUILD_CONTROL_MESSAGE (DB [D_TIM]);
end;
end;
[SS_MAINTENANCE] :
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_DEQUEUE_CCB (DB [S_WAITING_FOR_TRANSMIT], CCB) then return;
if (BUILD_MAINTENANCE_MESSAGE (DB [D_TIM], .CCB) eqla 0)
then
begin
$MCB_STACK_CCB (DB [S_WAITING_FOR_TRANSMIT], .CCB);
return;
end;
end;
[inrange] : return;
tes;
if .DB [SS_SEND_SELECT] and (.DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] neqa 0)
then
begin
local
CCB : ref block field (C_FIELDS);
CCB = .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_LAST)];
DB [SS_SEND_SELECT] = FALSE;
begin
local
HEADER : ref block [H_LENGTH] field (HDR_FIELDS);
HEADER = .CCB [C_ADDR];
HEADER [H_SELECT] = TRUE;
end;
CCB [C_MOD] = FM_SYN;
if (CCB = .CCB [C_PRM4]) neqa 0
then
begin
local
HEADER : ref block [H_LENGTH] field (HDR_FIELDS);
HEADER = .CCB [C_ADDR];
HEADER [H_QSYNC] = TRUE;
end;
if .DB [L_DUPLEX] neq DL_FULL
then
DB [LS_STATION_ENABLED] = FALSE;
end;
begin
local
CCB : ref block field (C_FIELDS);
if (CCB = .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)]) neqa 0
then
SYNCHRONIZE (DB [D_TIM], .CCB);
end;
begin
external routine
$DDXME : DDM_CCB novalue;
FLUSH_QUEUE (DB [L_PRE_TRANSMIT], %quote $DDXME);
end;
end; !of routine SEND_DATA
routine SEND_PERSISTENT_ERROR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
STATUS)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_STS novalue =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS);
if .DB [S_USER_HANDLE] eql 0 then return;
DB [S_PERSISTENT_ERROR] = .STATUS;
if $MCB_GET_CCB (CCB)
then
SCHEDULE_PERSISTENT_AST (.CCB, DB [D_TIM])
else
$MCB_REQUEST_CCB ();
end; !of routine SEND_PERSISTENT_ERROR
routine SEND_STATE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS);
if .DB [S_USER_HANDLE] eql 0 then return;
if .DB [S_PROTOCOL_STATE] eql SS_HALTED then DB [SS_NOTIFY_OFF] = TRUE;
DB [SS_NOTIFY_STATE] = TRUE;
if $MCB_GET_CCB (CCB)
then
SCHEDULE_STATE_AST (.CCB, DB [D_TIM])
else
$MCB_REQUEST_CCB ();
end; !of routine SEND_STATE
routine SEND_TRANSIENT_ERROR
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
STATUS)
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_STS novalue =
!
! SIDE EFFECTS:
! None
!--
begin
local
CCB : ref block field (C_FIELDS);
if .DB [S_USER_HANDLE] eql 0 then return;
DB [S_TRANSIENT_ERROR] = .STATUS;
if $MCB_GET_CCB (CCB)
then
SCHEDULE_TRANSIENT_AST (.CCB, DB [D_TIM])
else
$MCB_REQUEST_CCB ();
end; !of routine SEND_TRANSIENT_ERROR
global routine SET_DEVICE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
while .DB [D_CONTROL_FLAGS] neq 0 do
begin
if .DB [SS_DEVICE_BEING_SET] then return;
selectone TRUE of
set
[.DB [DC_STOP_DEVICE]] :
if .DB [SS_DEVICE_RUNNING]
then
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_GET_CCB (CCB) then return $MCB_REQUEST_CCB ();
STOP_DEVICE (.CCB, DB [D_TIM]);
end
else
DB [DC_STOP_DEVICE] = FALSE;
[.DB [DC_START_DEVICE]] :
if not .DB [SS_DEVICE_RUNNING]
then
begin
local
CCB : ref block field (C_FIELDS);
if not $MCB_GET_CCB (CCB) then return $MCB_REQUEST_CCB ();
START_DEVICE (.CCB, DB [D_TIM]);
end
else
DB [DC_START_DEVICE] = FALSE;
[.DB [DC_SET_REQUESTED_STATE]] :
selectone TRUE of
set
[.DB [L_LINE_STATE] neq DL_ON]:
DB [DC_SET_REQUESTED_STATE] = FALSE;
[.DB [S_PROTOCOL_STATE] eql .DB [S_REQUESTED_STATE]] :
DB [DC_SET_REQUESTED_STATE] = FALSE;
[otherwise] :
begin
SET_LINK (DB [D_TIM], .DB [S_REQUESTED_STATE]);
DB [DC_SET_REQUESTED_STATE] = FALSE;
end;
tes;
tes;
end;
if .DB [S_PROTOCOL_STATE] eql SS_HALTED then return;
SEND_DATA (DB [D_TIM]);
end; !of routine SET_DEVICE
global routine SET_LINK
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
STATE)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [LS_STATION_ENABLED] = FALSE;
DB [SS_TIMING_REP] = FALSE;
DB [SS_RETRANSMIT] = FALSE;
DB [SS_START_REP_TIMER] = FALSE;
DB [LS_RESYNCH_IN_PROGRESS] = FALSE;
DB [SS_SEND_SELECT] = FALSE;
DB [SS_SEND_ACK] = FALSE;
DB [SS_SEND_REP] = FALSE;
DB [SS_SEND_NAK] = FALSE;
DB [SS_SEND_START] = FALSE;
DB [SS_SEND_STACK] = FALSE;
DB [S_R] = 0;
DB [S_TM1] = 0;
DB [S_X] = 0;
DB [S_N] = 0;
DB [S_A] = 0;
DB [S_AR] = 0;
DB [S_PENDING_NAK_REASON] = 0;
DB [S_TRANSMIT_THRESHOLD] = 7;
DB [S_RECEIVE_THRESHOLD] = 7;
DB [S_SELECT_THRESHOLD] = 7;
case .STATE from SS_LOW to SS_HIGH of
set
[SS_ISTRT, SS_ASTRT, SS_RUNNING] :
begin
if .DB [L_DUPLEX] eql DL_FULL
then
DB [SS_HALF_DUPLEX] = FALSE
else
DB [SS_HALF_DUPLEX] = TRUE;
DB [SS_SEND_START] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
DB [DC_START_DEVICE] = TRUE;
DB [SS_ACTIVE] = TRUE;
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_ISTRT, LCL);
end;
[SS_MAINTENANCE] :
begin
DB [SS_HALF_DUPLEX] = TRUE;
DB [DC_START_DEVICE] = TRUE;
DB [SS_ACTIVE] = TRUE;
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_MAINTENANCE, LCL);
end;
[inrange] :
begin
DB [DC_STOP_DEVICE] = TRUE;
DB [SS_ACTIVE] = FALSE;
CHANGE_PROTOCOL_STATE (DB [D_TIM], SS_HALTED, LCL);
end;
tes;
end; !of routine SET_LINK
global routine STARCE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCBR novalue =
!
! SIDE EFFECTS:
! None
!--
begin
external routine
$DDRCE : DDM_CCB novalue;
CCB [C_ADDR] = .CCB [C_ADDR] - H_LENGTH*%upval;
CCB [C_CNT] = .CCB [C_CNT] + H_LENGTH*%upval;
CCB [C_HANDLE] = .DB [L_DRIVER_HANDLE];
$DDRCE (.CCB);
end; !of routine STARCE
routine START_DEVICE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
external routine
$DDSET : DDM_CCB novalue;
DB [DC_START_DEVICE] = FALSE;
DB [SS_DEVICE_BEING_SET] = TRUE;
CCB [C_PRM4] = .DB [L_CLOCK];
CCB [C_PRM3] = .DB [L_CONTROLLER];
CCB [C_PRM2] = .DB [L_DUPLEX];
CCB [C_HANDLE] = .DB [L_DRIVER_HANDLE];
$DDSET (.CCB);
end; !of routine START_DEVICE
routine STOP_DEVICE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(CCB : ref block field (C_FIELDS),
DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
! None
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_CCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
external routine
$DDSTP : DDM_CCB novalue;
DB [DC_STOP_DEVICE] = FALSE;
DB [SS_DEVICE_RUNNING] = FALSE;
DB [SS_DEVICE_BEING_SET] = TRUE;
CCB [C_HANDLE] = .DB [L_DRIVER_HANDLE];
$DDSTP (.CCB);
end; !of routine STOP_DEVICE
routine STOP_LINK
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [DC_SET_REQUESTED_STATE] = TRUE;
DB [S_REQUESTED_STATE] = SS_HALTED;
SET_DEVICE (DB [D_TIM]);
CCB [C_FNC] = FC_XCP;
CCB [C_STS] = DLL$_SUCCESS;
$MCB_SCHEDULE_CCB (.CCB);
end; !of routine STOP_LINK
routine SYNCHRONIZE
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CCB_N0 novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if .DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_FIRST)] neqa 0
then
begin
local
HEADER : ref block field (HDR_FIELDS);
HEADER = .block [.DB [$SUB_FIELD (L_PRE_TRANSMIT, LIST_LAST)], C_ADDR];
HEADER [H_QSYNC] = TRUE;
end;
CCB [C_MOD] = FM_SYN;
end; !of routine SYNCHRONIZE
routine TERMINATE_SELECTION_INTERVAL
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if .DB [SS_TIMING_REP]
then
begin
DB [SS_START_REP_TIMER] = FALSE;
DB [SS_TIMING_REP] = FALSE;
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_ISTRT] :
begin
DB [SS_SEND_START] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_ASTRT] :
begin
DB [SS_SEND_STACK] = TRUE;
DB [SS_SEND_SELECT] = TRUE;
end;
[SS_RUNNING] :
begin
DB [SS_SEND_REP] = TRUE;
COUNTER_INCREMENT (DB, S_LOCAL_REPLY_TIMEOUTS);
TEST_TRANSMIT_THRESHOLD (DB [D_TIM]);
end;
[inrange] :
NO_OPERATION;
tes;
end;
DB [LS_STATION_ENABLED] = TRUE;
if .DB [SS_HALF_DUPLEX] then DB [SS_SEND_SELECT] = TRUE;
SEND_DATA (DB [D_TIM]);
end; !of routine TERMINATE_SELECTION_INTERVAL
routine TEST_RECEIVE_THRESHOLD
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_N0 novalue =
!
! SIDE EFFECTS:
! None
!--
begin
TEST_THRESHOLD (DB [D_TIM], DB [S_RECEIVE_THRESHOLD], 4, DLL$_RECEIVE_THRESHOLD);
end; !of routine TEST_RECEIVE_THRESHOLD
routine TEST_SELECT_THRESHOLD
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_N0 novalue =
!
! SIDE EFFECTS:
! None
!--
begin
TEST_THRESHOLD (DB [D_TIM], DB [S_SELECT_THRESHOLD], 5, DLL$_SELECTION_THRESHOLD);
end; !of routine TEST_SELECT_THRESHOLD
routine TEST_THRESHOLD
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CTR : ref block,
TYPE,
STS)
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_CTR_STS novalue =
!
! SIDE EFFECTS:
! None
!--
begin
macro
NUM = 0, 0, 8, 1 %;
CTR [NUM] = .CTR [NUM] - 1;
if .CTR [NUM] neq 0
then
begin
if .CTR [NUM] lss 0 then CTR [NUM] = 0;
return;
end;
if .DB [S_PROTOCOL_STATE] eql SS_RUNNING
then
CTR [NUM] = 7;
begin
external routine
PARAMETER_CIRCUIT_COUNTERS : LINKAGE_DB novalue;
$NM_DLL_EVENT (.TYPE, .DB [S_CIRCUIT_ENTITY],
PARAMETER_CIRCUIT_COUNTERS (DB [D_TIM]));
end;
SEND_TRANSIENT_ERROR (DB [D_TIM], .STS);
end; !of routine TEST_THRESHOLD
routine TEST_TRANSMIT_THRESHOLD
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: DCP_DB_N0 novalue =
!
! SIDE EFFECTS:
! None
!--
begin
TEST_THRESHOLD (DB [D_TIM], DB [S_TRANSMIT_THRESHOLD], 3, DLL$_TRANSMIT_THRESHOLD);
end; !of routine TEST_TRANSMIT_THRESHOLD
routine TIMCCB
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
map
CCB : ref block field (C_FIELDS);
label
RECOVERY;
do RECOVERY :
begin
if .DB [DC_STOP_DEVICE]
then
leave RECOVERY with STOP_DEVICE (.CCB, DB [D_TIM]);
if .DB [DC_START_DEVICE]
then
leave RECOVERY with START_DEVICE (.CCB, DB [D_TIM]);
if .DB [S_USER_HANDLE] eql 0 then return $MCB_RETURN_CCB (.CCB);
if .DB [SS_NOTIFY_STATE] or .DB [SS_NOTIFY_OFF]
then
leave RECOVERY with SCHEDULE_STATE_AST (.CCB, DB [D_TIM]);
if .DB [S_TRANSIENT_ERROR] neq 0
then
leave RECOVERY with SCHEDULE_TRANSIENT_AST (.CCB, DB [D_TIM]);
if .DB [S_PERSISTENT_ERROR] neq 0
then
leave RECOVERY with SCHEDULE_PERSISTENT_AST (.CCB, DB [D_TIM]);
return $MCB_RETURN_CCB (.CCB);
end
while $MCB_GET_CCB (CCB);
$MCB_REQUEST_CCB ();
end; !of routine TIMCCB
routine TIMPWF
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
NO_OPERATION;
end; !of routine TIMPWF
routine TIMLTM
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
if .DB [L_DUPLEX] neq DL_FULL
then
begin
COUNTER_INCREMENT (DB, S_SELECTION_TIMEOUTS);
COUNTER_INCREMENT (DB, SS_NRT);
TEST_SELECT_THRESHOLD (DB [D_TIM]);
end;
case .DB [S_PROTOCOL_STATE] from SS_LOW to SS_HIGH of
set
[SS_HALTED] :
return;
[SS_ISTRT, SS_ASTRT, SS_RUNNING] :
if .DB [L_DUPLEX] neq DL_FULL then RESYNCHRONIZE (DB [D_TIM]);
[SS_MAINTENANCE] :
RESYNCHRONIZE (DB [D_TIM]);
tes;
TERMINATE_SELECTION_INTERVAL (DB [D_TIM]);
end; !of routine TIMLTM
routine TRANSMIT
!++
! FUNCTIONAL DESCRIPTION:
!
!
! FORMAL PARAMETERS:
!
(DB : ref block field (D_FIELDS),
CCB : ref block field (C_FIELDS))
!
! IMPLICIT INPUTS:
!
! IMPLICIT OUTPUTS:
! None
!
! ROUTINE VALUE:
!
: MCB_DB_CCB novalue =
!
! SIDE EFFECTS:
! None
!--
begin
DB [D_USER_BUFFERS] = .DB [D_USER_BUFFERS] + 1;
if .DB [SS_ACTIVE]
then
begin
if .DB [S_PROTOCOL_STATE] eql SS_MAINTENANCE
then
begin
local
SAVE_MAP;
SMAP$ (SAVE_MAP);
MAP$ (.CCB [C_BIAS]);
selectone ch$rchar (.CCB [C_ADDR]) of
set
[8, 12]:
ch$wchar (28, ch$plus (.CCB [C_ADDR], 1));
tes;
MAP$ (.SAVE_MAP);
end;
$MCB_QUEUE_CCB (DB [S_WAITING_FOR_TRANSMIT], .CCB);
SEND_DATA (DB [D_TIM]);
end
else
SCHEDULE_TRANSMIT (.CCB, DB [D_TIM], DLL$_ABORTED);
end; !of routine TRANSMIT
end
eludom