@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            AP7131
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                             ISSUE 11~
~V9 -1
~P
~V9 1
~YAP7131
~S1~M~OAP7 IMPLEMENTATION DESCRIPTION
~S1~M~OSection 13 Version 1
~S1~OSection 13.1 Paper Tape Reader Device Driver Appendix
~S1~O1. General Description
~BThis module is concerned with driving the
paper tape reader, described in the PDP11 Peripheral Handbook.~
~S1~O2. Interfaces~
Other modules used~
   AP1 Section 3 (I/O Appendix)~
Ideal hardware registers used~
   None~
Interrupt procedures~
   PR11.I.INT - RAW M/C LEVEL~
   PROCESS.SPECIAL.I.CH (DEV/COND)~
Interface procedures~
   I.CONTROL (PHYS.DEV.NO, COMMAND, ADDR, COUNT, I.MODE) STATUS~
   POLL ()~
Interface variables~
   None~
Configuration parameters~
   PR11.ADDR.
~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) POLL ()~
~BThis procedure, when called by AP103, checks device status and, if the
device is not in error, restarts it.~
~S1~O2.2 Reader Interface
~BSee PDP11 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.
~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~
~U 12
~
          ~O                 ~O
          ~O| | | | | | | | |~O
           | | | | | | | |
           | | | | | | |  -- 'LINE' TERMINATOR (CR, LF, FF)
           | | | | | |  ---- ETX
           | | | | |  ------ ALL CHARACTERS
           | | | |  -------- STX
           | | |  ---------- CR
           | |  ------------ DEL, BS
           |  -------------- BREAK (ETX)
            ---------------- XON/XOFF
~
~
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~
~
~M1) Stop device on error               ~
~N2) Change CR to Newline (tnen act as for NL)
~N3) Force transfer complete.
In addition, the buffer full condition has to be detected.~
~BTransfers from the reader are always initiated by calling
I.CONTROL, so a disengaged device is left in the stopped condition.~
~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.
~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) RAW.INPUT.INT
~BThis procedure services the reader 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.
~S12) PROCESS.SPECIAL.I.CH(DEV.NO/COND)
~BThis procedure implements the device behaviour as described above.
~S1~O3.2 Data Structures~
~T% 30
~
PR11.PARAMS~IA record holding the
information required by the 'raw' interrupt procedure, namely~
~
~IPTR/VAL OF BUFF.PTR~
~ICOUNT~
~IMODE~
~IREQ.MODE~
~
PR11.L.DEV~IThe logical device number assigned during initialisation.~
~
PR11.STATUS
~IThe status of the device.~
~
PR11.BUFFER~IThe current
starting address of the reader input buffer.~
~
I.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.~
~
~S1~O3.3 Special Notes
~Y
~V9 -1
~P
~V9 -1
~D15
~HFLOWCHARTS
~
~
~H               AP7131
~V9 -1
~F
@TITLE AP713.PR11(1,11)

@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
PR11 (TAPE READER) DRIVER
@BOX 4.0
PROCEDURES IN MODULE:
   1   I CONTROL
   2   RAW INPUT INT
   3   PROCESS SPECIAL I CH
   4   POLL
@BOX 6.0
END
@BOX 1.1
#AP713.PR11/1
MODULE PR11 (I.CONTROL, POLL);
@BOX 2.1
TYPE PTR.TYPE IS
   LOGICAL16 VAL
OR
   ADDR LOGICAL8 PTR;
TYPE PR11.PARAMS.TYPE IS
   LOGICAL16 FILLER
   PTR.TYPE BUFF.PTR
   INTEGER16 COUNT
   LOGICAL8 MODE, BIT.MASK;
@BOX 3.1
:: DATA DECLARATIONS
#AP713.PR11/2
@BOX 4.1
*CODE 23;
PSPEC I.CONTROL (INTEGER, INTEGER, ADDR, LOGICAL, LOGICAL32) / LOGICAL32;
:: RAW.INT
PSPEC PROCESS.SPECIAL.I.CH (INTEGER);
PSPEC POLL ();
   #AP713.PR11.1
   #AP713.PR11.2
   #AP713.PR11.3
   #AP713.PR11.4
