         PCC      0
UTSPROC  SET      1
S69PROC  SET      1
MONPROC  SET      1
DISCBPROC SET     1
         SYSTEM   UTS
         SPACE    6
*
*  ROUTINES TO IMPLEMENT READ AHEAD FOR DISC FILE MANAGEMENT
*
         SPACE    6
RA       EQU      %
         TITLE    '****  EXTERNAL DEFINITIONS  ****'
         SPACE    2
         DEF      RA
         SPACE    1
         DEF      RAPURGE
         DEF      T:RACHK
         DEF      T:RAPURGD
         DEF      T:RAMISRCH
         DEF      T:RACONSEC
         DEF      T:RADD
         DEF      T:RAREL
         SPACE    2
         REF      RA:CURA,RA:CURF,RA:CURR,RA:ABNTB,RA:ABNCO
         REF      RA:AINIT,RA:ABNPS,RA:ABNTR,RA:ABNTA,RA:ABNWP,RA:ABNNN
         REF      RA:ASTOR,RA:SSTOR,RA:AGET,RA:SGET,RA:SINIT
         REF      SL:RAMR,SL:RAMF,SL:AIRM,SL:RATOR,SL:AIRTO
         REF      RA:SCHK,RA:IOW
         TITLE    '****  EXTERNAL REFERENCES  ****'
         SPACE    2
         REF      ACNCFU
         REF      C:CTUN
         REF      C:TIC
         REF      C:TINC
         REF      DUALEA
         REF      FILCFU
         REF      FMCHKDA
         REF      GETORG
         REF      GETTBL
         REF      GETVDCTX
         REF      GETVNO
         REF      J:CLS
         REF      J:JIT
         REF      NEWQNW
         REF      PULLFOUR
         REF      RCVPSD
         REF      REGIPSD
         REF      S:STLC
         REF      SETPVI
         REF      SETVNO
         REF      T:RSPP
         REF      T:STLPP
         REF      T:XBUF
         REF      UB:MF
         SPACE    1
         REF      RAB:FLINK,RAB:BLINK,RAB:USER
         REF      RAH:DCB,RAH:TIME
         REF      RA:DA
         REF      RAX:PAGE
         REF      RAFLAG
         SPACE    1
         REF      S:CUN,S:CUP
         SPACE    1
         REF      Y8,Y4,Y2,Y1,Y08,Y04,Y02,Y00FE,Y0002
         REF      Y008,Y002
         REF      M16,M24
         TITLE    '****  REGISTERS AND CONSTANTS  ****'
         SPACE    2
R0       EQU      0
R1       EQU      1
R2       EQU      2
R3       EQU      3
R4       EQU      4
R5       EQU      5
R6       EQU      6
R7       EQU      7
R8       EQU      8
R9       EQU      9
R10      EQU      10
R11      EQU      11
R12      EQU      12
R13      EQU      13
R14      EQU      14
R15      EQU      15
         SPACE    3
FL:ACT   EQU      Y8                ENTRY IS ACTIVE
FL:IOP   EQU      Y4                I/O IN PROGRESS
MSK:IOP  EQU      NB31TO0+31
FL:AIR   EQU      Y2                AIR ENTRY
FL:WAIT  EQU      Y1                USER IS WAITING FOR I/O COMPLETE
MSK:WAIT EQU      NB31TO0+29
FL:REL   EQU      Y08               ENTRY IS TO BE RELEASED
FL:IW    EQU      Y5                IOP AND WAIT
         SPACE    2
AIRSHFT   EQU     3
DCDAM    EQU      ACNCFU+4          DUAL DISC ADDRESS
         TITLE    '****  INITIATE A READ AHEAD OPERATION  ****'
         SPACE    2
*  PURPOSE:  INITIATE A READ AHEAD IF POSSIBLE
*
*  INPUT:  R6 = DCB ADDRESS
*          R12 = DISC ADDRESS TO BE READ
*
*  CALL:  BAL,R0  T:RAINIT
*
*  VOLATILE:  R7,R8,R11
*
         SPACE    1
T:RAINIT EQU      %
         PUSH     9,R12
         MTW,1    RA:AINIT          INCR # ATTEMPTED TO INITIATE
*
         BAL,R11  PRIVDA            CONVERT PRIVATE FORM OF DISC ADDR
