@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP3081
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP3081
~S1~M~OAP3 IMPLEMENTATION DESCRIPTION
~S1~M~OSection 8 Version 1
~S1~OSection 4.1 Operators Console Device Driver Appendix
~S1~O1. General Description
~BThis module is concerned with driving the
operators console, described in the VAX Hardware Handbook.
~S1~O2. Interfaces~
Other modules used~
   AP1 Section 3 (I/O Appendix)~
Ideal hardware registers used~
   None~
Interrupt procedures~
   CONSI.INT - RAW M/C LEVEL~
   CONSO.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~
Interface variables~
   None~
Configuration parameters~
   None.
~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 Console Interface
~BSee VAX 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~
%~N7) 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.
An output device may, however, be disengaged by requesting it to transmit %1F
(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.INPUT.INT
~BThis procedure services the Console input 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) RAW.OUTPUT.INT
~BThis procedure services the Console output 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.
~S14) PROCESS.SPECIAL.CH(DEV.NO/COND)
~BThis procedure implements the device behaviour as described above.
~S15) COPY.OVERRUN()
~BThis procedure is used to copy characters from an overrun buffer
into the device buffer.
~S1~O3.2 Data Structures~
~T% 30
~
CONSOLE.PARAMS~IA record holding the
information required by the 'raw' interrupt procedure, namely~
~
~IPTR/VAL OF BUFF.PTR~
~ICOUNT~
~IMODE~
~IREQ.MODE~
~
CONSOLE.STATUS
~IThe status of the device.~
~
CONSOLE.BUFFER~IThe current
starting address of the console input buffer.~
~
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.~
~
CONS.OVERRUN.AREA.SIZE~IAn integer literal giving the overrun buffer size.~
~
~S1~O3.3 Special Notes
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               AP3081
~V9 -1
~F
@TITLE AP308.CONS(1,10)

@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
CONS 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
@BOX 6.0
END
@BOX 1.1
#AP308.CONS/1
MODULE CONS (I.CONTROL, O.CONTROL)
@BOX 2.1
TYPE PTR.TYPE IS
   ADDR VAL
OR
   ADDR LOGICAL8 PTR;
TYPE CONS.PARAMS.TYPE IS
   PTR.TYPE BUFF.PTR
   INTEGER16 COUNT
   LOGICAL8 MODE, BIT.MASK;
@BOX 3.1
:: DATA DECLARATIONS
#AP308.CONS/2
@BOX 4.1
*CODE 23;
PSPEC I.CONTROL (INTEGER, INTEGER, ADDR, LOGICAL, LOGICAL32) / LOGICAL32;
PSPEC O.CONTROL (INTEGER, INTEGER, ADDR, LOGICAL, LOGICAL32) / LOGICAL32;
:: RAW.INT
PSPEC PROCESS.SPECIAL.I.CH (INTEGER);
PSPEC PROCESS.SPECIAL.O.CH (INTEGER);
PSPEC ENTER.OVERRUN ();
   #AP308.CONS.1
   #AP308.CONS.2
   #AP308.CONS.3
   #AP308.CONS.4
   #AP308.CONS.5
   #AP308.CONS.6
   #AP308.CONS.7
@BOX 5.1
*CODE 7;
PSPEC INIT.AP308 ();
INIT.AP308 ();
PROC INIT.AP308;
*VTYPE LABEL;
VSTORE VEC.LABEL %80030074;
*VTYPE LOGICAL32;
VSTORE VEC.ADDR %80030074;
VSTORE INT.STORE [%FFFF] %80040000;
VSTORE CONS.I.WORKSPACE %80030074;
VSTORE CONS.O.WORKSPACE %80030078;
TYPE PROC.ADDR.TYPE IS
   ADDR PROCESS.SPECIAL.I.CH P
OR
   LOGICAL32 PROC.ADDRESS;
