Trailing-Edge
-
PDP-10 Archives
-
AP-4172F-BM
-
3a-sources/lnkxit.mac
There are 38 other files named lnkxit.mac in the archive. Click here to see a list.
TITLE LNKXIT - EXIT MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC 27-Feb-78
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
ENTRY LNKXIT
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM
EXTERN LNKCOR,LNKLOG,LNKFIO
EXTERN .JB41
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==0 ;DEC MINOR VERSION
DECEVR==765 ;DEC EDIT VERSION
VERSION
SEGMENT
;LOCAL ACC DEFINITION
R==R1
SALL
SUBTTL REVISION HISTORY
;START OF VERSION 1A
;50 H ANDLE PAGING DURING LOCAL SYMBOL OUTPUT CORRECTLY
;51 FIX BUG IF UNDEF SYMBOLS BUT DON'T WANT TO KEEP LOCAL SYMS
;53 FIX RETURNS FROM DVMOV. ROUTINE
;54 ADD KIONLY D.P. INST.
;55 STORE VERSION NUMBER (.JBVER) IN .RBVER OF SAVE FILE
;56 FIX LOOP AT JBEX2A IF CORE IMAGE IS MULTIPLE OF 2000
;57 SETUP VESTIGIAL JOB DATA AREA EVEN IF NOT A SAVE FILE
;63 REMOVE MULTIPLY-DEFINED SYMBOLS FROM SYMBOL TABLE (IN CORE)
;65 TENEX SPEEDUPS
;66 SAVE JOB DATA AREA ON /SAVE IF DDT, SYMBOLS AND ALL CODE IN HIGH SEG
;67 PUT ADDITIVE GLOBAL REQUESTS IN UNDEF TABLE
;70 FIX ADDRESS CHECK PROBLEM
;71 MAKE ALL INFO MESSAGES STANDARD FORM
;73 (11314) PREVENT EXECUTION IF UNDEF SYMBOLS
;100 FIX ILL MEM REL ON /SAVE IF LAST BLOCK FILLS ALL OF CORE
;104 OUTPUT FAIL BLOCK HEADER IN LOCAL SYMBOL TABLE
;106 REMOVE HIORG, REPLACE BY LL.S2
;115 MAKE /NOSYMBOLS WORK CORRECTLY
;START OF VERSION 2
;135 ADD OVERLAY FACILITY
;136 FIX VARIOUS BUGS
;140 (12617) FIX ?IO TO UNASSIGNED CHANNEL ON /SYMBOL:TRIPLET FILE
;154 (12991) ONLY LOOK AT RIGHT HALF OF .JBERR TO DELETE EXECUTION
;155 (12988) FIX TEST FOR COBDDT AT RUN UUO TIME
;166 MAKE RADIX50 SYMBOL FILE TYPE 776
;177 FIX ADDRESS CHECK BUG IF PAGING SYMBOLS
;211 FIX ZEROS IN MONITOR SYMBOL TABLE
;213 (12531) LOW SEG OF TWOSEG CORE IMAGE BAD
;221 GET PROTECTION CODE RIGHT ON XPN FILE
;START OF VERSION 2A
;244 DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
;START OF VERSION 2B
;224 PUT SECOND SYMBOL FOR COMMON BLOCK IN RADIX50 SYMBOL TABLE
;226 FIX UNDEFINED SYMBOL BUG (117 NOT SET UP)
;234 FIX VARIOUS BUGS IF HIGH FILE IS MADE RATHER THAN RENAMED
;235 (13845) FIX ZERO COMPRESSOR IF PAGED AND READING ZEROS
;241 USE LARGER OF ABS OR LOW REL BREAK FOR .JBFF
;242 HANDLE USER PAGE FAULT HANDLER CORRECTLY
;244 DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
;247 Change all references to DEBUGSW. Now lh is -1 if set,
; rh is table index for either /DEBUG or /TEST
;266 Correct problems with loading symbols when LS area
; overflows to the DSK.
;267 Get symbol table offest right when core window
; changes.
;270 Use the correct initialization routine when high
; core overflows to the disk during this phase.
;322 Get LSYM and other core management variables right
; so LNKCOR doesn't fail
;324 Don't release the symbol channel if still needed,
; when loading symbols into root of an overlay program.
;330 Release the correct channel when done with symbols
; being loaded into the root of an overlay program.
;335 Keep LSYM from being clobbered when loading symbols
; into root of overlay program. Don't confuse LNKCOR
;336 Fix /RUN switch to work properly
;337 Insert check for no core to zero before BLT and
; prevent possible ILL MEM REF
;353 REMOVE EDIT 225
;357 LABEL EDITS 224,226,234,235,241,242
;360 REMOVE EDIT 336
;401 Remove 5.06 compatability hack setting up vestigial jobdat.
;403 Fix HALT if generating new style symbol file.
;423 Fix ?ILL ADDR IN UUO when the zero compressor tried to use
; the LS area after it had done a CORE UUO to get rid of it.
;433 Support the /RUN switch.
;START OF VERSION 2C
;442 Fix the DVMOV. routine to either RENAME or copy,
; and delete copy routines called if DVMOV. fails.
;443 Don't lose part of local symbols if overflowing to disk.
;467 Correct RT.PT check at SYMO1
;471 Add code for ALGOL debugging system.
;476 Insert missing FTOVERLAY conditional.
;517 Make first word of ALGOL symbol file be 1044,,count.
;524 Check for symseg area reduced to one page & don't zero rest.
;530 Get triplet flag definitions right.
;544 SOUP in LINK version 3 stuff for TOPS-20.
;547 Make LINK assemble with MACRO 51.
;555 Don't round .RBSIZ up to block bound for symbol files.
;557 Clean up the listing for release.
;START OF VERSION 3
;446 CHANGES FOR TENEX
;START OF VERSION 3A
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
;START OF VERSION 4
;570 Don't lose local symbols when undefined globals exist.
;575 On /EXECUTE/SAVE to a two segment program, always run xxx.LOW
;606 Get the protection of .HGH and .XPN files right.
;616 Give appropriate error messages when RENAMEs fail
;621 /SAVE AND /SSAVE GENERATE EXE FILE.
; /SAVE AND /SSAVE NO LONGER TAKES ANY ARGUMENT. IF THE CORE
; SIZE IS SPECIFIED, LINK WILL IGNORE IT.
; THE CODE TO GENERATE .HGH/.SHR/.LOW FILES ARE UNDER THE
; CONDITIONAL ASSEMBLY SWITCH FTEXE==0.
;622 Don't set up vestigal JOBDAT unless there's a high segment.
;641 IF HIGH SEG IS PAGED, WRITE OUT WHAT'S IN CORE BEFORE UPDATING
; VESTIGAL JOBDAT AND DUMP TO EXE FILE.
;642 EXE FILE EXTENSION FOR DISK FILE GENERATED FOR NOT HAVING
; ENOUGH CORE
;643 FIX BUG WITH SWITCH SETTING FOR P4 IN XCMPRL.
;644 DON'T DO JSYS 147(RESET) IF WE DO EXIT.
;645 Loop back topage lc if not more core in LSREQ.
;646 Don't touch a high seg page again after high seg is removed
; in %LOW.
;647 Don't zero unneeded memory (better VM performance).
;650 Use VM on TOPS-10 if available.
;652 Avoid bad .SAV file when paging to disk.
;704 Don't write EXE-directory entries for psect gaps.
;713 Fix bug with sparse EXE-directory.
;715 Modify SYMSEG to take psect name.
;724 Check for symbol table range in INGAP.
;725 Fix bug with incrementing process page in XCMPOV.
;726 Fix bug in INGAP routine.
;727 Give Insufficient space error message when symbol table truncated.
;731 SEARCH MACTEN,UUOSYM instead of C.
;732 Use LOWLOC and fix bugs related to page 777.
;733 Fix bug with allocated high seg pages causing bad EXE format.
;742 Don't BLT JOBDAT if process page 0 not the first page.
;744 Fix bug with calculation of EXE file size.
;754 Don't page LS area when doing symbol table output, if paging is needed for the first time for LC(or HC).
;762 Page in the LOWLOC page before generating EXE file.
;764 Update LOWLOC in GETSST incase symbol table is lower than code.
; Also, corrects a bug in updating upper window in XCMPRS routine.
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
SUBTTL ENTER HERE
LNKXIT: JFCL .+1 ;IN CASE CCL ENTRY
.ERR. (MS,0,V%L,L%I,S%I,EXS,<EXIT segment>)
ZAPTMP ;CLEAR ALL TEMP SPACE
MOVE T1,HC.S0 ;GET ABS BREAK
CAMLE T1,HC.S1 ;LARGER THAN LOW SEG?
MOVEM T1,HC.S1 ;USE LARGER
MOVE T1,HL.S0 ;GET ABS BREAK
CAMLE T1,HL.S1 ;LARGER THAN LOW SEG?
MOVEM T1,HL.S1 ;USE LARGER
IFN FTOVERLAY,<
SKIPGE LNKMAX ;DID WE LOAD ANY OVERLAYS?
JRST LNKX1 ;NO
MOVE T1,PH.OVL ;GET START OF CODE FOR ROOT
USETI OC,(T1) ;POSITION ON THE BLOCK
MOVE P2,PH.LEN ;LENGTH WE NEED
ADD P2,LC.LB
SUB P2,LC.AB ;SEE IF ENOUGH
JUMPLE P2,LNKX0A ;YES
MOVEI P1,LC.IX
PUSHJ P,LNKCOR## ;MUST EXPAND
JRST LNKX0C ;DO IT THE HARD WAY
LNKX0A: MOVE T1,LC.LB
SUBI T1,1
HLL T1,PH.OVL ;SETUP IOWD
SETZ T2,
IN OC,T1 ;READ BACK CORE
LNKX0B: SKIPA T1,OV.S1 ;CORE BOUNDS
PUSHJ P,ER.IOV## ;INPUT ERROR
HRRZM T1,HL.S1 ;
HLRZM T1,HC.S1
JRST LNKX1 ;
;NOW TO READ BACK FIRST FEW BLOCK
LNKX0F: SETZM LW.S1 ;STARTS AT ZERO
MOVE T1,LC.UB
MOVEM T1,LC.AB ;USE IT ALL AGAIN
SUB T1,LC.LB
MOVEM T1,UW.S1 ;UPPER BOUND
PUSHJ P,LC.IN## ;READ IT BACK
JRST LNKX0B ;FIXUP VARIOUS POINTERS
LNKX0C: SETZM LW.S1 ;SET BACK TO START
MOVE T1,PH.OVL
USETI OC,(T1) ;SET ON BLOCK
MOVE T1,LC.UB
MOVEM T1,LC.AB ;USE ALL AVAILABLE SPACE
SUB T1,LC.LB ;GET SIZE OF WINDOW
MOVEM T1,UW.S1 ;UPPER WINDOW
ADDI T1,1
LNKX0D: MOVN T1,T1
HRLZ T1,T1
HRR T1,LC.LB ;IOWD
SUBI T1,1 ;AT LAST
SETZ T2,
IN OC,T1
SKIPA T1,LC.AB
PUSHJ P,ER.IOV##
SUB T1,LC.LB
ADD T1,LW.S1 ;ADD BASE
CAMG T1,PH.LEN ;REACHED END YET?
JRST LNKX0E ;NO
MOVE T1,PH.LEN ;YES, GET WHAT WE REALLY NEED
IORI T1,.IPM
MOVE T2,T1
SUB T2,LW.S1
ADD T2,LC.LB
CAMN T2,LC.UB ;ARE WE IN LAST BLOCK
JRST LNKX0E ;YES, NO CHANGE
MOVEM T2,LC.AB ;RESET UPPER BOUND IN USE
SETZM 1(T2) ;ZERO FIRST WORD
HRLI T2,1(T2)
HRRI T2,2(T2)
BLT T2,@LC.UB ;AND THROUGH REST
LNKX0E: HRL T1,LW.S1 ;ORIGIN
PUSHJ P,LC.OUT## ;WRITE OUT THIS MUCH
MOVE T1,LC.AB ;
SUB T1,LC.LB ;GET SIZE OF WINDOW
MOVE T2,T1
ADD T2,LW.S1
CAML T2,PH.LEN ;MORE TO DO?
JRST LNKX0F ;NO
AOS T2,T1 ;PUT COPY IN T2
ADDM T1,LW.S1 ;NEW WINDOW BASE
ADDB T2,UW.S1 ;GET NEXT UPPER BOUND
CAMG T2,PH.LEN ;DO WE NEED TO READ IT ALL IN?
JRST LNKX0D ;YES
MOVE T1,PH.LEN ;NO, GET HIGHEST WE NEED
ADDI T1,.DBM ;[650] UP TO NEXT BLOCK
ANDCMI T1,.DBM ;[650] INCASE WAS ALREADY THERE
SUB T1,LW.S1 ;NO. OF WORDS
JRST LNKX0D ;TO INPUT
>;END OF IFN FTOVERLAY
LNKX1: MOVEI R,1 ;SETUP TO POINT TO LOW SEG
MOVE R,@SG.TB
IFN FTOVERLAY,<
SKIPL LNKMAX ;IF LOADING OVERLAYS
SETZM USYM ;IGNORE UNDEFINED SYMBOLS TIL RUN TIME
>
MOVEI T1,PATSP. ;IF NOT ALREADY
SKIPN PATSPC ;SETUP PATCHING SIZE
MOVEM T1,PATSPC ;IN CASE REQUIRED
SETZM FRECOR ;NO NEED NOW
SKIPN FS.SS ;THESE ARE THE ONLY FIXUPS WE CAN DO NOW
SKIPE USYM ;BUT MAY HAVE GLOBAL REQUESTS
CAIA
PUSHJ P,FX.ZAP ;NONE, SO GET RID OF AREA
;NOW TEST FOR CASE INWHICH SYMBOL FILE WAS
;OPENED BUT NOT USED (NOT VERY LIKELY)
SKIPE UW.LS ;NEVER OPENED
SKIPE LW.LS ;NEVER USED IF STILL ZERO
JRST CLSMAP ;STILL IN USE, OR NEVER WAS
IFN FTOVERLAY,<
SKIPL LNKMAX ;IF LOADING OVERLAYS
SKIPN UW.LS ; AND PAGING SYMBOLS
CAIA ;NO
JRST CLSMAP ;KEEP FILE OPEN RATHER THAN READ IN
>
SETZM UW.LS ;CLEAR UNWANTED POINTER
MOVEI T1,SC ;SYMBOL FILE CHAN #
PUSHJ P,DVDEL.## ;DELETE FILE AND REMOVE ALL TRACES
JFCL
SETZM IO.PTR+SC ;AND FORGET ABOUT IT
CLSMAP: SKIPN IO.PTR+MC ;AN OPEN MAP?
JRST RDJBDA ;NO
MOVEI T1,MC ;SET CHAN#
MOVEM T1,IO.CHN ;IN ACTIVE STATE
PUSHJ P,DVRLS.## ;CLOSE FILL AND DO POSITIONING
PUSHJ P,DVZAP.## ;RETURN BUFFERS AND DATA BLOCK
RDJBDA: SKIPE PAG.S2 ;HIGH SEG PAGING?
PUSHJ P,RDJBH ;YES, READ IN .JBHDA
SKIPE PAG.S1 ;LOW SEG PAGING?
PUSHJ P,RDJBL ;YES
HRRZ T1,.JBERR ;GET ERRORS FOR THIS PROCESS
ADD T1,USYM ;EACH UNDEF COUNTS ONE
HRRM T1,.JBERR ;WILL STOP EXECUTION IF NON-ZERO
JRST UDF0 ;NOW FOR UNDEFINED SYMBOLS
;HERE TO READ IN FIRST 10 WORDS OF HIGH SEGMENT
RDJBH: MOVEI T2,.JBHDA ;NO OF WORDS WE NEED
PUSHJ P,DY.GET ;GET THEM
MOVEM T1,JBHPTR ;STORE LOCATION
SUBI T1,1 ;IOWD IS 1 LESS
HRLI T1,-10 ;SHOULD BE -.JBHDA BUT MACRO 50 NOT YET OUT
SETZ T2, ;TERMINATE LIST
USETI HC,1 ;SET ON BLOCK 1
IN HC,T1 ;READ FIRST 10 WORDS ONLY
POPJ P, ;OK
PUSH P,[HC]
.ERR. (ST,,V%L,L%F,S%F,IHC)
;HERE IF LOWSEG PAGED, WE NEED BOTH ENDS OF FILE AT ONCE
;THEREFORE PUT JOBDAT (0-137) IN DY AREA, POINTER IS JOBPTR
;AND TOP OF FILE IN LC AREA
RDJBL: MOVEI T2,.JBDA ;NEED ONE BLOCK
PUSHJ P,DY.GET
MOVEM T1,JOBPTR ;HOLD OFFSET IN CORE SO WE CAN FIXUP
; REFERENCES TO JOBDAT SYMBOLS
SKIPN LW.S1 ;HOWEVER IF 1ST PAGE IS IN CORE
JRST BLTJBL ;JUST MOVE IT
SUBI T1,1 ;IOWD IS ONE LESS
HRLI T1,-140 ;WORD COUNT
SETZ T2, ;TERMINATE LIST
USETI LC,1 ;READ BLOCK 1
IN LC,T1 ;AT LEAST FIRST 140 WORDS
POPJ P, ;NONE
PUSH P,[LC]
.ERR. (ST,,V%L,L%F,S%F,ILC)
;HERE TO JUST BLT JOBDAT AREA TO SAFE PLACE
BLTJBL: HRL T1,LC.LB ;FROM HERE
HRRI T2,.JBDA(T1) ;TO HERE
BLT T1,-1(T2) ;WELL ALMOST THERE
POPJ P,
SUBTTL UNDEFINED SYMBOLS
;HERE TO PUT UNDEFINED GLOBALS INTO UNDEF TABLE IN CORE
;THIS IS OLD FORMAT (2 WORD SYMBOLS)
UDF0: SKIPN R,SYMSEG ;LOAD OFFSET TO EITHER LC OR HC
MOVEI R,LC.IX ;ASSUME LOWSEG FOR SYMBOLS
SKIPN NOSYMS ;DON'T WANT UNDEFS IF /NOSYM
SKIPN P2,USYM ;ANY UNDEFINED SYMBOLS?
JRST NOUNDF ;NO, GET RID OF AREA
;BUT DO WE REALLY NEED UNDEFS?
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT POINTER
MOVE T1,LC.LB ;NO
SKIPN .JBDDT(T1) ;JOBDDT NON-ZERO
SKIPE SYMSEG ;OR SYMBOLS REQUESTED
JRST UDF0A ;YES
SKIPE IO.PTR+%SC ;BUT DO WE WANT SYMBOL FILE
SKIPL SYMFRM ; OLD STYLE?
JRST NOUNDF ;NO, GET RID OF THEM
UDF0A: LSH P2,1 ;2 WORDS PER SYMBOL
MOVE P4,PATSPC ;NEED TO LEAVE A HOLE FOR PATCHING
PUSHJ P,GETSST ;[715] GET FINAL SYMBOL START ADDR
SKIPE PAG.S0(R) ;PAGING?
PUSHJ P,LSYP ;YES, GET RIGHT PAGE IN CORE
ADDB P4,P2 ;SPACE WE NEED
ADD P2,TAB.LB(R) ;IN CORE
SUB P2,LW.S0(R) ;REMOVE WINDOW OFFSET
CAMG P2,TAB.AB(R) ;ENOUGH CORE?
JRST UDF1 ;YES,
SUB P2,TAB.AB(R) ;GET EXTRA WE NEED
MOVEI P1,(R) ;FROM WHERE
PUSHJ P,LNKCOR## ;GET IT
PUSHJ P,NO.COR## ;TOTAL FAILURE
SKIPN TAB.PG(R) ;[570] PAGING?
JRST UDF0B ;[570] NO, SKIP THIS
MOVE T1,P4 ;[570] YES, UPDATE UW
IORI T1,.IPM ;[570] SINCE PAGING ROUTINES DON'T
MOVEM T1,TAB.UW(R) ;[570] WHEN MAKING WINDOW BIGGER
UDF0B: PUSHJ P,CHKPAG ;[570] JUST INCASE WE STARTED PAGING
MOVE P2,P4 ;RELATIVE
ADD P2,TAB.LB(R) ;FIX IN CORE
SUB P2,LW.S0(R) ;REMOVE WINDOW OFFSET
UDF1: SKIPGE SYMSEG ;[715] PSECT NAME USED?
JRST .+3 ;[715] YES, JUMP
MOVEM P4,HC.S0(R) ;FOR .JBCOR
;NOW LOOP THROUGH GS AREA LOOKING FOR UNDEFINED SYMBOLS
EXCH P4,HL.S0(R) ;GET BASE OF UNDFS
MOVN T2,USYM ;NUMBER OF UNDEF SYMBOLS
MOVMM T2,JOB117 ;WILL FIX IT LATER, JUST NO. NOW
HRL P4,T2 ;AOBJN POINTER TO UNDEFS
LSH T2,^D18+1 ;PUT 2*COUNT IN LEFT HALF
HRR T2,P4 ;ADDRESS
ADD T2,LL.S0(R) ;+OFFSET
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
MOVEM T2,.JBUSY(T1) ;FIXUP POINTER
ADD P4,TAB.LB(R) ;FIX IN CORE
SUB P4,LW.S0(R) ;REMOVE WINDOW OFFSET
MOVE P2,HT.PRM ;GET HASH SIZE
SKIPE T1,@HT.PTR ;GET POINTER IF NON-ZERO
JRST UDFTRY ;SEE IF A REQUEST
UDFNXT: SOJGE P2,.-2 ;MORE?
JRST UDFDN ;NO
UDFTRY: ADD T1,GS.LB ;ADD IN BASE
MOVE W1,(T1) ;GET FLAGS
TXNN W1,PS.REQ ;GLOBAL REQUEST
JRST UDFNXT ;NO, TRY NEXT SYMBOL
DMOVE W2,1(T1) ;GET SIXBIT SYMBOL & VALUE (REQUEST POINTER)
PUSHJ P,SXBR50 ;CONVERT TO SIXBIT
TXO W2,R5.GLB ;MAKE GLOBAL DEFINITION
ADDI P4,1 ;WILL BUMP LOCATION BY 2 (LATER)
HRRZ T1,P4 ;ADDRESS ONLY
CAMLE T1,TAB.AB(R) ;WILL IT FIT IN WHAT WE HAVE?
PUSHJ P,UDFEXP ;NO, EXPAND AREA
DMOVEM W2,-1(P4) ;STORE NAME & VALUE
TXNE W1,PS.FXP ;ANY ADDITIVE GLOBAL FIXUPS
JRST UDFGB ;YES, RECREATE THE REQUESTS
UDFLUP: AOBJN P4,UDFNXT ;AND COUNT BY 1
UDFDN: ;UNLESS FINISHED
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
MOVE T2,JOB117 ;GET NUMBER OF UNDEFS
LSH T2,1 ;2 WORDS PER SYMBOL
MOVN T2,T2
HRLM T2,.JBUSY(T1) ;FIXUP POINTER
MOVE T2,.JBUSY(T1) ;GET A COPY
MOVEM T2,JOB117 ;FOR LATER
JRST GSDLT ;DELETE GLOBAL SYMBOL TABLE
UDFGB0: TXNE W1,S.LST ;IS THIS THE LAST BLOCK
JRST UDFLUP ;YES
ADDI T1,.L ;NO, GET NEXT TRIPLET
UDFGB: HRRZ T1,@HT.PTR ;GET POINTER AGAIN
ADD T1,GS.LB ;ADD IN BASE
SKIPG W1,.L(T1) ;GET NEXT FLAG WORD
JRST UDFERR ;MUST HAVE SIGN BIT ON
TXNN W1,S.FXP ;AND A FIXUP
JRST UDFGB0 ;NOT YET
MOVE W3,.L+2(T1) ;GET VALUE
MOVE T1,W3
UDFGB1: ADD T1,FX.LB ;RELOCATE IN FIXUP TABLE
SKIPL W1,0(T1) ;GET FLAGS
JRST UDFERR ;JUST INCASE
TXNN W1,FP.SYM ;ADDITIVE GLOBAL FIXUP?
JRST UDFGB2 ;NO
DMOVE W2,1(T1) ;GET DATA WORDS
TXNE W1,FS.FXS ;SYMBOL FIXUP?
JRST UDFGB2 ;*** DON'T KNOW HOW TO DO IT YET ***
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
TXO W2,R5.GLB ;MAKE INTO A GLOBAL DEFINITION
TXO W3,R5.FXA ;AND TURN ON ADDITIVE BIT
TXNE W1,FS.FXL ;LEFT HALF?
TXO W3,R5.FXL ;YES
ADDI P4,2 ;USES 2 WORDS
HRRZ T1,P4 ;ADDRESS ONLY
CAMLE T1,TAB.AB(R) ;WILL IT FIT
PUSHJ P,UDFEXP ;NO
DMOVEM W2,-1(P4) ;STORE
AOS JOB117 ;COUNT 1 MORE WORD PAIR
SKIPGE SYMSEG ;[715]
JRST UDFGB2 ;[715] JUMP IF PSECT SPCIFIED
MOVEI T1,2 ;AND INCLUDE IN SPACE ASSIGNED
ADDM T1,HL.S0(R) ;SINCE WE DIDN'T ACCOUNT FOR IT EARLIER
;FALL THROUGH TO NEXT PAGE
; JRST UDFGB2
;FALL IN FROM PREVIOUS PAGE
UDFGB2: HRRZ T1,W1 ;GET POINTER
JUMPE T1,UDFLUP ;ALL DONE IF ZERO
JRST UDFGB1 ;GET NEXT BLOCK
UDFEXP: PUSH P,P2 ;SAVE P2 BEFORE EXPANDING CORE
MOVEI P1,(R)
MOVEI P2,2 ;AT LEAST 2 WORDS EXTRA
SUB P4,TAB.LB(R) ;REMOVE BASE INCASE WE MOVE
ADD P4,LW.S0(R) ;INCASE PAGES CHANGE
PUSHJ P,LNKCOR##
PUSHJ P,NO.COR## ;FAILED
SKIPN TAB.PG(R) ;[570] PAGING THIS AREA?
JRST UDFEX1 ;[570] NO, FORGET IT
MOVE T1,P4 ;[570] YES, MUST UPDATE UW OURSELVES
IORI T1,.IPM ;[570] ONLY EXPANDED TO THIS PAGE
MOVEM T1,TAB.UW(R) ;[570] UPDATE THE WORD
UDFEX1: PUSHJ P,CHKPAG ;[570] INCASE WE STARTED PAGING
SUB P4,LW.S0(R) ;BACK AS IT WAS
ADD P4,TAB.LB(R)
POP P,P2 ;RESTORE P2 TO BEFORE UDFEXP
POPJ P,
UDFERR: JRST UDFLUP ;SYMBOL TABLE FOULED UP
;HERE TO GET RID OF GLOBAL TABLE AND IF POSSIBLE CUT BACK CORE
NOUNDF: SETZM USYM ;MAKE SURE ITS CLEAR
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;BASE OF LOW SEG
SETZM .JBUSY(T1) ;CLEAR UNDF POINTER
GSDLT: SKIPN .JBDDT(T1) ;SEE IF WE NEED LOCAL SYMBOLS
SKIPE SYMSEG ;EITHER FOR /DEB OR /SYMSEG
JRST GSNRED ;YES, DON'T CUT BACK CORE YET
MOVEI T1,GS.IX-1 ;START AT AREA JUST LOWER
SKIPN TAB.LB(T1) ;FIND HIGHEST AREA IN USE
SOJA T1,.-1 ;WILL GET THERE EVENTUALLY
MOVE T2,TAB.AB(T1) ;GET HIGHEST LOC IN USE IN IT
IORI T2,1777 ;K BOUND
ADDI T2,2000 ;EXTRA K FOR SAFETY
CAML T2,.JBREL ;ANYTHING TO GIVE BACK?
JRST GSNRED ;NO, REDUCED ALREADY
CORE T2, ;DELETE TOP PART
JRST GSNRED ;NEVER CAN HAPPEN
MOVE T2,.JBREL ;GET NEW TOP
MOVEM T2,GS.AB ;RESET TABLE
MOVEM T2,GS.UB
CAMLE T2,GS.LB ;INCASE WE REDUCED IT ALL
JRST GSRED ;NO, ALL IS WELL
MOVEM T2,TAB.UB(T1) ;RESET HIGHEST FREE LOC AGAIN
SETZM GS.LB ;SO XX.ZAP CAN WORK
GSRED: .ERR. (MS,.EC,V%L,L%I,S%I,RED,<Reducing low segment to >)
.ETC. (COR,.EP,,,,.JBREL)
GSNRED: PUSHJ P,GS.ZAP ;GET RID OF GS
JRST LSY0 ;[715] GO DO LOCAL SYMBOLS
;HERE TO SETUP THE SPECIFIED PSECT FOR SYMBOL TABLE
GETSST: PUSH P,T1 ;[727]
SKIPL SYMSEG ;[715] A PSECT WAS SPECIFIED?
JRST [SKIPGE T1,SYMLIM ;[727] HAVE A DEFAULT LIMIT?
HRRZM T1,SYMLIM ;[727] YES, MAKE IT THE LIMIT
SKIPN HL.S0(R) ;[715] NO, NULL SEGMENT?
ADD P4,[EXP .JBDA,.JBHDA]-1(R) ;[715] SAVE JOBDAT
ADDB P4,HL.S0(R) ;[715] HIGHEST LOADED FOR SEG
POP P,T1 ;[727] RESTORE T1
POPJ P,] ;[715] RETURN FROM HERE IF HIGH/LOW
SETZ R, ;[727] YES, HAVE PSECT NAME
GETS1: MOVE T1,@RC.TB ;[715]
MOVE T2,RC.NM(T1) ;[715] GET PSECT NAME
CAMN T2,SSGNAM ;[715] IS THIS THE ONE?
JRST GETS2 ;[715] YES,
ADDI R,1 ;[715] NEXT ONE
CAMG R,RC.NO ;[715] ANY MORE?
JRST GETS1 ;[715] YES, LOOP
.ERR. (MS,,V%M,L%W,S%W,NPS,<NON-EXISTENT PSECT SPECIFIED>)
SETZM SSGNAM ;[715]
MOVEI R,1 ;[715] SET TO LOW
MOVEM SYMSEG ;[715]
POP P,T1 ;[715] RESTORE AC'S
JRST GETSST+1 ;[715] AND LOOP BACK
GETS2: MOVE T2,RC.CV(T1) ;[715] GET HIGHEST LOCATION
ADDB P4,T2 ;[715] GET SYMBOL START ADDR
CAMLE P4,HL.S1 ;[715] GREATER THAN HIGHT LOCATION?
MOVEM P4,HL.S1 ;[715] UPDATE IT IN THAT CASE
SKIPLE SYMLIM ;[727] DO WE HAVE A LIMIT
JRST GETS3 ;[715] FROM THE LAST CALL TO HERE
GETS4: ADDI R,1 ;[715] NEXT PSECT
CAMG R,RC.NO ;[715] SKIP IF NO MORE
JRST [MOVE T1,@RC.TB ;[715] THERE IS ONE
MOVE T2,RC.IV(T1) ;[715] GET ITS ORIGIN
SUBI T2,1 ;[727] ONE LESS
MOVEM T2,SYMLIM ;[715] MAKE IT THE SYMBOL LIMIT
JRST GETS3] ;[715]
SETOM SYMLIM ;[715] NO LIMIT AND BEEN HERE BEFORE
GETS3: MOVE T1,P4 ;[764] GET START OF THE SYMBOL TABLE
TRZ T1,777 ;[764] ROUND DOWN TO PAGE BOUND
CAMGE T1,LOWLOC ;[764] LOWER THAN ANY CODE?
MOVEM T1,LOWLOC ;[764] YES, UPDATE LOWEST LOCATION
MOVEI R,1 ;[715] UPDATE SEGMENT#
POP P,T1 ;[715] RESTORE AC'S
POPJ P, ;[715]
SUBTTL LOCAL SYMBOLS
;IF LOCAL SYMBOLS AREA REQUIRED IN CORE STORE THEM ON TOP
; OF LOW SEG OR HIGH SEG CODE
;IF LOWSEG LEAVE A GAP (PATSPC) FOR MORE SYMBOLS OR PATCHING
; IF HIGH PUT AGAINST PAGE BOUND (0.5K)
;
;IF LOCAL SYMBOLS NOT REQUIRED JUST FLUSH SPACE
;IF SYMBOLS ON DSK READ BACK IN FIRST
LSY0: SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;LOAD UP OFFSET
SKIPN T2,VERNUM ;GET VERSION# SET BY SWITCH
SKIPA T2,.JBVER(T1) ;GET VERSION FROM LOC .JBVER
MOVEM T2,.JBVER(T1) ;STORE BACK IN CORE IMAGE
MOVEM T2,VERNUM ;SAVE FOR .RBVER OF FILES
SKIPE NOSYMS ;NOT IF /NOSYMS
JRST LSY00
SKIPN .JBDDT(T1) ;IF DDT WE NEED LOCALS
SKIPE SYMSEG ;OR IF USER SPECIFIED WHERE TO PUT THEM
JRST LSREQ ;YES,
LSY00: SETZM .JBSYM(T1) ;CLEAR POINTER
SKIPE IO.PTR+%SC ;HOWEVER IF WE WANT OLD SYMBOL FILE
SKIPL SYMFRM ;WE STILL NEED TO CONVERT SYMBOLS
JRST NOLOCS ;NO, DONT BOTHER
;HERE IF /SYMSEG, /SYFILE:RADIX50, OR C(.JBDDT) <> 0.
;CONVERT THE SYMBOLS IN THE LS AREA TO RADIX50 AND PUT THEM IN CORE.
LSREQ:
IFN FTOVERLAY,<
SKIPL LNKMAX ;DID WE SEE ANY OVERLAYS?
JRST LSOVS ;YES, SPECIAL
>
.ERR. (MS,0,V%L,L%I,S%I,SST,<Sorting symbol table>)
PUSHJ P,SYMINI ;DO THE MAGIC TO MOVE SYMBOLS UP IN CORE
LSREQ1: PUSHJ P,CHKPAG ;[645] INCASE PAGE FOR THE FIRST TIME
SKIPE USYM ;IF NO UNDEFINED SYMBOLS
TDZA P4,P4 ;YES, DONE ALREADY
MOVE P4,PATSPC ;NEED TO LEAVE A HOLE FOR PATCHING
PUSHJ P,GETSST ;[715] GET FINAL SYMBOL START ADDR
MOVE P2,P4 ;COPY INCASE NOT ENOUGH
SKIPE PAG.S0(R) ;PAGING THIS AREA?
SKIPE USYM ;YES, BUT ALREADY SETUP IF UNDEFS
CAIA ;DON'T HAVE TO WORRY
PUSHJ P,LSYP ;YES, GET RIGHT PAGES IN CORE
SUB P2,LW.S0(R) ;REMOVE PAGED BASE
ADD P2,TAB.LB(R) ;IN CORE
CAMG P2,TAB.AB(R) ;ENOUGH CORE?
JRST LSY1 ;YES,
SUB P2,TAB.AB(R) ;GET EXTRA WE NEED
MOVEI P1,(R) ;FROM WHERE
SETOM LS.PP ;[754] PROHIBIT PAGING OF SYMBOLS
PUSHJ P,LNKCOR## ;GET IT
JRST LSREQ1 ;[645] NO CORE, LOOP BACK AND PAGE
SKIPN TAB.PG(R) ;[570] PAGING?
JRST LSREQ0 ;[570] NO, FORGET IT
MOVE T1,P4 ;[570] YES, UPDATE UW
IORI T1,.IPM ;[570] FROM MAX VIRT ADDR, IN P4
MOVEM T1,TAB.UW(R) ;[570]
LSREQ0: MOVE P2,P4 ;[570] RELATIVE
SUB P2,LW.S0(R) ;REMOVE PAGED BASE
ADD P2,TAB.LB(R) ;FIX IN CORE
LSY1: SETZM LS.PP ;[754]
SKIPGE SYMSEG ;[715]
JRST .+3 ;[715] JUMP IF PSECT SPCIFIED
MOVEM P4,HC.S0(R) ;FOR .JBCOR
EXCH P4,HL.S0(R) ;GET BASE OF UNDFS
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
ADD P4,LL.S0(R) ;PLUS STARTING OFFSET
HRRZM P4,.JBSYM(T1) ;FIXUP POINTER (ADDRESS ONLY)
HRRZM P4,JOB116 ;AND FOR .SYM FILE
MOVEI T1,.IPS ;SIZE WE CARE ABOUT
SUB T1,LS.FR ;MINUS FREE
MOVEM T1,LSCNT ;LEFT IN THIS BLOCK
SKIPGE SYMSEG ;[715] PSECT NAME USED?
SKIPA T1,P4 ;[715] YES, USED P4 INSTEAD
MOVE T1,HL.S0(R) ;SETUP CORE POINTER
MOVEI T2,2(T1) ;REL ADDRESS OF "TITLE" FOR PAT..
MOVEM T2,TTLPTR
SUB T1,LW.S0(R) ;REMOVED PAGED BASE
ADD T1,TAB.LB(R) ;ADD FIXED BASE
MOVEM T1,TAB.PT(R) ;ABS POINTER TO NEXT FREE LOC
;NOW OUTPUT THE SYMBOL PAT.. IN MODULE PAT.. AS THE LAST SYMBOL
MOVE W2,[RADIX50 04,PAT..] ;BE COMPATIBLE (ALMOST)
SKIPGE SYMSEG ;[715] PSECT NAME USED?
SKIPA W3,P4 ;[715] YES, USE P4 INSTEAD
HRRZ W3,HL.S0(R) ;VALUE
SUB W3,PATSPC ;POINT TO BOTTOM OF AREA
HLRE T1,JOB117 ;BUT TAKE INTO ACCOUNT UNDEFINED SYMBOLS
ADD W3,T1 ;WHICH ARE BETWEEN PAT.. AND .JBSYM
ADD W3,LL.S0(R) ;ADD IN OFFSET TO SEGMENT
PUSHJ P,SYMOUT ;LAST SYMBOL
JRST SYDONE ;[715] EXCEEDED SPACE, ALL DONE
TLZ W2,740000 ;MAKE RADIX50 0,PAT.. BE THE TITLE
PUSHJ P,SYMOUT
SKIPA ;[715] EXCEEDED SPACE, ALL DONE
PUSHJ P,LSLOOP ;READ ALL OF SYMBOLS
JRST SYDONE ;ALL DONE
IFN FTOVERLAY,<
LSOVX:: MOVEM T1,LSCNT ;STORE WORDS LEFT IN THIS BLOCK
SETZM TTLPTR ;START AFRESH
POPJ P,
LSOVS: HLRE T2,PH.RDX ;GET - NO. OF SYMBOLS
MOVM T3,T2 ;+
ADD T3,HL.S1 ;HIGHEST LOCATION
ADD T3,SPACE ;PLUS BUFFER SPACE
ADD T3,PATSPC ;AND PATCHING SPACE
IOR. T3,.PGSIZ ;UP TO PAGE BOUND
ADDI T3,1 ;NEXT FREE
ADD T3,T2 ;START OF SYMBOLS
HLL T3,PH.RDX ;- COUNT
MOVEM T3,JOB116
MOVEM T3,.JBSYM(T1) ;STORE SYMBOL TABLE PTR
JRST NOLOCS ;BUT DON'T READ IN
>
;HERE TO SETUP CORRECT LC/HC PAGES
;WRITE OUT ALL OF CURRENT (UPTO START OF LAST LOC IN USE)
;ALLOCATE INITIALLY 1 BLOCK (IT WILL EXPAND AS REQUIRED)
LSYP: HRLZ T1,LW.S0(R) ;BASE
HRR T1,UW.S0(R) ;UPPER LIMIT
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;GO TO CORRECT ROUTINE
SKIPGE SYMSEG ;[715] PSECT SPECIFIED?
SKIPA T2,P4 ;[715] YES,
HRRZ T2,HL.S0(R) ;THIS IS THE LOCATION WE REQUIRE
ANDCMI T2,.IPM ;WILL BE LOWER PAGE BOUND
MOVEM T2,LW.S0(R) ;STORE IT NOW
IORI T2,.IPM ;THENCE UPPER BOUND
EXCH T2,UW.S0(R) ;SWAP WITH CURRENT
CAME T2,UW.S0(R) ;IF IDENTICAL
JRST [MOVE T1,UW.S0(R) ;GET UPPER LIMIT
HRLI T1,-.IPM(T1) ;GET LOWER LIMIT FOR THIS BLOCK
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;READ IN TOP BLOCK
JRST LSYP1] ;AND CONTINUE
HRLZ T2,TAB.AB(R) ;WE MUST BLT DOWN THE LAST BLOCK
TLZ T2,.IPM ;AS IT MAY CONTAIN DATA
HRR T2,TAB.LB(R)
MOVEI T1,.IPS(T2) ;BASE OF FREE
BLT T2,-1(T1) ;MOVE IT
LSYP1: HRRZ T1,TAB.LB(R) ;LOWEST LOC IN CORE
ADDI T1,.IPS ;FIRST BLOCK NOW CONTAINS DATA
CAML T1,TAB.AB(R) ;AREA ONLY ONE PAGE LONG?
JRST LSYP2 ;YES, DON'T ZERO NEXT AREA
HRL T1,T1
SETZM (T1) ;ZERO IT
ADDI T1,1 ;FORM BLT PTR
BLT T1,@TAB.AB(R) ;CLEAR ALL OF THIS CORE
;NOW GIVE REST TO NEXT LOWER AREA
LSYP2: MOVE T1,TAB.LB(R) ;GET BASE
IORI T1,.IPM ;MAKE IT ONE BLOCK LONG
MOVEM T1,TAB.AB(R) ;SO WE CAN CORRECTLY COUNT
MOVEI T1,-1(R) ;GET INDEX TO NEXT AREA
SKIPN TAB.LB(T1) ;FIND ONE SETUP (MUST BE)
SOJA T1,.-1 ;SHOULD NEVER GET HERE ANYWAY
MOVE T2,TAB.AB(T1) ;GET HIGHEST IN USE
ADDI T2,1 ;POINT TO NEXT FREE
CAML T2,TAB.LB(R) ;ALREADY HERE?
POPJ P, ;YES, NOTHING WE CAN DO ABOUT IT
SUBI T2,1 ;UPPER LIMIT AGAIN
MOVEM T2,TAB.UB(T1) ;RESET IT FOR LOWER AREA
HRRZI T1,1(T2) ;NEXT FREE WHERE BLOCK WILL GOTO
HRL T1,TAB.LB(R) ;FROM WHERE IN LEFT
HRRZM T1,TAB.LB(R) ;NOW RESET IT
MOVE T2,T1 ;GET A COPY
BLT T1,.IPM(T2) ;THIS BLOCK DOWN
MOVS T2,T2 ;PUT FROM ADDR. IN RIGHT
HRLI T1,(T2) ;NOW FOR ZERO BLT
HRRI T1,1(T2)
SETZM (T2)
TLO T2,.IPM ;STILL HAVE TO SET TOP INUSE
HLRZM T2,TAB.AB(R) ;FOR 1 BLOCK
BLT T1,.IPM(T2) ;THROUGH THIS BLOCK
POPJ P,
LSLOOP::PUSHJ P,GETSYM ;GET SYMBOL IN W1,W2,W3
POPJ P, ;ALL DONE
JUMPGE W1,LSLOOP ;IGNORE ALL EXTENDED BLOCK
TXNE W1,PT.TTL ;SPECIAL IF TITLE BLOCK
JRST LTITLE ;NEED TO KEEP POINTERS ETC
TXNE W1,PT.SYM ;ONLY WANT REAL SYMBOLS
TXNE W1,PS.MDF ;BUT NOT MULTIPLE DEFINITION
JRST LSLOOP ;MUST BE SOME THING ELSE
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
TXNE W1,PS.GLB ;GLOBAL?
TXO W2,R5.GLB ;YES
TXNE W1,PS.COM ;COMMON?
JRST LSLUPC ;YES, NEEDS TWO SYMBOLS
TXNE W1,PS.LCL ;THEN LOCAL?
TXO W2,R5.LCL ;YES
TXNE W1,PS.DDT ;NO DDT OUTPUT?
TXO W2,R5.DDT ;YES SET BIT
LSLUP1: PUSHJ P,SYMOUT ;PUT SYMBOL IN CORE
POPJ P, ;[715] EXCEEDED SPACE, RETURN
SKIPGE LSCNT ;DO WE HAVE SOMETHING TO GIVE BACK?
PUSHJ P,RDUSYM ;YES, SAFE TO DO SO NOW
JRST LSLOOP ;AND BACK FOR MORE
LSLUPC: PUSHJ P,SYMOUT ;OUTPUT IT
POPJ P, ;[715] EXCEEDED SPACE, RETURN
PUSH P,W3 ;SAVE ADDRESS
MOVX T1,S.COM ;PART WE WANT
PUSHJ P,GETAST ;GET REST OF SYMBOL
JRST [POP P,W3 ;TOO BAD
JRST LSLOOP] ;JUST IGNORE
PUSHJ P,SXBR50 ;IN RADIX50
TXO W2,R5.DDT!R5.GLB ;CODE 44
POP P,T1 ;GET ADDRESS
HRL T1,W3 ;LENGTH ,, ADDRESS
MOVE W3,T1 ;...
JRST LSLUP1 ;OUTPUT IT
;HERE TO GET NEXT SYMBOL BLOCK
;CALLED BY
; PUSHJ P,GETSYM
;RETURNS
;W1, W2, W3 WITH SYMBOL INFO
;USES T1
;READS SYMBOL TABLE IN REVERSE ORDER
GTSYM1: PUSHJ P,PAGSYM ;SEE IF PAGING
POPJ P, ;NO, ALL DONE
;FALL INTO GETSYM
GETSYM: MOVNI T1,3 ;BACKUP POINTET TO
ADD T1,LS.PT ;GET NEXT TRIPLET
CAMGE T1,LS.LB ;DON'T GO TOO FAR
JRST GTSYM1 ;SEE IF PAGING
MOVEM T1,LS.PT ;SAFE TO STORE NOW
TMOVE W1,0(T1) ;FLAGS, SYMBOL, VALUE
MOVNI T1,3
ADDB T1,LSCNT ;REDUCE COUNT IN THIS BLOCK
JRST CPOPJ1 ;SKIP RETURN
;HERE TO GIVE BACK TOP BLOCK OF SYMBOLS
;CAN ONLY BE DONE IF WE HAVE FINISHED WITH CURRENT SYMBOL
;AND ITS SECONDARY TRIPLETS
;SPECIFICALLY TITLE SECONDARIES MUST NOT BE DELETED UNTIL
;TITLE IS OUTPUT
RDUSYM: MOVE T1,LS.PT ;GET LOWEST ADDRESS WE STILL NEED
IORI T1,.IPM ;FORM BLOCK BOUND
MOVE T2,LS.AB ;PREV TOP
SUBI T2,(T1) ;LENGTH
JUMPE T2,CPOPJ ;JUST IN CASE
HRLZ T3,T1 ;FORM BLT PTP
HRRI T3,1(T1)
SETZM (T1) ;CLEAR FIRST WORD
EXCH T1,LS.AB ;SET IT SO
BLT T3,(T1)
MOVEI T1,.IPS ;RESET COUNT
ADDM T2,LSCNT ;RESET WORD COUNT
MOVN T2,T2 ;NEGATE IT
SKIPE UW.LS ;LEAVE ALONE IF NOT PAGING
ADDM T2,UW.LS ;ADJUST UPPER WINDOW
POPJ P,
;HERE TO READ MORE SYMBOLS IF THEY ARE ON DSK
PAGSYM: SKIPE UW.LS ;NEVER WERE
SKIPN LW.LS ;WERE BUT ALL DONE
POPJ P, ;IN EITHER CASE JUST RETURN CPOPJ
SKIPE T1,FX.LB ;ANY FIXUPS LEFT
SOJA T1,.+2 ;YES, BETTER LEAVE AREA WHERE IT IS
MOVE T1,.JBREL ;MOVE LAST BLOCK TO A SAFE PLACE
MOVE T2,T1 ;GET A COPY FOR END OF BLT
ANDCMI T1,.IPM ;AT TOP OF CORE
CAMG T1,LS.LB ;SAME AREA BLT FROM/TO?
JRST PAGSY2 ;YES, DON'T CLEAR IT!
MOVEI T3,-1(T1) ;END OF VACATED AREA
CAMLE T3,LS.AB ;CLEAR ALL OF IT?
MOVE T3,LS.AB ;NO, JUST PART NOT DONE
HRL T1,LS.LB ;SO WE HAVE THE HOLE IN THE MIDDLE
BLT T1,(T2) ;GO
HRRZ T1,LS.LB ;NOW TO ZERO THE JUNK WE LEFT BEHIND
SETZM (T1) ;FIRST WORD
HRL T1,T1
ADDI T1,1 ;BLT PTR
BLT T1,(T3) ;CLEAR 200 WORDS (USUALLY)
PAGSY2: MOVE T1,T2 ;
MOVEM T1,LS.UB ;ABSOLUTE NEW TOP
MOVEM T1,LS.AB ;NO FREE SPACE (AB SAME)
SUB T1,LS.LB ;+DIFF (TOTAL AREA - 1)
ANDCMI T1,.IPM ;DON'T COUNT PART IN USE
ADDM T1,LS.LB ;FIXUP PTRS
ADDM T1,LS.PT
MOVEI T1,LS.IX ;ACCOUNT FOR NEW FREE SPACE
PUSHJ P,ADJ.L ;BY GIVING IT TO NEXT LOWER AREA
;NOW CHECK TO SEE IF AREA IS BIG ENOUGH
PAGSY1: PUSHJ P,FR.CNT## ;SEE WHATS FREE
LSH T1,-1 ;CUT IN HALF
ANDCMI T1,.IPM ;BUT KEEP ON A BLOCK BOUND
JUMPE T1,[MOVEI T1,(R) ;AREA
MOVEI T2,2*.IPS ;SIZE
PUSHJ P,EXPSYM ;INCREASE SYMBOL SIZE
MOVNI T1,2*.IPS ;NOW GIVE BACK SPACE
ADDM T1,TAB.AB(R)
JRST PAGSY1] ;AND TRY AGAIN
CAMLE T1,LW.LS ;DO WE NEED ALL OF THIS SPACE
MOVE T1,LW.LS ;NO, JUST USE ENOUGH
MOVN T1,T1 ;-INCREASE IN SIZE
ADDM T1,LS.LB ;ADJUST LOWER BOUND
MOVEI T2,LS.IX-1 ;NOW TO FIND NEXT LOWER BOUND
SKIPN TAB.LB(T2) ;IN USE
SOJA T2,.-1
MOVE T3,TAB.AB(T2) ;GET UPPER BOUND OF NEXT LOWER
CAML T3,LS.LB ;IS THERE ENOUGH ROOM?
AOJA T3,[SPUSH <P1,P2> ;SAVE
MOVEI P1,LS.IX ;AREA TO EXPAND
MOVM P2,T1 ; AND SIZE
ADDM P2,LS.LB ;ADD BACK
PUSHJ P,LNKCOR## ;GET THE SPACE
PJRST NO.COR## ;SHOULD NEVER OCCUR
SPOP <P2,P1> ;RESTORE
PJRST PAGSYM] ;GO GET SYMBOLS
MOVE T3,LS.LB ;BOTTOM OF THIS AREA
SUBI T3,1 ;-1 IS TOP OF NEXT
MOVEM T3,TAB.UB(T2) ;TAKE IT ALL (SHUFFLER WILL GET US OUT OF TROUBLE)
ADDM T1,LW.LS ;BACKUP WINDOW
HRLZ T1,LW.LS ;FORM INPUT PTR
HRR T1,UW.LS ;LOWER ,, UPPER
PUSHJ P,LS.IN## ;INPUT AREA
JRST CPOPJ1 ;SKIP RETURN
;HERE TO GET ASSOCIATED SECONDARY TRIPLET
;CALLED BY
; MOVE T1,FLAGS
; PUSHJ P,GETAST
;RETURNS
;+1 FAILED
;+2 SUCCESS
;USES T1, T2, T3
;SETS UP W1, W2, W3
GETAST: MOVE T2,LS.PT ;GET POINTER
GETNAS: ADDI T2,.L ;ENTER HERE WITH T2 SETUP
CAMLE T2,LS.AB ;STILL IN CORE?
JRST FNDNIC ;NOT IN CORE
SKIPGE T3,(T2) ;GET FLAGS
POPJ P, ;FOUND A PRIMARY (FAILED)
XOR T3,T1 ;IFF ALL BITS MATCH
TXZ T3,S.LST ;IGNORE THIS BIT HOWEVER
JUMPN T3,GETNAS ;TRY AGAIN
TMOVE W1,(T2) ;FLAGS, SYMBOL, VALUE
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
FNDNIC: SKIPN UW.LS
POPJ P, ;ALL DONE
.ERR. (MS,.EC,V%L,L%F,S%F,CNW)
.ETC. (STR,,,,,,<FNDNIC>)
SYMOUT: AOS T1,TAB.PT(R) ;SEE IF ENOUGH TO STORE 2 WORDS
SKIPG T2,SYMLIM ;[715] IS IT LIMITED BY NEXT PSECT?
JRST SYMO4 ;[715] NO,
PUSH P,T1 ;[715] YES, SAV T1
SUB T1,LC.LB ;[715] MINUS WINDOW
ADD T1,LW.LC ;[715] CONVERT TO VIRTUAL ADDR
CAMGE T1,SYMLIM ;[715] EXCEEDED THE LIMIT
JRST [POP P,T1 ;[715] RESTURE T1
JRST SYMO4] ;[715] AND RETURN
SKIPN SSGNAM ;[727] HAVE A NAME TO OUTPUT?
JRST SYMOE1 ;[727] NO, JUMP OVER OUTPUTTING NAME
.ERR. (MS,.EC,V%L,L%W,S%W,ISS,<Insufficient space for symbol table>)
.ETC. (STR,.EC,,,,,< after PSECT >)
.ETC. (SBX,.EP!.EC,,,,SSGNAM)
.ETC. (STR,,,,,,<--Table truncated>)
JRST SYMOE2 ;[727]
SYMOE1: .ERR. (MS,.EC,V%L,L%W,S%W,ISS)
.ETC. (STR,,,,,,<--table truncated>)
SYMOE2: SOS TAB.PT(R) ;[727] DECREMENT ONE
POP P,T1 ;[715]
POPJ P, ;[715] ERROR RETURN
SYMO4: CAMG T1,TAB.AB(R)
JRST SYMO1 ;YES
;SEE IF WE CAN JUST EXPAND
CAML T1,TAB.UB(R) ;INTO FREE SPACE?
JRST SYMO2 ;NO, EXPAND OR WRITE PAGE OUT
MOVEI T2,.IPS ;PAGE SIZE
ADDM T2,TAB.AB(R) ;ACCOUNT FOR IT
SKIPE UW.S0(R) ;IF PAGING THIS SEGMENT
ADDM T2,UW.S0(R) ;INCREASE WINDOW
;FALL INTO SYMO1
SYMO1: AOS T1,TAB.PT(R) ;POINT TO NEXT FREE
DMOVEM W2,-2(T1) ;STORE SYMBOL & VALUE
IFN FTOVERLAY,<
SKIPE T1,RT.PT ;RELOCATABLE?
CAMN T1,RT.LB ;MAYBE, IS IT?
JRST CPOPJ1 ;[715] NO, SKIP RETURN
IBP RT.PT ;SYMBOL IS NOT
TXNN W1,PS.REL ;IS IT RELOCATABLE?
TDZA T1,T1 ;NO
MOVEI T1,1 ;YES
IDPB T1,RT.PT ;SET BIT
>
JRST CPOPJ1 ;[715] SKIP RETURN
POPJ P,
;HERE WHEN NOT ENOUGH ROOM
SYMO2: SKIPE PAG.S0(R) ;PAGING?
JRST SYMO3 ;YES, NOT WORTH EXPANDING, JUST OUTPUT IT
MOVE T1,R ;EITHER LC.IX OR HC.IX
MOVEI T2,.IPS ;EXPAND THIS MUCH
PUSHJ P,EXPSYM ;GET SPACE
JRST SYMO1 ;AND STORE
;SUBROUTINE TO EXPAND CORE, BUT NOT TO PAGE SYMBOLS
;USUALLY CALLED TO CAUSE OTHER AREA TO START PAGING
;CALLED BY
; MOVEI T1,AREA
; MOVEI T2,SIZE
; PUSHJ P,EXPSYM
EXPSYM: PUSHJ P,.SAVE2## ;USES P1, P2
SETOM LS.PP ;PROHIBIT PAGING OF SYMBOLS
DMOVE P1,T1 ;GET ARGS
PUSHJ P,LNKCOR## ;MUST BE ABLE TO GET IT
JRST NO.COR## ;SHOULD NEVER HAPPEN
;HERE TO SEE IF WE JUST STARTED PAGING AND IF SO, COPY
;JOBDAT OR VESTIGAL JOBDAT INTO DY AREA, SO WE CAN ALWAYS
;REFERENCE THEM EVEN IF THEY ARE PAGED OUT.
CHKPAG: SKIPE PAG.S1 ;IF WE ARE PAGING
SKIPE JOBPTR ;FOR FIRST TIME
CAIA ;NO
PUSHJ P,RDJBL ;MUST SETUP JOB DATA AREA
SKIPE PAG.S2 ;SAME FOR HIGH SEG
SKIPE JBHPTR
CAIA
PUSHJ P,RDJBH ;SET UP JOBDAT IN HIGH
SETZM LS.PP ;BACK AS BEFORE
POPJ P,
;HERE WHEN WE HAVE TO OUTPUT CORE
;THERE IS NO NEED TO KEEP ANY OF IT SO OUTPUT IT ALL
SYMO3: AOS T1,TAB.PT(R) ;POINT TO NEXT FREE
TRNE T1,1 ;SEE IF 1 FREE LOC
MOVEM W2,-2(T1) ;YES, OUTPUT HALF OF SYMBOL
HRLZ T1,LW.S0(R) ;OUTPUT ALL OF WINDOW
HRR T1,UW.S0(R)
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;GO TO CORRECT ROUTINE
SKIPGE SYMFRM ;NEED OLD SYMBOLS (RADIX50)
PUSHJ P,OLDSYM ;YES
HRRZ T1,TAB.LB(R) ;NOW TO CLEAR JUNK
HRLI T1,(T1)
ADDI T1,1 ;LOW,,LOW+1
SETZM -1(T1)
BLT T1,@TAB.AB(R) ;TO HIGH
MOVE T1,UW.S0(R) ;PREVIOUS HIGH WINDOW
ADDI T1,1 ;NEW LOW
MOVEM T1,LW.S0(R)
IORI T1,.IPM ;NEW HIGH IS END OF PAGE
MOVEM T1,UW.S0(R)
MOVE T1,TAB.PT(R) ;GET POINTER (JUST BEYOND END OF CORE)
ANDI T1,.IPM ;SO JUST KEEP OFFSET IN THIS PAGE
IOR T1,TAB.LB(R) ;ADD IN BASE
MOVEM T1,TAB.PT(R) ;AND STORE
TRNN T1,1 ;DID WE STORE 1 WORD BEFORE?
MOVEM W2,-2(T1) ;NO, DO SO NOW
MOVEM W3,-1(T1)
IORI T1,.IPM ;LAST ADDRESS IN BLOCK
MOVEM T1,TAB.AB(R) ;NOW WINDOWS MATCH
JRST CPOPJ1 ;[715] SKIP RETURN
;HERE TO GET RID OF VARIOUS AREAS
GS.ZAP: MOVEI T1,GS.IX ;GET AREA
PJRST XX.ZAP## ;GENERAL ROUTINE
FX.ZAP: MOVEI T1,FX.IX
PJRST XX.ZAP##
LS.ZAP: MOVEI T1,LS.IX
PJRST XX.ZAP##
AS.ZAP: MOVEI T1,AS.IX ;
PJRST XX.ZAP## ;
;HERE TO MOVE SYMBOLS TO TOP OF CORE
;IF SORTING PUT SORT BUFFER IN AREA GS
SYMINI: SKIPE FX.LB ;ANY FIXUPS LEFT?
PUSHJ P,MOVFX ;YES, MUST MOVE THEM UP
SKIPN UW.LS ;IF LOCAL SYMBOLS ON DSK?
PJRST MOVSYM ;NO, JUST MOVE UP
; PJRST LKPSYM ;READ BACK INTO CORE
;HERE TO WRITE OUT END OF SYMBOL TABLE AND SET IT UP FOR SORTING
LKPSYM: SKIPL UW.LS ;IF -1 THEN SYMBOL TABLE NOT OUTPUT YET
JRST RDSYM ;JUST READ IT BACK IN
MOVE T1,LSYM ;ADRESS OF LAST SYMBOL STORED +1
SUBI T1,1
IORI T1,.IPM ;BLOCK BOUND
HRL T1,LW.LS ;FORM BLT WORD
HRRZM T1,UW.LS ;SIGNAL ALL OF SYMBOLS ON DSK
PUSHJ P,LS.OUT## ;AND OUTPUT IT
;FALL INTO RDSYM TO READ IT BACK
RDSYM: PUSHJ P,MOVSYM ;MOVE WHAT WE HAVE UP IN CORE
;AT THIS POINT THERE IS NO NEED TO READ
;MORE SYMBOLS, THAT WILL HAPPEN NEXT TIME ANYWAY
;UNLESS WE ONLY HAVE ONE BLOCK IN CORE
;THIS CASES PROBLEMS SO READ IN MORE
MOVE T1,UW.LS ;UPPER LIMIT
ANDCMI T1,.IPM ;START OF THIS PAGE
CAME T1,LW.LS ;IS IT THE LOWER PAGE BOUND?
POPJ P, ;NO, JUST RETURN
MOVEI T1,LS.IX-1 ;YES, SEE HOW MUCH SPACE WE HAVE WITHOUT SHUFFLING
SKIPN TAB.LB(T1) ;USUAL LOOK FOR LOWER AREA
SOJA T1,.-1
MOVE T2,LS.LB ;WHERE WE START AT
SUB T2,TAB.AB(T1) ;MINUS WHATS IN USE
SUBI T2,1 ;COUNT OF WHATS FREE
LSH T2,-1 ;CUT IN HALF
ANDCMI T2,.IPM ;ON BLOCK BOUND
CAMLE T2,LW.LS ;BUT DON'T GET TOO MUCH
MOVE T2,LW.LS ;IF WE DON'T HAVE ENOUGH SYMBOLS
MOVN T2,T2 ;GET NEG SO WE CAN BACKUP
ADDM T2,LS.LB ;MOVE DOWN IN CORE
ADDM T2,TAB.UB(T1) ;AND TAKE THIS SPACE
ADDM T2,LW.LS ;OPEN WINDOW WIDER
MOVE T1,UW.LS ;GET TOP OF WINDOW
SUBI T1,.IPS ;BUT WE ALREADY HAVE THIS PAGE
HRL T1,LW.LS ;FORM TRANS WORD
PJRST LS.IN## ;READ IT IN
;HERE IF TOP OF SYMBOL TABLE IS ALREADY IN CORE
;HOWEVER IT IS NOT AT TOP OF CORE WHERE WE WOULD LIKE IT
;THEREFOR MOVE ALL LS UP TO .JBREL
;USE REVERSE BLT IN ACCS
MOVSYM:
IFN FTOVERLAY,<
SKIPLE LNKMAX ;ANY OVERLAYS
SKIPN LNKNO. ;BUT NOT ROOT
JRST .+3 ;NO
MOVE T1,LS.UB ;CAN NOT USE TOP OF CORE
JRST .+4
>
SKIPE T1,FX.LB ;STILL FIXUPS TO DO?
SOJA T1,.+2 ;YES, MAKE T1 POINT TO HIGHEST FREE
MOVE T1,.JBREL ;NO, GET TOP OF CORE
CAMN T1,LS.AB ;AT ACTUAL TOP OF LS?
POPJ P, ;YES, JUST RETURN
MOVEM T1,LS.UB ;MAKE IT TOP
SUB T1,LS.AB ;GET DIFFERENCE = OFFSET
PUSH P,T1 ;SAVE OFFSET
MOVE T4,LS.AB ;TOP
SUB T4,LS.LB ;-BOTTOM
ADDI T4,400001 ;400000+LENGTH
MOVS T4,T4
HRR T4,LS.AB ;TOP OF OLD DATA
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVSI T3,(POPJ P,) ;REVERSE BLT NOW SET UP
PUSHJ P,T1 ;DO IT
MOVE T2,LS.AB ;[647]
MOVE T1,LS.UB
MOVEM T1,LS.AB ;SET BOUNDS THE SAME
POP P,T1 ;OFFSET
ADD T1,LS.LB ;NEW BASE
SUBI T1,1 ;HIGHEST TO GIVE BACK
HRL T1,T2 ;[647] HIGHEST ADDR TO ZERO
PUSHJ P,GBCK.L##
MOVE T1,LSYM ;NOW RESET LS.PT TO POINT TO LAST SYMBOL
SUB T1,LW.LS ;MINUS WINDOW BASE
ADD T1,LS.LB ;PLUS OFFSET IN CORE
MOVEM T1,LS.PT ;OK NOW
POPJ P,
;HERE TO ADD FREE SPACE TO NEXT LOWEST AREA IN USE
;CALLED BY
; MOVEI T1,THIS AREA
; PUSHJ P,ADJ.L
;USES T1, T2
ADJ.L: MOVE T2,TAB.LB(T1) ;GET CURRENT LOWEST SIZE
SUBI T2,1 ;THIS IS NOW UPPER OF NEXT LOWER
SKIPN TAB.LB-1(T1) ;FIND ONE
SOJA T1,.-1 ;EVENTUALLY
MOVEM T2,TAB.UB-1(T1)
POPJ P, ;RETURN
;HERE IF WE HAVE TO MOVE FIXUP AREA (IT MAY CONTAIN SYMBOL FIXUPS)
;MOVE UP TO VERY TOP OF CORE, OUT OF WAY OF SYMBOLS
;USE REVERSE BLT IN ACCS
MOVFX: MOVE T1,.JBREL ;GET TOP OF CORE
CAMN T1,FX.AB ;AT ACTUAL TOP OF FIXUPS?
POPJ P, ;YES, JUST RETURN
MOVEM T1,FX.UB ;MAKE IT TOP
SUB T1,FX.AB ;GET DIFFERENCE = OFFSET
PUSH P,T1 ;SAVE OFFSET
MOVE T4,FX.AB ;TOP
SUB T4,FX.LB ;-BOTTOM
ADDI T4,400001 ;400000+LENGTH
MOVS T4,T4
HRR T4,FX.AB ;TOP OF OLD DATA
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVSI T3,(POPJ P,) ;REVERSE BLT NOW SET UP
PUSHJ P,T1 ;DO IT
MOVE T1,FX.UB
MOVEM T1,FX.AB ;SET BOUNDS THE SAME
POP P,T1 ;OFFSET
ADDM T1,FX.PT
ADD T1,FX.LB ;NEW BASE
SUBI T1,1 ;HIGHEST LOC TO GIVE AWAY
PJRST GBCK.L## ;TO NEXT LOWER
SYDONE: SKIPE PAG.S1 ;PAGING LOW SEG?
SKIPA P1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE P1,LC.LB ;LOAD UP OFFSET
SKIPE PAG.S2 ;PAGING HIGH SEG?
SKIPA P2,JBHPTR ;YES, LOAD CORRECT OFFSET
MOVE P2,HC.LB ;LOAD UP OFFSET
MOVE T2,.JBSYM(P1) ;GET ADDRESS OF BASE OF SYMBOLS
HRRZ T3,TAB.PT(R) ;AND CURRENT TOP
SUB T3,TAB.LB(R) ;REMOVE OFFSET
ADD T3,LW.S0(R) ;BUT ADD IN BASE OF INCORE WINDOW
CAMG T3,HC.S0(R) ;[715] PSECT NAME USED?
JRST .+3 ;[715] YES, DON'T UPDATE
MOVEM T3,HC.S0(R) ;RESET HIGHEST LOC IN USE COUNTERS
MOVEM T3,HL.S0(R) ;SO WE WILL PRESERVE THE SYMBOLS
ADD T3,LL.S0(R) ;ADD IN SEGMENT OFFSET
SUBI T2,0(T3) ;FIND - LENGTH
HRLM T2,.JBSYM(P1) ;FIXUP SYMBOL TABLE POINTER
HRLM T2,JOB116 ;AND FOR .SYM FILE
SKIPGE SYMFRM ;OLD STYLE SYMBOL FILE REQUIRED?
PUSHJ P,OLDSYM ;YES, WRITE OR COMPLETE IT
.ERR. (MS,0,V%L,L%I,S%I,STC,<Symbol table completed>)
JRST REMVLS ;SETUP REST AND DELETE LS AREA
NOLOCS: SKIPE PAG.S1 ;PAGING LOW SEG?
SKIPA P1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE P1,LC.LB ;LOAD UP OFFSET
SKIPE PAG.S2 ;PAGING HIGH SEG?
SKIPA P2,JBHPTR ;YES, LOAD CORRECT OFFSET
MOVE P2,HC.LB ;LOAD UP OFFSET
REMVLS:
SKIPLE T1,SYMFRM ;NEW STYLE SYMBOL FILE NEEDED?
PUSHJ P,SAVSYM ;YES, OUTPUT THEM NOW
PUSHJ P,AS.ZAP ;DONE WITH ALGOL SYMBOLS
PUSHJ P,FX.ZAP ;ALSO DONE WITH FIXUP BY NOW
IFN FTOVERLAY,<
SKIPL LNKMAX ;OVERLAYS?
JRST SAVTST ;KEEP UNTIL SAV FILE MADE
>
PUSHJ P,LS.ZAP ;GET RID OF LS
SKIPN PAG.LS ;IF NOT PAGING
JRST SAVTST ;DON'T DELETE LS FILE
MOVEI T1,SC ;CAN DELETE CHAN# NOW
PUSHJ P,DVDEL.##
JFCL
SAVTST: SKIPE IO.PTR+%VC ;SAVE FILE REQUIRED?
JRST JBSAVE ;YES
JRST JBEXIT ;NO, EXECUTE OR FORM CORE IMAGE
SUBTTL ROUTINES FOR SYMBOLS
LTITLE: PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
TXNE W1,PT.BLK ;ONLY A FAIL BLOCK HEADER?
JRST BTITLE ;YES
MOVE T2,TTLPTR ;GET ADDRESS OF LAST PROG
HRRZ T1,TAB.PT(R) ;GET THIS ADDRESS
SUB T1,TAB.LB(R) ;MINUS OFFSET
ADD T1,TAB.LW(R) ;PLUS BASE OF WINDOW
MOVEM T1,TTLPTR ;SAVE FOR NEXT
SUB T1,T2 ;GET DIFFERENCE
MOVN T1,T1 ;NEGATE
JUMPE T2,.+2 ;IGNORE IF FIRST TIME
HRL W3,T1 ;FIXUP POINTER
PUSH P,W2 ;SAVE SYMBOLS
PUSH P,W3
TTLLUP: MOVX T1,S.TTL!S.SEG ;FLAGS
PUSHJ P,GETAST ;GET EXTENSION TRIPLET
SETZB W2,W3 ;ONLY HERE IF DEFINED BY /SWITCH
SKIPE W3 ;IF ANY HIGH SEG STUFF
MOVE W2,W3 ;USE IT
POP P,W3 ;GET W3 BACK
HLR W3,W2 ;FIX IT UP
POP P,W2
PUSHJ P,SYMOUT ;OUTPUT PSEUDO SYMBOL
POPJ P, ;[715] EXCEEDED SPACE, RETURN
JRST LSLOOP ;RETURN
BTITLE: TXO W2,R5.LCL!R5.GLB ;MAKE RADIX50 14,SYM
HRRZ W3,W3 ;BLOCK LEVEL ONLY
JRST LSLUP1 ;AND TREAT AS LOCAL SYMBOL
;SXBR50 -- SUBROUTINE TO CONVERT SIXBIT TO RADIX-50
;CALLED BY
; MOVE W2,SIXBIT WORD
; PUSHJ P,SXBR50
;RETURN
; RADIX-50 IN W2
;USES T1, T2
SXBR50: MOVE T2,W2 ;GET SIXBIT SYMBOL
SETZ W2, ;WHERE TO STORE RADIX50 SYMBOL
SETZ T1, ;CLEAR RECEIVING ACC
LSHC T1,6 ;GET NEXT CHAR
IMULI W2,50 ;MULTIPLE BY 50
ADD W2,SXBTAB(T1) ;ADD IN NEW CHAR
JUMPN T2,.-4 ;NOT DONE YET
POPJ P,
DEFINE SXBCHR (CHR)<
IRPC CHR,<
RADIX50 0,CHR
>>
XALL
SXBTAB: SXBCHR ( $% . 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ )
SALL
;HERE FOR OLD FORM SYMBOLS (RADIX-50)
;IF IN CORE WRITE THEM OUT WITH THREE INFORMATION WORDS AT FRONT
;HEADER, .JBSYM (116) AND .JBUSY (117)
;HEADER IS 776(TYPE) ,, LENGTH
;OTHER TWO WORDS ARE RELATIVE TO ZERO
;.JBSYM MUST HAVE A NEGATIVE LEFT HALF
;.JBUSY IS ZERO IF NO UNDEFINED SYMBOLS
OLDSYM: MOVEI T1,MC ;USE MAP CHAN INCASE PAGING LC
MOVEM T1,IO.CHN
MOVE T1,IO.PTR+%SC ;POINT TO CORRECT DATA
MOVEM T1,IO.PTR+MC
PUSHJ P,DVCHN.##
MOVSI T2,(Z MC,) ;RESET CHAN #
MOVEM T2,I.CHN(T1) ;SINCE %SC IS THERE CURRENTLY
HLRO T2,JOB116 ;NUMBER OF SYMBOLS
MOVM T2,T2
LSH T2,-.DBS2W ;[650] INTO BLOCKS (ASSUME FEW UNDEFS)
MOVEM T2,I.EST(T1)
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
MOVEM T2,I.VER(T1) ;NO, SO SET IT
PUSHJ P,DVNAM.## ;MAKE SURE NAME SETUP
PUSHJ P,DVOPN.## ;INIT DEV
PUSHJ P,DVENT.## ;DO ENTER
;NOW TO STORE THREE INFO WORDS
HLRE T1,JOB116 ;NO. OF DEFINED SYMBOLS
HLRE T2,JOB117 ;NO. OF UNDEFS
MOVM T1,T1 ;+
MOVM T2,T2
ADDI T2,2(T1) ;PLUS TWO EXTRA WORDS
HRLI T2,776 ;BLOCK TYPE FOR LINK
SKIPN T1,JOB117 ;.JBUSY IF NON-ZERO
MOVE T1,JOB116 ;OTHERWISE .JBSYM
HRRZ T1,T1 ;REMOVE NEG LEFT HALF
SUB T1,LL.S0(R) ;REMOVE ORIGIN
SUB T1,LW.S0(R) ;INCASE PAGING
ADD T1,TAB.LB(R) ;FIX IN CORE
;NOW PUT HEADER WORDS IN CORE IMAGE SO WE CAN DUMP IT ALL WITH
;ONE IOWD. PUSH REAL CONTENTS OF THOSE LOCATIONS (USUALLY 0) FIRST,
;THEN RESTORE THEM LATER
SUBI T1,3 ;BACKUP 3
PUSH P,0(T1) ;SAVE WORDS INCASE NOT ZERO
PUSH P,1(T1)
PUSH P,2(T1)
MOVEM T2,0(T1) ;SAVE HEADER
HLLZ T2,JOB117 ;COPY INFO WORDS
MOVEM T2,2(T1) ;TO NEXT 2 LOCS
HLRE T2,T2 ;GET - LENGTH (OR 0)
MOVM T2,T2 ;+
HLL T2,JOB116 ;-LENGTH,,OFFSET
MOVEM T2,1(T1) ;FIRST INFO WORD
HLRE T2,JOB116 ;FIND TOTAL LENGTH TO OUTPUT
HLRE T3,JOB117 ;.JBSYM+.JBUSY
ADD T2,T3
SUBI T2,3 ;+3 INFO WORDS
HRLZ T2,T2 ;-LENGTH
HRRI T2,-1(T1) ;IOWD LENGTH,ADDRESS
SETZ T3, ;TERMINATE
OUT MC,T2 ;DUMP IT
JRST [POP P,2(T1) ;RESTORE DATA
POP P,1(T1)
POP P,0(T1)
PJRST DVRLS.##] ;CLOSE FILE
POP P,2(T1) ;RESTORE DATA
POP P,1(T1)
POP P,0(T1)
PUSH P,[MC]
.ERR. (ST,,V%L,L%W,S%W,OES,<Output error on symbol file, file closed, job continuing>)
POPJ P,
;HERE TO SAVE NEW FORM SYMBOL TABLE
;IF ALL IN CORE JUST OPEN AND WRITE OUT
;IF ON DSK EITHER RENAME OR COPY THEM
SAVSYM: PUSHJ P,.SAVE1## ;NEED AN AC
CAIN T1,1 ;SIXBIT SYM FILE WANTED?
MOVEI P1,LS.IX ;YES, STORED IN LS AREA
CAIN T1,2 ;HOW ABOUT ALGOL .SYM FILE?
MOVEI P1,AS.IX ;YES, USE AS AREA INSTEAD
SKIPN TAB.UW(P1) ;PAGING?
JRST WRTSYM ;NO
MOVE T1,TAB.AB(P1) ;MAKE SURE UW.XX IS OK
SUB T1,TAB.LB(P1) ;MIGHT BE -1 IF LS AREA
ADD T1,TAB.LW(P1) ;NOW HAVE HIGHEST LOC IN CORE
MOVEM T1,TAB.UW(P1) ;UPDATE UW.XX
SETCM T1,TAB.LB(P1) ;ALSO MAKE SURE DISK FILE IS OK
ADD T1,TAB.PT(P1) ;IN CASE NEVER OUTPUT BEFORE
JUMPE T1,.+4 ;FORGET IT IF NOTHING TO OUTPUT
ADD T1,TAB.LW(P1) ;NOTE WE'RE GETTING EXACT WORD CNT
HRL T1,TAB.LW(P1) ;ALGOL 7 NEEDS .RBSIZ EXACT
PUSHJ P,@TB.OUT##(P1) ;SO USE XX.PT INSTEAD OF XX.AB
MOVE T1,TAB.AB(P1) ;NOW READ IN FRONT OF FILE
SUB T1,TAB.LB(P1) ;SO CAN SET UP 10??,,COUNT
SETZM TAB.LW(P1) ;?W.?S MUST BE UP TO DATE
MOVEM T1,TAB.UW(P1) ;FOR FOLLOWING CALL
PUSHJ P,@TB.IN##(P1) ;AS FIRST WORD OF FILE
CAIE P1,AS.IX ;ALGOL?
JRST SAVSY0 ;NO, DO IT FOR LS AREA
MOVE T2,ASYM ;YES, GET SYMBOL COUNT
HRLI T2,1044 ;AND BLOCK TYPE
JRST SAVSY1 ;AND CONTINUE
SAVSY0: MOVE T2,LSYM ;COUNT FOR LS AREA
HRLI T2,1700 ;AND BLOCK TYPE
SAVSY1: SUBI T2,1 ;WORDS FOLLOWING IS 1 LESS
MOVEM T2,@TAB.LB(P1) ;STORE COUNT WORD
PUSHJ P,@TB.OUT##(P1) ;AND UPDATE FILE
MOVEI T1,SC ;FROM CHAN#
CAIN P1,AS.IX ;UNLESS AS AREA
MOVEI T1,AC ;IN WHICH CASE ALGOL CHANNEL
MOVE T2,IO.PTR+%SC ;TO CHANNEL
PUSHJ P,DVPRO. ;GET PROTECTION RIGHT
MOVEI T2,%SC ;TO CHAN#
MOVE T3,IO.PTR+%SC ;GET POINTER TO NEW FILE
MOVE T4,VERNUM ;GET VERSION OF PROGRAM
SKIPN I.VER(T3) ;UNLESS ALREADY SET BY SWITCH...
MOVEM T4,I.VER(T3) ;SAVE FOR ENTER
PJRST DVMOV. ;GO COPY PAGED FILE TO SYMBOL FILE
WRTSYM: MOVEI T1,DC ;USE THIS CHAN
MOVEM T1,IO.CHN
MOVE T1,IO.PTR+%SC ;HIDE DATA BLOCK HERE
MOVEM T1,IO.PTR+DC ;NOW BRING IT FORTH
PUSHJ P,DVCHN.## ;PUT ADDRESS OF BLOCK IN T1
MOVSI T2,(Z DC,) ;RESET CHAN # IN AC FIELD
MOVEM T2,I.CHN(T1) ;SINCE %SC IS THERE CURRENTLY
CAIE P1,AS.IX ;ALGOL?
JRST WRTSY0 ;NO, SETUP 1ST WORD FOR LS
MOVE T3,ASYM ;YES, SETUP COUNT WORD
HRLI T3,1044 ;AND BLOCK TYPE
JRST WRTSY1 ;CONTINUE
WRTSY0: MOVE T3,LSYM ;LS AREA COUNT
HRLI T3,1700 ;BLOCK TYPE FOR TRIPLET SYMBOLS
WRTSY1: HRRZ T2,T3 ;SAVE COUNT FOR ESTIMATE
SUBI T3,1 ;WORDS FOLLOWING IS 1 LESS
MOVEM T3,@TAB.LB(P1) ;SAVE WORD COUNT IN AREA
LSH T2,-.DBS2W ;[650] INTO BLOCKS
MOVEM T2,I.EST(T1) ;WE NEED THIS MUCH
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
MOVEM T2,I.VER(T1) ;NO, SO SET IT
PUSHJ P,DVNAM.## ;MAKE SURE NAME IS SET UP
PUSHJ P,DVOPN.## ;INIT DEVICE
PUSHJ P,DVENT.## ;ENTER FILE
;NOW FOR OUTPUT
WRTSY2: MOVE T1,TAB.LB(P1) ;GET BOTTOM ADDR IN CORE
SUB T1,TAB.PT(P1) ;-LENGTH
HRLZ T1,T1 ;-LENGTH,,0
HRR T1,TAB.LB(P1) ;FIRST ADDR OF BUFFER
HRRI T1,-1(T1) ;-LENGT