*
         LW,R8    R12               DISC ADDRESS TO BE READ
         BAL,R11  FMCHKDA           VALIDATE IT
         BCR,15   CHKXIT            BAD DISC ADDRESS
*
         DISABLE
*
         OR,R12   FL:IOP            I/O IN PROGRESS FLAG
         BAL,R11  GETENTRY          GET TABLE ENTRY
         MTW,1    RA:CURR,R4        INCR APPROPRIATE BUCKET
         ENABLE
         AI,R4    0                 WAS AN ENTRY OBTAINED
         BNEZ     RAINXIT6          NO
*
         LW,R13   R6
         SLS,R13  -1
         STH,R13  RAH:DCB,R7        PUT DCB IN TABLE
*
         LI,R2    BARAX
         STB,R7   *R6,R2            SAVE TABLE INDEX IN DCB
*
         MTW,1    RA:SINIT          INCR # SUCCESSFULLY INITIATED
*
         LI,R2    0                 FUNCTION CODE (READ)
*
RAIO     LW,R1    R7                MOVE END-ACTION INFO
RAIO1    AND,R12  M24
         LW,R15   R12               DISC ADDRESS
         LI,R14   512*4             BYTE COUNT
         CI,R15   1
         BAZ      %+2
         LI,R14   256*4             HALF GRANULE
         LOAD,R13 RAX:PAGE,R7       PAGE # OF BUFFER
         SLS,R13  9+2               BYTE ADDRESS
         LDCTX,R12  R15             DCT INDEX
         LW,R11   S:CUP             CURRENT USER'S PRIORITY
         STH,R11  R12               PRIORITY
         STB,R2   R12               FUNCTION CODE
         AI,R12   X'0A00'           NRT=10
         LI,R0    RAENDAC           END ACTION ADDRESS
         BAL,R11  NEWQNW            QUEUE THE I/O
         NOP
         LB,R11   R7
         BEZ      CHKXIT            NO DUAL
         LW,R12   DCDAM             DISC ADDRESS OF DUAL
         LI,R2    1                 FUNCTION CODE = WRITE
         LW,R1    R7                MOVE END-ACTION INFO
         AND,R7   M24               MASK OFF DUAL FLAG
         B        RAIO1             WRITE THE DUAL
         SPACE    3
RAINXIT6 EQU      %
         BAL,R0   RAPURGE           PURGE TIMED-OUT ENTRIES
*
RAINXIT2 B        RACHKCC1
         SPACE    2
GETIME   LW,R1    C:CTUN
         SW,R1    C:TINC
         AW,R1    C:TIC
         SLS,R1   -4                MSEC/32
         AND,R1   M16
         BNEZ     *R0
         AI,R1    1                 FORCE TIME TO BE NON-ZERO
         B        *R0
         TITLE    '****  END ACTION ROUTINE  ****'
         SPACE    2
RAENDAC  EQU      %
         PUSH     R11
         LB,R3    R14               DUAL FLAG
         BEZ      RAENDAC1          NOT DUAL WRITE
         BAL,R0   DUALEA            CHECK IF LAST WRITE
         AND,R14  M24
RAENDAC1 LW,R7    R14               READ-AHEAD TABLE INDEX
         LW,R2    RA:DA,R7
         AND,R2   MSK:IOP           RESET FL:IOP
         STW,R2   RA:DA,R7
         CW,R2    FL:REL
         BAZ      CHKERR            ENTRY IS TO BE RELEASED
         B        CHKREL
*
*  RELEASE THE ENTRY
*
RAENDREL BAL,R10  T:RAREL
         PULL     R11
         B        *R11
         SPACE    2
*
*  CHECK COMPLETION CODE
*
CHKERR   EQU      %
         LB,R4    R12               TYC
         CI,R4    1
         BE       CHKWAIT           NO ERROR
*
*  I/O ERROR
*
CHKREL   CW,R2    FL:WAIT
         BAZ      RAENDREL          USER IS NOT WAITING
         OR,R2    FL:REL            SET RELEASE FLAG
         SPACE    2
*
*  REPORT I/O COMPLETE FOR WAITING USER
*
REPIOC   STW,R2   RA:DA,R7          STORE FLAGS
         ENABLE
         PULL     R11               GET RETURN ADDRESS
         LB,R2    RAB:USER,R7       GET USER NUMBER
         STW,R2   *TSTACK           IOQ WILL REPORT I/O COMPLETE
         B        *R11
         SPACE    2
