*COMDECK,COMCRDW
          CTEXT  COMCRDW - READ WORDS TO WORKING BUFFER.
 RDW      SPACE  4
          IF     -DEF,QUAL$,1 
          QUAL   COMCRDW
          BASE   D
*         COMMENT COPYRIGHT CONTROL DATA CORP. 1970.
 RDW      SPACE  4
***       RDW - READ WORDS TO WORKING BUFFER. 
*         D. A. CAHLANDER.  70/11/29. 
 RDW      SPACE  4
***              RDW READS A GIVEN NUMBER OF WORDS FROM A CIO BUFFER TO 
*         A WORKING BUFFER.  THIS DECK ALSO CONTAINS LCB=, RDX=.
* 
*         ENTRY  (X2) = ADDRESS OF FET FOR FILE.
*                (B6) = FWA WORKING BUFFER. 
*                (B7) = WORD COUNT OF WORKING BUFFER. 
* 
*         EXIT   (X1) = 0 FOR TRANSFER COMPLETE.
*                (X1) = -1 IF EOF DETECTED ON FILE. 
*                (X1) = -2 IF EOI DETECTED ON FILE. 
*                (X1) = (B6) IF EOR WAS DETECTED ON FILE BEFORE 
*                             TRANSFER WAS COMPLETED. 
*                (B6) = ADDRESS PLUS ONE OF LAST WORD TRANSFERRED TO
*                             WORKING BUFFER. 
*                (X2) = ADDRESS OF FET FOR FILE.
* 
*         USES   X - 1, 2, 3, 4, 6, 7.
*                B - 1, 2, 3, 4, 5, 6, 7. 
*                A - 1, 2, 3, 4, 6, 7.
* 
*         CALLS  CIO=, LCB=, RDX=.
  
  
 RDW7     SX6    B4+B3       ADVANCE OUT
          SB4    B4+B3
          SB6    B6+B3
          SB7    B7-B3
          NE     B4,B5,RDW8  IF OUT " LIMIT 
          SA1    X2+B1       READ FIRST 
          SX6    X1          OUT = FIRST
 RDW8     SA6    A3          UPDATE OUT 
          MX1    0
          NZ     B7,RDW1     IF NOT END OF TRANSFER 
  
 RDW=     PS                 ENTRY/EXIT 
 RDW1     SA3    X2+3        (B4) = OUT 
          SA1    X2+2        (B3) = IN
          IF     -DEF,B1=1,1
          SB1    1
          SA4    A3+B1       (B5) = LIMIT 
          SB4    X3 
          SB3    X1 
          SA1    X3          READ FIRST WORD
          SB5    X4 
          GE     B3,B4,RDW2  IF NO END AROUND 
          SB3    B5 
 RDW2     SB3    B3-B4       FREE DATA LENGTH 
          LE     B3,B7,RDW3  IF NOT ENOUGH ROOM 
          SB3    B7 
 RDW3     ZR     B3,RDW9     IF NO DATA 
          BX7    X1 
          SA1    A1+B1
  
*         INITIALIZE REGISTERS FOR TRANSFER.
  
          SX4    B3-B1
          MX6    -3 
          SA7    B6 
          BX3    -X6*X4      NUMBER OF ODD WORDS
          AX4    3           NUMBER OF BLOCKS 
  
*         TRANSFER UP TO 7 WORDS. 
  
          ZR     X3,RDW5     IF NO ODD WORDS
 RDW4     SX3    X3-1 
          BX7    X1 
          SA1    A1+B1
          SA7    A7+B1
          NZ     X3,RDW4     LOOP 
  
*         PRE-READ REGISTERS. 
  
 RDW5     ZR     X4,RDW7     IF NO BLOCKS 
          SB5    X2 
          SA2    A1+B1
          SB2    B1+B1       (B2) = 2 
          SA3    A2+B1
          SB4    X4          (B4) = LOOP COUNT
          SA4    A3+B1
  
*         TRANSFER 8 WORD BLOCKS. 
  
 RDW6     BX6    X1 
          LX7    X2 
          SA1    A3+B2
          SA2    A4+B2
          SA6    A7+B1
          SB4    B4-B1
          SA7    A6+B1
          BX6    X3 
          LX7    X4 
          SA3    A1+B2
          SA4    A2+B2
          SA6    A6+B2
          SA7    A7+B2
          BX6    X1 
          LX7    X2 
          SA1    A3+B2
          SA2    A4+B2
          SA6    A6+B2
          SA7    A7+B2
          BX6    X3 
          LX7    X4 
          SA3    A1+B2
          SA4    A2+B2
          SA6    A6+B2
          SA7    A7+B2
          NZ     B4,RDW6     LOOP 
  