@BOX 5.1
*CODE 7;
PSPEC INIT.AP713 ();
INIT.AP713 ();
PROC INIT.AP713;
*VTYPE LOGICAL16;
VSTORE INT.STORE [%100] %0;
VSTORE PR11.WORKSPACE %236;
VSTORE PR11.CSR.ADDR %238;
VSTORE SPECIAL.I.CH.PTR %23A;
TYPE PROC.ADDR.TYPE IS
   ADDR PROCESS.SPECIAL.I.CH P
OR
   LOGICAL16 PROC.ADDRESS;
PROC.ADDR.TYPE PROC.ADDR;
RAW.INPUT.INT => INT.STORE [%1C];
%E0 => INT.STORE [%1D];
^PROCESS.SPECIAL.I.CH => P OF PROC.ADDR;
PROC.ADDRESS OF PROC.ADDR => SPECIAL.I.CH.PTR;
MAKE (LOGICAL16, 2, PR11.ADDR) => PR11.CSR;
PR11.ADDR => PR11.CSR.ADDR;
BYTE (^PR11.PARAMS) => PR11.WORKSPACE;
::STOP DEVICE
STOP &> PR11.CSR^ [PRS];
END
@BOX 6.1
*END
@END
@TITLE AP713.PR11/1(1,11)

@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 START.TR.CMD, INIT.CMD, DISENGAGE.CMD,
   CON.OUT.CMD, TR.COMP, ENGAGE.DEV, DISENGAGE.DEV, DEV.DISENGAGED;
IMPORT LABEL PDP11.APPENDIX.INT;
@BOX 3.1
PSPEC NOTIFY (INTEGER, LOGICAL, LOGICAL);
LOGICAL8 [256] I.CH.TABLE;
IMPORT LITERAL ADDR PR11.ADDR;
@END
@TITLE AP713.PR11/2(1,11)

@COL 1S
@BOX 1.0
DATA DECLARATIONS
@BOX 1.1
*GLOBAL 5;
LITERAL / INTEGER PRS = 0;
LITERAL / LOGICAL8 LF = %A;
LITERAL / LOGICAL8 CONNECTED = 1, ENGAGED = 2,
   STARTED = 8, DISCONNECTED = %FE, DISENGAGED = %FD,
   STOPPED = %F7, SUSPENDED = %DF,
   NORMAL = %FB, LINE.MODE = 1;
LITERAL / LOGICAL16 START = %41, STOP = 0;
PR11.PARAMS.TYPE PR11.PARAMS;
INTEGER PR11.L.DEV;
LOGICAL8 PR11.STATUS, REQ.I.MODE;
LOGICAL8 STOP.RX;
ADDR PR11.BUFFERS;
ADDR [LOGICAL16] PR11.CSR;
@END

@TITLE AP713.PR11.1(1,11)

@COL 9T-10R-12T-11R-16T-13R-17R
@COL 1S-14R-2T-5R-6R-15R-7F
@ROW 5-9
@ROW 6-13
@ROW 15-17
@FLOW 1-14-2TRANSFER-5-6-15-7
@FLOW 2NON TRANSFER-9YES-10-11
@FLOW 9NO-12YES-11-7
@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 5.0
SET BUFF.PTR/SIZE/MODE
IN PR11.PARAMS FOR DEV
@BOX 6.0
NOTE STATUS
@BOX 7.0
END
@BOX 9.0
CONFIGURE COMMAND?
@BOX 10.0
INITIALISE DEVICE
@BOX 11.0
SET DISENGAGED STATUS
@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);
0 => I.CONTROL;
@BOX 2.1
IF CMD & START.TR.CMD = 0
@BOX 5.1
BUFFER => VAL OF BUFF.PTR;
I.SIZE => COUNT;
REQ.I.MODE => MODE;
@BOX 6.1
NORMAL & PR11.STATUS
   ! STARTED => PR11.STATUS;