CHKWAIT  CW,R2    FL:WAIT
         BANZ     REPIOC            USER IS WAITING
         ENABLE
         PULL     R11
         B        *R11
         SPACE    2
PRIVDA   EQU      %
         LI,R15   DCBPRIVBIT
         CW,R15   PRIV,R6
         BAZ      *R11              NOT PRIVATE
         PUSH     6,R7
         BAL,R0   GETVNO            R3 = CURRENT VOL #
         LDCTX,R0 R12               VOL # OF DESIRED DA
         CW,R3    R0
         BE       PRIV2             SAME - ALL OK
         BAL,R0   GETORG            NOT SAME - BETTER NOT BE CONSEC
         BL       PRIV8             CONSEC - ONLY ONE VOL OPEN
         BAL,R0   SETVNO            PUT IN DESIRED VOL #
         BAL,R15  SETPVI            FIND THE HGP, PUT IN DCTX
*
PRIV2    BAL,R0   GETVDCTX          GET DCTX OF CURRENT VOL
         LW,R12   *TSTACK
         STDCTX,R3  R12             PUT IN DCT INDEX
         STW,R12  *TSTACK
         PULL     6,R7
         B        *R11
*
PRIV8    PULL     6,R7              CAN'T DO READ-AHEAD
         B        CHKXIT
         TITLE    '****  CHECK FOR BLOCK READ AHEAD  ****'
         SPACE    2
*  PURPOSE:  CHECK IF DESIRED BLOCK WAS READ AHEAD.  IF SO,
*            MAP BUFFER PAGE OVER USER'S BUFFER AND RELEASE
*            HIS OLD BUFFER.
*
*  INPUT:  R6 = DCB ADDRESS
*          R12 = DISC ADDRESS
*          R14 = BUFFER ADDRESS
*
*  CALL:  BAL,R0  T:RACHK
*
*  OUTPUT:  CC=0  BLOCK READ AHEAD AND MAPPED IN
*             =1  NO BLOCK OR WRONG BLOCK READ AHEAD
*
*  VOLATILE:  R5,R7,R8,R10,R11,R13
*
         SPACE    2
T:RACHK  EQU      %
         LI,R15   X'1FFFF'
         AND,R15  CFU,R6            CFU ADDRESS
         CI,R15   FILCFU            IS THIS A FILE DIRECTORY READ
         BE       RACHKAIR          MAYBE
         BL       CHKXIT1           ACCOUNT DIRECTORY - IGNORE
         LI,R5    BARAX
         LB,R7    *R6,R5            CURRENT READ-AHEAD INDEX
         BEZ      CHKXIT1           NO READ-AHEAD IN PROGRESS
         CI,R7    X'FF'
         BE       CHKXIT1           READ-AHEAD NOT ALLOWED
         LI,R4    0
         STB,R4   *R6,R5            CLEAR RAX IN DCB
*
         PUSH     9,R12
         BAL,R11  PRIVDA            CONVERT PRIVATE DISC ADDRESS
         LW,R13   M24
         DISABLE
         LB,R4    RAB:USER,R7
         CW,R4    S:CUN
         BNE      RACHKCC1          DOESN'T BELONG TO THIS USER
         LW,R4    FL:ACT
         CW,R4    RA:DA,R7
         BAZ      RACHKCC1          ENTRY NOT ACTIVE
*
         LH,R4    RAH:DCB,R7
         LW,R5    M16
         SLD,R4   1
         CS,R4    R6
         BNE      RACHKCC1          NOT FOR THIS DCB
*
         CS,R12   RA:DA,R7
         BE       CHKIOC            DISC ADDRESS CORRECT
*
*  WRONG DISC ADDRESS READ
*
         MTW,1    RA:ABNWP          INCR # WRONG PAGES READ
RACHKREL BAL,R10  T:RAREL           RELEASE THE ENTRY
*
RACHKCC1 ENABLE
         PULL     9,R12
         LCI      1
         B        *R0
*
CHKXIT   PULL     9,R12
         LCI      0
         B        *R0
*
CHKXIT1  ENABLE
         LCI      1
         B        *R0
         SPACE    3
