@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            SYS074
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                            ISSUE 11~
~V9 -1
~P
~V9 1
~YSYS074
~M~OSYS IMPLEMENTATION DESCRIPTION
~
~M~OSection 7 Version 4
~S1~OSection 7.4 Communications input/output
~S1~O1. General Introduction
~BSee SYS072.~
~S1~O2.1 Hardware Interface
~BSee SYS072.~
~S1~O2.2 Software Interface
~S1See SYS072.~
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BThe procedures used by SYS072 from this submodule are:
~S11) COMMS.INPUT.TR.COMP (DEVICE NO) STATUS~
~BThe function of this procedure is obvious from the flowchart.~
~S12) COMMS.OUTPUT.TR.COMP (DEVICE NO) STATUS~
~BThe function of this procedure is obvious from the flowchart.~
~S13) COMMS.INPUT.TASK (DEVICE NO) STATUS~
~BThe function of this procedure is obvious from the flowchart.~
~S14) COMMS.INPUT.TR.TASK (DEVICE NO) STATUS~
~BThe function of this procedure is obvious from the flowchart.~
~S1~O3.2 Data Structures
~BSee SYS072.~
~S1~O3.3 Special Notes
~BNone.
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                SYS074
~V9 -1
~F
@TITLE SYS07(4,10)

@COL 1S-2R-3R-4R-5R-6F

@FLOW 1-2-3-4-5-6

@BOX 1.0
COMMUNICATIONS INPUT/OUTPUT MANAGEMENT
@BOX 4.0
PROCEDURES IN SECTION
   INT1 COMMUNICATIONS INPUT TRANSFER COMPLETE
   INT1 COMMUNICATIONS OUTPUT TRANSFER COMPLETE
   TSK1 COMMUNICATIONS INPUT TASK
   TSK1 COMMUNICATIONS OUTPUT TASK
@BOX 6.0
END OF SECTION
@BOX 1.1
::COMMUNICATIONS INPUT/OUTPUT MANAGEMENT
@BOX 4.1
::PROCEDURES IN SUB-MODULE
::*INIT %6000;
*CODE 2;
::PSPEC COMMS.INPUT.TR.COMP (INTEGER) / INTEGER;
::PSPEC COMMS.OUTPUT.TR.COMP (INTEGER) / INTEGER;
   #SYSINT07.1
   #SYSINT07.2
::*INIT %7000;
*CODE 4;
::PSPEC COMMS.INPUT.TASK (INTEGER) / INTEGER;
::PSPEC COMMS.OUTPUT.TASK (INTEGER) / INTEGER;
   #SYSTSK07.1
   #SYSTSK07.2
