SPL,L,M,O,T,C 
!      REV G  4/15/77 
       NAME LLINK(8) "REV G 770415" 
!      ALLOCATES SPACE FOR A LINK WORD. 
       LET IWP,STAK BE PSEUDO,EXTERNAL
       LET SLNKS,LOCC,LINKF,BPLKS,NBPLK,GUESS,XBPLK,XGESS,XSEC,\
       LWAM1,NXTPG,LWABP,MAXAB,FREBE,\
       UFREB,\
       SEC BE INTEGER,EXTERNAL
       LET PBPLK BE SUBROUTINE,EXTERNAL!PUT BACK BASE PAGE LINK 
LINK:  FUNCTION(VALUE,NCPL1,RPAGE,NCPL2,EXTF,LAPAG) GLOBAL,FEXIT
       LET VALUE BE INTEGER!      VALUE LINK SHOULD CONTAIN.
       LET RPAGE BE INTEGER            !PAGE ADDRESS OF REF. INSTR. 
       LET NCPL2 BE INTEGER            !#SECONDARY LINKS CURRENTLY
                                       !ALLOCATED.
       LET EXTF BE INTEGER             !0=NO EXTERNAL,1=EXTERNAL REF. 
                                       !FOR USE IN DECIDING ON BASE 
                                       !PAGE WHEN IN CP MODE. 
! 
       LET PGCK,CHEK BE SUBROUTINE,DIRECT 
       LET MIN,MAX,B76 BE FUNCTION,EXTERNAL 
! 
!          SEARCH BASE PAGE AREA FOR SAME-VALUED LINK WORD
! 
       BPF,CP1F,CP2F_0
       X_BPLKS   !START BASE-PAGE STRING SEARCH.
       SBPAG_IWP(X)                     !DEFINE START ADDRESS BASEPAGE
       CHEK(SBPAG)?[GOTO LINK2]        !CHECK IF A BASE PAGE LINK EXISTS
LNK11: LINKV_SBPAG                     !FOUND A MATCHING LINK 
LNK12: RETURN 
LINK2: BPF_[IF SBPAG>LWABP THEN -1,ELSE 0]!SET BASE PAGE FULL FLAG. 
! 
!     SEARCH PRIMARY CURRENT PAGE AREA FOR LINK WHICH IS ON SAME
!          PAGE AS REFERENCE WORD.
! 
LIN2:  CALL PGCK(GUESS,SGPAG,CP1F,LOCC)?[GOTO LIN4] 
       RETURN 
LIN4:  CALL PGCK(SEC,SC2PG,CP2F,MIN(NXTPG,LWAM1))?[GOTO LINK7]
       RETURN 
! 
!      SEARCH "SECRET BASE PAGE LINKS STRING". IF MATCH NOT FOUND,
!      TOUGH.  THIS STRING CAN ONLY BE DEFINED BY LINKS CREATION
!      STATEMENT
! 
LINK7: X_SLNKS
       SC3PG_IWP(X)?[GOTO LINK8]
       CALL CHEK(SC3PG)?[GOTO LINK8]
       RETURN SC3PG                    !FOUND A SECRET LINK.
! 
!          MUST ALLOCATE A LINK.
! 
LINK8: IF LINKF AND 1 THEN GOTO CURRN,ELSE GOTO BASEP!BRANCH ON LINK MOD
       LET BP,CP1,CP2 BE SUBROUTINE,DIRECT
!     SUBROUTINES TO ALLOCATE LINKS FROM BASEPAGE,PRIMARY OR SECONDARY
!     AREAS.
!     THEY WILL TRANSFER DIRECTLY TO LNK12 IF A LINK CAN BE ALLOCATED F 
!     FROM THE RESPECTIVE AREAS, AND WILL RETURN ONLY IF NONE 
!     CAN BE ALLOCATED. 
! 
BASEP: CALL BP  !TRY TO ALLOCATE FROM BASE PAGE 
       FRETURN        !IN THIS MODE, ONLY THIS CHOICE POSSIBLE
! 
CURRN: IF EXTF THEN CALL BP         !ATTEMPT BASE PAGE LINK FOR EXTS
       CALL CP1                         !ELSE PRIMARY AREA
! 
      CALL CP2 !TRY TO ALLOCATE FROM SECONDARY AREA.
      GOTO BASEP          !IF NONE OF ABOVE POSSIBLE. 
! 
! 
      END 