*         READ EXIT.
  
          SA3    B5+3        OUT
          SX2    B5 
          SA1    A3+B1       (B5) = LIMIT 
          SA4    B5          CHECK BUFFER STATUS
          SB6    B6+B3
          SB7    B7-B3
          SB4    X3+B3       ADVANCE OUT
          SX6    X3+B3
          SB5    X1 
          LX4    59-0 
          SA1    X2+B1       READ FIRST 
          NE     B4,B5,RDW14 IF OUT " LIMIT 
          SX6    X1          OUT = FIRST
  
*         TRY TO BUFFER AHEAD.
  
 RDW14    PL     X4,RDW8     IF BUFFER BUSY 
          LX4    0-4
          NG     X4,RDW8     IF EOR/EOF SET 
          SA4    X2+2        READ IN
          SB2    X1          (LIMIT - FIRST)
          SX1    B5-B2
          IX7    X4-X6       (IN-OUT) 
          LX3    X7,B1       2*(IN-OUT) 
          AX7    60          SIGN OF (IN-OUT) 
          BX4    X7-X1       INVERT BUFFER IF OUT \ IN
          IX7    X4-X3       BUFFER SIZE - 2*(IN-OUT) 
          NG     X7,RDW8     IF BUFFER THRESHOLD NOT REACHED
          SA6    A3          UPDATE OUT 
          SA1    X2          ISSUE PREVIOUS READ FUNCTION 
          SX7    740770B/2
          AX1    1
          BX7    X7*X1
          LX7    1
          RJ     =XCIO= 
          MX1    0           RESPONSE = 0 
          NZ     B7,RDW1     IF NOT DONE
          JP     RDW=        RETURN 
  
*         LOAD CIRCULAR BUFFER. 
  
 RDW9     SA1    X2          CHECK BUFFER STATUS
          SA3    X2+2        READ IN
          LX1    59-0 
          NG     X1,RDW11    IF BUFFER NOT BUSY 
          RECALL
 RDW10    JP     RDW1        CONTINUE READ
  
 RDW11    SB3    X3 
          LX1    0-4
          NE     B3,B4,RDW1  IF BUFFER NOT EMPTY
          NG     X1,RDW12    IF EOR SET 
          SX6    740770B/2   ISSUE PREVIOUS READ FUNCTION 
          LX1    4
          BX7    X6*X1
          LX7    1
          RJ     =XCIO= 
          JP     RDW1        CONTINUE READ
  
 RDW12    SA3    X2+B1       SET IN = OUT = FIRST 
          LX6    X1,B1
          SX1    B6+0 
          PL     X6,RDW13    IF NOT EOF 
          LX6    3-9
          MX1    -1 
          PL     X6,RDW13    IF NOT EOI 
          SX1    -2 
 RDW13    SX7    X3 
          SA7    A3+B1
          NO
          SA7    A7+B1
          JP     RDW=        RETURN 
 RDX      SPACE  4
**        RDX - READ EXIT.
*         EXIT FROM READ SUBROUTINE TO CALLER.
*         IF CIRCULAR BUFFER IS BUSY, OR EOR/EOF IS SENSED, NO ACTION 
*         IS TAKEN. 
*         OTHERWISE, THE WORD COUNT REMAINING IN THE BUFFER IS CHECKED
*         AND PREVIOUS READ FUNCTION ISSUED IF NECESSARY. 
* 
*         ENTRY  (A2) = ADDRESS OF OUT. 
*                (A3) = ADDRESS OF FIRST. 
*                (A4) = RETURN ADDRESS. 
*                (X3) = FIRST.
*                (B3) = IN. 
*                (B4) = OUT.
*                (B5) = LIMIT.
* 
*         EXIT   TO RETURN ADDRESS. 
* 
*         CALLS  CIO=.
  
  
 RDX=     SA1    A3-B1       CHECK BUFFER STATUS
          SX6    B4          STORE OUT
          LX1    59 
          SA6    A2 
          SX2    A3-B1       RESET (X2) 
          PL     X1,RDX1     IF BUFFER BUSY 
          LX1    -4 
          NG     X1,RDX1     IF EOR/EOF SET 
  