PROC.ADDR.TYPE PROC.ADDR;
RAW.INPUT.INT => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%C3E];
RAW.OUTPUT.INT => VEC.LABEL;
VEC.ADDR + 3 & %FFFFFFFC + 1 => INT.STORE [%C3F];
^PROCESS.SPECIAL.I.CH => P OF PROC.ADDR;
PROC.ADDRESS OF PROC.ADDR => INT.STORE [%D3E];
^PROCESS.SPECIAL.O.CH => P OF PROC.ADDR;
PROC.ADDRESS OF PROC.ADDR => INT.STORE [%D3F];
BYTE (^CONS.I.PARAMS) => CONS.I.WORKSPACE;
BYTE (^CONS.O.PARAMS) => CONS.O.WORKSPACE;
BYTE (^OVERRUN.AREA) => OVERRUN.BUFFS;
*#%DA %00 %20;
*#%DA %00 %22;
END
@BOX 6.1
*END
@END
@TITLE AP308.CONS/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 CONS.OVERRUN.AREA.SIZE,
   START.TR.CMD, START.COMMS.CMD, INIT.CMD, DISENGAGE.CMD, CON.OUT.CMD,
   TR.COMP, BREAKIN, ENGAGE.DEV, DISENGAGE.DEV, DEV.DISENGAGED;
@BOX 3.1
PSPEC NOTIFY (INTEGER, LOGICAL, LOGICAL);
LOGICAL8 [256] I.CH.TABLE, O.CH.TABLE;
@END
@TITLE AP308.CONS/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
;
DATAVEC BIT.MASKS (LOGICAL8)
   %1F %3F %7F %FF
END
CONS.PARAMS.TYPE CONS.I.PARAMS, CONS.O.PARAMS;
INTEGER CONS.I.L.DEV, CONS.O.L.DEV;
LOGICAL8 CONS.I.STATUS, CONS.O.STATUS, REQ.I.MODE, REQ.O.MODE;
LOGICAL8 STOP.RX;
*GLOBAL 24;
LOGICAL8 [CONS.OVERRUN.AREA.SIZE] OVERRUN.AREA;
*GLOBAL 5;
INTEGER XOFF.COUNT;
ADDR CONS.I.BUFFERS, OVERRUN.BUFFS;
@END

@TITLE AP308.CONS.1(1,10)

@COL 9T-10R-12T-11R-16T-13R-17R
@COL 1S-14R-2T-3T-5R-6R-15R-7F
@COL 8T
@ROW 3-9
@ROW 8-10
@ROW 5-12
@ROW 6-13
@ROW 15-17
@FLOW 1-14-2TRANSFER-3NO-5-6-15-7
@FLOW 8YES-7
@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 CONS.PARAMS FOR DEV
@BOX 6.0
NOTE STATUS
@BOX 7.0
END
@BOX 8.0
COPY OVERRUN BUFFER
TO DEVICE BUFFER
#AP308.CONS.1.1
IS DEVICE STOPPED?
@BOX 9.0
CONFIGURE COMMAND?
@BOX 10.0
INITIALISE DEVICE
@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 1.1
PROC I.CONTROL (DEV, CMD, BUFFER, I.SIZE, I.MODE);
INTEGER OVERRUN.CHARS;
0 => I.CONTROL => OVERRUN.CHARS;
@BOX 2.1
IF CMD & START.TR.CMD = 0
@BOX 3.1
IF CMD /= START.COMMS.CMD AND
  CONS.I.STATUS & OVERRUN /= 0
@BOX 5.1
BUFFER => CONS.I.BUFFERS
   + OVERRUN.CHARS => VAL OF BUFF.PTR;
I.SIZE - OVERRUN.CHARS => COUNT;
REQ.I.MODE => MODE;
@BOX 6.1
NORMAL & CONS.I.STATUS
   ! STARTED => CONS.I.STATUS;
@BOX 7.1
END
@BOX 8.1
:: COPY OVERRUN
#AP308.CONS.1.1
IF I.CONTROL = 0
@BOX 9.1
IF CMD /= INIT.CMD
@BOX 10.1
BUFFER => CONS.I.L.DEV;
I.MODE => REQ.I.MODE;
BIT.MASKS [I.MODE ->> 10 & 3]
   => BIT.MASK OF CONS.I.PARAMS;
