COMCRDW 
COMMON
          CTEXT  COMCRDW - READ WORDS TO WORKING BUFFER.
 RDW      SPACE  4
          IF     -DEF,QUAL$,1 
          QUAL   COMCRDW
          BASE   D
*         COMMENT  COPYRIGHT CONTROL DATA SYSTEMS INC.  1992. 
 RDW      SPACE  4
***       RDW - READ WORDS TO WORKING BUFFER. 
*         D. A. CAHLANDER.   70/11/29.
*         R. E. TATE.        73/11/04.
 RDW      SPACE  4
***              RDW READS A GIVEN NUMBER OF WORDS FROM A CIO BUFFER TO 
*         A WORKING BUFFER.  THIS DECK ALSO CONTAINS LCB=, RDX=.
* 
*         A *READW* REQUEST MAY ACCESS DATA FROM BEYOND THE END OF THE
*         *CIO* BUFFER, THUS CAUSING AN ABORT IF THE LAST WORD ADDRESS
*         OF THE *CIO* BUFFER IS WITHIN 4 WORDS OF THE PROGRAM-S FIELD
*         LENGTH. 
* 
*         THE THRESHOLD CONDITION TO ISSUE READ FUNCTIONS 
*         IS BUFFER HALF EMPTY FOR BUFFERS LARGER 
*         THAN 511 DECIMAL WORDS, AND BUFFER TOTALLY
*         EMPTY FOR SMALLER BUFFERS.  IF THE SYMBOL 
*         RDX$ IS DEFINED, THEN THE THRESHOLD IS
*         BUFFER EMPTY FOR ALL BUFFER SIZES.
*         ENTRY  (X2) = ADDRESS OF FET FOR FILE.
*                (B6) = FWA WORKING BUFFER. 
*                (B7) = WORD COUNT OF WORKING BUFFER. 
*                IF (B7) = 0, NO TRANSFER WILL BE PERFORMED.
* 
*         EXIT   (X1) = 0 FOR TRANSFER COMPLETE.
*                (X1) = -1 IF EOF DETECTED ON FILE. 
*                (X1) = -2 IF EOI DETECTED ON FILE. 
*                (X1) = -3 IF *CIO=* WAS CALLED TO READ MORE DATA AND 
*                       RETURNED AN ERROR STATUS. 
*                (X1) = (B6) IF EOR WAS DETECTED ON FILE BEFORE 
*                             TRANSFER WAS COMPLETED. 
*                (B6) = ADDRESS PLUS ONE OF LAST WORD TRANSFERRED TO
*                             WORKING BUFFER. 
*                (B7) = WORD COUNT REMAINING TO BE TRANSFERRED. 
*                (X2) = ADDRESS OF FET FOR FILE.
*                (X7) = ERROR STATUS IF (X1) = -3.
* 
*         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=.
  
  
*         PROCESS 1 WORD OR BUFFER EMPTY. 
  
 RDW18    ZR     B3,RDW11    IF NO DATA 
          BX7    X1          STORE 1 WORD 
          SA7    B6 
 RDW19    SX6    B4+B3       ADVANCE OUT
          SB4    B4+B3
          SB6    B6+B3
          SB7    B7-B3
          NE     B4,B5,RDW20 IF OUT " LIMIT 
          SA1    X2+B1       READ FIRST 
          SX6    X1          OUT = FIRST
 RDW20    SA6    A3          UPDATE OUT 
          BX1    X1-X1       RESPONSE = 0 
          NZ     B7,RDW1     IF NOT END OF TRANSFER 
  
 RDW=     PS                 ENTRY/EXIT 
 RDW0     SX1    B0+
          LE     B7,RDW=     IF NO WORDS TO TRANSFER
 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 
 RDWA     BSS    0
 RDW3     SA3    RDWB        PRESET CMU CODE
          RJ     RDW16       PRESET CMU CODE
*         LE     B3,B1,RDW18 IF 1 WORD OR LESS OF DATA (NO CMU) 
*         BX7    X1          (NO CMU) 
*         SA1    A1+B1       (NO CMU) 
* 
*         LE     B3,B1,RDW18 IF 1 WORD OR LESS OF DATA (CMU)
*         JP     RDW14       (CMU)
  
*         INITIALIZE REGISTERS FOR TRANSFER.
  
 RDW4     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,RDW6     IF NO ODD WORDS
          SB2    X3 
 RDW5     SB2    B2-B1
          BX7    X1 
          SA1    A1+B1
          SA7    A7+B1
          NZ     B2,RDW5     IF MORE WORDS
  
*         PRE-READ REGISTERS. 
  
 RDW6     ZR     X4,RDW19    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. 
  
 RDW7     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,RDW7     LOOP 
  
*         READ EXIT.
  
          SX2    B5          RESET FET ADDRESS
          SA3    B5+3        OUT
          SA1    A3+B1       (B5) = LIMIT 
          SB5    X1 
 RDW8     SA4    X2          CHECK BUFFER STATUS
          SB6    B6+B3
          SB7    B7-B3
          SB4    X3+B3       ADVANCE OUT
          SX6    X3+B3
          LX4    59-0 
          SA1    X2+1        READ FIRST 
          NE     B4,B5,RDW9  IF OUT " LIMIT 
          SX6    X1+         OUT = FIRST
 RDX$     IF     DEF,RDX$ 
 RDW9     EQ     RDW20       CLEAN UP AND RETURN
 RDX$     ELSE
  