BP:   SUBROUTINE DIRECT!TRY ALLOCATING FROM BASEPAGE AREA.
       SBPAG_STAK(FREBE)?[GOTO BP5] 
       STAK(UFREB) _ SBPAG   !  KEEP TRACK OF THE LINKS OBTAINED FROM 
                             !  "FREBE" 
       CALL PBPLK(SBPAG,VALUE); GOTO LNK11
BP5:   IF BPF THEN RETURN !BASE PAGE AREA FULL. 
       IWP(XBPLK)_VALUE 
       NBPLK_NBPLK+1
       MAXAB_MAX(MAXAB,SBPAG) 
       GOTO LNK11 
       END
CP1:   SUBROUTINE DIRECT!TRY ALLOCATING FROM PRIMARY AREA 
       IF CP1F THEN RETURN             !PRIMARY AREA FULL.
       IWP(XGESS)_VALUE 
       LINKV_SGPAG                     !LINK ADDRESS
       NCPL1_NCPL1+1
       GOTO LNK12 
       END
CP2:   SUBROUTINE DIRECT!TRY ALLOCATING FROM SEC. LINKS AREA
       IF CP2F THEN RETURN             !SECONDARY AREA FULL.
       IWP(XSEC)_VALUE
       LINKV_SC2PG                     !LINK ADDRESS
       NCPL2_NCPL2+1
       GOTO LNK12 
       END
CHEK:  SUBROUTINE(CHE) FEXIT,DIRECT    !SUBROUTINE TO SCAN EITHER 
!   BASE PAGE, OR EITHER CURRENT PAGE LINK STRING, DEPENDING ON WHICH 
!   OF THESE "X" POINTS TO, TO DETERMINE IF ANY OF THE LINKS IN THE LINK
!   STRING MATCHES "VALUE."  A NORMAL RETURN, WITH CHE = ADDRESS OF THE 
!   IS MADE IF A MATCH OCCURS, OTHERWISE AN F-RETURN IS MADE, WITH CHE1 
!   POINTING TO THE PLACE IN THE STRING WHERE THE LINK VALUE IS TO
!   GO, IF IT IS APPLICABLE.
! 
!      IF ANY LINK IN THE LINKS STRING IS FOUND TO BE -1,THEN IT
!      MARKS THE END OF THAT GROUP. ANOTHER GROUP MAY START, THE
!      NEXT WORD IN THE STRING BEING THE START ADDRESS OF THE NEXT
!      LINKS GROUP.  THIS ALLOWS DATA TO BE MIXED WITH LINKS
!      RELATIVELY INDISCRIMINATELY. 
! 
CHEK0: IFNOT[CHEKV_IWP(X)?[FRETURN]] < -1 THEN\ 
         [IF CHEKV < 2 THEN GOTO CHEK1] 
       IF CHEKV#VALUE THEN GOTO CHEK1  !REJECT LINK IF <2 OR IF NO MATCH
       RETURN 
CHEK1: CHE_CHE+1
       IF CHEKV #(-1) THEN GOTO CHEK0 
       CHE_IWP(X)?[FRETURN] 
       GOTO CHEK0 
       END
PGCK:  SUBROUTINE(LSTRG,CPG,CPF,PLAST) FEXIT,DIRECT 
!      SUBROUTINE TO CHECK IF A LINKS STRING IS ON THE CURRENT
!      PAGE(RPAGE), AND TO SET THE PAGE-STRING CLOSED FLAG(CPF) IF
!      NOT, AND TO DETERMINE IF A LINK ALREADY EXISTS ON THAT STRING. 
       X_LSTRG     !SET  DYNAMIC POINTER TO BEG. OF STRING
       CPG_IWP(X)?[GOTO CLOSE]!GET ADDRESS OF STRING; CLOSE IF NO STRING
       IF B76(CPG)#RPAGE THEN GOTO CLOSE!STRING NOT ON RIGHT PAGE 
       CALL CHEK(CPG)?[GOTO MCLOS]!SEARCH STRING FOR MATCH;MAYBE CLOSE I
       LINKV_CPG                       !RETURN ADDRESS OF MATCHING LINK 
       RETURN 
MCLOS: IF CPG < PLAST THEN FRETURN     !STILL ROOM LEFT IN LINK AREA
CLOSE: CPF_-1      !SET AREA CLOSED FLAG
       FRETURN
       END
      END 
      END$
                                            