*DECK C$RLRA
          IDENT  C$RLRA 
          TITLE  CBRLRA - RELATIVE RANDOM I-O 
          SST 
          COMMENT  RELATIVE RANDOM I-O
          B1=1
* 
**        CBRLRA - RELATIVE RANDOM I-O
* 
*         ENTRY POINTS
* 
*                X1 HAS KEY IN ALL CASES
*                A0 HAS FIT 
* 
*            C.DELRL - DELETE 
* 
*            C.REWRL - REWRITE
* 
*            C.RDRRL - READ RANDOM
* 
*            C.STARL - START
*                B4 HAS RELATION
* 
*            C.WRRRL - WRITE
* 
* 
*CALL IODEFSC 
*CALL IOMICROS
          SPACE  2
          ENTRY  C.DELRL
 C.DELRL  BSS    0           DELETE 
          SX6    DELETE 
          EQ     INIT 
          SPACE  2
          ENTRY  C.RDRRL
 C.RDRRL  BSS    0           READ 
          SX6    READ 
          EQ     INIT 
          SPACE  2
          ENTRY  C.REWRL
 C.REWRL  BSS    0           REWRITE
          SX6    REWRITE
          EQ     INIT 
          SPACE  2
          ENTRY  C.STARL
 C.STARL  BSS    0           START
          STORE  A0,SVRL=B4  SAVE RELATION
          SX6    START
          EQ     INIT 
          SPACE  2
          ENTRY  C.WRRRL
 C.WRRRL  BSS    0
          SX6    WRITE
          SPACE  2
 INIT     BSS    0
          SA6    =SPROC      SAVE THE PROCESSOR ADDRESS 
          RJ     =XC.SVRTN   SAVE RETURN
          STORE  A0,REOI=NO  CLEAR AT END POSITION IF SET 
          FETCH  A0,NREC,X4  GET NEXT RECORD POINTER
          STORE  A0,SVRP=X4  SAVE IT
          SA2    PROC 
          SX3    X2-READ
          NZ     X3,INNTR    JP IF NOT A READ OPERATION 
          FETCH  A0,OPOF,X5  GET OPEN OUTPUT FLAG 
          PL     X5,NOTSQ    JP IF NOT OPEN OUTPUT
          SX1    #RDOPF      ERROR - OUTPUT MESSAGE AND ABORT 
          RJ     =XC.FIOER
 INNTR    BSS    0
          SX3    X2-DELETE
          SX5    X2-REWRITE 
          ZR     X3,CKLASTR  JUMP IF  THIS IS A DELETE
          NZ     X5,NOTSQ    JUMP IF NOT A REWRITE
 CKLASTR  BSS    0
*      A DELETE OR REWRITE IN SEQUENTIAL MODE MUST HAVE A GOOD READ PREV
          FETCH  A0,PM,X5    GET PROCESSING MODE (ACCESS MODE)
          PL     X5,NOTSQ    JUMP IF NOT SEQUENTIAL 
          FETCH  A0,LORD,X5  GET LAST OP READ FLAG
          NG     X5,OKRD     JUMP IF IT WAS A READ
          SX1    #DLRWSQ     GIVE ERROR MESSAGE 
          RJ     =XC.FIOER
 OKRD     BSS    0
          SX1    X4-1        USE LAST RECORD READ 
 NOTSQ    BSS    0
          STORE  A0,LORD=NO  CLEAR LAST OP READ FLAG
          STORE  A0,NREC=X1  SET NEXT RECORD POINTER
          NZ     X1,KEYNTZ   JUMP IF NOT A ZERO KEY 
          SX5    X2-START    SEE IF START 
          SX1    2R24        STATUS RETURN FOR BOUNDARY VIOLATION 
          ZR     X5,ZRKST    JUMP IF IT IS A START
          SX5    X2-READ
          ZR     X5,INVKYN   GO TO INVALID KEY FOR READ AND START 
          EQ     INVKY1      GO TO OTHER INVALID KEY PROC 
 ZRKST    BSS    0           ZERO KEY ON A START
          FETCH  A0,SVRL,X2  GET RELATION 
          SX2    X2-#GT#
          SX4    B1          SET FOR START PROC - NO REC FOUND
          ZR     X2,START    OK ONLY IF START GREATER THAN
          EQ     INVKYN      INVALID KEY
 KEYNTZ   BSS    0
          RJ     GETKEY      READ THE KEY 
          SA2    PROC 
          SB5    X2 
          JP     B5          GO TO PROPER OPERATION 
          SPACE  2
 DELETE   BSS    0
          NZ     X4,INVKYN1  JP IF NO RECORD EXISTS 
          MX6    0
          SA6    KEY
          SA5    KEYWA
          PUT    A0,KEY,10,,X5  WRITE ZERO KEY
          STORE  A0,WRIF=YES FLAG THAT A WRITE WAS DONE 
          FETCH  A0,LREC,X4  LAST REC 
          FETCH  A0,NREC,X5  THIS REC 
          IX5    X5-X4
          NZ     X5,NORM1    EXIT IF NOT LAST REC 