*
*  CHECK FOR FILE DIRECTORY GRANULE
*
RACHKAIR   EQU    %
         LI,R7    DCBPRIVBIT
         CW,R7    PRIV,R6
         BANZ     CHKXIT1           NO AIR FOR PRIVATE
         LW,R13   M24
*
         MTW,1    RA:AGET           INCR # ATTEMPTED GETS
         LW,R8    FL:AIR
         LI,R7    0
         DISABLE
AIR10    LB,R7    RAB:FLINK,R7      GET NEXT ENTRY
         BEZ      CHKXIT1           NO MORE
         CW,R8    RA:DA,R7          IS THIS AN AIR ENTRY
         BAZ      AIR10             NO
         CS,R12   RA:DA,R7          IS IT RIGHT DISC ADDRESS
         BNE      AIR10             NO
*
         MTW,1    RA:SGET           INCR # SUCCESSFUL GETS
         PUSH     9,R12
         B        CHKIOC2
         SPACE    3
*
*  THE CORRECT GRANULE WAS READ AHEAD
*
CHKIOC   EQU      %
         MTW,1    RA:SCHK           INCR # SUCCESSFUL CHECKS
CHKIOC2  EQU      %
         LW,R4    RA:DA,R7
         AND,R4   MSK:WAIT          RESET FL:WAIT
         STW,R4   RA:DA,R7
         CW,R4    FL:IOP            IS I/O IN PROGRESS
         BAZ      IOC               NO
*
IOWAIT   OR,R4    FL:WAIT           SET USER WAITING FLAG
         STW,R4   RA:DA,R7
         MTW,1    RA:IOW            INCR # I/O WAIT REGS
*
         LW,R4    S:CUN
         STB,R4   RAB:USER,R7       STORE USER # (NEEDED FOR AIR)
         MTB,1    UB:MF,R4          INCR MASTER FUNCTON COUNT
         PUSH     R6
         LI,R6    0                 SPECIAL DCB ADDRESS
         XPSD,0   REGIPSD           WAIT FOR I/O TO COMPLETE
         PULL     R6
         B        CHKIOC2
*
*  I/O COMPLETE
*
IOC      CW,R4    FL:REL
         BANZ     RACHKREL          BR TO RELEASE ENTRY
         ENABLE
         LW,R5    R7                T:XBUF DESTROYS R7
         LOAD,R3  RAX:PAGE,R7
         BEZ      SC2E01            BAD PAGE #
         SLS,R3   9                 ADDRESS OF READ AHEAD BUFFER
         BAL,R2   T:XBUF            EXCHANGE BUFFERS
         LW,R7    R5
         SLS,R10  -9                USER'S BUFFER PAGE
         STORE,R10  RAX:PAGE,R7
         BAL,R10  T:RAREL           RELEASE ENTRY AND PAGE
         B        CHKXIT            NORMAL EXIT
         TITLE    '****  PURGE READ AHEAD FOR A GIVEN DCB  ****'
         SPACE    2
*  PURPOSE:  PURGE READ AHEAD FOR A GIVEN DCB
*
*  INPUT:  R6 = DCB ADDRESS
*
*  CALL:  BAL,R11  T:RAPURGD
*
*  VOLATILE:  R0,R2,R4,R5,R10,R15
*
         SPACE    2
T:RAPURGD  EQU    %
         LW,R15   R7                SAVE R7 - CLS USES IT
         LI,R2    BARAX
         LB,R7    *R6,R2            INDEX OF CURRENT READ AHEAD
         BEZ      RAPURGD7          NONE ACIVE
         CI,R7    X'FF'
         BE       RAPURGD7          NONE POSSIBLE
*
         DISABLE
         LW,R4    RA:DA,R7
         CW,R4    FL:ACT
         BAZ      RAPURGD5          ENTRY INACTIVE
*
         LB,R5    RAB:USER,R7
         CW,R5    S:CUN
         BNE      RAPURGD5          DOESN'T BELONG TO THIS USER
*
         LH,R4    RAH:DCB,R7
         LW,R5    M16
         SLD,R4   1
         CS,R4    R6
         BNE      RAPURGD5          DOESN'T BELONG TO THIS DCB
*
         PUSH     R11
         BAL,R10  T:RAREL           RELEASE IT
         PULL     R11
         MTW,1    RA:ABNNN          INCR # READS UNUSED