@BOX 7.1
END
@BOX 9.1
IF CMD /= INIT.CMD
@BOX 10.1
BUFFER => PR11.L.DEV;
I.MODE => REQ.I.MODE;
@BOX 11.1
DISENGAGED &> PR11.STATUS;
DISENGAGE.DEV => I.CONTROL;
@BOX 12.1
IF CMD /= DISENGAGE.CMD
@BOX 13.1
DISCONNECTED &> PR11.STATUS;
STOP &> PR11.CSR^ [PRS];
@BOX 14.1
SELECT PR11.PARAMS;
@BOX 15.1
START !> PR11.CSR^ [PRS];
@BOX 16.1
IF CMD /= CON.OUT.CMD
@BOX 17.1
IF PR11.STATUS & ENGAGED = 0 THEN
   DEV.DISENGAGED !> I.CONTROL;
FI
@END
@TITLE AP713.PR11.2(1,11)
@COL 1S-2R-3R-4R-5T-6T-7T-8T-10R-11F
@COL 13N-14R
@ROW 8-13
@FLOW 1-2-3-4-5NO-6NO-7NO-8NO-10-11
@FLOW 5YES-13-14
@FLOW 6YES-10
@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
PR11 PARAMETERS
@BOX 4.0
FIND CSR ADDRESS,
GET CHARACTER
@BOX 5.0
ANY FAULT?
@BOX 6.0
NUL/DEL?
PLACE CHARACTER IN BUFFER
(EXCEPT NUL OR DEL)
@BOX 7.0
SPECIAL CHARACTER?
@BOX 8.0
IS BUFFER FULL?
@BOX 10.0
START DEVICE
UNSTACK REGISTERS
AND RETURN FROM INTERRUPT
@BOX 11.0
END
@BOX 14.0
ENTER PROCESS SPECIAL I CH
#AP713.PR11.2.1
@BOX 1.1
RAW.INPUT.INT: BEGIN
@BOX 2.1
*#%15E6 %0000 ::PUSH SPACE FOR PARAMETER;
*#%1026  ::SAVE REGISTERS ON STACK;
*#%1066;
*#%10A6;
*#%10E6;
*#%1126;
*#%1166;
@BOX 3.1
::R1 = ADDRESS OF PARAMETERS
*#%17C1 %0236  ::MOV I.PARAMETERS, R1;
::R2 = BUFFER ADDRESS
*#%1C42 %0002  ::MOV 2(R1), R2;
*#%15C4 %0040 ::MOV #40, R4;
@BOX 4.1
::R0 = PR11 REGISTER ADDRESS
*#%17C0 %0238 ::MOV @#CSR.PTR,R0;
::R3 = DATA
*#%1C03 %0002 ::MOV 2(R0), R3;
@BOX 5.1
*#%0BC8  ::TST (R0);
*#%0401  ::BGE + 1;
-> RII.14;
::IGNORE JUMP
@BOX 6.1
::MASK CHAR, IGNORE IF NUL OR DEL
*#%45C3 %FF80 ::BIC #%FF80,R3;
*#%0201  ::BNE + 1;
-> OUT;
*#%20D7 %007F ::CMP R3,#%7F;
*#%0201  ::BNE + 1;
-> OUT;
*#%90D2  ::MOVB R3, (R2)+;
*#%10B1 %0002  ::MOV R2, 2(R1);
*#%0AF1 %0004 ::DEC 4(R1);
@BOX 7.1
*#%17C2 %0222  ::MOV @#I.CH.TABLE.PTR, R2;
*#%60C2  ::ADD R3,R2;
*#%9282  ::MOVB (R2),R2;
*#%8A42  ::COMB R2;
*#%9C44 %0006 ::MOVB 6(R1),R4;
*#%C084  ::BICB R2,R4;
*#%45C4 %FF00 ::BIC %FF00 R4;
*#%0301  ::BEQ + 1;
-> RII.14; ::IGNORE FLIP JUMP
@BOX 8.1
*#%0BF1 %0004 ::TST 4(R1);
*#%0301 ::BEQ + 1;
-> OUT;
*#%15C4 %0001  ::MOV #1, R4;
-> RII.14; ::IGNORE FLIP JUMP
@BOX 10.1
OUT:
*#%15C8 %0041 ::START DEVICE;
*#%1585 ::MOV (SP)+,R5;
*#%1584 ::MOV (SP)+,R4;
*#%1583 ::MOV (SP)+,R3;
*#%1582 ::MOV (SP)+,R2;
*#%1581 ::MOV (SP)+,R1;
*#%1580 ::MOV (SP)+,R0;
*#%0A16 ::REMOVE PARAMETER;
*#%0002 ::RTI;
@BOX 11.1
END
@BOX 14.1
RII.14:
#AP713.PR11.2.1
@END
@TITLE AP713.PR11.2.1(1,11)
@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
*#%0A00 ::CLR R0;
*#%25C4 %000F ::CMP #%F, R4;
*#%0404 ::BGE + 4;
*#%7517 %FFFC ::ASH - 4,R4;
*#%65C0 %0004 ::ADD 4, R0;
*#%25C4 %0003 ::CMP #%3, R4;
*#%0404 ::BGE + 4;
*#%7517 %FFFE ::ASH - 2,R4;
*#%65C0 %0002 ::ADD 2, R0;
*#%25C4 %0001 ::CMP #%1, R4;
*#%0401 ::BGE + 1;
*#%0A80 ::INC R0;
@BOX 3.1
*#%1036 %000C ::MOV R0, %C(SP);
@BOX 4.1
*#%1585 ::MOV (SP)+,R5;
*#%1584 ::MOV (SP)+,R4;
*#%1583 ::MOV (SP)+,R3;
*#%1582 ::MOV (SP)+,R2;
*#%1581 ::MOV (SP)+,R1;
*#%1580 ::MOV (SP)+,R0;
*#%17E6 %023A  ::MOV PROC.ADDR,-(SP);
-> PDP11.APPENDIX.INT;
@BOX 5.1
END
@END
@TITLE AP713.PR11.3(1,11)

