@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP3041
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP3041
~S1~M~OAP3 IMPLEMENTATION DESCRIPTION
~S1~M~OSection 4 Version 1
~S1~OSection 4.1 DZ11 Multiplexer Device Driver Appendix
~S1~O1. General Description
~BThis module is concerned with driving the
DZ11 multiplexer, described in the DEC handbook 'DZ11 User's Guide'.
~S1~O2. Interfaces~
Other modules used~
   AP1 Section 3 (I/O Appendix)~
Ideal hardware registers used~
   None~
Interrupt procedures~
   DZ11.INT - RAW M/C LEVEL~
   SPECIAL.CHAR (DEV/COND)~
Interface procedures~
   I.CONTROL (PHYS.DEV.NO, COMMAND, ADDR, COUNT, I.MODE) STATUS~
   O.CONTROL (PHYS.DEV.NO, COMMAND, ADDR, COUNT, O.MODE) DUMMY~
   POLL~
Interface variables~
   None~
Configuration parameters~
   NO.OF.DZ11S~
   NO.OF.DZ11.CHANNELS~
   NO.OF.DZ11.DEVICES~
   DZ11.ADDRS~
~S1~O2.1 MUSS Interface
~BThis module does not interface with MUSS in the normal
way.  Its only interface is a
procedural one with Appendix 1 Section 3 (the I/O Appendix).
~S1~O2.1.1 Hardware Interface
~BNone.
~S1~O2.1.2 Software Interface
~S11) I,CONTROL (PHYS.DEV.NO,COMMAND,BUFFER,ADDR,COUNT,I.O.MODE) STATUS
~BThis procedure implements the ideal input commands configure, disconnect, star
t,
disengage.  Some commands may result in immediate interrupts
(see 3.1), therefore this procedure returns a STATUS which contains
the interrupt status and count which would otherwise be returned by
calling the NOTIFY procedure of AP103.
~S12) O.CONTROL (PHYS.DEV.NO,COMMAND,BUFFER,ADDR,COUNT,I.O.MODE) DUMMY
~BThis procedure implements the ideal output commands configure,
disconnect, start, disengage.
~S1~O2.2 DZ11 Interface
~BSee DZ11 documentation.
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BThe devices under the control of this module are managed through
the CONTROL procedure.  This has a command
parameter which may specify the operations~
~
~Mconfigure  = 1
~Ndisconnect = 2
~Ndisengage  = 3
~Nstart      = 4-7
~
~
encoded as in V.IO.CONTROL.  Started devices operate under the
rules specified by the MODE parameter, encoded as in V.IO.MODE.
When the command is start, the ADDR and COUNT parameters specify
a device buffer.  They have no significance when the command
is disengage or disconnect and in the case of initialise the 'ADDR' parameter
actually gives the logical device number.  This number is used
as the device identification when the NOTIFY procedure of AP103
is called.
~BAn input device may be in one of four internal modes, started,
stopped, disengaged or disconnected.
When a specified stopping condition arises on a started device,
or when the device buffer becomes full, the main I/O appendix is
notified and stopped mode is entered.
However, there is an overrun buffer which
allows input (up to the size limit of the overrun buffer) to be
received whilst the device is apparently stopped.
When the overrun buffer is nearly full an attempt is made to
prevent further input by removing the ready to receive signal.
If input continues to arrive characters will be lost.  If an apparently
stopped device is started the contents of its overrun buffer are
immediately copied to the device buffer,
and if a stopping condition is detected stopped mode is
immediately entered, otherwise new input will be accepted into the device
buffer until a stopping condition arises.
~BIn order to keep the path length minimal, in the case when the
required interrupt action is to transfer a character between buffer
and device, a table lookup technique is used to identify special
action characters.  There is a table with one entry per character
which defines particular properties of characters as follows~
~3
~U 12
~
          ~O                 ~O
          ~O| | | | | | | | |~O
           | | | | | | | |
           | | | | | | |  -- 'LINE' TERMINATOR (CR, LF, FF)
           | | | | | |  ---- ETX
           | | | | |  ------ ALL CHARACTERS
           | | | |  -------- STX
           | | |  ---------- CR
           | |  ------------ DEL, BS
           |  -------------- BREAK (ETX)
            ---------------- XON/XOFF