*
RAPURGD5 ENABLE
RAPURGD7 LW,R7    R15
         LI,R2    BARAX
         LI,R4    X'FF'             SET NO MORE READ-AHEADS ALLOWED
         STB,R4   *R6,R2
         B        *R11
         TITLE    '****  PURGE ALL TIMED OUT READ AHEADS  ****'
         SPACE    2
*  PURPOSE:  PURGE ONE TIMED-OUT ENTRY
*
*  CALL:  BAL,R0  RAPURGE
*
*  VOLATILE:  R11
*
RAPURGE  EQU      %
         PUSH     8,R0
         BAL,R0   GETIME            R1 = CURRENT TIME
*
         LI,R7    0
         DISABLE
RPURG10  LB,R7    RAB:BLINK,R7      GET LAST ENTRY
         BEZ      RPURGEXIT         DONE IF NO MORE
         LW,R2    R1                CURRENT TIME
         LH,R4    RAH:TIME,R7       TIME READ AHEAD STARTED
         BEZ      RPURG20           TIMED OUT
         AND,R4   M16
         SW,R2    R4
         BGEZ     %+2
         AI,R2    X'FFFF'           WRAP AROUND
         SLS,R2   5
         LW,R4    FL:AIR
         AND,R4   RA:DA,R7
         BNEZ     RPURG14           BR IF AIR
         CW,R2    SL:RATOR          COMPARE AGAINST READ-AHEAD
         B        RPURG15
RPURG14  LI,R4    1
         CW,R2    SL:AIRTO          COMPARE AGAINST AIR
RPURG15  BL       RPURG10           NOT TIMED OUT
         MTW,1    RA:ABNTR,R4       INCR # TIMED OUT
*
*  RELEASE TIMED OUT ENTRY
*
RPURG20  EQU      %
         BAL,R10  T:RAREL           RELEASE IT
         SPACE    2
RPURGEXIT EQU     %
         ENABLE
         PULL     8,R0
         B        *R0
         TITLE    '****  SEARCH MI BLOCK  ****'
         SPACE    2
*  PURPOSE:  SEARCH CURRENT MASTER INDEX BLOCK FOR NEXT DATA DISC
*              ADDRESS THAT IS DIFFERENT FROM CURRENT, OR FLINK
*              IF NO DATA GRANULE FOUND.  INITIATE A READ AHEAD
*              OF THE GRANULE FOUND.
*
*  INPUT:  R3 = INDEX INTO BUF2 OF START OF CURRENT KEY
*
*  CALL:  BAL,R0  T:RAMISRCH
*
*  VOLATILE:  R7,R8,R9,R11
*
         SPACE    2
T:RAMISRCH EQU    %
         BAL,R9   RACHK
         PUSH     9,R12
         LI,R14   BUFF2             BUFFER ADDRESS FOR PULLFOUR
         LI,R4    BASCR
         LB,R4    *R6,R4            LENGTH OF KEY
         B        %+2
*
INCRKEY  AI,R3    5                 POSITION TO NEXT KEY
         CH,R3    BUFF2+NAVX
         BGE      CHKFLINK          AT END OF BLOCK
         AW,R3    R4                POINT PAST KEY
         BAL,R0   PULLFOUR          GET DISPL AND SIZE
         INT,R9   R12               SAVE SIZE
         BAL,R0   PULLFOUR          GET DISC ADDRESS
         AI,R12   0
         BEZ      INCRKEY           NOTHING - CHECK NEXT
         CW,R12   BCDA,R6
         BE       INCRKEY           SAME AS CURRENT GRANULE
         CI,R9    BUFSIZ-15
         BGE      INCRKEY           IGNORE UNBLOCKED SEGMENTS
*
MIEXIT   BAL,R0   T:RAINIT          START A READ AHEAD
MIEXIT5  PULL     9,R12
         B        *R0
         SPACE    3
*
*  NO DATA GRANULE TO READ - TRY NEXT MI GRANULE
*
CHKFLINK LW,R12   BUFF2+FLINK
         BEZ      MIEXIT5           NO FLINK
         B        MIEXIT            START READ AHEAD OF FLINK
         TITLE    '****  START READ AHEAD FOR CONSECUTIVE  ****'
         SPACE    2
