CONSTSTRING  (15) VSN="7A 19/10/82"
!     AMENDMENT RECORD
!****************
!     VSN 7A dated 19th November 1982
!     1) Restart stack lengthened to X'1800'
!        (to allow greater 'CALL' depth for auto IPL)
!        ( S series writeout may encroach onto LP buffer)
!     2) PST moved to segment 11
!     3) ISTs in segments 0-3
!
!     VSN 6E DATED 23/10/81
!     1) AMENDED FOR IMP80
!
!     VSN 6D DATED 30/3/81
!     1) IST MOVED TO RA X8200
!        (ALLOWS 16 ENTRIES FOR "S" SERIES VECTORED INTERRUPTS)
! 
!     VSN 6C DATED 11/2/81
!     1) SYSERRS MASKED ON ENTRY TO CHOPSUPE
!        (IN CASE OF SUCCESSFUL RETRY)
!
!     VSN 6B DATED 19/09/80
!     1) RESTART STACK MOVED FROM RA X1800 TO X3000
!        LENGTH SHORTENED TO 4K
!        (DUAL OCP PHOTO USES X1800)
!     2) 'PARM' VALUES PRESERVED
!
!     VSN 6A DATED 26/06/80
!     1) MAIN DBOOT CODE NOW AT X'14000' - X'15000'
!     2) 1ST CHOPSUPE CODE CHUNK AT X'15000'
!     3) DBOOT DESCRIPTOR SET UP TO ADDRESS & LENGTH OF OVERLAYS
!
!     VSN 5G DATED 25MAR80
!     1) LNB SF AND PSTB FOR BOOT LOADER NOT NOW SET UP
!        THIS IS FOR DBOOT15S&SEQ (MAPLE WRITTEN VSNS)
!     VSN 5F DATED 9TH NIV79
!     1) INCREASE IN PST FOR 16 SMACS
!     VSN 5E DATED 06/08/79
!     1) CODE ADDED TO DETECT UNUSED EXTERNAL PROCEDURES
!     2) CODE ADDED TO ACCEPT MICROPROGRAM AS A FILE NAME
!     3) MUCH HISTORIC MATERIAL DELETED
!
!     VSN 5D DATED 12/12/78
!     1) PST CORRECTED TO 255 SEGMENNT AND BASED ON CONSTINTEGERS
!     2) POST MORTEM SEGMENT INITIALISE ABANDONED
!     3) HEADER OF 'CHOPIPL' IS CORRECT USEFULE LENGTH
!     4) NEW MPROG REMOVED TO SEPARATE FILE
!     5) ABLE TO WORK WITHOUT AN OCP MICROPROGRAM FILE
!     6) CODE FIXUPS PERMITTED WITHOUT "FUNNY RELOC" MESSAGE

!*
! OCP MICROPROGRAM & MICROPROGRAM OVERLAYS RESIDE IN FILE OCPMPRG
! VERSION:- "MP7000P0070C" WITH PATCHES 1-C 
!*
! PUBLIC SEGMENT TABLE LAYOUT
! ==========================
!     0-4      ISTs for up to 4 processors
!     4&5      SUPERVISOR STACK +SSN+1
!     6&7      RESTART STACK & SSN+1
!     8        SUPERVISOR CODE
!     9        SUPERVISOR GLA
!     10       TEMP COMMS AREA FOR GROPE
!     11       Public segment table
!     12 UP    FREE FOR GLOBAL TABLES
!     20       EXTENDABLE SEGMENT FOR PARAM TABLE
!     21 & 22  EXTENDABLE PAIR OF SEGMENTS FOR AMT & POINTERS
!     23       Store table (extensible)
!     44       CHOPSUPE CODE
!     45       CHOPSUPE GLA
!     46&47    STACK & SSN+1 FOR CHOPSUPE
!     48       COMMUNICATION SEGMENT FOR CONFIGURATION DETAILS
!     49-63    DEVICE COMMS AREA QUEUE SPACE ETC
!     64 UP VIRTUAL-REAL MAPPINGS
SYSTEMROUTINESPEC  PSYSMES(INTEGER  ROOT, FLAG)
RECORDFORMAT  CONRECF(INTEGER  CONAD, FILETYPE, RELSTART, RELEND)
SYSTEMROUTINESPEC  CONNECT(STRING  (31) S,  C 
         INTEGER  M, H, P, RECORD (CONRECF)NAME  R, INTEGERNAME  F)
SYSTEMROUTINESPEC  MOVE(INTEGER  LEN, FROM, TO)
EXTERNALSTRINGFNSPEC  DATE
EXTERNALSTRINGFNSPEC  TIME
EXTERNALROUTINESPEC  PARM(STRING  (255) S)
SYSTEMROUTINESPEC  PHEX(INTEGER  I)
SYSTEMROUTINESPEC  OUTFILE(STRING  (31) F,  C 
         INTEGER  S, H, P, INTEGERNAME  C, F)
RECORDFORMAT  OBJF(INTEGER  NEXTFREEBYTE, CODERELST, PSIZE,  C 
         FILETYPE, SUM, DATETIME, LDRELST, OFM)
EXTERNALROUTINESPEC  DEFINE(STRING  (63) S)
EXTERNALROUTINESPEC  COPY(STRING  (63) S)
EXTERNALROUTINESPEC  DESTROY(STRING  (63) S)
SYSTEMINTEGERMAPSPEC  COMREG(INTEGER  N)
CONSTINTEGER  MAXSEG=32
!
!
INTEGERFN  NWFILEAD(STRING (15) S,INTEGER  PGS)
INTEGER  I,FLAG
       FLAG=1
       IF  0<LENGTH(S)<=15 THEN  OUTFILE(S,PGS<<12,X'40000',0,I,FLAG)
       IF  FLAG#0 START 
         SELECT OUTPUT(0)
          PRINTSTRING("OUTFILE flag for ".S." =")
          WRITE(FLAG,1)
          I=0
         STOP 
          FINISH 
       RESULT =I
       END ; ! NWFILEAD
