SPL,L,M,O,T,C 
      NAME PAGER(8) "REV G 770321"
! 
!     THIS MODULE HANDLES ALLOCATION OF DYNAMIC CORE AREA FOR SYMBOLS 
!     AND FOR WORKSPACE. SYMBOL ALLOCATION IS MECHANIZED THRU A VIRTUAL 
!     ADDRESSING/PAGING SCHEME WHILE WORKSPACE IS MECHANIZED THRU A 
!     FIXED SIZE ABSOLUTE ADDRESS SCHEME. 
! 
      LET LUCNT BE INTEGER,GLOBAL!LAST PAGE USAGE COUNTER 
      LET EXBAS BE INTEGER,EXTERNAL!FIRST WORD FREE MEMORY
      LET LPAGE BE INTEGER,GLOBAL  ! LARGEST PAGE NUMBER
      LET FRLST BE INTEGER,GLOBAL ! FREE WORKSPACE LIST POINTER 
      LET FIRST BE INTEGER,GLOBAL ! SMALLEST ADDRESS NOT USED 
      LET LAST  BE INTEGER,GLOBAL ! LARGEST  ADDRESS NOT USED 
      LET WKTOP BE INTEGER,GLOBAL ! LARGEST USABLE ADDRESS=7MOD8
      LET PD(240)BE INTEGER ,GLOBAL! PAGE DIRECTORY FOR SYMBOL TABLE
      LET PDSIZ BE INTEGER,GLOBAL!MAXIMUM PAGE NUMBER 
      LET DIAG BE SUBROUTINE,EXTERNAL 
      LET EXEC BE SUBROUTINE,EXTERNAL 
      LET FETRK BE INTEGER,GLOBAL !FIRST DISC TRACK 
      LET SESIZ BE INTEGER,GLOBAL ! NO. OF TRACKS IN EXTENSION
      LET TSIZE BE INTEGER,GLOBAL!# PAGES/TRACK(128-WD SCTRS) 
      LET LID BE INTEGER,GLOBAL   !LOGICAL UNIT DISC TRACKS ON
      LET ZZZ BE INTEGER,GLOBAL!CREATE NEW PAGE FLAG
! 
!     MAXIMUM NUMBER OF SYMBOL TABLE PAGES ALLOWED IS EQUAL TO THE
!     SIZE OF THE "PD" ARRAY, OR LESS IF THE NUMBER OF TRACKS 
!     ALLOCATED < 5.  THE LARGEST PAGE WHICH MAY BE ALLOCATED 
!     IS CONTAINED IN PDSIZ, AND IS SET BY SUBROUTINE "DINIT".
! 
! 
PAGE: PSEUDO(PAGA3)GLOBAL 
! 
!     INSERTS / YIELDS  PAGE FIELD OF VIRTUAL ADDRESS 
! 
      IF PAGEF \
          THEN PAGA3 _ (PAGA3 AND 177K) OR ((PAGEV-<7)AND 77600K),\ 
          ELSE PAGEV _ (PAGA3 AND 77600K)->7
      RETURN
      END 
! 
RWPAG:SUBROUTINE(PNO,PAD,RWCOD) 
! 
!     SUBROUTINE TO READ/WRITE SYMBOL TABLE PAGES 
! 
!     PNO=PAGE NUMBER 
!     PAD=PAGE ADDRESS
!     RWCOD=1(READ), OR 2(WRITE)
! 
      RTRK_FETRK+(PNO/TSIZE)
      RSEC_(PNO-(TSIZE*(RTRK-FETRK)))<-1
      CALL EXEC(RWCOD, LID,$PAD,128,RTRK,RSEC)
      RETURN
      END 
! 
PDXAD:SUBROUTINE
! 
!     CONVERTS PAGE DIRECTORY INDEX (>0) TO ABSOLUTE ADDRESS OF PAGE
      CADDR_EXBAS+((PDINX-1)-<7)
      RETURN
      END 
! 
ADPDX:SUBROUTINE
! 
!     CONVERTS ABSOLUTE (CORE) PAGE ADDRESS 
!     TO PAGE DIRECTORY INDEX ( > 0)
! 
      PDINX_(((CADDR-EXBAS)AND 77600K)->7)+1
      RETURN
      END 
! 
OLDPG:SUBROUTINE
! 
!     DETERMINES CORE ADDRESS OF EXTENSION PAGE WHICH HAS BEEN IN 
!     CORE FOR THE LONGEST PERIOD WITHOUT BEING REFERENCED
! 
! 
!     THIS IS DONE BY SEARCHING EACH PAGE IN CORE FOR THE MINIMUM 
!     VALUE OF THE LAST-USAGE COUNTER.
! 
      DO[OLDAD,PDINX_0; K_77777K] 
      WHILE PD([PDINX_PDINX+1])=>0 DO \ 
         [PDXAD;IF K>$([I_CADDR+2])THEN[OLDAD_CADDR; K_$I]] 
      IF OLDAD THEN RETURN