@BOX 6.1
**IN -1
::END OF SECTION
@END
@TITLE SYSINT07.1(4,10)
@COL 1S-3T-4T-5T-6R-7R-8R-9F
@COL 10R
@ROW 6-10
@FLOW 1-3NO-4NO-5NO-6-7-8-9
@FLOW 3YES-10-9
@FLOW 4YES-9
@FLOW 5YES-10
@BOX 1.0
COMMUNICATIONS INPUT TRANSFER COMPLETE (DEVICE.NO)
@BOX 3.0
ARE START OF MESSAGE OR
END OF MESSAGE SET?
@BOX 4.0
IS THERE MORE SPACE IN
CURRENT BUFFER BLOCK?
@BOX 5.0
AT END OF BUFFER SEGMENT?
@BOX 6.0
RELEASE CURRENT BUFFER BLOCK
[SYS14]
@BOX 7.0
FETCH NEXT BUFFER BLOCK TO CORE
[SYS14]
@BOX 8.0
SET UP CHARACTER COUNT AND
ADDRESS FOR THIS BLOCK
@BOX 9.0
END
@BOX 10.0
SET TASK REQUEST FOR THIS DEVICE
@BOX 1.1
PROC COMMS.INPUT.TR.COMP (DEV.NO);
SELECT IO.VARS [DEV.NO];
DEV.NO => V.IO.DEV.NO;
0 => COMMS.INPUT.TR.COMP;
@BOX 3.1
IF V.IO.CONTROL & (SOMR ! EOMR) /= 0
@BOX 4.1
IF COUNT > 0
@BOX 5.1
IF 1 +> BLOCK.NO = DOC.SIZE
@BOX 6.1
SYS14.UPDATE.BLOCK (BLOCK.RA);
SYS14.REL.BLOCK (BLOCK.RA);
@BOX 7.1
SYS14.GET.BLOCK (SEG, BLOCK.NO) => BLOCK.RA;
@BOX 8.1
BLOCK.RA => ADDRESS;
SYS14.PAGE.SIZE => COUNT;
@BOX 9.1
END
@BOX 10.1
1 => COMMS.INPUT.TR.COMP;
@END
@TITLE SYSINT07.2(4,10)
@COL 1S-3T-4T-5R-6R-7R-9R-10F
@COL 11R
@ROW 5-11
@FLOW 1-3NO-4NO-5-6-7-9-10
@FLOW 3YES-9
@FLOW 4YES-11-10
@BOX 1.0
COMMS OUTPUT TRANSFER COMPLETE (DEVICE NO)
@BOX 3.0
ARE THERE MORE CHARACTERS
IN CURRENT BUFFER BLOCK?
@BOX 4.0
WAS THIS THE LAST
BLOCK OF DOCUMENT?
@BOX 5.0
RELEASE CURRENT BUFFER BLOCK
[SYS14]
@BOX 6.0
FETCH NEXT BUFFER BLOCK TO CORE
[SYS14]
@BOX 7.0
SET UP CHARACTER COUNT
AND ADDRESS FOR THIS BLOCK
@BOX 9.0
SET UP COMMAND AND CHARACTER COUNT
FOR NEXT OUTPUT TRANSFER
@BOX 10.0
END
@BOX 11.0
SET TASK REQUEST FOR THIS DEVICE
@BOX 1.1
PROC COMMS.OUTPUT.TR.COMP (DEV.NO);
SELECT IO.VARS [DEV.NO];
0 => COMMS.OUTPUT.TR.COMP;
@BOX 3.1
IF COUNT +> BLOCK.COUNT > 0
@BOX 4.1
IF DOC.SIZE =< 0
@BOX 5.1
SYS14.REL.BLOCK (BLOCK.RA);
@BOX 6.1
SYS14.GET.BLOCK (SEG, 1 +> BLOCK.NO) => BLOCK.RA => ADDRESS;
@BOX 7.1
IF SYS14.PAGE.SIZE => BLOCK.COUNT > DOC.SIZE THEN
   DOC.SIZE => BLOCK.COUNT;
FI
BLOCK.COUNT -> DOC.SIZE;
@BOX 9.1
IF MAX.TR => COUNT > BLOCK.COUNT THEN
   BLOCK.COUNT => COUNT;
FI
IF DOC.SIZE + BLOCK.COUNT = COUNT THEN
   EOM.CMD => CONTROL;
FI
COUNT -> BLOCK.COUNT;
@BOX 10.1
END
@BOX 11.1
1 => COMMS.OUTPUT.TR.COMP;
@END
@TITLE SYSTSK07.1(4,10)
@COL 21R-15R-24N
@COL 1S-12T-2T-3T-6T-7R-26R-25N-8R-19N-9R-27N-10F
@COL 22N-11R-23N-13T-14R-29R-28N
@ROW 29-8
@ROW 27-28
@ROW 2-22
@ROW 3-23
@ROW 21-2
@ROW 15-7
@ROW 24-25
@FLOW 1-12TR COMP-2NO-3NO-6OK-7-26-25-8-19-9-27-10
@FLOW 12OTHER-21-24-25
@FLOW 2YES-22-11-28-27
@FLOW 3YES-23-13OK-14-19
@FLOW 6FAULTY-15-26
@FLOW 13FAIL-29-19
@BOX 1.0
COMMUNICATIONS INPUT TASK (DEVICE NO)
@BOX 2.0
TERMINATION ERROR?
(DOCUMENT TOO LONG OR
INCORRECTLY TERMINATED)
@BOX 3.0
START OF LONG MESSAGE?
@BOX 6.0
SEND THE MESSAGE
[SYSTSK07.3]
@BOX 7.0
SET COMMAND TO ACCEPT MESSAGE
@BOX 8.0
SET COUNT AND ADDRESS TO
READ A HEADER
@BOX 9.0
SET SOFTWARE INTERRUPT
FOR THE DEVICE
@BOX 10.0
END
@BOX 11.0
SWITCH TO HELD,
INFORM CONFIGURATION MANAGER
@BOX 12.0
TRANSFER COMPLETE INTERRUPT?
@BOX 13.0
CREATE BUFFER SEGMENT
@BOX 14.0
SET COMMAND TO READ
INTO THE SEGMENT
@BOX 15.0
SET COMMAND TO REJECT MESSAGE
@BOX 21.0
SET COMMAND TO START TRANSFER
@BOX 26.0
RESET STATUS OF DEVICE
@BOX 29.0
SET COMMAND TO REJECT MESSAGE
@BOX 1.1
PROC COMMS.INPUT.TASK (DEV.NO);
INTEGER ERROR, I;
INTEGER32 SEG.SIZE;
SELECT IO.VARS [DEV.NO];
0 => COMMS.INPUT.TASK;
@BOX 2.1
IF [IO.STATUS & BUFFERED /= 0 AND
      INT.STATUS & EOMR = 0] OR
   [IO.STATUS & BUFFERED = 0 AND
      INT.STATUS & SOMR = 0]