@BOX 11.1
ENTER.OVERRUN ();
STARTED !> CONS.I.STATUS;
DISENGAGED &> CONS.I.STATUS;
ALL => MODE;
DISENGAGE.DEV => I.CONTROL;
@BOX 12.1
IF CMD /= DISENGAGE.CMD
@BOX 13.1
DISCONNECTED &> CONS.I.STATUS;
*#%DA %00 %20; ::STOP RECEIVER
@BOX 14.1
SELECT CONS.I.PARAMS;
@BOX 15.1
*#%DA %8F %40 %00; ::ENABLE RECEIVER INTS
*#%00 %00 %20;
@BOX 16.1
IF CMD /= CON.OUT.CMD
@BOX 17.1
IF CONS.I.STATUS & ENGAGED = 0 THEN
   DEV.DISENGAGED !> I.CONTROL;
FI
@END
@TITLE AP308.CONS.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, CONS.OVERRUN.AREA.SIZE, OVERRUN.BUFFS) => ORUN.B;
@BOX 2.1
IF CONS.OVERRUN.AREA.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.I.MODE & 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.I.MODE & 2 /= 0 AND
   DEV.B^ [OVERRUN.CHARS - 1] = ETX THEN
   1 -> OVERRUN.CHARS;
FI
@BOX 8.1
END
@END
@TITLE AP308.CONS.2(1,10)

@COL 9T-10R-12T-11R-15T-13R-16R
@COL 1S-2T-3T-14R-17T-5R-6R-7F
@COL 4R-18R-19N
@ROW 3-9
@ROW 4-14
@ROW 5-18
@ROW 6-16
@FLOW 1-2TRANSFER-3NO-14-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
@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 CONS.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
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 1.1
PROC O.CONTROL (DEV, CMD, BUFFER, O.SIZE, O.MODE);
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.O.MODE => MODE;
@BOX 6.1
STARTED !> CONS.O.STATUS;
*#%DA %8F %40 %00; ::ENABLE OUTPUT INTERRUPTS
*#%00 %00 %22;
@BOX 7.1
END
@BOX 9.1
IF CMD /= INIT.CMD
@BOX 10.1
BUFFER => CONS.O.L.DEV;
O.MODE => REQ.O.MODE;
STOPPED &> CONS.O.STATUS;
FREE ! ENGAGED !> CONS.O.STATUS;
BIT.MASKS [O.MODE ->> 10 & 3]
   => BIT.MASK OF CONS.O.PARAMS;
@BOX 11.1
DISENGAGED &> CONS.O.STATUS;
DISENGAGE.DEV !> O.CONTROL;
@BOX 12.1
IF CMD /= DISENGAGE.CMD
@BOX 13.1
DISCONNECTED &> CONS.O.STATUS;
@BOX 14.1
SELECT CONS.O.PARAMS;
@BOX 15.1
IF CMD /= CON.OUT.CMD
@BOX 16.1
IF CONS.O.STATUS & ENGAGED = 0 THEN
   DEV.DISENGAGED !> O.CONTROL;