*      IF THE LAST RECORD WAS DELETED, LREC MUST BE SET TO NEW LAST ONE 
 FINDLST  BSS    0           FIND NEW LAST ONE
          FETCH  A0,LREC,X4 
          SX5    B1 
          IX4    X4-X5
          STORE  A0,LREC=X4  DEC REC
          ZR     X4,NORM1    FILE EMPTY 
          STORE  A0,NREC=X4 
          RJ     GETKEY      READ KEY 
          ZR     X4,NORM1    EXIT IF REC FOUND
          EQ     FINDLST
          SPACE  2
 READ     BSS    0
          NZ     X4,INVKYN   JP IF NO RECORD EXISTS 
          RJ     =XC.GETRL   READ THE RECORD
          RJ     =XC.BMPRP   BUMP REC POINTER 
          EQ     =XC.NORRT   RETURN 
          SPACE  2
 REWRITE  BSS    0
          NZ     X4,INVKYN1  JP IF NO RECORD EXISTS 
          RJ     =XC.PUTRL   WRITE THE REC
          EQ     NORM1
          SPACE  2
 START    BSS    0
          FETCH  A0,SVRL,X2  GET SAVED RELATION 
          SX3    X2-#EQ#
          NZ     X3,STARNQ   NOT = RELATION 
          ZR     X4,=XC.NORRT  RETURN NORMALLY IF MATCH FOUND 
 INVKYN   BSS    0
          STORE  A0,NREC=0   SET KEY TO ZERO - UNKNOWN CRP
          SX1    2R23        FILE STATUS CODE FOR NO MATCH
          EQ     =XC.INVKY   GO TO INV KEY PROCESSOR
 STARNQ   BSS    0
          SX3    X2-#GE#
          NZ     X3,STARNGE 
          ZR     X4,=XC.NORRT  RETURN IF REC FOUND
 STARNGE  BSS    0
          FETCH  A0,LREC,X3  GET LAST REC 
          FETCH  A0,NREC,X4  NEXT (CURRENT) REC 
          IX5    X3-X4
          NG     X5,INVKYN   JP IF NO REC ON FILE 
          ZR     X5,INVKYN   THERE IS NO GREATER KEY
 STARTLP  BSS    0
          RJ     =XC.BMPRP   BUMP REC NBR 
          RJ     GETKEY 
          ZR     X4,=XC.NORRT  EXIT IF REC FOUND
          EQ     STARTLP
 WRITE    BSS    0
          ZR     X4,INVKYD1  JUMP IF RECORD ALREADY ON FILE 
          RJ     =XC.PUTRL   WRITE THE REC
          EQ     NORM1
          SPACE  2
*      THIS EXIT IS TAKEN FOR ALL EXCEPT START AND READ BECAUSE 
*      THE CURRENT RECORD POINTER (REALLY NEXT RECORD POINTER) IS NOT 
*      TO BE CHANGED EXCEPT BY READ OR START. 
 NORM1    BSS    0
          FETCH  A0,SVRP,X2  GET SAVED RECORD POINTER 
          STORE  A0,NREC=X2  RESET NEXT REC POINTER 
          EQ     =XC.NORRT
 INVKYN1  BSS    0
          SX1    2R23        CODE FOR NO MATCH
          EQ     INVKY1 
 INVKYD1  SX1    2R22        CODE FOR INV KEY WITH DUPLICATE
 INVKY1   BSS    0
          FETCH  A0,SVRP,X2  GET SAVED RECORD POINTER 
          STORE  A0,NREC=X2 
          EQ     =XC.INVKY
          SPACE  2
* 
**        GETKEY - READS THE KEY FROM THE RECORD
* 
*         ON EXIT 
*                X4 IS ZERO IF KEY MATCHES COMPUTED ONE 
*                ALL OTHER REGS EXCEPT A0 CLOBBERED 
*                KEYWA HAS KEY WORD ADDRESS 
*                KEY HAS KEY
* 
 GETKEY   DATA   0
          RJ     =XC.CWARL   COMPUTE REC POSN 
*      C.CWARL RETURNS REC NO IN X0, REC LEN IN X1,  1 IN X4, WA IN X5
          FETCH  A0,LREC,X3,3      GET LAST REC NBR 
          IX3    X3-X0       LAST - CURR
          NG     X3,GETKEY   EXIT IF NOT IN FILE
          FETCH  A0,V4FL,X3,3      GET VERSION 4 FLAG 
          PL     X3,GETKN4   JUMP IF VERSION 5 FILE 
          IX1    X1-X4       REC SIZE - 1 
          IX5    X1+X5       POINT TO KEY 
 GETKN4   BSS    0
          BX6    X5 
          SA6    =SKEYWA     SAVE KEY ADDR
          GET    A0,KEY,10,,X5  GET THE KEY 
          SA4    KEY
          FETCH  A0,CKEY,X5  GET COMPUTED KEY 
          IX4    X4-X5
          EQ     GETKEY 
 KEY      BSSZ   1
          END 