*         TRY TO BUFFER AHEAD.
  
 RDW9     PL     X4,RDW20    IF BUFFER BUSY 
          LX4    0-4
          NG     X4,RDW20    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) 
          AX1    9
          NG     X7,RDW20    IF BUFFER THRESHOLD NOT REACHED
          ZR     X1,RDW20    IF BUFFER NOT BIG ENOUGH TO READ AHEAD 
          SA6    A3+         UPDATE OUT 
 RDX$     ENDIF 
 RDW10    SA1    X2          ISSUE PREVIOUS READ FUNCTION 
          SX7    740770B/2
          LX4    X7,B1
          BX7    X4*X1
          RJ     =XCIO= 
          ZR     X7,RDW0     IF NO ERROR
          SA3    X2+3        OUT
          SA4    X2+2        IN 
          MX1    -2 
          IX3    X3-X4
          NZ     X3,RDW0     IF BUFFER NOT EMPTY
          JP     RDW=        RETURN 
  
*         LOAD CIRCULAR BUFFER. 
  
 RDW11    SA1    X2          CHECK BUFFER STATUS
          SA3    X2+2        READ IN
          LX1    59-0 
          PL     X1,RDW13    IF BUFFER BUSY 
          SB3    X3 
          LX1    0-4
          NE     B3,B4,RDW1  IF BUFFER NOT EMPTY
          PL     X1,RDW10    IF NOT EOR SET 
          SA3    X2+B1       SET IN = OUT = FIRST 
          LX6    X1,B1
          SX1    B6+0 
          PL     X6,RDW12    IF NOT EOF 
          LX6    3-9
          MX1    -1 
          PL     X6,RDW12    IF NOT EOI 
          SX1    -2 
 RDW12    SX7    X3+
          SA7    A3+B1
          SA7    A7+B1
          JP     RDW=        RETURN 
  
*         RECALL WAITING FOR I/O. 
  
 RDW13    RECALL
          JP     RDW1 
  
*         MOVE DATA WITH CMU. 
  
 RDW14    SX4    B3-819 
          PL     X4,RDW15    IF MOVE TOO BIG FOR CMU
          SX4    B3          10 * WORDS = CHARACTERS
          LX6    X4,B1
          BX1    X0          SAVE X0
          LX4    3
          IX6    X4+X6
          SX7    B6          SET DESTINATION ADDRESS
          LX3    30 
          MX4    -4 
          BX7    X7+X3
          BX3    X4*X6       EXTRACT UPPER PORTION OF CHARACTER COUNT 
          LX3    48-4 
          BX4    -X4*X6 
          BX7    X3+X7
          LX4    26 
          BX7    X4+X7
          AX3    51 
          SA7    RDWB        STORE DESCRIPTOR WORD
          IM     RDWB        MOVE DATA
          BX0    X1          RESTORE X0 
          ZR     X3,RDW19    IF NO READ EXIT CHECK
          SX3    B4          SET OUT
          JP     RDW8 
  
 RDW15    BX7    X1 
          SA1    A1+B1
          JP     RDW4 
  
*         PRESET FOR CMU. 
*         RDWB IS READ UP AND THEN RETURN JUMPED TO IN ORDER TO VOID
*         THE INSTRUCTION STACK.
  
 RDWB     LE     B3,B1,RDW18  IF 1 WORD OR LESS (CMU) 
          JP     RDW14
  
 RDW16    EQU    RDWB        USED TO VOID STACK AT PRESET 
  
*         PRESET FOR CMU. 
  
          SA4    CMUR        CHECK IF CMU AVAIALABLE
          SB3    RDWA 
          NG     X4,RDW17    IF CMU 
          SA3    RDWC 
 RDW17    BX6    X3 
          SA6    B3 
          JP     RDW1 
  
 RDWC     LE     B3,B1,RDW18  IF 1 WORD OR LESS (NO CMU)
          BX7    X1 
          SA1    A1+B1
 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. 
* 
*         USES   A - 1, 6.
*                B - 2. 
*                X - 1, 2, 3, 6, 7. 
* 
*         CALLS  CIO=.
  
  
 RDX=     SA1    A3-B1       CHECK BUFFER STATUS
          SX6    B4          STORE OUT
          LX1    59 
          SA6    A2 
          SX2    A3-B1       RESET (X2) 
 RDX$     IF     -DEF,RDX$
          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.
  
          SA1    A2-B1       REREAD IN
          SB3    X1 
          SX6    B3-B4       (IN-OUT) 
          SB2    X3          (LIMIT-FIRST)
          LX3    X6,B1       2*(IN-OUT) 
          SX7    B5-B2
          AX6    60          SIGN OF (IN-OUT) 
          BX6    X6-X7       INVERT BUFFER IF OUT .GE. IN 
          IX6    X6-X3       BUFFER SIZE - 2 * ( IN - OUT ) 
          AX7    9
          NG     X6,RDX1     IF BUFFER THRESHOLD NOT REACHED
          ZR     X7,RDX1     IF BUFFER NOT BIG ENOUGH TO READ AHEAD 
          SA1    X2          ISSUE PREVIOUS READ FUNCTION 
          SX6    740770B/2
          LX6    1
          BX7    X6*X1
          RJ     =XCIO= 
 RDX1     SX1    B0          RESPONSE = 0 
 RDX$     ELSE
          SX1    B0+         RESPONSE = 0 
 RDX$     ENDIF 
          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,LCB6  IF LEVEL 1 
 LCB4     SX2    A3-B1       RESET (X2) 
          SA7    A7+B1
          NG     X1,LCB7     IF EOF/EOI 
 LCB5     JP     B2          RETURN 
  
 LCB6     SA7    A7+B1       STORE OUT
          READ   A3-B1       RESTART READ 
          SB2    A4-B1       CONTINUE 
          JP     B2 
  
 LCB7     LX6    3-9
          PL     X6,LCB5     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