! 
!     NOTE: CONTROL IS PASSED TO ER50 (SYMBOL TABLE OR WORKSPACE
!           OVERFLOW) FOR ANY ONE OF THE FOLLOWING REASONS: 
!                   1. "PRGPG" CALLED BUT NO PAGES IN CORE, 
!                   2."GETRM" CALLED TO CREATE NEW PAGE, BUT
!                      THE MAXIMUM PAGE HAS ALREADY BEEN ALLOCATED, 
!                   3. OLDPG CALLED BUT NO PAGES LEFT IN CORE.
! 
ER50: DIAG(50,0)
      END 
! 
PRGPG:SUBROUTINE(GADPR)GLOBAL 
! 
! 
!     THIS SUBROUTINE IS CALLED TO ROLL A SYMBOL TABLE PAGE 
!     OUT TO THE DISC, TO MAKE ROOM FOR ANOTHER, OR TO MAKE 
!     WORKSPACE AVAILABLE.
! 
!      GADPR = CORE ADDRESS OF PAGE TO BE ROLLED OUT. 
! 
!     IF SPECIFIED PAGE IS DIFFERENT THAN ITS DISK IMAGE (IF ANY),
!     IT IS WRITTEN ON THE DISK. THE APPROPRIATE PAGE DIRECTORY 
!     SLOT IS SET TO ZERO.
! 
!    IF GADPR<ADDRESS OF FIRST AVAILABLE WORKSPACE, THEN THERE
!    ARE NO PAGES WHICH CAN BE PURGED, AND WORKSPACE HAS
!    OVERFLOWED.
      IF GADPR<EXBAS THEN GOTO ER50 
      CADDR_GADPR 
      ADPDX 
      IF $(GADPR+3) THEN CALL RWPAG(PAGE(PD(PDINX)),GADPR,2)
      PD(PDINX)_-1
      RETURN
      END 
! 
LDPAG:SUBROUTINE
! 
!     LOAD SPECIFIED PAGE INTO CORE, MARK APPROPRIATE PD SLOT.
! 
      IF LAST-FIRST>126 \ 
          THEN [PRGAD_FIRST; FIRST_FIRST+128],\ 
          ELSE [OLDPG; PRGAD_OLDAD; PRGPG(PRGAD)] 
!     ZZZ:CREATE/LOAD PAGE FLAG. 0=PAGE TO BE CREATED ONLY. 
!      ZZZ # 0 PAGE TO BE READ FROM DISC
      IF ZZZ THEN CALL RWPAG(PAGE(LDPNO),PRGAD,1),\ 
             ELSE [$PRGAD_4; $(PRGAD+1)_127]
      $(PRGAD+3)_0
      CADDR_PRGAD 
      ADPDX 
      PD(PDINX)_LDPNO 
      RETURN
      END 
! 
GETAB:SUBROUTINE (VRTAD,CORAD) GLOBAL 
! 
!     CONVERTS VIRTUAL ADDRESS (VRTAD) TO CORE ADDRESS (CORAD). 
!     PAGE IS ALWAYS IN CORE ON RETURN. 
! 
GET1: LDPNO_VRTAD AND 77600K
      PDINX_1 
GET2: IF PD(PDINX)=LDPNO \
      THEN[PDXAD; CORAD_CADDR+(VRTAD AND 177K);\
          $(CADDR+2)_[LUCNT_(LUCNT+1) AND 77777K];RETURN] 
      IF PD(PDINX)<0 THEN[ZZZ_-1; LDPAG; GOTO GET2] 
GET3: PDINX_PDINX+1 
      GOTO GET2 
      END 
! 
GETRM:SUBROUTINE(NO,VRTUL) GLOBAL 
! 
!     IF NO=0 A 4 WORD SYMBOL BLOCK IS ALLOCATED FROM SYMB PAGE(TOP DWN)
!     IF NO>0 A (NO) WORD BLOCK IS ALLOCATED FROM  SYMB PAGE (BOTTOM UP)
!     NEW PAGES ARE CREATED AS REQUIRED 
! 
GRM1:  M_0
       PAGE(M)_LPAGE
       GETAB(M,N) 
      Q_[IF NO THEN NO, ELSE 4] 
      IF -($N+Q)+$(N+1)+1=>0 THEN GOTO GRM2 
      ZZZ,LDPNO_0 
      IF [LPAGE_LPAGE+1] => PDSIZ THEN GOTO ER50
      PAGE(LDPNO)_LPAGE 
      LDPAG 
      GETAB(LDPNO,Q)
      GOTO GRM1 
GRM2: IF NO \ 
          THEN[VRTUL_M+$([I_N+1])-NO+1; M_-NO+N+$I+1; $I_$I-NO],\ 
          ELSE[VRTUL_M+$N;M_N+$N;$N_$N+4] 
      VRTUL_VRTUL OR 100000K
      WHILE Q DO [$M_0;M_M+1;Q_Q-1] 
      $(N+3)_1
      RETURN
      END 
! 
      END 
END$
                                                    