*         IF BUFFER IS NOT BUSY, CHECK BUFFER SIZE. 
*         ISSUE READ IF BUFFER THRESHOLD IS REACHED.
  
          SX6    B3-B4       (IN-OUT) 
          SB2    X3          (LIMIT-FIRST)
          LX3    X6,B1       2*(IN-OUT) 
          SX7    B5-B2
          AX6    60          SIGN OF (IN-OUT) 
          BX4    X6-X7       INVERT BUFFER IF OUT \ IN
          IX6    X4-X3       BUFFER SIZE - 2*(IN-OUT) 
          NG     X6,RDX1     IF BUFFER THRESHOLD NOT REACHED
          LX1    4           ISSUE PREVIOUS READ FUNCTION 
          SX6    740770B/2
          BX7    X6*X1
          LX7    1
          RJ     =XCIO= 
 RDX1     SX1    B0          RESPONSE = 0 
          SB2    A4          SET RETURN ADDRESS 
          JP     B2          RETURN 
 LCB      SPACE  4
**        LCB - LOAD CIRCULAR BUFFER. 
*         REQUEST READ IF BUFFER IS EMPTY, NOT BUSY AND NOE EOR/EOF.
*         IF BUFFER IS BUSY, RECALL AND RETURN. 
* 
*         ENTRY  (A2) = ADDRESS OF OUT. 
*                (A3) = ADDRESS OF FIRST. 
*                (A4) = RETURN ADDRESS. 
*                (B4) = OUT.
* 
*         EXIT   TO RETURN ADDRESS - 1 IF CONTINUATION READ.
*                TO RETURN ADDRESS IF EOR/EOF.
*                (X1) = LAST WORD ADDRESS OF WORKING BUFFER.
*                (X1) = -1 IF EOF.
*                (X1) = -2 IF EOI.
* 
*         CALLS  CIO=.
  
  
 LCB=     SA1    A3-B1       CHECK BUFFER STATUS
          SX6    B4          STORE OUT
          LX1    59 
          SA6    A2 
          NG     X1,LCB2     IF BUFFER NOT BUSY 
          RECALL
 LCB1     SB2    A4-B1       CONTINUE READ
          JP     B2 
  
 LCB2     SA1    A2-B1       RE-READ IN 
          SB3    X1 
          NE     B3,B4,LCB1  IF BUFFER NOT EMPTY
          SA1    A3-B1       CHECK BUFFER STATUS
          LX1    59-4 
          NG     X1,LCB3     IF EOR SET 
          SX6    740770B/2   ISSUE PREVIOUS READ FUNCTION 
          LX1    4
          SX2    A3-B1
          BX7    X6*X1
          LX7    1
          RJ     =XCIO= 
          SB2    A4-B1       CONTINUE READ
          JP     B2 
  
 LCB3     LX6    B1,X1
          SA1    A3          SET IN = OUT = FIRST 
          SX7    X1 
          SA7    A1+B1
          SX1    -B1         RESPONSE = -1
          SB2    A4          SET RETURN ADDRESS 
          NG     X6,LCB4     IF EOF 
          MX2    -4 
          SX1    B6          RESPONSE = LAST WORD ADDRESS 
          LX6    -14+4
          BX2    -X2*X6 
          SB3    X2+
          EQ     B3,B1,LCB5  IF LEVEL 1 
 LCB4     SX2    A3-B1       RESET (X2) 
          SA7    A7+B1
          NG     X1,LCB6     IF EOF/EOI 
 LCB4.1   JP     B2          RETURN 
  
 LCB5     SA1    A3          CHECK DEVICE TYPE
          MX2    -12
          LX1    12 
          BX1    -X2*X1 
          SX6    X1-2RTT
          SX1    B6          RESPONSE = LAST WORD ADDRESS 
          NZ     X6,LCB4     IF DEVICE TYPE NOT *TT*
          SA7    A7+B1       STORE OUT
          READ   A3-B1       RESTART READ 
          SB2    A4-B1       CONTINUE 
          JP     B2 
 LCB6     LX6    3-9
          PL     X6,LCB4.1   IF NOT EOI 
          LX1    1           RESPONSE= -2 
          JP     B2          RETURN 
          SPACE  4
          BASE   *
 QUAL$    IF     -DEF,QUAL$ 
          QUAL   *
 RDW=     EQU    /COMCRDW/RDW=
 RDX=     EQU    /COMCRDW/RDX=
 LCB=     EQU    /COMCRDW/LCB=
 QUAL$    ENDIF 
          ENDX