~0
~
~
As each input character is processed it is '&'d with the device MODE and a
non-zero result causes the special action implied by the most
significant '1' to be initiated.  These actions are as follows~
~T% 13
~
%1) PAUSE OR RESUME output~
%2) Break both input and output~
%3) Delete previous character~
%4) Change CR to Newline (tnen act as for NL)~
%5) Start ignoring buffered prelude~
%6) Act according to status~
%7) Delete ETX and force transfer complete~
%8) Force transfer complete.~
In addition, the buffer full condition has to be detected.~
~BThe only special action required on output involves the
detection of the buffer being empty.~
~BWhen a device is disengaged its overrun buffer is cleared.
Receipt of the first input character from a disengaged device
will cause stopped state to be entered and an engaged notification
is sent to the main I/O appendix.
~BAn output device may only be started, stopped or disconnected.  Disengage is a
null command in the case of a DZ11 output channel.
~X%`
An output device may, however, be disengaged by requesting it to transmit %1F
~X%%
(ASCII group separator) character. Started devices
will output a character each time an interrupt is received
until the buffer is emptied, when stopped mode is assumed.
A started output device may be started again, in which case transfer
starts with the new count and address.
~BThe result returned by the I.CONTROL procedure
and the parameter of the NOTIFY procedure give the
interrupt status of the device, and, in the case of an
input transfer complete, a count of the number of
characters in the buffer.
~BA break condition can only occur when an input device is
started or when an output device is started/stopped. If the
output device is stopped, the break action will notify with
%0040 as the reason, otherwise as stated above.
~BAt system START UP time devices are put into disconnected mode.
The configure command may then
specify an operating mode and the mode will
switch to stopped.
~S~O3.1.1 Procedures Private to This Module
~S11) INIT(DEV.NO,L.DEV.NO,SETTINGS)
~BThis procedure is used to initialise a device whenever it is reconfigured.  A
successful
initialisation puts the device into disengage mode.
~S12) RAW.INT
~BThis procedure services the DZ11 I/O interrupts.  It is entered
directly from the interrupt vector and must therefore preserve the
register contents of any registers which it uses.  If the action
required is more than simply a transfer between device and buffer the
procedure will save the machine state and make a call into the
SPECIAL.CHAR procedure.
~S13) PROCESS.SPECIAL.CH(DEV.NO/COND)
~BThis procedure implements the device behaviour as described above.
~S14) COPY.OVERRUN()
~BThis procedure is used to copy characters from an overrun buffer
into the device buffer.
~S1~O3.2 Data Structures~
~T% 30
~
DZ11.PARAMS~IAn array indexed by device number holding the
information required by the 'raw' interrupt procedure, namely~
~
~IPTR/VAL OF BUFF.PTR~
~ICOUNT~
~IMODE~
~IREQ.MODE~
~
DZ11.STATUS
~IAn array, indexed by device number, holding the status
of the device.~
~
INIT.I.COUNT~IAn array indexed by input device number,
holding the initial count of each
input transfer.~
~
CH.TABLE~IAn array of bytes indexed by character code.  The
bit encoding of the byte associated with each character indicates
whether or not it is special in any of the senses encoded into the
I.O.MODE.~
~
OVERRUN.AREA~IAn array of bytes into which the overrun buffers
are mapped.~
~
OVERRUN.BUFFS~IAn array indexed by input device number
(device number/2) holding the starting address of each overrun buffer.~
~
OVERRUN.SIZE~IAn integer literal giving the overrun buffer size.~
~
DZ11.L.DEV
~IAn array, indexed by device number, giving the ideal
device corresponding to a DZ11 device.~
~
NO.OF.DZ11S~IAn integer literal specifying the number
of DZ11's serviced.~
~
NO.OF.CHANNELS
~IAn integer literal, specifying the total number of the
DZ11 channels.~
~
NO.OF.DEVICES~IAn integer literal, specifying the total number
of input/output devices.~
~
DZ11.ADDRS~IA data vector giving the bus address of each DZ11 device.~
~S1~O3.3 Special Notes
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               AP3041
~V9 -1
~F
@TITLE AP304.DZ11(1,10)

@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
DZ11 DRIVER
@BOX 4.0
PROCEDURES IN MODULE:
   1 I CONTROL
   2 O CONTROL
   3 INIT
   4 RAW INPUT INT
   5 RAW OUTPUT INT
   6 PROCESS SPECIAL I CH
   7 PROCESS SPECIAL O CH
   8 ENTER OVERRUN
   9 POLL
@BOX 6.0
END
@BOX 1.1
#AP304.DZ11/1
MODULE DZ11 (I.CONTROL, O.CONTROL, POLL);
@BOX 2.1
TYPE PTR.TYPE IS
   ADDR VAL
OR
   ADDR LOGICAL8 PTR;
TYPE DZ11.PARAMS.TYPE IS
   PTR.TYPE BUFF.PTR
   INTEGER16 COUNT
   LOGICAL8 MODE, BIT.MASK;
@BOX 3.1
:: DATA DECLARATIONS
#AP304.DZ11/2
@BOX 4.1
*CODE 23;
PSPEC I.CONTROL (INTEGER, INTEGER, ADDR, LOGICAL, LOGICAL32) / LOGICAL32;
PSPEC O.CONTROL (INTEGER, INTEGER, ADDR, LOGICAL, LOGICAL32) / LOGICAL32;
PSPEC INIT (LOGICAL, LOGICAL, LOGICAL32);
:: RAW.INT
PSPEC PROCESS.SPECIAL.I.CH (INTEGER);
PSPEC PROCESS.SPECIAL.O.CH (INTEGER);
PSPEC ENTER.OVERRUN (INTEGER);
PSPEC POLL ();
   #AP304.DZ11.1
   #AP304.DZ11.2
   #AP304.DZ11.3
   #AP304.DZ11.4
   #AP304.DZ11.5
   #AP304.DZ11.6
   #AP304.DZ11.7
   #AP304.DZ11.8
   #AP304.DZ11.9
@BOX 5.1
*CODE 7;
PSPEC INIT.AP304 ();
INIT.AP304 ();
PROC INIT.AP304;
INTEGER I, J;
ADDR OB.ADDR;
ADDR [LOGICAL16] CSR;
*VTYPE LABEL;
VSTORE VEC.LABEL %80030064;
*VTYPE LOGICAL32;
VSTORE VEC.ADDR %80030064;
VSTORE INT.STORE [%FFFF] %80040000;
VSTORE WORKSPACE.PTR %80030064;
VSTORE CSR.PTR %80030068;
TYPE PROC.ADDR.TYPE IS
   ADDR PROCESS.SPECIAL.I.CH P
OR
   LOGICAL32 PROC.ADDRESS;
PROC.ADDR.TYPE PROC.ADDR;
RAW.INPUT.INT.0 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB0];
RAW.OUTPUT.INT.0 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB1];
RAW.INPUT.INT.1 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB2];
RAW.OUTPUT.INT.1 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB3];
RAW.INPUT.INT.2 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB4];
RAW.OUTPUT.INT.2 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB5];
RAW.INPUT.INT.3 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB6];
RAW.OUTPUT.INT.3 => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%CB7];
^PROCESS.SPECIAL.I.CH => P OF PROC.ADDR;
PROC.ADDRESS OF PROC.ADDR => INT.STORE [%DB0]
   => INT.STORE [%DB2] => INT.STORE [%DB4] => INT.STORE [%DB6];
^PROCESS.SPECIAL.O.CH => P OF PROC.ADDR;
PROC.ADDRESS OF PROC.ADDR => INT.STORE [%DB1]
   => INT.STORE [%DB3] => INT.STORE [%DB5] => INT.STORE [%DB7];
BYTE (^DZ11.PARAMS [0]) => WORKSPACE.PTR;
BYTE (^DZ11.ADDRS [0]) => CSR.PTR;
BYTE (^OVERRUN.AREA) => OB.ADDR;
FOR I < NO.OF.DZ11.CHANNELS DO
   OB.ADDR => OVERRUN.BUFFS [I];
   OVERRUN.SIZE +> OB.ADDR;
OD
FOR I < NO.OF.DZ11S DO
   IF DZ11.ADDRS [I] /= 0 THEN
      MAKE (LOGICAL16, 4, DZ11.ADDRS [I]) => CSR;
      %10 => CSR^ [0];
   FI
OD
END
@BOX 6.1
*END
@END
@TITLE AP304.DZ11/1(1,10)

@COL 1S-2R-3R
@FLOW 1-2-3
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 1.1
:: EXTERNAL ENVIRONMENT
@BOX 2.1
IMPORT LITERAL INTEGER NO.OF.DZ11S, NO.OF.DZ11.CHANNELS,
   NO.OF.DZ11.DEVICES, OVERRUN.SIZE, DZ11.OVERRUN.AREA.SIZE,
   START.TR.CMD, START.COMMS.CMD, INIT.CMD, DISENGAGE.CMD, CON.OUT.CMD,
   TR.COMP, TR.FAILED, BREAKIN, ENGAGE.DEV, DISENGAGE.DEV, DEV.DISENGAGED;
ADDR [NO.OF.DZ11S] DZ11.ADDRS;
@BOX 3.1
PSPEC NOTIFY (INTEGER, LOGICAL, LOGICAL);
LOGICAL8 [256] I.CH.TABLE, O.CH.TABLE;
@END
@TITLE AP304.DZ11/2(1,10)

@COL 1S
@BOX 1.0
DATA DECLARATIONS
@BOX 1.1
*GLOBAL 5;
LITERAL / INTEGER CSR = 0, RBUF = 1, LPR = 1, TCR = 2, MSR = 3, TDR = 3;
LITERAL / LOGICAL8 ETX = 3, LF = %A, CR = %D, XON = %11, XOFF = %13, BS = %8;
LITERAL / LOGICAL8 CONNECTED = 1, ENGAGED = 2, OVERRUN = 4,
   STARTED = 8, PRELUDE = 16, FREE = %20, DISCONNECTED = %FE, DISENGAGED = %FD,
   STOPPED = %F7, NOT.PRELUDE = %EF, SUSPENDED = %DF, ALL = 4, ECHO.ON = %10,
   OVERRUN.MASK = %F8, COPY.MASK = 7, NORMAL = %FB, LINE.MODE = 1, EDULERP = %1E
;
DZ11.PARAMS.TYPE [NO.OF.DZ11.DEVICES] DZ11.PARAMS;
INTEGER [NO.OF.DZ11.DEVICES] DZ11.L.DEV;
LOGICAL8 [NO.OF.DZ11.DEVICES] DZ11.STATUS, REQ.MODE;
LOGICAL16 [NO.OF.DZ11.CHANNELS] STOP.RX;
*GLOBAL 24;
LOGICAL8 [DZ11.OVERRUN.AREA.SIZE] OVERRUN.AREA;
*GLOBAL 5;
INTEGER [NO.OF.DZ11.CHANNELS] XOFF.COUNT, TIMEOUT, INIT.I.COUNT;
ADDR [LOGICAL16] [NO.OF.DZ11S] DZ11.CSR;
ADDR [NO.OF.DZ11.CHANNELS] OVERRUN.BUFFS;
DATAVEC SETBIT (LOGICAL8)
%01 %02 %04 %08 %10 %20 %40 %80
END
DATAVEC CLEARBIT (LOGICAL16)
   %FFFE  %FFFD  %FFFB  %FFF7
   %FFEF  %FFDF  %FFBF  %FF7F
END
DATAVEC BR.CONSTANT (LOGICAL16)
   %200 ::110
   %500 ::300
   %700 ::1200
   %A00 ::2400
   %C00 ::4800
   %E00 ::9600
END
DATAVEC BITS.PARITY (LOGICAL8)
%40 %C0 %00 %00 %48 %C8 %08 %08
%50 %D0 %10 %10 %58 %D8 %18 %18
%60 %E0 %20 %20 %68 %E8 %28 %28
%70 %F0 %30 %30 %78 %F8 %38 %38
%60 %E0 %20 %20 %68 %E8 %28 %28
%70 %F0 %30 %30 %78 %F8 %38 %38
%60 %E0 %20 %20 %68 %E8 %28 %28
%70 %F0 %30 %30 %38 %F8 %38 %38
END
@END

@TITLE AP304.DZ11.1(1,10)

@COL 9T-10R-12T-11R-16T-13R-17R
@COL 1S-18T-14R-2T-3T-5R-6R-15R-7F
@COL 19R-8T-20N
@ROW 14-19
@ROW 3-9
@ROW 8-10
@ROW 5-12
@ROW 6-13
@ROW 17-15-20
@FLOW 1-18NO-14-2TRANSFER-3NO-5-6-15-7
@FLOW 8YES-20-7
@FLOW 18YES-19-20
@FLOW 3YES-8NO-5
@FLOW 2NON TRANSFER-9YES-10-11
@FLOW 9NO-12YES-11-15
@FLOW 12NO-16YES-13-7
@FLOW 16N0-17-7
@BOX 1.0
I CONTROL (DEV, COMMAND, BUFF.ADDR, I.SIZE, I.MODE)
-ASSUMES INTERRUPTS INHIBITED-
@BOX 2.0
CHECK COMMAND TYPE
@BOX 3.0
OVERRUN STATE
@BOX 5.0
SET BUFF.PTR/SIZE/MODE
IN DZ11.PARAMS FOR DEV
@BOX 6.0
NOTE STATUS
@BOX 7.0
END
@BOX 8.0
COPY OVERRUN BUFFER
TO DEVICE BUFFER
#AP304.DZ11.1.1
IS DEVICE STOPPED?
@BOX 9.0
CONFIGURE COMMAND?
@BOX 10.0
INITIALISE DEVICE
[AP304.DZ11.3]
@BOX 11.0
SET DISENGAGED STATUS AND
SET NOTIFY ON ALL CHARS MODE
@BOX 12.0
DISENGAGE COMMAND?
@BOX 13.0
SET DISCONNECTED STATUS
AND DISABLE RECEIVER
@BOX 14.0
SELECT DEVICE PARAMETERS
@BOX 15.0
START DEVICE
@BOX 16.0
DISCONNECT COMMAND?
@BOX 17.0
RETURN DEVICE STATUS
@BOX 18.0
INVALID DEVICE?
@BOX 19.0
RETURN FAIL STATUS
@BOX 1.1
PROC I.CONTROL (DEV, CMD, BUFFER, I.SIZE, I.MODE);
INTEGER OVERRUN.CHARS, DZ11;
0 => I.CONTROL => OVERRUN.CHARS;
@BOX 2.1
IF CMD & START.TR.CMD = 0
@BOX 3.1
IF CMD /= START.COMMS.CMD AND
   DZ11.STATUS [DEV] & OVERRUN /= 0
@BOX 5.1
BUFFER + OVERRUN.CHARS => VAL OF BUFF.PTR;
I.SIZE => INIT.I.COUNT [DEV ->> 1]
   - OVERRUN.CHARS => COUNT;
REQ.MODE [DEV] => MODE;
@BOX 6.1
NORMAL & DZ11.STATUS [DEV]
   ! STARTED => DZ11.STATUS [DEV];
@BOX 7.1
END
@BOX 8.1
:: COPY OVERRUN
#AP304.DZ11.1.1
IF I.CONTROL = 0
@BOX 9.1
IF CMD /= INIT.CMD
@BOX 10.1
INIT (DEV, BUFFER, I.MODE);
%60 !> DZ11.CSR [DZ11]^ [0];
@BOX 11.1
ENTER.OVERRUN (DEV);
STARTED !> DZ11.STATUS [DEV];
DISENGAGED &> DZ11.STATUS [DEV];
REQ.MODE [DEV] & %80 ! ALL => MODE;
DISENGAGE.DEV => I.CONTROL;
@BOX 12.1
IF CMD /= DISENGAGE.CMD
@BOX 13.1
DISCONNECTED &> DZ11.STATUS [DEV];
STOP.RX [DEV ->> 1] => DZ11.CSR [DZ11]^ [LPR];
@BOX 14.1
SELECT DZ11.PARAMS [DEV];
@BOX 15.1
STOP.RX [DEV ->> 1] ! %1000 => DZ11.CSR [DZ11]^ [LPR];
@BOX 16.1
IF CMD /= CON.OUT.CMD
@BOX 17.1
IF DZ11.STATUS [DEV] & ENGAGED = 0 THEN
   DEV.DISENGAGED !> I.CONTROL;
FI
@BOX 18.1
IF DEV ->> 4 => DZ11 >= NO.OF.DZ11S
   OR DZ11.ADDRS [DZ11] = 0
@BOX 19.1
IF CMD /= 0 THEN
   TR.FAILED !> I.CONTROL;
ELSE
   DEV.DISENGAGED !> I.CONTROL;
FI
@END
@TITLE AP304.DZ11.1.1(1,10)

@COL 1S-2T-3R-4R-5R-6R-7R-8F
@FLOW 1-2YES-3-4-5-6-7-8
@FLOW 2NO-8
@BOX 1.0
COPY OVERRUN BUFFER
@BOX 2.0
ANY OVERRUN
@BOX 3.0
SET OVERRUN.CHARS TO THE MAXIMUM AMOUNT
OF OVERRUN WHICH THE DEVICE BUFFER WILL HOLD
AND SET RESULT IF BUFFER FULL CONDITION IMPLIED
@BOX 4.0
RESET OVERRUN.CHARS TO EXCLUDE ANY
OVERRUN AFTER MOST RECENT NOTIFY CONDITION
AND RESET RESULT ACCORDINGLY
@BOX 5.0
COPY THE AMOUNT SPECIFIED BY OVERRUN.CHARS
FROM OVERRUN TO DEVICE BUFFERS
@BOX 6.0
DELETE COPIED CHARS FROM
OVERRUN BUFFER
@BOX 7.0
REMOVE ETX FROM END OF DEV BUFFER IF ANY
@BOX 8.0
END
@BOX 1.1
:: COPY OVERRUN
BEGIN
INTEGER I, K, COPY.MODE;
ADDR [LOGICAL8] DEV.B, ORUN.B;
MAKE (LOGICAL8, I.SIZE, BUFFER) => DEV.B;
MAKE (LOGICAL8, OVERRUN.SIZE, OVERRUN.BUFFS [DEV ->> 1]) => ORUN.B;
@BOX 2.1
IF OVERRUN.SIZE - COUNT => OVERRUN.CHARS = 0
@BOX 3.1
IF OVERRUN.CHARS > I.SIZE THEN
   I.SIZE => OVERRUN.CHARS;
   TR.COMP => I.CONTROL;
FI
@BOX 4.1
REQ.MODE [DEV] & COPY.MASK => COPY.MODE;
FOR I < OVERRUN.CHARS DO
   IF I.CH.TABLE [ORUN.B^ [OVERRUN.CHARS - I - 1]] & COPY.MODE /= 0 THEN
      I -> OVERRUN.CHARS;
      TR.COMP => I.CONTROL;
      -> OUT;
   FI
OD
0 => I;
OUT:
@BOX 5.1
FOR K < OVERRUN.CHARS DO
   ORUN.B^ [K] => DEV.B^ [K];
OD
@BOX 6.1
FOR K < I DO
   ORUN.B^ [K + OVERRUN.CHARS] => ORUN.B^ [K];
OD
OVERRUN.CHARS -> VAL OF BUFF.PTR;
OVERRUN.CHARS +> COUNT;
IF I.CONTROL /= 0 THEN
   I.SIZE - OVERRUN.CHARS <<- 16 !> I.CONTROL;
FI
@BOX 7.1
IF REQ.MODE [DEV] & 2 /= 0 AND
   DEV.B^ [OVERRUN.CHARS - 1] = ETX THEN
   1 -> OVERRUN.CHARS;
FI
@BOX 8.1
END
@END
@TITLE AP304.DZ11.2(1,10)

@COL 9T-10R-12T-11R-15T-13R-16R
@COL 1S-20T-14R-2T-3T-17T-5R-6R-7F
@COL 21R-4R-18R-19N
@ROW 2-21
@ROW 3-9
@ROW 5-18
@ROW 6-16
@FLOW 1-20NO-14-2TRANSFER-3NO-17NO-5-6-7
@FLOW 2NON TRANSFER-9YES-10-7
@FLOW 3YES-4-19-7
@FLOW 9NO-12YES-11-7
@FLOW 12NO-15YES-13-7
@FLOW 15NO-16-7
@FLOW 17YES-18-19
@FLOW 20YES-21-19
@BOX 1.0
O CONTROL (DEV, COMMAND, BUFF.ADDR, O.SIZE, O.MODE)
-ASSUMES INTERRUPTS INHIBITED-
@BOX 2.0
CHECK COMMAND TYPE
@BOX 3.0
BUFFER EMPTY?
@BOX 4.0
RETURN TRANSFER COMPLETE
STATUS
@BOX 5.0
SET BUFF.PTR/SIZE/MODE
IN DZ11.PARAMS FOR DEV
@BOX 6.0
START DEVICE AND
NOTE STATUS
@BOX 7.0
END
@BOX 9.0
CONFIGURE COMMAND?
@BOX 10.0
INITIALISE DEVICE
[AP304.DZ11.3]
AND SET STOPPED STATUS
@BOX 11.0
SET DISENGAGE STATUS
@BOX 12.0
DISENGAGE COMMAND?
@BOX 13.0
SET DISCONNECTED STATUS
@BOX 14.0
SELECT DEVICE PARAMETERS
@BOX 15.0
DISCONNECT COMMAND?
@BOX 16.0
RETURN DEVICE STATUS
@BOX 17.0
OUTPUT SUSPENDED?
@BOX 18.0
NOTE REQUIRED COUNT
@BOX 20.0
INVALID DEVICE?
@BOX 21.1
RETURN FAIL STATUS
@BOX 1.1
PROC O.CONTROL (DEV, CMD, BUFFER, O.SIZE, O.MODE);
INTEGER DZ11;
0 => O.CONTROL;
@BOX 2.1
IF CMD & START.TR.CMD = 0
@BOX 3.1
IF O.SIZE = 0
@BOX 4.1
TR.COMP
   => O.CONTROL;
@BOX 5.1
BUFFER => VAL OF BUFF.PTR;
O.SIZE => COUNT;
REQ.MODE [DEV] => MODE;
@BOX 6.1
STARTED !> DZ11.STATUS [DEV];
SET.BIT [DEV ->> 1 & %7] !> DZ11.CSR [DZ11]^ [TCR];
%4020 !> DZ11.CSR [DZ11]^ [0];
@BOX 7.1
END
@BOX 9.1
IF CMD /= INIT.CMD
@BOX 10.1
INIT (DEV, BUFFER, O.MODE);
0 => BIT.MASK;
STOPPED &> DZ11.STATUS [DEV];
FREE ! ENGAGED !> DZ11.STATUS [DEV];
@BOX 11.1
DISENGAGED &> DZ11.STATUS [DEV];
DISENGAGE.DEV !> O.CONTROL;
@BOX 12.1
IF CMD /= DISENGAGE.CMD
@BOX 13.1
DISCONNECTED &> DZ11.STATUS [DEV];
@BOX 14.1
SELECT DZ11.PARAMS [DEV];
@BOX 15.1
IF CMD /= CON.OUT.CMD
@BOX 16.1
STOPPED &> DZ11.STATUS [DEV];
0 => COUNT;
IF DZ11.STATUS [DEV] & ENGAGED = 0 THEN
   DEV.DISENGAGED !> O.CONTROL;
FI
@BOX 17.1
IF DZ11.STATUS [DEV] & FREE = 0
@BOX 18.1
STARTED !> DZ11.STATUS [DEV];
BUFFER => VAL OF BUFF.PTR;
O.SIZE => XOFF.COUNT [DEV ->> 1];
REQ.MODE [DEV] => MODE;
@BOX 20.1
IF DEV ->> 4 => DZ11 >= NO.OF.DZ11S
   OR DZ11.ADDRS [DZ11] = 0
@BOX 21.1
IF CMD /= 0 THEN
   TR.FAILED => O.CONTROL;
ELSE
   DEV.DISENGAGED => O.CONTROL;
FI
@END
@TITLE AP304.DZ11.3(1,10)

@COL 1S-6R-4R-2R-3R-9R-5F
@FLOW 1-6-4-2-3-9-5
@BOX 1.0
INIT (PHYSICAL DEV NO, LOGICAL DEV NO, SETTINGS)
@BOX 2.0
GENERATE CONTROL REGISTER ADDRESS
@BOX 3.0
SET UP BAUD RATE
@BOX 4.0
SET UP DEVICE MODE
@BOX 5.0
END
@BOX 6.0
NOTE LOGICAL DEVICE NO
@BOX 9.0
SET CHARACTER SIZE
PARITY AND STOP BITS
@BOX 1.1
PROC INIT (DEV, L.DEV, SET);
INTEGER BAUD, LINE.INIT;
ADDR [LOGICAL16] CSR;
DATAVEC BIT.MASKS (LOGICAL8)
   %1F %3F %7F %FF
END
@BOX 2.1
MAKE (LOGICAL16, 4, DZ11.ADDRS [DEV ->> 4])
 => CSR => DZ11.CSR [DEV ->> 4];
@BOX 3.1
SET ->> 14 & %F => BAUD;
IF BAUD >= SIZE (^BR.CONSTANT) THEN
   SIZE (^BR.CONSTANT) - 1 => BAUD;
FI
BR.CONSTANT [BAUD] => BAUD;
@BOX 4.1
SET => REQ.MODE [DEV];
@BOX 5.1
END
@BOX 6.1
L.DEV => DZ11.L.DEV [DEV];
@BOX 9.1
BIT.MASKS [SET ->> 10 & 3] => BIT.MASK OF DZ11.PARAMS [DEV];
DEV ->> 1 & 7 ! BITS.PARITY [SET ->> 8 & %3F] !> BAUD ! %1000 => CSR^ [LPR];
IF DEV & 1 = 0 THEN
   BAUD => STOP.RX [DEV ->> 1];
FI
@END
@TITLE AP304.DZ11.4(1,10)
@COL 1S-2R-3R-4R-5T-6R-7T-8T-16R-9N-10R-11F
@COL 12T-13N-14R-15N
@ROW 6-12
@ROW 8-13
@ROW 9-15
@FLOW 1-2-3-4-5NO-6-7NO-8NO-16-9-10-11
@FLOW 5YES-12BREAK-13-14
@FLOW 7YES-13-14
@FLOW 8YES-13-14
@FLOW 12-15-9
@BOX 1.0
RAW INPUT INTERRUPT
@BOX 2.0
STACK REGISTERS
@BOX 3.0
SET POINTERS TO DZ11 CHANNEL
@BOX 4.0
GET CHARACTER AND SET
POINTER TO CORRESPONDING PARAMETERS
@BOX 5.0
ANY FAULT?
@BOX 6.0
PLACE CHARACTER IN BUFFER
@BOX 7.0
SPECIAL CHARACTER?
@BOX 8.0
IS BUFFER FULL?
@BOX 10.0
UNSTACK REGISTERS
AND RETURN FROM INTERRUPT
@BOX 11.0
END
@BOX 12.0
BREAK?
@BOX 14.0
ENTER PROCESS SPECIAL I CH
#AP304.DZ11.4
@BOX 16.0
ECHO CHARACTER
IF NECESSARY
@BOX 1.1
RAW.INPUT.INT.0: ::STACK DZ11 NUMBER;
   *#%01 %01 %01 %01;
   *#%DD %00 ::PUSHL #0;
   -> RAW.INPUT.INT;

RAW.INPUT.INT.1: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %01 ::PUSHL #1;
   -> RAW.INPUT.INT;

RAW.INPUT.INT.2: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %02 ::PUSHL #2;
   -> RAW.INPUT.INT;

RAW.INPUT.INT.3: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %03 ::PUSHL #3;
   -> RAW.INPUT.INT;

RAW.INPUT.INT: BEGIN
@BOX 2.1
*#%BB %8F %3F %00 ::PUSHR %003F;
@BOX 3.1
::R0 = DZ11 REGISTER ADDRESS
*#%D0 %AE %18 %52 ::MOVL %18(R14), R2;
*#%D0 %9F %68 ::MOVL @CSR.PTR, R1;
*#%00 %03 %80 %51;
*#%D0 %42 %61 %50 ::MOVL (R1)[R2], R0;
*#%D0 %8F %40 %00 ::MOVL #40, R4;
*#%00 %00 %54;
@BOX 4.1
::R3 = DATA
*#%B0 %A0 %02 %53 ::MOVW 2(R0), R3;
::R1 = ADDRESS OF PARAMETERS
*#%78 %8F %FC %53 %51 ::ASHL - 4, R3, R1;
*#%CA %8F %8F %FF ::BICL #FFFFFF8F, R1;
*#%FF %FF %51;
*#%78 %07 %52 %52 ::ASHL #7, R2, R2;
*#%C0 %52 %51 ::ADD2 R2, R1;
*#%D0 %51 %55 ::MOVL R1, R5;
*#%C0 %9F %64 %00 ::ADDZ PARAMETER, R1;
*#%03 %80 %51;
::R2 = BUFFER ADDRESS
*#%D0 %61 %52 ::MOVL (R1) R2;
@BOX 5.1
*#%B3 %8F %00 %70 %53 ::BITW #7000, R3;
*#%13 %03 ::BEQL + 3;
-> RII.12;
::IGNORE JUMP
@BOX 6.1
*#%9A %53 %53 ::MOVZBL R3, R3;
*#%92 %A1 %07 %54 ::MCOMB 7(R1), R4;
*#%8A %54 %53 ::BICB2 R4, R3;
*#%90 %53 %82 ::MOVB R3, (R2)+;
*#%D0 %52 %61 ::MOVL R2, (R1);
*#%B7 %A1 %04 ::DECW 4(R1);
@BOX 7.1
*#%D0 %9F %5C ::MOVL @I.CH.TABLE.PTR, R2;
*#%00 %03 %80 %52;
*#%92 %42 %63 %54 ::MCOMB (R3) [R2], R4;
*#%8B %54 %A1 %06 %54 ::BICB3 R4, 6(R1), R4;
*#%13 %03 ::BEQL + 3;
-> RII.14; ::IGNORE FLIP JUMP
@BOX 8.1
*#%B5 %A1 %04 ::TSTW 4(R1);
*#%13 %03 ::BEQL + 3;
-> ECHO;
*#%D0 %01 %54 ::MOVL #1, R4;
-> RII.14; ::IGNORE FLIP JUMP
@BOX 10.1
OUT:
*#%BA %8F %3F %00 ::POPR %003F;
*#%D5 %8E ::REMOVE PARAMETER;
*#%02 ::REI;
@BOX 11.1
END
@BOX 12.1
RII12:
::LOOK FOR FRAMING ERROR
*#%B3 %8F %00 %20 ::BITW #%2000, R3;
*#%53;
*#%12 %02 ::BNEQ + 2;
-> OUT;
::IGNORE FLIP JUMP
@BOX 14.1
RII.14:
#AP304.DZ11.4.1
@BOX 16.1
ECHO:
*#%93 %10 %A1 %0E ::BITB #10, E(R1);
*#%12 %03 ::BNEQ +3;
-> OUT;
*#%90 %53 %A1 %0F ::MOVB R3, F(R1);
*#%78 %8F %FC %55 %55 ::ASHL - 4, R5, R5;
*#%CA %8F %F8 %FF ::BICL2 #FFFFFFF8, R5;
*#%FF %FF %55;
*#%78 %55 %01 %55 ::ASHL R5, #1, R5;
*#%A8 %55 %A0 %04 ::BISW R5, 4(R0);
@END
@TITLE AP304.DZ11.4.1(1,10)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
ENTER PROCESS SPECIAL I CH
@BOX 2.0
OBTAIN CONDITION INDEX
@BOX 3.0
GENERATE DEV NO / CONDITION INDEX
ON STACK
@BOX 4.0
UNSTACK REGISTERS, STACK
SPECIAL PROCEDURE NUMBER
AND ENTER PROC ENTRY CODE
@BOX 5.0
END
@BOX 1.1
:: ENTER PROCESS.SPECIAL.I.CH
BEGIN
@BOX 2.1
*#%D4 %50 ::CLRL R0;
*#%B1 %0F %54 ::CMPW #%F, R4;
*#%18 %08 ::BGEQ + 8;
*#%78 %8F %FC %54 %54 ::ASHL - 4, R4, R4;
*#%80 %04 %50 ::ADDB2 4, R0;
*#%B1 %03 %54 ::CMPW #%3, R4;
*#%18 %08 ::BGEQ + 8;
*#%78 %8F %FE %54 %54 ::ASHL - 2, R4, R4;
*#%80 %02 %50 ::ADDB2 2, R0;
*#%B1 %01 %54 ::CMPU #%1, R4;
*#%18 %02 ::BGEQ + 2;
*#%96 %50 ::INCB R0;
@BOX 3.1
*#%78 %05 %55 %55 ::ASHL #5, R5, R5;
*#%C9 %50 %55 %AE %18 ::BISL R0, R5, %18(R14);
@BOX 4.1
*#%BA %8F %3F %00 ::POPR %003F;
*#%DD %8F ::PUSHL PROC ADDR;
*#%C0 %36 %04 %80;
*#%17 %9F ::JUMP TO END VAX11 INT;
*#%00 %00 %02 %80;
@BOX 5.1
END
@END
@TITLE AP304.DZ11.5(1,10)
@COL 1S-2R-3R-13T-14R-4T-6T-5R-7R-8F
@COL 9R-10R-11R
@ROW 7-9
@FLOW 1-2-3-13OUTPUT-4NO-6NO-5-7-8
@FLOW 13ECHO-14-7
@FLOW 4YES-9-10-11
@FLOW 6YES-9-10-11
@BOX 1.0
RAW OUTPUT INT
@BOX 2.0
STACK REGISTERS
@BOX 3.0
SET POINTER TO DZ11 CHANNEL
AND DZ11 PARAMETERS
@BOX 4.0
BUFFER EMPTY?
@BOX 5.0
OUTPUT CHARACTER
@BOX 6.0
SPECIAL CHARACTER?
@BOX 7.0
UNSTACK REGISTERS AND
RETURN FROM INTERRUPT
@BOX 8.0
END
@BOX 9.0
OBTAIN CONDITION INDEX
@BOX 10.0
GENERATE DEV NO/CONDITION
INDEX PARAMETER
@BOX 11.0
UNSTACK REGISTERS, STACK
SPECIAL PROCEDURE INDEX
AND JUMP TO PROCEDURE ENTRY CODE
@BOX 13.0
ECHO OR OUTPUT?
@BOX 14.0
PRINT ECHO CHARACTER
@BOX 1.1
RAW.OUTPUT.INT.0: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %00 ::PUSHL #0;
   -> RAW.OUTPUT.INT;

RAW.OUTPUT.INT.1: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %01 ::PUSHL #1;
   ->RAW.OUTPUT.INT;

RAW.OUTPUT.INT.2: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %02 ::PUSHL #2;
   ->RAW.OUTPUT.INT;

RAW.OUTPUT.INT.3: ::STACK DZ11 NUMBER
   *#%01 %01 %01 %01;
   *#%DD %03 ::PUSHL #3;
   ->RAW.OUTPUT.INT;

RAW.OUTPUT.INT: BEGIN
@BOX 2.1
*#%BB %8F %3F %00 ::PUSHR %003F;
@BOX 3.1
::R0 = DZ11 REGISTER ADDRESS
*#%D0 %AE %18 %52 ::MOVL %18(R14), R2;
*#%D0 %9F %68 ::MOVL @CSR.PTR, R1;
*#%00 %03 %80 %51;
*#%D0 %42 %61 %50 ::MOVL (R1) [R2], R0;
::R1 = ADDRESS OF PARAMETERS
*#%B0 %60 %53 ::MOVW (R0), R3;
*#%78 %8F %FC %53 %51 ::ASHL - 4, R3, R1;
*#%CA %8F %8F %FF ::BICL #FFFFFF8F, R1;
*#%FF %FF %51;
*#%78 %07 %52 %52 ::ASHL #7, R2, R2;
*#%C0 %52 %51 ::ADD2 R2, R1;
*#%C0 %8F %08 ::ADDL2 #8 R1;
*#%00 %00 %00 %51;
*#%D0 %51 %55 ::MOVL R1, R5;
*#%C0 %9F %64 %00 ::ADDL2 PARAMETER, R1;
*#%03 %80 %51;
::R2 = BUFFER ADDRESS
*#%D0 %61 %52 ::MOVL (R1), R2;
*#%D4 %54 ::CLRL R4;
@BOX 4.1
ROI.4:
*#%B5 %A1 %04 ::TSTW 4(R1);
*#%15 %03 ::BLEQ + 3;
-> ROI.6;
*#%D0 %8F %80 %00 ::MOVL %80, R4;
*#%00 %00 %54;
-> ROI.9 ::IGNORE FLIP JUMP
@BOX 5.1
*#%B0 %53 %A0 %06 ::MOVW R3, 6(R0)
@BOX 6.1
ROI.6:
*#%9A %82 %53 ::MOVB (R2)+, R3;
*#%D0 %52 %61 ::MOVL R2, (R1);
*#%B7 %A1 %04 ::DECW 4(R1);
*#%D0 %9F %60 %00  ::MOVL @O.CH.TABLE.PTR, R2;
*#%03 %80 %52;
*#%92 %42 %63 %54 ::MCOMB (R3) [R2], R4;
*#%8B %54 %A1 %06 %54 ::BICB3 R4, 6(R1), R4;
*#%13 %03 ::BEQL + 3;
-> ROI.9 ::IGNORE FLIP JUMP
@BOX 7.1
*#%BA %8F %3F %00 ::POPR %003F;
*#%D5 %8E ::REMOVE PARAMETER;
*#%02 ::REI;
@BOX 8.1
END
@BOX 9.1
ROI.9:
*#%D4 %50 ::CLRL R0;
*#%B1 %0F %54 ::CMPW #%F, R4;
*#%18 %08 ::BGEQ + 8;
*#%78 %8F %FC %54 %54 ::ASHL - 4, R4, R4;
*#%80 %04 %50 ::ADDB2 4, R0;
*#%B1 %03 %54 ::CMPW #%3, R4;
*#%18 %08 ::BGEQ + 8;
*#%78 %8F %FE %54 %54 ::ASHL - 2, R4, R4;
*#%80 %02 %50 ::ADDB2 2, R0;
*#%B1 %01 %54 ::CMPW #%1, R4;
*#%18 %02 ::BGEQ + 2;
*#%96 %50 ::INCB R0;
@BOX 10.1
*#%78 %05 %55 %55 ::ASHL #5, R5, R5;
*#%C9 %50 %55 %AE %18 ::BISL R0, R5, %18(R14);
@BOX 11.1
*#%BA %8F %3F %00 ::POPR %003F;
*#%DD %8F ::PUSHL PROC ADDR;
*#%C4 %36 %04 %80;
*#%17 %9F ::JUMP TO END VAX11 INT;
*#%00 %00 %02 %80;
@BOX 13.1
*#%9A %A1 %07 %53 ::MOVBLZ 7(R1), R3;
*#%12 %03 ::BNEQ +3;
-> ROI.4 ::IGNORE FLIP JUMP
@BOX 14.1
*#%94 %A1 %07 ::CLRB 7(R1);
*#%B0 %53 %A0 %06 ::MOVW R3, 6(R0);
*#%91 %53 %0D ::CMPB R3, CR;
*#%12 %04 ::BNEQ +4;
*#%90 %0A %A1 %07 ::MOVB NL, 7(R1);
@END
@TITLE AP304.DZ11.6(1,10)

@COL 10C-11R-12C-13R-14C-15R-22N
@COL 1S-2R-28R-3R-4C-5R-6T-7C-8R-23N-29R-9F
@COL 16C-17R-18C-25T-19R-26R-20C-21R-27R-24N
@ROW 10-4-16
@ROW 22-23-24
@FLOW 1-2-28-3
@FLOW 4-5-6YES-7-8-23-29-9
@FLOW 6NO-23
@FLOW 10-11-22-23
@FLOW 12-13-22
@FLOW 14-15-22
@FLOW 16-17-8
@FLOW 18-25NO-19-23
@FLOW 20-21-27-24-23
@FLOW 25YES-26-24
@BOX 1.0
PROCESS SPECIAL I CH (DEV/COND)
@BOX 2.0
SELECT DZ11 PARAMS
FOR SPECIFIED DEVICE
@BOX 3.0
SWITCH ON COND
@BOX 4.0
CR
@BOX 5.0
CHANGE BUFF CHAR TO LF
@BOX 6.0
BUFF FULL OR LINE MODE
@BOX 7.0
XFER CH/BUFF FULL
@BOX 8.0
NOTIFY AND ENTER OVERRUN MODE
@BOX 9.0
END
@BOX 10.0
DEL
@BOX 11.0
DELETE PREVIOUS CH
@BOX 12.0
STX
@BOX 13.0
SET STATUS FOR PRELUDE
AND MODE TO ALL
@BOX 14.0
ALL
@BOX 15.0
PROCESS ALL CONDITION
ACCORDIND TO STATUS
#AP304.DZ11.6.1
@BOX 16.0
ETX
@BOX 17.0
DELETE ETX AND
ADJUST COUNT
@BOX 18.0
BREAK
@BOX 19.0
STOP DEVICE,
CLEAR OVERRUN
AND NOTIFY
@BOX 20.0
XOFF/XON
@BOX 21.0
DELETE AND NOTE CH
@BOX 25.0
BREAK IS
ENGAGE/DISENGAGE?
@BOX 26.0
NOTE WHETHER ENGAGE
OR DISENGAGE REQUIRED
@BOX 27.0
PROCESS XOFF/XON
#AP304.DZ11.6.2
@BOX 28.0
RETRIEVE ECHO CHARACTER
@BOX 29.0
START OUTPUT DEVICE
IF ECHO REQUIRED
@BOX 1.1
PROC PROCESS.SPECIAL.I.CH (DEV.COND);
INTEGER DEV, CH, REASON, CNT, ECHO.CH;
@BOX 2.1
SELECT DZ11.PARAMS [DEV.COND ->> 8 => DEV];
@BOX 3.1
SWITCH DEV.COND & %FF \
   EOM, ETX, PROCESS.ALL, STX,
   CR, DEL, BREAK, XOFF.XON;
@BOX 4.1
CR:
@BOX 5.1
1 -> VAL OF BUFF.PTR;
LF => PTR^ OF BUFF.PTR;
 1 +> VAL OF BUFF.PTR;
@BOX 6.1
IF COUNT /= 0 AND MODE & LINE.MODE = 0
@BOX 7.1
EOM:
@BOX 8.1
IF DZ11.STATUS [DEV] & OVERRUN = 0 THEN
   COUNT => CNT;
   ENTER.OVERRUN (DEV);
   NOTIFY (DZ11.L.DEV [DEV], TR.COMP, CNT);
ELSE
   STOPPED &> DZ11.STATUS [DEV];
   ALL => MODE;
FI
@BOX 9.1
END
@BOX 10.1
DEL:
@BOX 11.1
IF 1 +> COUNT /=
   INIT.I.COUNT [DEV ->> 1] THEN
   2 -> VAL OF BUFF.PTR;
   1 +> COUNT;
   BS => ECHO.CH;
ELSE
   1 -> VAL OF BUFF.PTR;
   0 => ECHO.CH;
FI
@BOX 12.1
STX:
@BOX 13.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
ALL => MODE;
PRELUDE !> DZ11.STATUS [DEV];
@BOX 14.1
PROCESS.ALL:
@BOX 15.1
#AP304.DZ11.6.1
@BOX 16.1
ETX:
@BOX 17.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 18.1
BREAK:
@BOX 19.1
IF DZ11.STATUS [DEV] & (OVERRUN ! STARTED) = STARTED THEN
   BREAKIN ! TR.COMP => REASON;
ELSE
   BREAKIN => REASON;
FI
ENGAGED !> DZ11.STATUS [DEV];
NOTIFY (DZ11.L.DEV [DEV], REASON, COUNT);
0 => COUNT OF DZ11.PARAMS [DEV + 1];
IF DZ11.STATUS [DEV + 1] & STARTED /= 0 THEN
   NOTIFY (DZ11.L.DEV [DEV + 1], BREAKIN ! TR.COMP, 0);
ELSE
   IF DZ11.STATUS [DEV + 1] & ENGAGED = 0 THEN
      NOTIFY (DZ11.L.DEV [DEV + 1], ENGAGE.DEV, 0);
   FI
FI
STOPPED & DZ11.STATUS [DEV + 1] ! FREE => DZ11.STATUS [DEV + 1];
ENGAGED !> DZ11.STATUS [DEV + 1];
ENTER.OVERRUN (DEV);
@BOX 20.1
XOFF.XON:
@BOX 21.1
0 => ECHO.CH;
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
PTR^ OF BUFF.PTR => CH;
@BOX 25.1
0 => ECHO.CH;
IF REQ.MODE [DEV + 1] & 1 /= 0
@BOX 26.1
IF DZ11.STATUS [DEV + 1] & ENGAGED /= 0 THEN
   NOTIFY (DZ11.L.DEV [DEV + 1], DISENGAGE.DEV ! TR.COMP,
      COUNT OF DZ11.PARAMS [DEV + 1]);
   0 => COUNT OF DZ11.PARAMS [DEV + 1];
   DISENGAGED &> DZ11.STATUS [DEV + 1];
   STOPPED &> DZ11.STATUS [DEV + 1];
ELSE
   ENGAGED !> DZ11.STATUS [DEV + 1];
   NOTIFY (DZ11.L.DEV [DEV + 1], ENGAGE.DEV, 0);
FI
@BOX 27.1
:: PROCESS.XOFF.XON
#AP304.DZ11.6.2
@BOX 28.1
1 -> VAL OF BUFF.PTR;
PTR^ OF BUFF.PTR => ECHO.CH;
1 +> VAL OF BUFF.PTR;
@BOX 29.1
IF ECHO.CH /= 0 THEN
   BEGIN
   SELECT DZ11.PARAMS [DEV + 1];
   IF MODE & ECHO.ON /= 0 THEN
      ECHO.CH => BIT.MASK;
      SET.BIT [DEV ->> 1 & 7] !> DZ11.CSR [DEV ->> 4]^ [TCR];
   FI
   END
FI
@END

@TITLE AP304.DZ11.6.1(1,10)

@COL 5R
@COL 1S-2T-4T-3T-9R-14N-7F
@COL 8R-10R-11T-12R-15N
@ROW 4-8
@ROW 5-9
@ROW 14-15
@FLOW 1-2NO-4NO-3NOTIFY ON ALL-9-14-7
@FLOW 2YES-8-15-14
@FLOW 3YES-5-14
@FLOW 4YES-10-11YES-12-15
@FLOW 11NO-15
@BOX 1.0
PROCESS ALL MODE
@BOX 2.0
STOPPED?
@BOX 3.0
DISENGAGED?
@BOX 4.0
PRELUDE?
@BOX 5.0
NOTIFY TO ENGAGE DEVICE
@BOX 7.0
END
@BOX 8.0
DELETE CH
@BOX 9.0
NOTIFY AND CHANGE TO OVERRUN
@BOX 10.0
DELETE CH
@BOX 11.0
END OF PRELUDE?
@BOX 12.0
CLEAR PRELUDE STATUS
@BOX 1.1
:: PROCESS ALL
BEGIN
@BOX 2.1
IF DZ11.STATUS [DEV] & STARTED = 0
@BOX 3.1
IF DZ11.STATUS [DEV] & ENGAGED = 0
@BOX 4.1
IF DZ11.STATUS [DEV] & PRELUDE /= 0
@BOX 5.1
OVERRUN.MASK &> MODE;
NOTIFY (DZ11.L.DEV [DEV], ENGAGE.DEV, 0);
ENGAGED !> DZ11.STATUS [DEV];
IF DZ11.STATUS [DEV + 1] & ENGAGED = 0 THEN
   NOTIFY (DZ11.L.DEV [DEV + 1], ENGAGE.DEV, 0);
   ENGAGED !> DZ11.STATUS [DEV + 1];
FI
@BOX 7.1
END
@BOX 8.1
0 => ECHO.CH;
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 9.1
NOTIFY (DZ11.L.DEV [DEV], TR.COMP, COUNT);
ENTER.OVERRUN (DEV);
@BOX 10.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 11.1
IF PTR^ OF BUFF.PTR /= EDULERP
@BOX 12.1
NOT.PRELUDE &> DZ11.STATUS [DEV];
REQ.MODE [DEV] => MODE;
@END

@TITLE AP304.DZ11.6.2(1,10)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
PROCESS XOFF/XON
@BOX 2.0
STOP OR START OUTPUT
AS APPROPRIATE
@BOX 3.0
END
@BOX 1.1
:: PROCESS.XOFF.XON
BEGIN
LOGICAL O.STATUS;
@BOX 2.1
IF CH = XOFF THEN
   IF DZ11.STATUS [DEV + 1] & FREE /= 0 THEN
      SUSPENDED &> DZ11.STATUS [DEV + 1];
      BEGIN
         CLEAR.BIT [DEV ->> 1 & 7] &> DZ11.CSR [DEV ->> 4]^ [TCR];
         SELECT DZ11.PARAMS [DEV + 1];
         COUNT => XOFF.COUNT [DEV ->> 1];
         0 => COUNT;
      END
   FI
ELSE
   IF DZ11.STATUS [DEV + 1] & FREE = 0 THEN
      FREE !> DZ11.STATUS [DEV + 1];
      O.CONTROL (DEV + 1, START.TR.CMD,
         VAL OF BUFF.PTR OF DZ11.PARAMS [DEV + 1],
         XOFF.COUNT [DEV ->> 1], 0) => O.STATUS;
      IF O.STATUS /= 0 THEN
         NOTIFY (DZ11.L.DEV [DEV + 1], O.STATUS,
            COUNT OF DZ11.PARAMS [DEV + 1]);
      FI
   FI
FI
@BOX 3.1
END
@END

@TITLE AP304.DZ11.7(1,10)

@COL 10C-17R-11R-14C-15R-22N
@COL 1S-2R-3R-4C-5R-25N-23N-9F
@COL 16C-18C-20R-19R
@ROW 10-4-16
@ROW 22-23
@FLOW 1-2-3
@FLOW 4-5-25-23-9
@FLOW 10-17-11-14
@FLOW 14-15-22-23
@FLOW 16-25
@FLOW 18-20-19-23
@BOX 1.0
PROCESS SPECIAL O CH (DEV/COND)
@BOX 2.0
SELECT DZ11 PARAMS
FOR SPECIFIED DEVICE
@BOX 3.0
SWITCH ON COND
@BOX 4.0
LF
@BOX 5.0
OUTPUT CR/LF
@BOX 9.0
END
@BOX 10.0
DISEN
@BOX 11.0
SET STATUS FOR DISENGAGED
@BOX 14.0
OUTPUT BUFFER EMPTY
@BOX 15.0
NOTIFY TRANSFER COMPLETE
@BOX 16.0
OTHERS
@BOX 17.0
OUTPUT DISENGAGE CHARACTER
@BOX 18.0
SUSPEND
@BOX 19.0
SUSPEND OUTPUT DEVICE
@BOX 20.0
OUTPUT SUSPEND CHARACTER
@BOX 1.1
PROC PROCESS.SPECIAL.O.CH (DEV.COND);
INTEGER DEV.NO, REASON, CNT;
0 => REASON;
@BOX 2.1
SELECT DZ11.PARAMS [DEV.COND ->> 8 => DEV.NO];
@BOX 3.1
SWITCH DEV.COND & %FF \
   C7, C6, C5, SUSPEND, C3,
   LINEFEED, DISEN, BUFF.EMPTY;
@BOX 4.1
LINEFEED:
@BOX 5.1
LF => BIT.MASK;
CR => DZ11.CSR [DEV.NO ->> 4]^ [TDR];
@BOX 9.1
END
@BOX 10.1
DISEN:
@BOX 11.1
DISENGAGED &> DZ11.STATUS [DEV.NO];
DISENGAGE.DEV !> REASON;
IF DZ11.STATUS [DEV.NO - 1] & ENGAGED /= 0 THEN
   DISENGAGED &> DZ11.STATUS [DEV.NO - 1];
   NOTIFY (DZ11.L.DEV [DEV.NO], TR.COMP ! DISENGAGE.DEV,
      INIT.I.COUNT [DEV.NO - 1 ->> 1]);
   ENTER.OVERRUN (DEV.NO - 1);
   STARTED !> DZ11.STATUS [DEV.NO - 1];
   ALL => MODE OF DZ11.PARAMS [DEV.NO - 1];
FI
@BOX 14.1
BUFF.EMPTY:
@BOX 15.1
CLEAR.BIT [DEV.NO ->> 1 & 7] &> DZ11.CSR [DEV.NO ->> 4]^ [TCR];
IF DZ11.STATUS [DEV.NO] & (FREE ! STARTED) = FREE ! STARTED THEN
   STOPPED &> DZ11.STATUS [DEV.NO];
   COUNT => CNT;
   0 => COUNT;
   NOTIFY (DZ11.L.DEV [DEV.NO], TR.COMP ! REASON, CNT);
FI
@BOX 16.1
C3:
C4:
C5:
C6:
C7:
@BOX 17.1
1 -> VAL OF BUFF.PTR;
PTR^ OF BUFF.PTR => DZ11.CSR [DEV.NO ->> 4]^ [TDR];
1 +> VAL OF BUFF.PTR;
@BOX 18.1
SUSPEND:
@BOX 19.1
SUSPENDED &> DZ11.STATUS [DEV.NO];
COUNT => XOFF.COUNT [DEV.NO ->> 1];
0 => COUNT;
@BOX 20.1
1 -> VAL OF BUFF.PTR;
PTR^ OF BUFF.PTR => DZ11.CSR [DEV.NO ->> 4]^ [TDR];
1 +> VAL OF BUFF.PTR;
@END

@TITLE AP304.DZ11.8(1,10)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ENTER OVERRUN (DEV)
@BOX 2.0
SET UP BUFFER ADDRS,
COUNT AND MODE FOR OVERRUN
@BOX 3.0
END
@BOX 1.1
PROC ENTER.OVERRUN (DEV);
@BOX 2.1
OVERRUN !> DZ11.STATUS [DEV];
SELECT DZ11.PARAMS [DEV];
OVERRUN.BUFFS [DEV ->> 1] => VAL OF BUFF.PTR;
OVERRUN.SIZE => INIT.I.COUNT [DEV ->> 1]
   => COUNT;
REQ.MODE [DEV] & OVERRUN.MASK => MODE;
@BOX 3.1
END
@END

@TITLE AP304.DZ11.9(1,10)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
POLL
@BOX 2.0
CHECK FOR LINES RINGING
OR LOSS OF CARRIER
@BOX 3.0
END
@BOX 1.1
PROC POLL;
INTEGER DEV, DZ11.NO;
ADDR [LOGICAL16] CSR;
@BOX 2.1
FOR DZ11.NO < NO.OF.DZ11S DO
   IF BYTE (DZ11.CSR [DZ11.NO] => CSR) /= 0 THEN
      IF CSR^ [TCR] & %FF00 /= 0
         OR CSR^ [MSR] /= 0 THEN
         FOR DEV < 8 DO
            ::HANG UP TELEPHONE
            IF CSR^ [TCR] ->> 8 & SET.BIT [DEV] /= 0
               AND CSR^ [MSR] ->> 8 & SET.BIT [DEV] = 0 THEN
               ::DTR BUT NO CARRIER
               IF 1 -> TIMEOUT [DZ11.NO <<- 3 + DEV] =< 0 THEN
                  SET.BIT [DEV] <<- 8 -=> CSR^ [TCR];
               FI
            ELSE
               30 => TIMEOUT [DZ11.NO <<- 3 + DEV];
            FI
            ::ANSWER TELEPHONE
            IF CSR^ [MSR] & SET.BIT [DEV] /= 0 THEN
               SET.BIT [DEV] <<- 8 !> CSR^ [TCR];
               30 => TIMEOUT [DZ11.NO <<- 3 + DEV];
            FI
         OD
      FI
   FI
OD
@BOX 3.1
END
@END