@BOX 3.1
IF SOMR ! EOMR & INT.STATUS = SOMR
@BOX 6.1
IF SEND.MESS (DEV.NO) => ERROR /= 0
@BOX 7.1
ACK.CMD => CONTROL;
@BOX 8.1
BUF.RA => ADDRESS;
BUF.SIZE => COUNT;
@BOX 9.1
1 => COMMS.INPUT.TASK;
@BOX 10.1
END
@BOX 11.1
TR.COMP & INT.STATUS -=> INT.STATUS;
HOLD (DEV.NO);
SYS19.HELD (DEV.NO, INT.STATUS);
@BOX 12.1
IF INT.STATUS & TR.COMP = 0
@BOX 13.1
FOR I < 4 DO
   SEG.SIZE <<- 8 ! HEADER^ [5 - I] => SEG.SIZE;
OD
CREATE.X.SEGMENT (SEG.SIZE + SYS14.PAGE.SIZE - 1
   ->> SYS14.PAGE.SHIFT => DOC.SIZE);
IF PW0 /= 0
@BOX 14.1
PW1 => SEG;
LONG.MESS ! BUFFERED !> IO.STATUS;
START.TR.CMD => CONTROL;
0 => ADDRESS => BLOCK.NO => PTR;
SYS14.PAGE.SIZE => COUNT;
@BOX 15.1
NAK.CMD => CONTROL;
IF SEG /= 0 THEN
   RELEASE.SEGMENT (SEG);
FI
@BOX 21.1
START.TR.CMD => CONTROL;
@BOX 26.1
IF IO.STATUS & LONG.MESS /= 0 THEN
   LONG.MESS ! BUFFERED & IO.STATUS -=> IO.STATUS;
   0 => SEG;
FI
@BOX 29.1
NAK.CMD => CONTROL;
BUF.RA => ADDRESS;
BUF.SIZE => COUNT;
@END
@TITLE SYSTSK07.2(4,10)
@COL 1S-3T-5T-6R-8R-9F
@COL 10N-11T-12R-13R
@ROW 5-10
@FLOW 1-3NO-5NO-6-8-9
@FLOW 3YES-8
@FLOW 5YES-10-11NO-12-13-9
@FLOW 11YES-13
@BOX 1.0
COMMS OUTPUT TASK (DEVICE NO)
@BOX 3.0
IS IT WAITING FOR A
DOCUMENT TO OUTPUT?
@BOX 5.0
IS THERE MORE OF THE CURRENT
DOCUMENT STILL TO BE OUTPUT?
@BOX 6.0
DISCARD THE CURRENT DOCUMENT
NOTE DEVICE WAITING FOR DOC.
@BOX 8.0
SET UP TO OUTPUT THE
NEXT DOCUMENT, IF ANY
#SYSTSK07.2.1
@BOX 9.0
END
@BOX 11.0
HEADER NOT YET COMPLETED OR
ALREADY OUTPUTTING SEGMENT?
@BOX 12.0
SWITCH TO OUTPUTTING SEGMENT
#SYSTSK07.2.2
@BOX 13.0
SET SOFTWARE INTERRUPT
@BOX 1.1
PROC COMMS.OUTPUT.TASK (DEV.NO);
ADDR [LOGICAL8] SEG.BYTE;
INTEGER BYTE.NO;
INTEGER32 SPN.PID, SEG.START, SEG.COUNT;
SELECT IO.VARS [DEV.NO];
0 => COMMS.OUTPUT.TASK;
@BOX 3.1
IF IO.STATUS & WAITING /= 0
@BOX 5.1
IF DOC.SIZE + BLOCK.COUNT + COUNT > 0
@BOX 6.1
IF IO.STATUS & LONG.MESS /= 0 THEN
   RELEASE.SEGMENT (SEG);
   LONG.MESS ! BUFFERED & IO.STATUS -=> IO.STATUS;