INTEGERFN  RDFILEAD(STRING (63) S)
RECORD (CONRECF) R
INTEGER  I,FLAG
! CONNECT IN A SUITABLE MODE
       FLAG=1
       R=0
       IF  0<LENGTH(S)<=31 THEN  CONNECT(S,0,X'40000',0,R,FLAG)
      IF  FLAG#0 THEN  START 
         SELECT OUTPUT(0)
         PRINTSTRING("
Connect of ".S." fails,  flag =")
         WRITE(FLAG,1)
         NEWLINE
      FINISH 
       I=R_CONAD
       I=0 IF  FLAG#0
       RESULT =I
       END ; ! RDFILEAD
INTEGERFN  WRFILEAD(STRING (31) S)
RECORD (CONRECF) R
INTEGER  I,FLAG
! CONNECT IN WRITE MODE
       FLAG=1
       R=0
       IF  0<LENGTH(S)<=31 THEN  CONNECT(S,3,X'40000',0,R,FLAG)
      IF  FLAG#0 THEN  START 
         SELECT OUTPUT(0)
         PRINTSTRING("Connect of ".S." fails, flag =")
         WRITE(FLAG,1)
         NEWLINE
         STOP 
      FINISH 
       I=R_CONAD
       I=0 IF  FLAG#0
       RESULT =I
       END ; ! WRFILEAD
ROUTINE  FIX(STRING  (31) IN, OUT,  C 
         INTEGER  CODESTART, GLASTART)
!THIS VERSION BASED ON FIX USED BY SUPFIX ETC. AS AT 28/8/78
!**** RECORD FORMATS ****
RECORDFORMAT  RF(INTEGER  AREALOC, BASELOC)
RECORDFORMAT  RELF(INTEGER  LINK, N, RECORD (RF)ARRAY  R(1:1000))
RECORDFORMAT  OFMF(INTEGER  START, L, PROP)
RECORDFORMAT  CENTF(INTEGER  LINK, LOC, STRING  (31) IDEN)
RECORDFORMAT  DENTF(INTEGER  LINK, DISP, L, A,  C 
         STRING  (31) IDEN)
RECORDFORMAT  CREFF(INTEGER  LINK, REFLOC, STRING  (31) IDEN)
RECORDFORMAT  DREFF(INTEGER  LINK, REFARRAY, L,  C 
         STRING  (31) IDEN)
INTEGER  AREACODE, AREADISP, BASECODE, BASEDISP, N, DR0, DR1
INTEGER  UNSATCODE, UNSATDATA, RLINK
INTEGER  FLAG, INBASE, OUTBASE, LOC, I, LINK, LEN, AD, REFARRAY
INTEGERARRAY  BASE(1:7);                !AREA START ADDRESSES IN  FILE 'OUT'
INTEGERARRAY  LBASE(1:7);               !AREA START ADDRESSES WHEN LOADED
INTEGERARRAYFORMAT  LDATAAF(0:14)
INTEGERARRAYFORMAT  REFLOCAF(1:1000)
INTEGERARRAYNAME  LDATA, REFLOC
RECORD (CENTF)NAME  CENT
RECORD (DENTF)NAME  DENT
RECORD (OFMF)ARRAYFORMAT  OFMAF(1:7)
RECORD (OFMF)ARRAYNAME  OFM
RECORD (CREFF)NAME  CREF
RECORD (DREFF)NAME  DREF
RECORD (RELF)NAME  REL
RECORD (CONRECF)  RR
STRING  (31) IDEN
ROUTINESPEC  FAIL(STRING (100)S)
ROUTINESPEC  FINDCODEEP(STRING (31) ENTRY,INTEGERNAME  DR0,DR1,FLAG)
ROUTINESPEC  FINDDATAEP(STRING (31) ENTRY,INTEGERNAME  AD, FLAG)
      PRINTSTRING("FIX called at ".TIME." on ".DATE)
      NEWLINES(2)
      PRINTSTRING("Input: ".IN)
      NEWLINE
      PRINTSTRING("Output: ".OUT)
      NEWLINE
      PRINTSTRING("Codestart: ")
      PHEX(CODESTART+32)
      NEWLINE
      PRINTSTRING("Glastart: ")
      PHEX(GLASTART)
      NEWLINES(2)
      UNSATCODE=0
      UNSATDATA=0
      CONNECT(IN,0,0,0,RR,FLAG);        !CONNECT INPUT FILE - READ
      ->ERR IF  FLAG#0
      IF  INTEGER(RR_CONAD+12)#1 THEN  FAIL("INVALID FILETYPE")
      INBASE=RR_CONAD
      LEN=RR_RELEND
      OUTFILE(OUT,LEN+4096,0,0,OUTBASE,FLAG)
      ->ERR IF  FLAG#0
      MOVE(LEN,INBASE,OUTBASE);         !COPY FILE TO 'OUT'
      LDATA==ARRAY(INBASE+INTEGER(INBASE+24),LDATAAF)
                                        !LOAD DATA
      OFM==ARRAY(INBASE+INTEGER(INBASE+28)+4,OFMAF)
                                        !OBJECT FILE MAP
      CYCLE  I=1,1,5
         BASE(I)=OUTBASE+OFM(I)_START
      REPEAT 
      LBASE(1)=OFM(1)_START+CODESTART;  !START OF LOADED CODE
      LBASE(2)=GLASTART;                !START OF LOADED GLA
      LBASE(4)=OFM(4)_START+CODESTART;  !START OF LOADED SST
      LBASE(5)=OFM(2)_L+GLASTART;       !START OF LOADED UST
!NOW GO THROUGH CODE REFS FILLING IN INFO
      LINK=LDATA(7);                    !STATIC CODE REFS
      WHILE  LINK#0 CYCLE 
         CREF==RECORD(LINK+INBASE)
         FINDCODEEP(CREF_IDEN,DR0,DR1,FLAG)
         LOC=BASE(CREF_REFLOC>>24)+CREF_REFLOC&X'FFFFFF'
         INTEGER(LOC)=DR0
         INTEGER(LOC+4)=DR1
         LINK=CREF_LINK
      REPEAT 
!NOW DEAL WITH DATA REFS
      LINK=LDATA(9)
      WHILE  LINK#0 CYCLE 
         DREF==RECORD(LINK+INBASE)
         REFARRAY=(DREF_REFARRAY&X'7FFFFFFF')+INBASE
                                        !AND OFF COMMON BIT
         N=INTEGER(REFARRAY)
         REFLOC==ARRAY(REFARRAY+4,REFLOCAF)
         FINDDATAEP(DREF_IDEN,AD,FLAG)
         CYCLE  N=1,1,N
            LOC=BASE(REFLOC(N)>>24)+REFLOC(N)&X'FFFFFF'
            INTEGER(LOC)=INTEGER(LOC)+AD
         REPEAT 
         LINK=DREF_LINK
      REPEAT 
! NOW DEAL WITH RELOCATION REQUESTS
      LINK=LDATA(14)
      WHILE  LINK#0 CYCLE 
         REL==RECORD(LINK+INBASE)
         CYCLE  N=1,1,REL_N;            !NO OF RELOCATION ENTRIES IN THIS BLOCK
            AREACODE=REL_R(N)_AREALOC>>24
            AREADISP=REL_R(N)_AREALOC&X'FFFFFF'
            BASECODE=REL_R(N)_BASELOC>>24
            BASEDISP=REL_R(N)_BASELOC&X'FFFFFF'
            LOC=BASE(AREACODE)+AREADISP
            INTEGER(LOC)=INTEGER(LOC)+LBASE(BASECODE)+BASEDISP
         REPEAT 
         LINK=REL_LINK
      REPEAT 
!
! NOW PRINT MAP OF ENTRY POINTS
!
      NEWLINES(2)
      PRINTSTRING("Name                          entry point")
      NEWLINES(2)
      LINK=LDATA(1);                    !HEAD OF CODE EP LIST
      WHILE  LINK#0 CYCLE 
         CENT==RECORD(INBASE+LINK)
         PRINTSTRING(CENT_IDEN)
         SPACES(32-LENGTH(CENT_IDEN))
         LOC=BASE((CENT_LOC>>24)&X'F')+CENT_LOC&X'FFFFFF'
         PHEX(INTEGER(LOC+4))
         NEWLINE
         LINK=CENT_LINK
      REPEAT 
!NOW PRINT MAP OF DATA ENTRIES IF ANY
      LINK=LDATA(4);                    !HEAD OF DATA EP LIST
      IF  LINK#0 START 
         NEWLINES(2)
         PRINTSTRING( C 
            "Name                        length              address")
         NEWLINES(2)
         WHILE  LINK#0 CYCLE 
            DENT==RECORD(INBASE+LINK)
            PRINTSTRING(DENT_IDEN)
            SPACES(32-LENGTH(DENT_IDEN))
            WRITE(DENT_L,10)
            SPACES(5)
            PHEX(LBASE(DENT_A)+DENT_DISP)
            NEWLINE
            LINK=DENT_LINK
         REPEAT 
      FINISH 
      SELECTOUTPUT(0)
!NOW CHECK FOR UN-USED ENTRIES
      LINK=LDATA(1);                    !LIST HEAD OF CODE ENTRIES
      WHILE  LINK#0 CYCLE 
         CENT==RECORD(INBASE+LINK)
         IDEN=CENT_IDEN
         RLINK=LDATA(7);                !HEAD OF CODE REF LIST
         WHILE  RLINK#0 CYCLE 
            CREF==RECORD(INBASE+RLINK)
            EXIT  IF  IDEN=CREF_IDEN;   !ENTRY IS USED
            RLINK=CREF_LINK
         REPEAT 
         IF  RLINK=0 AND  IDEN#"ENTER" START ;    !ENTRY IS NOT REFERENCED
            PRINTSTRING("**Warning - procedure ".IDEN. C 
               " not used")
            NEWLINE
         FINISH 
         LINK=CENT_LINK
      REPEAT 
      IF  UNSATCODE=0=UNSATDATA START 
         PRINTSTRING("All refs filled")
         NEWLINE
      FINISH  ELSE  START 
         IF  UNSATCODE>0 START 
            WRITE(UNSATCODE,1)
            PRINTSTRING("  Unsatisfied code references")
            NEWLINE
         FINISH 
         IF  UNSATDATA>0 THEN  START 
            WRITE(UNSATDATA,1)
            PRINTSTRING("  Unsatisfied data references")
            NEWLINE
         FINISH 
      FINISH 
      NEWLINE
ERR:
      SELECTOUTPUT(0)
      IF  FLAG#0 THEN  PSYSMES(1000,FLAG)
      RETURN 
ROUTINE  FAIL(STRING  (100) S)
      SELECTOUTPUT(0)
      PRINTSTRING("Failure in FIX - ".S)
      STOP 
END ;                                   !OF FAIL
ROUTINE  FINDCODEEP(STRING  (31) ENTRY, INTEGERNAME  DR0, DR1, FLAG)
INTEGER  LINK
RECORD (CENTF)NAME  CENT
      LINK=LDATA(1)
      WHILE  LINK#0 CYCLE 
         CENT==RECORD(INBASE+LINK)
         IF  ENTRY=CENT_IDEN START 
            DR0=X'B1000000'
            DR1=LBASE((CENT_LOC>>24)&X'F')+CENT_LOC&X'FFFFFF'
            FLAG=0
            RETURN 
         FINISH 
         LINK=CENT_LINK
      REPEAT 
      PRINTSTRING("Unsat ref ".ENTRY)
      NEWLINE
      FLAG=1
      DR0=M'NORT';                      !USEFUL FOR DIAGNOSING FAULTS
      MOVE(4,ADDR(ENTRY)+1,ADDR(DR1));  !FIRST FOUR BYTES OF ENTRY NAME
      DR1=X'54524546'
      UNSATCODE=UNSATCODE+1
END ;                                   !OF FINDCODEEP
ROUTINE  FINDDATAEP(STRING  (31) ENTRY, INTEGERNAME  AD, FLAG)
INTEGER  LINK
RECORD (DENTF)NAME  DENT
      LINK=LDATA(4)
      WHILE  LINK#0 CYCLE 
         DENT==RECORD(INBASE+LINK)
         IF  ENTRY=DENT_IDEN START 
            AD=LBASE(DENT_A)+DENT_DISP
            FLAG=0
            RETURN 
         FINISH 
         LINK=DENT_LINK
      REPEAT 
      PRINTSTRING("Unsat data ref ".ENTRY)
      NEWLINE
      AD=0;                             !NULL VALUE
      FLAG=1
      UNSATDATA=UNSATDATA+1
END ;                                   !OF FINDDATAEP
END ;                                   !OF FIX
EXTERNALROUTINE  CHOPFIX(STRING  (63) S)
ROUTINESPEC  ST ENTRY(INTEGERARRAYNAME  ST,  C 
         INTEGER  SEGNO, SLAVED, SEGLIMBYTES, RA, EXECBIT, WACR, RACR)
ROUTINESPEC  HEAD(STRING  (71) S)
ROUTINESPEC  PSTRG0(STRING  (255) S)
ROUTINESPEC  MULSYM(INTEGER  SYM, MUL)
INTEGERFNSPEC  FIND EP(INTEGER  FILEADDR, STRING  (31) S)
ROUTINESPEC  TREAT BLOCK(INTEGER  AD)
INTEGER  OFM, GLARELST
RECORDFORMAT  LDATF(INTEGER  PTRS, PROCENTS, Z2, Z3, DATENTS,  C 
         Z5, TOSREFS, PROCREFS, DPROCREFS, DATREFS, Z10, Z11,  C 
         SRCFNAME, Z13, RELOCRQS)
RECORDFORMAT  L1F(INTEGER  LINK, REFLOC, STRING  (31) IDEN)
RECORD (L1F)NAME  LIST1
RECORD (LDATF)NAME  LDAT
!----------------------------------- CONSTS - SEGMENT ALLOCATIONS ETC.---
CONSTINTEGER  TOPPSEG=X'213F';          ! PUBLIC 319 (64+SMACS 0-F)
CONSTINTEGER  TOPLSEG=8
CONSTINTEGER  SLAVED=0, NONSLAVED=X'20000000'
CONSTINTEGER  LST RA=X'8080'
CONSTINTEGER  PSTBLKNO=2
CONSTINTEGER  PST RA=X'8400'
CONSTINTEGER  INF BLK RA=X'8000'
CONSTINTEGER  IST RA=X'8200'
CONSTINTEGER  VR MAP SEG=0;             ! MAPS VIRTUAL TO REAL
CONSTINTEGER  PUBLIC0=8192
CONSTINTEGER  PSTVSEG=PUBLIC0+11
CONSTINTEGER  LAST PUB SEG=TOPPSEG-X'2000'
CONSTINTEGER  IST0=PUBLIC0
CONSTINTEGER  IST1=PUBLIC0+1
CONSTINTEGER  IST2=PUBLIC0+2
CONSTINTEGER  IST3=PUBLIC0+3
! USE SEGS AS FOLLOWS:-
!     SEG 44 FOR CHOPSUPCODE
!     SEG 45 FOR GLA
!     SEG 46 FOR STACK
!     SEG 47 FOR SSN+1
CONSTINTEGER  CODESEG=PUBLIC0+44
CONSTINTEGER  GLASEG=PUBLIC0+45
CONSTINTEGER  UNDUMPSEG=PUBLIC0+47
CONSTINTEGER  STACKSEG=PUBLIC0+46
CONSTINTEGER  PUBLIC7=PUBLIC0+7
CONSTINTEGER  PUB7 SIZE=X'200';         ! BYTES
CONSTINTEGER  RES STKSEG=PUBLIC0+6;     ! restart stack
CONSTINTEGER  RES STK RA=X'3000'
CONSTINTEGER  RES STK SIZE=X'1800'
! STACK SHOLD NOT EXCEED 255 PGS, SEE PLI 4.2.4.1, SHEET 42
CONSTINTEGER  STACKSIZE=X'3FC00';       ! 255K BYTES
CONSTINTEGER  DISCCA SEG=PUBLIC0+10
CONSTINTEGER  DISCCA SIZE=X'400'
CONSTINTEGER  REAL0 SEG=PUBLIC0+64;     ! maps to RA 0
CONSTINTEGER  REAL0 SIZ=X'40000'
! LOCAL SEGMENT NUMBERS ........................................
CONSTINTEGER  DRDR0=X'B0000000';        ! 1ST WORD OF A DESCRIPTOR DESCRIPTOR
CONSTINTEGER  GLACODE=2
CONSTLONGINTEGER  OVERLAY DESCR=X'1800400000004000';       !FOR DBOOT
INTEGERARRAYFORMAT  PSTF(0:2*LAST PUB SEG)
INTEGERARRAYFORMAT  LSTF(0:255)
INTEGERARRAYNAME  PST, LST
INTEGERARRAYNAME  PCA ST
RECORDFORMAT  REGF(INTEGER  LNB, PSR, PC, SSR, SF, IT, IC, LTB)
RECORD (REGF)ARRAYFORMAT  ISTF(0:11);   ! 12*32=384(DEC) OR X180 BYTES
RECORD (REGF)ARRAYNAME  IST
OWNINTEGERARRAY  INFO BLOCK(0 : 255) =     C 
0(224),M'INFO'(32);                     ! 256 WORDS = 1024 BYTES
OWNINTEGERARRAY  PSTBLK(0 : 2*LAST PUB SEG+1)=0(2*LAST PUB SEG+2)
                                        ! ANOTHER 2K BYTES
OWNINTEGERARRAY  ZERBLK(0 : 255) =    0(256)
OWNINTEGERARRAY  EEE(0 : 255) =    X'EEEEEEEE'(256)
OWNINTEGERARRAY  UNDUMP(0 : 255) =    C 
 0(224),M'UNDU'(32)
RECORDFORMAT  INFBF(INTEGER  A1, A2, A3, A4, CODEBLK RA,  C 
         GLABLK RA, UNDUMPBLK RA, STACKBLK RA, ACTLSTB0,  C 
         ACTLSTB1, SP10, ACTSSN, SP12, SP13, SP14, SP15, SP16,  C 
         SP17, SP18, SP19, SP20, SP21, SP22, SP23, SP24, SP25,  C 
         SP26, SP27, SP28, SP29, SP30, SP31,  C 
         INTEGERARRAY  ST(0:31))
RECORD (INFBF)NAME  INF
RECORDFORMAT  RF(INTEGER  LNB, PSR, PC, SSR, SF, IT, IC, LTB,  C 
         XNB, B, DR0, DR1, A0, A1, A2, A3, LSTB0, LSTB1, PSTB0,  C 
         PSTB1)
RECORD (RF)NAME  R
RECORD (OBJF)NAME  HO
RECORD (OBJF)NAME  HT
STRING  (17) GGFILE, IMPFILE, DIAGFILE, TAPEFILE, WK, MPFILE,  C 
         MPIND
CONSTINTEGER  MAX PAGES=55;             ! maximum CHOPSUPE pages
CONSTINTEGER  TPFPGS=64
INTEGER  TAPEFILEAD
INTEGER  AGLA, ACODE, AFILEEND, J
INTEGER  LDATADDR, CODELEN, GLALEN
INTEGER  RA, CODE BLOCKS, GLA BLOCKS
INTEGER  CODE DR RELAD, EP AD
INTEGER  LEN, BLOCKS
INTEGER  FLAG
INTEGER  BLEN, CONAD
INTEGER  MPROGAD
INTEGER  PUB7 RA
INTEGER  PST IN GGFILE
INTEGER  GLOBSTK RA, DISCCA RA
INTEGER  BOOTL, AD, BLKSEQ
INTEGER  IPLAD, SIPLAD
INTEGER  PSAVE
INTEGERARRAY  DUMMYBLK(0:1023)
!-----------------------------------------------------------------------
      PSAVE=COMREG(27);                 ! SAVE PARMS
      PRINTSTRING("VSN ".VSN."
")
!      PRINTSTRING("***** Caution - PST in segment 11 *****
!")
      IMPFILE="";  MPFILE=""
      IF  LENGTH(S)>0 START 
         IF  S->MPFILE.(",").IMPFILE START 
         FINISH  ELSE  MPFILE=S
      FINISH 
      IF  IMPFILE="" THEN  IMPFILE="CHOPZ";  !DEFAULT OBJECT FILE
      J=RDFILEAD(IMPFILE)
      ->QUIT IF  J<=0
      TAPEFILE=IMPFILE
      GGFILE="T#TEMPOBJ"
! REMOVE FILE OWNER NAME FROM STRING IF PRESENT
      IF  TAPEFILE->WK.(".").TAPEFILE START 
      FINISH 
      LENGTH(TAPEFILE)=LENGTH(TAPEFILE)-1
      DIAGFILE=TAPEFILE."D"
      TAPEFILE=TAPEFILE."T"
      TAPEFILEAD=NWFILEAD(TAPEFILE,TPFPGS)
      ->QUIT IF  TAPEFILEAD<=0
      NEWLINE
      PRINTSTRING("Diag file:         ".DIAGFILE."
")
      HT==RECORD(TAPEFILEAD)
      HT=0
      HT_NEXTFREEBYTE=16
      HT_CODERELST=HT_NEXTFREEBYTE
! TAPEFILE IS A FILE TO HAVE A COPY OF THE TAPE FILE IN
! HT _ NEXTFREEBYTE - USUAL MEANING
!      CODERESLT    - START OF IPL BLOCK
!      PSIZE        - START OF 1K BLOCKS
!      FILETYPE     - NO OF 1K BLOCKS
      DEFINE("57,".DIAGFILE);           ! LAST PARAM IS NO OF KBYTES REQD
      SELECT OUTPUT(57)
      SPACES(20)
      PRINTSTRING("CHOPFIX version ".VSN.", called at ".TIME. C 
         " on ".DATE)
      NEWLINE
      PRINTSTRING("Object file was        ".IMPFILE."
")
      PRINTSTRING("Diag file is           ".DIAGFILE."
")
!-----------------------------------------------------------------
! FIX UP AND WRITE OUT TO TAPE THE BOOTSTRAP FILE 'BOOTZ'
      RA=0
      IF  RDFILEAD("DBOOTZ")<=0 THEN  ->QUIT
      COPY("DBOOTZ,DBOOTZT")
      CONAD=WRFILEAD("DBOOTZT")
      FLAG=0
      HO==RECORD(CONAD)
      OFM=CONAD+HO_OFM;                 !START OF OBJECT FILE MAP
      AGLA=CONAD+INTEGER(OFM+16);       !START OF AREA 2
      ACODE=CONAD+HO_CODERELST
      AFILEEND=CONAD+HO_NEXTFREEBYTE
      LDATADDR=CONAD+HO_LDRELST
      BLEN=LDATADDR-CONAD
      LDAT==RECORD(LDATADDR)
      BLEN=(BLEN+X'F')&(¬X'F')
!
! IF THERE IS A DUMMT MICROPROGRAM THEN  ADDTHE OVERLAYS INTO EPAGE 4
! OTHERWISE OR IN THE OCP MICROPROGRAM FROM X100
!
      SELECT OUTPUT(0)
      IF  MPFILE="" THEN  START 
         MPROGAD=RDFILEAD("OCPMPRG")
         INTEGER(ACODE+X'104')=X'000F0000'
         IF  MPROGAD<=0 THEN  PRINTSTRING("

Warning - microprogram overlays ommitted. CHOPSUPE will not work
            on a 2970 (P3) processor.

" C 
            ) ELSE  MOVE(4*4096,MPROGAD+X'1C000'+INTEGER( C 
            MPROGAD+4),ACODE+X'4000')
         MPIND="without "
      FINISH  ELSE  START 
         MPROGAD=RDFILEAD(MPFILE)
         ->QUIT IF  MPROGAD<=0
         MOVE(X'13F00',MPROGAD+X'100'+INTEGER(MPROGAD+4),ACODE+ C 
            X'100')
!THIS IS THE MAX MPROG SIZE 'COS THE CODE STARTS AT X'14000'
         MPIND="with "
      FINISH 
      SELECT OUTPUT(57)
      LONGINTEGER(ACODE+X'A8')=OVERLAY DESCR
      TREAT BLOCK(ACODE)
      HT_PSIZE=HT_NEXTFREEBYTE;         ! START POSITION OF 1K BLOCKS
      RA=X'8000'
!-----------------------------------------------------------------
! LOAD AND WRITE TO TAPE THE IMP OBJECT FILE
      PARM("MAP")
      PSTRG0("
Loading CHOPSUPE file")
      HEAD("Load 'CHOPSUPE' file")
      FIX(IMPFILE,GGFILE,(CODESEG<<18)-32,GLASEG<<18)
      SELECT OUTPUT(57)
      CONAD=WRFILEAD(GGFILE)
      HO==RECORD(CONAD)
      GLARELST=INTEGER(CONAD+HO_OFM+16);!START OF AREA 2
      AGLA=CONAD+GLARELST
      ACODE=CONAD+HO_CODERELST
      CODELEN=AGLA-ACODE
      GLALEN=HO_LDRELST-GLARELST
      LDATADDR=CONAD+HO_LDRELST
      LDAT==RECORD(LDATADDR)
! FIND REQUIRED ENTRY DESCRIPTOR
      IF  FIND EP(CONAD,"ENTER")=0 START 
         SELECT OUTPUT(0)
         PRINTSTRING("Entry point 'ENTER' not found
")
         ->QUIT
      FINISH 
      CODE DR RELAD=LIST1_REFLOC&X'FFFFFF';  ! DISPL OF ENTRY DESCRIPTOR FROM START OF
                                        ! GLA
! GET THE EP ADDRESS FROM THE ENTRY DESCRIPTOR IN GLA (ALREADY FIXED
! UP TO THE CORRECT VA BY THE LOADER.
      EP AD=INTEGER(AGLA+CODE DR RELAD+4)
! NEXT LINK THE LOCAL TO THE GLOBAL CONTROLLER
!-------------------------------------------------- INFO -----------------
! EVALUATE NUMBER OF BLOCKS TO BE WRITTEN, SET UP INFO BLOCK
! (ACTIVATE WORDS), SET UP SEG TABLE.
      INF==RECORD(ADDR(INFO BLOCK(0)))
      CODE BLOCKS=(CODELEN+X'3FF')>>10
      GLA BLOCKS=(GLALEN+X'3FF')>>10
!      INF_UNDUMPBLK RA = INF_GLA BLK RA + (GLA BLOCKS<<10)
!      INF_STACKBLK RA=INF_UNDUMPBLK RA + X'400'
      NEWLINES(2)
      PRINTSTRING("Info block RA    = ");  PHEX(RA)
      NEWLINE
      PRINTSTRING("Activ words RA   = ");  PHEX(RA+X'20')
      NEWLINE
      PRINTSTRING("Local seg tab RA = ");  PHEX(RA+128)
      NEWLINE
      PRINTSTRING("IST RA           = ");  PHEX(IST RA)
      NEWLINE
!--------------------------------------------------- ACTIVATE WORDS ---------
! SET UP THE ACTIVATE WORDS
      INF_ACTLSTB0=MAXSEG<<18
      INF_ACTLSTB1=RA+(ADDR(INF_ST(0))-ADDR(INF))
      INF_ACTSSN=STACKSEG<<18
      NEWLINES(4)
      PRINTSTRING("For the IMP program
!
")
      SPACES(36);  PRINTSTRING("Virtual         real")
      NEWLINES(2)
      SPACES(20);  PRINTSTRING("Code address  = ")
      PHEX(CODESEG<<18)
      NEWLINE
      SPACES(20);  PRINTSTRING("Entry address = ")
      PHEX(EP AD)
      NEWLINE
      SPACES(20);  PRINTSTRING("GLA address   = ")
      PHEX(GLASEG<<18)
      NEWLINE
      SPACES(20);  PRINTSTRING("STACK address = ")
      PHEX(INF_ACTSSN)
      NEWLINES(4)
! NOW CREATE THE SEGMENT TABLE IN THE INFO BLOCK
      PST==ARRAY(ADDR(PSTBLK(0)),PSTF)
      LST==ARRAY(ADDR(INFOBLOCK(0))+LSTRA-INFBLKRA,LSTF)
      ST ENTRY(INF_ST,VRMAPSEG,NONSLAVED,X'40000',0,1,15,15)
                                        ! MAP LOC SEG 0 TO RA 
      ST ENTRY(LST,1,SLAVED,X'100',X'80',0,1,1)
      ST ENTRY(PST,RES STK SEG,SLAVED,RES STK SIZE,RES STK RA,0, C 
         1,1)
! NOW THE PUBLIC SEG TABLE IN THE SECOND INFO BLOCK, WITH PUBLIC 0 THE
! INTERRUPT STEERING TABLE AT X2400
      IST==ARRAY(ADDR(INFO BLOCK(0))+IST RA-INF BLK RA,ISTF)
      IST(0)_LNB=X'200';                ! HOPEFULLY NOT NEEDED
      IST(0)_PSR=X'0014FF01'
      IST(0)_PC=INF BLK RA
      IST(0)_SSR=X'01800FFF';           ! VA MODE
      IST(0)_SF=X'204';                 ! ALSO HOPEFULLY NOT NEEDED
      INFO BLOCK(0)=X'4F801111';        ! AN IDLE 1111 INSTRUCTION !
      ST ENTRY(PST,IST0,SLAVED,16*32,IST RA,0,1,1)
      ST ENTRY(PST,IST1,SLAVED,16*32,IST RA,0,1,1)
      ST ENTRY(PST,IST2,SLAVED,16*32,IST RA,0,1,1)
      ST ENTRY(PST,IST3,SLAVED,16*32,IST RA,0,1,1)
      TREAT BLOCK(ADDR(INFO BLOCK(0))); ! INFO
      HEAD("This block to be overwritten later with PST block")
      TREAT BLOCK(ADDR(ZERBLK(0)))
      TREAT BLOCK(ADDR(ZERBLK(0)))
! NOW THE GROPE TEMP C/A BLOCKS
      DISCCA RA=RA+X'200';              ! ONLY HALF OF BLOCK
                                        ! FRONT HALF PART OF PST

      HEAD("Disc comms area")
      ST ENTRY(PST,DISCCA SEG,NONSLAVED,DISC CA SIZE,DISCCA RA, C 
         0,1,1)
      TREAT BLOCK(ADDR(ZERBLK(0)))
! PUBLIC 7 - SSN+1 FOR RETART STACK (WAS EXTRADUMP INFORMATION)
      PUB7 RA=RA+X'200'
      ST ENTRY(PST,PUBLIC7,SLAVED,PUB7 SIZE,PUB7 RA,0,1,1)
      HEAD("Post mortem info segment")
      TREAT BLOCK(ADDR(ZERBLK(0)));     ! PUBLIC7 (POST MORTEM)
! NOW THE UN-DUMP SEGMENT, SSN+1
      ST ENTRY(PST,UNDUMP SEG,SLAVED,X'400',RA,0,1,1)
      R==RECORD(ADDR(UNDUMP(0)))
      R_LNB=STACKSEG<<18
      R_PSR=X'00140001';                ! PSR, PRIV=1  PM=00  ACS=1  ACR=1
      R_PC=EP AD
      R_SSR=X'0180FFFF';                ! VA MODE   ALL MASKED 
      R_SF=R_LNB+28;                    ! 5 WORDS FO DISPLAY + 2 ONE-WORD PARAMS
      R_XNB=GLASEG<<18;                 !ASSUME GLA OFFSET FOR 'ENTER' IS ZERO
      R_DR0=DRDR0+GLALEN
      R_DR1=GLASEG<<18+CODE DR RELAD
! (DR MUST POINT TO THE DESCRIPTOR (IN CALLED ROUTINE'S GLA) TO THE
!  CALLED ROUTINE'S ENTRY POINT).
      HEAD("The 'SSN+1' segment")
      TREAT BLOCK(ADDR(UNDUMP(0)))
! GLOBAL CODE BLOCKS NEXT
      ST ENTRY(PST,CODESEG,SLAVED,CODELEN,RA,1,0,1)
      BLOCKS=(CODELEN+X'3FF')>>10
      LEN=BLOCKS<<10
      MOVE(LEN,ACODE,TAPEFILEAD+HT_NEXTFREEBYTE)
      HT_NEXTFREEBYTE=HT_NEXTFREEBYTE+LEN
      HT_FILETYPE=HT_FILETYPE+BLOCKS
      RA=RA+LEN
!      HEAD('Global code')
!      %CYCLE J=0,X'400',(CODELEN-1)&(¬X'3FF')
!      TREAT BLOCK(ACODE+J)
                                        ! GLOBAL CODE
!      %REPEAT
! NOW GLOBAL GLA BLOCKS
      ST ENTRY(PST,GLASEG,SLAVED,GLALEN,RA,0,1,1)
      BLOCKS=(GLALEN+X'3FF')>>10
      LEN=BLOCKS<<10
      MOVE(LEN,AGLA,TAPEFILEAD+HT_NEXTFREEBYTE)
      HT_NEXTFREEBYTE=HT_NEXTFREEBYTE+LEN
      HT_FILETYPE=HT_FILETYPE+BLOCKS
      RA=RA+LEN
!      HEAD('Global GLA')
!      NEWLINE
!      %CYCLE J=0,X'400',(GLALEN-1) & (¬X'3FF')
!      TREAT BLOCK(AGLA+J)
!      %REPEAT
! THE PROCESS C/A SEG. (USING ZERBLK)
      PCA ST==ARRAY(ADDR(ZERBLK(0)),LSTF)
! THE PROCESS C/A SEG. (USINGZERBLK)
!      PROCCA RA=RA
!      ST ENTRY(PST,PROCCA SEG,SLAVED,PROCCA SIZE, PROCCA RA,0,1,1)
!      HEAD('''Process C/A'' segment')
!      TREAT BLOCK(ADDR(ZERBLK(0)))
!      %CYCLE J=0,1,7
!         ZERBLK(J)=0
!      %REPEAT
                                        ! RE-INIT THIS
!      PST RA=RA + X'400'
                                        ! NEXT AFTER UNDUMP ..............
      GLOBSTK RA=RA+X'800'
!----------------------------------------------------- PROGRAM REGISTERS
! PUBLIC SEGMENT TABLE
      ST ENTRY(PST,STACKSEG,SLAVED,STACKSIZE,GLOBSTK RA,0,1,1)
      ST ENTRY(PST,PSTVSEG,SLAVED,8*(LAST PUB SEG+1),PST RA,0,1, C 
         1)
      ST ENTRY(PST,REAL0 SEG,SLAVED,REAL0 SIZ,0,0,1,1)
      HEAD("Public segment table")
                                        ! PST
! AND PLACE THIS BLOCK FOR RA 2400 IN THE TAPE FILE ALSO
      MOVE(X'800',ADDR(PST(0)),PST IN GGFILE)
!
! FINALLY, SET UP STACK SEGMENT AS THOUGH THE IMP PROGRAM HAS
! BEEN CALLED. LNB POINTS TO BEGINNING OF STACK SEGMENT.
!
      HEAD("Global stack")
      TREAT BLOCK(ADDR(ZERBLK(0)))
!
! TWO BLOCKS OF E'S TO SHOW IN DUMP
!
      CYCLE  J=0,1,1
         TREAT BLOCK(ADDR(EEE(0)))
      REPEAT 
      NEWLINES(5)
      SELECT OUTPUT(0)
!
! FORMAT OF "FILE" IS:
!     'CODERELST' POINTS TO START OF DATA
!     'GLA RELST' POINTS TO START OF THE 1K BLOCKS
!     'LDRELST' CONTAINS TOTAL NUMBER OF BLOCKS FOR THE TAPE
! THE FIRST BLOCK FROM 'CODERELST' IS THE IPL BLOCK, FOLLOWED BY
! 1K BLOCKS OF CODE + GLA.
!
      CYCLE  J=0,1,1023
         DUMMYBLK(J)=M'DMBK'
      REPEAT 
      AD=RDFILEAD(TAPEFILE)
      RETURN  IF  AD<=0
      HT==RECORD(AD)
      BLEN=4096
      J=(HT_FILETYPE+99)>>2
      NEWLINE
      PRINTSTRING("Number of blocks to 'PLOD' from 'SITE'+1 :")
      WRITE(J,1)
      NEWLINE
      IF  J>MAX PAGES START 
         PRINTSTRING("*** Warning - CHOPSUPE is oversize ***
")
      FINISH 
      BOOTL=HT_PSIZE-HT_CODERELST
      OUTFILE("CHOPIPL",HT_NEXTFREEBYTE+X'8FF0',0,0,IPLAD,FLAG)
      IF  FLAG#0 START 
         PRINTSTRING("'CHOPIPL' not created - FLAG =")
         WRITE(FLAG,1)
         ->QUIT
      FINISH 
      MOVE(16,AD,IPLAD);                !COPY HEADER
      SIPLAD=IPLAD
      INTEGER(IPLAD+4)=4096
      IPLAD=IPLAD+4096
! PAD OUT TO X'8000' WITH DUMMIES THIS SPACE TO CONTAIN THE OCP
! MICROPROGRAM AND TEMP STACK SPACE FOR CHOPSUPI
      CYCLE  J=0,1,20
         IF  J*BLEN<BOOTL THEN  MOVE(BLEN,AD+HT_CODERELST+J* C 
            BLEN,IPLAD+J*BLEN) ELSE  MOVE(BLEN,ADDR(DUMMYBLK(0)), C 
            IPLAD+J*BLEN)
      REPEAT 
      IPLAD=IPLAD+(J+1)*BLEN
      AD=AD+HT_PSIZE;                   ! TO START OF 4K BLOCKS
      J=1;  BLKSEQ=21
      UNTIL  J>=HT_FILETYPE CYCLE 
         IF  BLKSEQ=X'1C' START ;       ! PLACE FOR OVERLAYS
            IF  MPROGAD>0 THEN  MOVE(4*4096,MPROGAD+X'1C000'+ C 
               INTEGER(MPROGAD+4),IPLAD)
            BLKSEQ=BLKSEQ+4
            IPLAD=IPLAD+4*BLEN
         FINISH 
         MOVE(BLEN,AD,IPLAD)
         IPLAD=IPLAD+BLEN
         BLKSEQ=BLKSEQ+1
         AD=AD+BLEN
         J=J+(BLEN//1024)
      REPEAT 
      INTEGER(SIPLAD)=IPLAD-SIPLAD;     ! CORRECT 'USEFULL' LENGTH
      PRINTSTRING("'CHOPIPL' generated ".MPIND. C 
         "OCP microprogram")
      DESTROY(TAPEFILE.",DBOOTZT")
QUIT:
      COMREG(27)=PSAVE;                 ! RESTORE PARMS
      RETURN 
!----------------------------------------------------------------------
INTEGERFN  FIND EP(INTEGER  FILEADDR, STRING  (31) S)
! RESULT IS  0 IF EP 'S' NOT FOUND
!            1 IF EP 'S' IS FOUND
RECORD (OBJF)NAME  H
RECORD (LDATF)NAME  LDAT
      H==RECORD(FILEADDR)
      LDAT==RECORD(FILEADDR+H_LDRELST)
      LIST1==RECORD(ADDR(LDAT_PROCENTS))
      WHILE  LIST1_LINK#0 CYCLE 
         LIST1==RECORD(FILEADDR+LIST1_LINK)
         IF  LIST1_IDEN=S START ;       ! IDEN FOUND
            UNLESS  LIST1_REFLOC>>24=GLACODE START 
                                        ! CHECKA
               PSTRG0("EP IN GLA ?? ")
               RESULT  =0;              ! NOT FOUND
            FINISH ;                    ! CHECKA
            RESULT  =1;                 ! FOUND
         FINISH ;                       ! IDEN FOUND
      REPEAT 
      RESULT  =0;                       ! NOT FOUND
END ;                                   ! FIND EP
ROUTINE  TREAT BLOCK(INTEGER  AD)
!***********************************************************************
!*    TAPEFILE IS A FILE TO HAVE A COPY OF THE TAPE FILE IN            *
!*    HT _ NEXTFREEBYTE - USUAL MEANING                                *
!*         CODERESLT    - START OF IPL BLOCK                           *
!*         GLARELST     - START OF 1K BLOCKS                           *
!*         LDRELST      - NO OF 1K BLOCKS                              *
!***********************************************************************
OWNINTEGER  BLOCK NO=0
INTEGER  BLKSI
      PRINTSTRING("Block number");  WRITE(BLOCK NO,1)
      PRINTSTRING("  for real address ")
      PHEX(RA)
      NEWLINES(2)
      BLKSI=X'400'
      IF  BLOCKNO=0 THEN  BLKSI=BLEN;   ! FOR BOOT LOADER
      IF  HT_NEXTFREEBYTE+BLKSI>TPFPGS<<12 START 
         SELECT OUTPUT(0)
         PRINTSTRING("File for mag tape is not big enough
")
         STOP 
      FINISH 
      MOVE(BLKSI,AD,TAPEFILEAD+HT_NEXTFREEBYTE)
      IF  BLOCKNO=PSTBLKNO THEN  PST IN GGFILE=TAPEFILEAD+HT_ C 
         NEXTFREEBYTE
      HT_NEXTFREEBYTE=HT_NEXTFREEBYTE+BLKSI
      HT_FILETYPE=HT_FILETYPE+1;        ! COUNT OF BLOCKS FOR TAPE
      BLOCK NO=BLOCK NO+1
      RA=RA+X'400'
END ;                                   ! TREAT BLOCK
ROUTINE  HEAD(STRING  (71) S)
INTEGER  J
      S=" ".S." "
      J=(120-LENGTH(S))>>1
      MULSYM('-',J)
      PRINTSTRING(S)
      MULSYM('-',J)
      NEWLINE
END ;                                   ! HEAD
ROUTINE  PSTRG0(STRING  (255) S)
      SELECT OUTPUT(0)
      PRINTSTRING(S)
      NEWLINE
      SELECT OUTPUT(57)
END ;                                   ! PSTRG0
ROUTINE  MULSYM(INTEGER  SYM, MUL)
INTEGER  J
      RETURN  IF  MUL<=0
      CYCLE  J=1,1,MUL;  PRINT SYMBOL(SYM)
      REPEAT 
END ;                                   ! MULSYM
ROUTINE  ST ENTRY(INTEGERARRAYNAME  ST,  C 
         INTEGER  SEGNO, SLAVED, SEGLIMBYTES, RA, EXECBIT, WACR, RACR)
! MAKES A NON-PAGED, NON-SHARED, SLAVABLE, FIXED SEG TAB ENTRY
CONSTINTEGER  LIM=X'0003FF80'
!%CONSTINTEGER APF=X'1FF00000'
CONSTINTEGER  FIX=X'00000001'
! APF IS NINE BITS STARTING AT BIT 3 IN 1ST WORD OF ST ENTRY
!     FROM LEFT   EXEC  1 BIT
!                 WRITE 4 BITS
!                 READ  4 BITS
! PERMITTED -  EXEC  IF EXEC=1
!              WRITE IF WRITE>=ACR
!              READ  IF READ>=ACR
CONSTINTEGER  AVAIL=X'80000000'
INTEGER  ENTNO, APF
      IF  SEGNO<X'2000' START 
         UNLESS  0<=SEGNO<=TOPLSEG THEN  ->ERROR
      FINISH  ELSE  START 
         UNLESS  SEGNO<=TOPPSEG THEN  ->ERROR
         SEGNO=SEGNO-X'2000'
      FINISH 
      ENTNO=SEGNO<<1
      UNLESS  0<SEGLIMBYTES<=X'40000' START 
         SELECT OUTPUT(0)
         PRINTSTRING("Segment ")
         PHEX(SEGNO)
         PRINTSTRING(" limit in error (local or public)
")
         SELECT OUTPUT(57)
         RETURN 
      FINISH 
      UNLESS  0<=EXECBIT<=1 AND  0<=WACR<=15 C 
         AND  0<=RACR<=15 START 
         SELECT OUTPUT(0)
         PRINTSTRING("Invalid APF value
")
         SELECT OUTPUT(57)
         RETURN 
      FINISH 
      APF=(EXECBIT<<28)!(WACR<<24)!(RACR<<20)
! MAX ADDRESS WITHIN SEGMENT IS SEGLIMBYTES-1
      ST(ENTNO)=((SEGLIMBYTES-1)&LIM)!APF!SLAVED
      ST(ENTNO+1)=RA!AVAIL!FIX
      RETURN 
ERROR:
      SELECT OUTPUT(0)
      PRINTSTRING("Segno too high to make entry
")
END ;                                   ! ST ENTRY
END ;                                   ! CHOPFIX
ENDOFFILE 
!