*  PURPOSE:  START READ AHEAD FOR CONSECUTIVE FILE
*
*  INPUT:  R6 = DCB ADDRESS
*
*  CALL:  BAL,R0  T:RACONSEC
*
*  VOLATILE:  R7,R9,R11,R13
*
         SPACE    2
T:RACONSEC EQU    %
         BAL,R9   RACHK
*
         LW,R13   R8
         PUSH     5,R12
         LW,R12   BUFF1+FLINK       PICK UP FLINK
         BEZ      %+2
         BAL,R0   T:RAINIT          INITIATE READ AHEAD
         PULL     5,R12
         LW,R8    R13
         B        *R0
         TITLE    '****  CHECK LEGALITY OF STARTING READ-AHEAD  ****'
         SPACE    2
*  PURPOSE:  CHECK IF IT IS LEGAL TO START A READ AHEAD
*
*  CALL:  BAL,R9  RACHK
*
*  RETURNS *R9 IS LEGAL
*  RETURNS *R0 IF ILLEGAL
*
         SPACE    2
RACHK    EQU      %
         LW,R7    SL:RAMR
         CW,R7    RA:CURR           CHECK LIMIT AGAINST CURRENT
         BLE      *R0               TOO MANY ALREADY IN PROGRESS
         LI,R7    BARAX
         LB,R7    *R6,R7
         BNEZ     *R0               ONE ALREADY IN PROGRESS
         LI,R11   X'400'
         CW,R11   DIR,R6
         BAZ      *R9               NOT READ REVERSE
         B        *R0               NONE FOR READ REVERSE
         TITLE    '****  RELEASE ENTRY FROM READ AHEAD TABLES  ****'
         SPACE    2
*  PURPOSE:  RELEASE AN ENTRY FROM READ AHEAD TABLES
*
*  INPUT:  R7 = TABLE INDEX
*
*  CALL:  BAL,R10  T:RAREL
*
*  VOLATILE:  R0,R2,R4,R5,R11
*
         SPACE    2
T:RAREL  EQU      %
         DISABLE
         LW,R4    RA:DA,R7          FLAGS
         CW,R4    FL:IW             I/O IN PROGRESS OR USER WAITING
         BAZ      RAREL10           NO - RELEASE IT NOW
         OR,R4    FL:REL            SET RELEASE AT END ACTION FLAG
         STW,R4   RA:DA,R7
         ENABLE
         B        *R10
         SPACE    2
RAREL10  EQU      %
         BAL,R0   RADCHAIN          REMOVE FROM BLINK/FLINK CHAINS
         LI,R0    0
         STB,R0   RAB:USER,R7       CLEAR SOME TABLE ENTRIES
         STH,R0   RAH:TIME,R7
         STH,R0   RAH:DCB,R7
         XW,R0    RA:DA,R7
         BEZ      RAREL15           RELEASING FREE POOL ENTRY
         LI,R4    RA:CURA
         CW,R0    FL:AIR
         BANZ     %+2
         LI,R4    RA:CURR
         MTW,-1   0,R4              DECR # ACTIVE ENTRIES
*
         LW,R4    RA:CURF           # CURRENTLY IN FREE POOL
         BLZ      RAREL20           SOMETHING WRONG
         CW,R4    SL:RAMF           MAX ALLOWED
         BGE      RAREL20           TOO MANY - RELEASE PAGE
         MTW,1    RA:CURF
         LB,R4    RAB:FLINK         CHAIN ENTRY
         STB,R4   RAB:FLINK,R7        ONTO OLDEST
         STB,R7   RAB:FLINK           END OF
         STB,R7   RAB:BLINK,R4        BLINK/FLINK
         LI,R4    0                   CHAIN
         STB,R4   RAB:BLINK,R7
         ENABLE
         B        *R10
         SPACE    2
*
*  RELEASE PAGE TO FREE POOL
*
RAREL15  MTW,-1   RA:CURF           DECR # IN FREE POOL
RAREL20  EQU      %
         LB,R4    RAB:USER          CHAIN ENTRY
         STB,R4   RAB:USER,R7         ONTO FREE
         STB,R7   RAB:USER              ENTRY CHAIN
         ENABLE
         PUSH     8,R12
         LOAD,R3  RAX:PAGE,R7       PAGE #
         BEZ      RAREL25           ERROR - NO PAGE
         SLS,R3   9                 WORD ADDRESS
         LI,R2    0
         STORE,R2 RAX:PAGE,R7
         BAL,R11  T:RSPP            RELEASE STOLEN PAGE