FI
WAITING !> IO.STATUS;
@BOX 8.1
:: READ NEXT DOCUMENT
#SYSTSK07.2.1
@BOX 9.1
END
@BOX 11.1
IF IO.STATUS & LONG.MESS = 0 OR
   IO.STATUS & BUFFERED /= 0 OR
   COUNT > 0
@BOX 12.1
:: OUTPUT SEGMENT
#SYSTSK07.2.2
@BOX 13.1
1 => COMMS.OUTPUT.TASK;
@END
@TITLE SYSTSK07.2.1(4,11)
@COL 1S-2T-3R-5R-6R-7R-8F
@FLOW 1-2OK-3-5-6-7-8
@FLOW 2NONE-8
@BOX 1.0
READ NEXT DOCUMENT
@BOX 2.0
READ MESSAGE FROM
PERIPHERAL CHANNEL
@BOX 3.0
NOTE THAT THE DEVICE IS
NOT WAITING FOR A DOCUMENT
@BOX 5.0
COMPUTE SIZE OF DOCUMENT
@BOX 6.0
SET UP POINTERS
TO OUTPUT HEADER
@BOX 7.0
SET SOFTWARE INTERRUPT
@BOX 8.0
END
@BOX 1.1
READ.NEXT.DOCUMENT: BEGIN
LOGICAL ACCESS;
:: IO.VARS [DEV.NO] SELECTED
@BOX 2.1
SYS15.READ.PERI.MESSAGE (HEADER, ^DEST, CH.NO, -1);
PW1 => SEG;
PW3 => ACCESS;
IF PW0 /= 0
@BOX 3.1
PW4 => UID;
WAITING -=> IO.STATUS;
@BOX 5.1
IF SEG /= 0 AND ACCESS & %C = %C THEN
   MAKE (LOGICAL8, 12, MAP.SEG (SEG)) => SEG.BYTE;
   PW1 <<- SYS14.PAGE.SHIFT => DOC.SIZE;
   SOM.CMD => CONTROL;
   LONG.MESS !> IO.STATUS;
ELSE
   0 => DOC.SIZE;
   SOM.EOM.CMD => CONTROL;
FI
@BOX 6.1
0 => BLOCK.COUNT;
BUF.RA => ADDRESS;
HEADER^ [0] + HEADER^ [1] => COUNT;
@BOX 7.1
1 => COMMS.OUTPUT.TASK;
@BOX 8.1
END
@END
@TITLE SYSTSK07.2.2(4,10)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
OUTPUT SEGMENT
@BOX 2.0
SET DEVICE STATUS TO "BUFFERED"
@BOX 3.0
COMPUTE STARTING ADDRESS
AND SIZE OF FIRST BLOCK
@BOX 4.0
COMPUTE COUNT FOR FIRST TRANSFER
@BOX 5.0
SELECT APPROPRIATE TRANSFER COMMAND
@BOX 6.0
END
@BOX 1.1
OUTPUT.SEGMENT: BEGIN
:: IO.VARS [DEV.NO] SELECTED
@BOX 2.1
BUFFERED !> IO.STATUS;
@BOX 3.1
0 => BLOCK.NO => ADDRESS;
SYS14.PAGE.SIZE => COUNT;
IF COUNT > DOC.SIZE THEN
   DOC.SIZE => COUNT;
FI
@BOX 4.1
IF COUNT > MAX.TR THEN
   COUNT - MAX.TR => BLOCK.COUNT;
   MAX.TR => COUNT;
ELSE
   0 => BLOCK.COUNT;
FI
@BOX 5.1
BLOCK.COUNT + COUNT -> DOC.SIZE;
IF DOC.SIZE + BLOCK.COUNT = 0 THEN
   EOM.CMD => CONTROL;
ELSE
   START.TR.CMD => CONTROL;
FI
@BOX 6.1
END
@END