@COL 10C-13R-22N
@COL 1S-2R-3R-4C-5R-6T-7C-8R-23N-9F
@COL 11C-12R
@ROW 10-4-11
@ROW 13-8
@FLOW 1-2-3
@FLOW 4-5-6YES-7-8-23-9
@FLOW 6NO-13
@FLOW 10-13-22-23
@FLOW 11-12-23
@BOX 1.0
PROCESS SPECIAL I CH (COND)
@BOX 2.0
SELECT PR11 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
@BOX 9.0
END
@BOX 10.0
ALL OTHER CONDITIONS
@BOX 11.0
ERROR
@BOX 12.0
DISABLE DEVICE INTERRUPTS
AND DISENGAGE DEVICE
@BOX 13.0
START DEVICE
@BOX 1.1
PROC PROCESS.SPECIAL.I.CH (COND);
@BOX 2.1
SELECT PR11.PARAMS;
@BOX 3.1
SWITCH COND & %FF \
   TRANSFER, C1, C2, C3,
   CR, C5, ERROR, C7;
@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
TRANSFER:
@BOX 8.1
STOP &> PR11.CSR^ [PRS];
STOPPED &> PR11.STATUS;
NOTIFY (PR11.L.DEV, TR.COMP, COUNT);
@BOX 9.1
END
@BOX 10.1
C1:
C2:
C3:
C5:
C7:
@BOX 11.1
ERROR:
@BOX 12.1
STOP &> PR11.CSR^ [PRS];
DISENGAGED &> PR11.STATUS;
@BOX 13.1
START !> PR11.CSR^ [PRS];
@END

@TITLE AP713.PR11.4(1,11)

@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
POLL PROC
@BOX 2.0
START DEVICE IF ITS
STATUS HAS CHANGED
@BOX 3.0
END
@BOX 1.1
PROC POLL;
@BOX 2.1
IF PR11.CSR^ [PRS] >= 0 THEN
   ENGAGED !> PR11.STATUS;
   START !> PR11.CSR^ [PRS];
FI
@BOX 3.1
END
@END