RAREL25  PULL     8,R12
         B        *R10
         TITLE    '****  DECHAIN ENTRY FROM ACTIVE CHAIN  ****'
         SPACE    2
*  PURPOSE:  DECHAIN AN ENTRY FROM THE ACTIVE CHAIN
*
*  INPUT:  R7 = TABLE INDEX OF ENTRY TO BE DE-CHAINED
*
*  CALL:  BAL,R0  RADCHAIN
*
*  VOLATILE:  R4,R5
*
         SPACE    2
RADCHAIN EQU      %
         LB,R4    RAB:FLINK,R7
         LB,R5    RAB:BLINK,R7
         STB,R5   RAB:BLINK,R4
         STB,R4   RAB:FLINK,R5
         B        *R0
         TITLE    '****  ADD AIR ENTRY  ****'
         SPACE    2
*  PURPOSE:  ADD AIR ENTRY TO READ AHEAD TABLES
*
*  INPUT:  R12 = DISC ADDRESS
*          R14 = BUFFER ADDRESS
*
*  CALL:  BAL,R0  T:RADD
*
*  OUTPUT:  CC = 0  GRANULE WAS ADDED
*              = 1  COULD NOT ADD GRANULE
*
         SPACE    2
T:RADD   EQU      %
         LW,R15   Y008
         CW,R15   FUN,R6            IS THIS A CANDIDATE FOR ADDING
         BAZ      CHKXIT1           NO
         STS,R14  FUN,R6            YES - RESET FLAG
         LI,R1    X'1FFFF'
         AND,R1   CFU,R6
         CI,R1    FILCFU
         BNE      CHKXIT1           CAN'T BE FILE DIRECTORY
         LI,R15   DCBPRIVBIT
         CW,R15   PRIV,R6
         BANZ     CHKXIT1           NO AIR FOR PRIVATE
*
         LW,R15   SL:AIRM           MAX # ALLOWED
         BLEZ     CHKXIT1           NONE - GET OUT NOW
         PUSH     9,R12
         LW,R8    R12
         BAL,R11  FMCHKDA           VALIDATE DISC ADDRESS
         BCR,15   RACHKCC1          BAD - IGNORE
         MTW,1    RA:ASTOR          INCR # ATTEMPTED STORES
         LI,R7    0
         LW,R2    FL:AIR
         LI,R5    0
         LW,R13   M24
         OR,R12   FL:AIR
         DISABLE                    **** DISABLE ****
RADD10   LB,R7    RAB:FLINK,R7      GET NEXT ENTRY
         BEZ      RADD20            NO MORE
         LW,R2    RA:DA,R7          GET FLAGS AND DISC ADDR
         CW,R2    FL:AIR            IS THIS ONE AN AIR
         BAZ      RADD10            NO
         CW,R2    FL:IOP            IGNORE ONES WITH I/O
         BANZ     RADD15
         AI,R5    0
         BNE      %+2               REMEMBER FIRST AIR ENTRY
         LW,R5    R7
RADD15   CS,R12   RA:DA,R7
         BE       SC2E01            CAN'T ALREADY BE THERE
         B        RADD10
*
RADD20   EQU      %
         LW,R2    RA:CURA           CURRENT # INITIATED
         CW,R2    SL:AIRM           MAX # ALLOWED
         BG       RACHKCC1          TOO MANY ALREADY
         BE       RADD30            TRY TO STEAL EXISTING ENTRY
         PUSH     R5                SAVE TABLE ENTRY
         BAL,R11  GETENTRY          GET TABLE ENTRY
         PULL     R5
         AI,R4    0
         BEZ      RADD50            GOT ONE
*
*  NO TABLE ENTRY AVAIL - TRY TO USE EXISTING ONE
*
RADD30   EQU      %
         LW,R7    R5                SAVED ENTRY INDEX
         BEZ      RACHKCC1          NONE - CAN'T DO ANYTHING
*
         BAL,R0   RADCHAIN          DE-CHAIN ENTRY
         BAL,R11  GETEXIT           CHAIN ON AND FILL IN
         B        RADD60