FI
@BOX 17.1
IF CONS.O.STATUS & FREE = 0
@BOX 18.1
BUFFER => VAL OF BUFF.PTR;
O.SIZE => XOFF.COUNT;
REQ.O.MODE => MODE;
@END
@TITLE AP308.CONS.3(1,10)
@COL 1S-2R-3R-4R-5T-6R-7T-8T-12R-10R-11F
@COL 13N-14R
@ROW 8-13
@FLOW 1-2-3-4-5NO-6-7NO-8NO-12-10-11
@FLOW 5YES-13-14
@FLOW 7YES-13-14
@FLOW 8YES-13-14
@BOX 1.0
RAW INPUT INTERRUPT
@BOX 2.0
STACK REGISTERS
@BOX 3.0
SET POINTERS TO
CONSOLE PARAMETERS
@BOX 4.0
GET CHARACTER
@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 14.0
ENTER PROCESS SPECIAL I CH
#AP308.CONS.3.1
@BOX 12.0
ECHO CHARACTER
IF NECESSARY
@BOX 1.1
RAW.INPUT.INT: BEGIN
*#%01 %01 %01 %01;
@BOX 2.1
*#%DD %00 ::PUSHL SPACE FOR PARAMETER;
*#%BB %8F %3F %00 ::PUSHR %003F;
@BOX 3.1
::R1 = ADDRESS OF PARAMATERS
*#%D0 %9F %74 %00 ::MOVL I PARAMETERS, R1;
*#%03 %80 %51;
::R2 = BUFFER ADDRESS
*#%D0 %61 %52 ::MOVL (R1), R2;
*#%D0 %8F %40 %00 ::MOVL #40, R4;
*#%00 %00 %54;
@BOX 4.1
::R3 = DATA
*#%DB %21 %53 ::MFPR # RXDB, R3;
@BOX 5.1
*#%B5 %53 ::TSTW R3;
*#%18 %03 ::BGEQ + 3;
-> RII.14;
::IGNORE JUMP
@BOX 6.1
*#%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 14.1
RII.14:
#AP308.CONS.3.1
@BOX 12.1
ECHO:
*#%93 %10 %A1 %0E ::BITB #10, E(R1);
*#%12 %03 ::BNEQ + 3;
-> OUT;
*#%90 %53 %A1 %0F ::MOVB R3, F(R1);
*#%DA %8F %40 %00 ::MTPR #40, TXCS;
*#%00 %00 %22;
@END
@TITLE AP308.CONS.3.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
*#%D0 %50 %AE %18 ::MOVL R0, %18(R14);
@BOX 4.1
*#%BA %8F %3F %00 ::POPR %003F;
*#%DD %8F ::PUSHL PROC ADDR;
*#%F8 %34 %04 %80;
*#%17 %9F ::JUMP TO END VAX11 INT;
*#%00 %00 %02 %80;
@BOX 5.1
END
@END
@TITLE AP308.CONS.4(1,10)
@COL 1S-2R-3R-13T-14R-4T-5R-6T-7R-8F
@COL 12R-9R-10R-11R
@ROW 5-12
@ROW 7-9
@FLOW 1-2-3-13OUTPUT-4NO-5-6NO-7-8
@FLOW 13ECHO-14-7
@FLOW 4YES-12-9-10-11
@FLOW 6YES-9
@BOX 1.0
RAW OUTPUT INT
@BOX 2.0
STACK REGISTERS
@BOX 3.0
SET POINTER TO
CONSOLE 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 CONDITION
INDEX PARAMETER
@BOX 11.0
UNSTACK REGISTERS, STACK
SPECIAL PROCEDURE INDEX
AND JUMP TO PROCEDURE ENTRY CODE
@BOX 12.0
INHIBIT TRANSMITTER INTERRUPTS
@BOX 13.0
ECHO OR OUTPUT?
@BOX 14.0
PRINT ECHO CHARACTER
@BOX 1.1
RAW.OUTPUT.INT: BEGIN
*#%01 %01 %01 %01;
@BOX 2.1
*#%DD %00 ::PUSHL SPACE FOR PARAMETER;
*#%BB %8F %3F %00 ::PUSHR %003F;
@BOX 3.1
::R1 = ADDRESS OF PARAMETERS
*#%D0 %9F %78 %00 ::MOVL 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.5;
*#%D0 %8F %80 %00 ::MOVL %80, R4;
*#%00 %00 %54;
-> ROI.9 ::IGNORE FLIP JUMP
@BOX 5.1
ROI.5:
*#%9A %82 %53 ::MOVBLZ (R2)+, R3;
*#%DA %53 %23 ::MTPR R3, TXDB;
*#%D0 %52 %61 ::MOVL R2, (R1);
*#%B7 %A1 %04 ::DECW 4(R1);
@BOX 6.1
*#%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
*#%D0 %50 %AE %18 ::MOVL R0, %18(R14);
@BOX 11.1
*#%BA %8F %3F %00 ::POPR %003F;
*#%DD %8F ::PUSHL PROC ADDR;
*#%FC %34 %04 %80;
*#%17 %9F ::JUMP TO END VAX11 INT;
*#%00 %00 %02 %80;
@BOX 12.1
*#%DA %00 %22 ::MTPR #0, TXCS;
@BOX 13.1
*#%9A %A1 %07 %53 ::MOVB 7(R1), R3;
*#%12 %03 ::BNEQ + 3;
-> ROI.4 ::IGNORE FLIP JUMP
@BOX 14.1
*#%94 %A1 %07 ::CLRB 7(R1);
*#%DA %53 %23 ::MTPR R3, TXDB;
*#%91 %53 %0D ::CMPB R3, CR;
*#%12 %04 ::BNEQ + 4;
*#%90 %0A %A1 %07 ::MOVB NL, 7(R1);
@END
@TITLE AP308.CONS.5(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 (COND)
@BOX 2.0
SELECT CONSOLE PARAMS
@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
#AP308.CONS.5.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
#AP308.CONS.5.2
@BOX 28.0
NOTE ECHO CHARACTER
@BOX 29.0
OUTPUT ECHO CHARACTER
IF NECESSARY
@BOX 1.1
PROC PROCESS.SPECIAL.I.CH (COND);
INTEGER DEV, CH, REASON, CNT, ECHO.CH;
@BOX 2.1
SELECT CONS.I.PARAMS;
@BOX 3.1
SWITCH 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 CONS.I.STATUS & OVERRUN = 0 THEN
   COUNT => CNT;
   ENTER.OVERRUN ();
   NOTIFY (CONS.I.L.DEV, TR.COMP, CNT);
ELSE
   STOPPED &> CONS.I.STATUS;
   ALL => MODE;
FI
@BOX 9.1
END
@BOX 10.1
DEL:
@BOX 11.1
IF 1 -> VAL OF BUFF.PTR /=
   CONS.I.BUFFERS THEN
   1 -> VAL OF BUFF.PTR;
   2 +> COUNT;
   BS => ECHO.CH;
ELSE
   1 +> COUNT;
   0 => ECHO.CH;
FI
@BOX 12.1
STX:
@BOX 13.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
ALL => MODE;
PRELUDE !> CONS.I.STATUS;
@BOX 14.1
PROCESS.ALL:
@BOX 15.1
#AP308.CONS.5.1
@BOX 16.1
ETX:
@BOX 17.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 18.1
BREAK:
@BOX 19.1
IF CONS.I.STATUS & (OVERRUN ! STARTED) = STARTED THEN
   BREAKIN ! TR.COMP => REASON;
ELSE
   BREAKIN => REASON;
FI
NOTIFY (CONS.I.L.DEV, REASON, COUNT);
0 => COUNT OF CONS.O.PARAMS;
IF CONS.O.STATUS & STARTED /= 0 THEN
   NOTIFY (CONS.O.L.DEV, BREAKIN ! TR.COMP, 0);
FI
STOPPED & CONS.O.STATUS ! FREE => CONS.O.STATUS;
ENTER.OVERRUN ();
IF CONS.I.STATUS & ENGAGED = 0 THEN
   ALL => MODE;
FI
@BOX 20.1
XOFF.XON:
@BOX 21.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
PTR^ OF BUFF.PTR => CH;
@BOX 25.1
0 => ECHO.CH;
IF REQ.O.MODE & 1 /= 0
@BOX 26.1
IF CONS.O.STATUS & ENGAGED /= 0 THEN
   NOTIFY (CONS.O.L.DEV, DISENGAGE.DEV ! TR.COMP,
      COUNT OF CONS.O.PARAMS);
   0 => COUNT OF CONS.O.PARAMS;
   DISENGAGED &> CONS.O.STATUS;
   STOPPED &> CONS.O.STATUS;
ELSE
   ENGAGED !> CONS.O.STATUS;
   NOTIFY (CONS.O.L.DEV, ENGAGE.DEV, 0);
FI
@BOX 27.1
:: PROCESS.XOFF.XON
#AP308.CONS.5.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 CONS.O.PARAMS;
   IF MODE & ECHO.ON /= 0 THEN
      ECHO.CH => BIT.MASK;
      *#%DA %8F %40 %00 ::ENABLE OUTPUT INTS;
      *#%00 %00 %22;
   FI
   END
FI
@END

@TITLE AP308.CONS.5.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 CONS.I.STATUS & STARTED = 0
@BOX 3.1
IF CONS.I.STATUS & ENGAGED = 0
@BOX 4.1
IF CONS.I.STATUS & PRELUDE /= 0
@BOX 5.1
NOTIFY (CONS.I.L.DEV, ENGAGE.DEV, 0);
ENGAGED !> CONS.I.STATUS;
IF CONS.O.STATUS & ENGAGED = 0 THEN
   NOTIFY (CONS.O.L.DEV, ENGAGE.DEV, 0);
   ENGAGED !> CONS.O.STATUS;
FI
@BOX 7.1
END
@BOX 8.1
0 => ECHO.CH;
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 9.1
NOTIFY (CONS.I.L.DEV, TR.COMP, COUNT);
ENTER.OVERRUN ();
@BOX 10.1
1 +> COUNT;
1 -> VAL OF BUFF.PTR;
@BOX 11.1
IF PTR^ OF BUFF.PTR /= EDULERP
@BOX 12.1
NOT.PRELUDE &> CONS.I.STATUS;
REQ.I.MODE => MODE;
@END

@TITLE AP308.CONS.5.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 CONS.O.STATUS & FREE /= 0 THEN
      SUSPENDED &> CONS.O.STATUS;
      BEGIN
         SELECT CONS.O.PARAMS;
         COUNT => XOFF.COUNT;
         0 => COUNT;
      END
   FI
ELSE
   IF CONS.O.STATUS & FREE = 0 THEN
      FREE !> CONS.O.STATUS;
      O.CONTROL (1, START.TR.CMD,
         VAL OF BUFF.PTR OF CONS.O.PARAMS,
         XOFF.COUNT, 0) => O.STATUS;
      IF O.STATUS /= 0 THEN
         NOTIFY (CONS.O.L.DEV, O.STATUS,
            COUNT OF CONS.O.PARAMS);
      FI
   FI
FI
@BOX 3.1
END
@END

@TITLE AP308.CONS.6(1,10)

@COL 10C-11R-14C-15R-22N
@COL 1S-2R-3R-4C-5R-25N-23N-9F
@COL 16C
@ROW 10-4-16
@ROW 22-23
@FLOW 1-2-3
@FLOW 4-5-25-23-9
@FLOW 10-11-14
@FLOW 14-15-22-23
@FLOW 16-25
@BOX 1.0
PROCESS SPECIAL O CH (COND)
@BOX 2.0
SELECT CONSOLE OUTPUT PARAMS
@BOX 3.0
SWITCH ON COND
@BOX 4.0
LF
@BOX 5.0
CHANGE BUFF CHAR TO CR
@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 1.1
PROC PROCESS.SPECIAL.O.CH (DEV.COND);
INTEGER DEV.NO, REASON, CNT;
0 => REASON;
@BOX 2.1
SELECT CONS.O.PARAMS;
@BOX 3.1
SWITCH DEV.COND & %FF \
   C7, C6, C5, C4, C3,
   LF, DISEN, BUFF.EMPTY;
@BOX 4.1
LF:
@BOX 5.1
1 -> VAL OF BUFF.PTR;
1 +> COUNT;
CR => PTR^ OF BUFF.PTR;
@BOX 9.1
END
@BOX 10.1
DISEN:
@BOX 11.1
DISENGAGED &> CONS.O.STATUS;
DISENGAGE.DEV !> REASON;
@BOX 14.1
BUFF.EMPTY:
@BOX 15.1
*#%DA %00 %22 ::INHIBIT TRANSMITTER INTERRUPTS;
IF CONS.O.STATUS & (FREE ! STARTED) = FREE ! STARTED THEN
   STOPPED &> CONS.O.STATUS;
   COUNT => CNT;
   0 => COUNT;
   NOTIFY (CONS.O.L.DEV, TR.COMP ! REASON, CNT);
FI
@BOX 16.1
C3:
C4:
C5:
C6:
C7:
@END

@TITLE AP308.CONS.7(1,10)

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