*
RADD50   MTW,1    RA:CURA           INCR # IN PROGRESS
RADD60   MTW,1    RA:SSTOR          INCR # SUCCESSFULLY STORED
         LW,R5    R7                SAVE TABLE INDEX
         LOAD,R3  RAX:PAGE,R7       PAGE #
         SLS,R3   9                 WORD ADDRESS
         BAL,R2   T:XBUF            EXCHANGE USER PAGE
         LW,R7    R5
         SLS,R10  -9
         STORE,R10 RAX:PAGE,R7      USER'S OLD PHYS PAGE ADDR
*
         LW,R3    Y002
         LI,R2    1                 FUNCTION CODE FOR WRITE
         CW,R3    MIUD,R6           IS BUFFER UPDATED
         BAZ      CHKXIT            NO
         STS,R2   MIUD,R6           YES - RESET MIUD
         LW,R12   RA:DA,R7          DISC ADDRESS
         LW,R5    FL:IOP
         STS,R5   RA:DA,R7          SET I/O IN PROGRESS
         CI,R1    FILCFU
         BG       RAIO              NOT A DIRECTORY
         LW,R8    DCDAM             DUAL DISC ADDRESS
         BAL,R11  FMCHKDA
         BCR,15   RAIO              BAD
         BAL,R10  GETTBL            GET END-ACTION TABLE
         STB,R3   R7                SAVE ITS INDEX
         B        RAIO
         TITLE    '****  GET TABLE ENTRY  ****'
         SPACE    2
*  PURPOSE:  OBTAIN A TABLE ENTRY
*
*  CALL:  BAL,R11  GETENTRY
*
*  OUTPUT:  R4 = 0  GOT ONE
*              = 1  NO ENTRY AVAILABLE
*              = 2  NO PAGE AVAILABLE
*
         SPACE    2
GETENTRY EQU      %
         LW,R2    RA:CURF           # ENTRIES WITH PAGES IN FREE POOL
         BLEZ     GET10             NONE
         MTW,-1   RA:CURF           DECR # IN POOL
         LI,R7    0
GET05    LB,R7    RAB:FLINK,R7      GET NEXT ENTRY
         BEZ      GET10             DONE - DIDN'T FIND
         LW,R2    RA:DA,R7
         BNEZ     GET05             NOT FREE POOL ENTRY
         BAL,R0   RADCHAIN          DE-CHAIN FROM ACTIVE CHAIN
*
*  FILL IN THIS ENTRY
*
GETEXIT  EQU      %
         LW,R2    S:CUN
         STB,R2   RAB:USER,R7       USER #
*
         BAL,R0   GETIME
         STH,R1   RAH:TIME,R7       CURRENT TIME
*
         OR,R12   FL:ACT            SET ACIVE BIT
         STW,R12  RA:DA,R7
*
         LB,R2    RAB:BLINK         CHAIN
         STB,R2   RAB:BLINK,R7        ONTO
         STB,R7   RAB:BLINK           BLINK/FLINK
         LB,R4    RAB:FLINK,R2        CHAIN
         STB,R4   RAB:FLINK,R7
         STB,R7   RAB:FLINK,R2
*
         LI,R4    0
         B        *R11
         SPACE    2
GET10    EQU      %
         PUSH     2,R11
         BAL,R11  T:STLPP           STEAL A PHYSICAL PAGE
         PULL     2,R11
         LI,R4    2                 ASSUME NO PAGE AVAIL
         AI,R3    0
         BLEZ     *R11              NO PAGE AVAIL
         DISABLE
         LB,R7    RAB:USER          LOOK FOR AVAILABLE ENTRIES
         BNEZ     GET20             THERE ARE SOME
         PUSH     2,R11
         BAL,R11  T:RSPP            GIVE THE PAGE BACK
         PULL     2,R11
         LI,R4    1                 NO TABLE ENTRIES AVAILABLE
         DISABLE                    T:RSPP ENABLES
         B        *R11
*
GET20    EQU      %
         SLS,R3   -9
         LB,R2    RAB:USER,R7       DE-CHAIN FROM FREE CHAIN
         STB,R2   RAB:USER
         STORE,R3 RAX:PAGE,R7       PUT IN PAGE
         B        GETEXIT
         SPACE    4
Y5       DATA     X'50000000'
SC2E01   SCREECH  X'2E',X'01'
         END

