Trailing-Edge
-
PDP-10 Archives
-
bb-d868c-bm_tops20_v4_2020_distr
-
language-sources/lnkov1.mac
There are 48 other files named lnkov1.mac in the archive. Click here to see a list.
TITLE LNKOV1 - PHASE 1 OVERLAY MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC/DZN 24-Aug-79
;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, 1979 BY DIGITAL EQUIPMENT CORPORATION
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL
ENTRY LNKOV1
EXTERN LNKLOD,LNKWLD,LNKOV2
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==1 ;DEC MINOR VERSION
DECEVR==1220 ;DEC EDIT VERSION
VERSION
SEGMENT
;LOCAL ACC DEFINITIONS
R=:R1 ;CURRENT RELOCATION COUNTER
SUBTTL REVISION HISTORY
;START OF VERSION 2
;135 ADD OVERLAY FACILITY
;136 FIX VARIOUS BUGS
;170 MAKE PLOT SWITCH WORK
;174 FIX RELOCATABLE OVERLAY BUGS
;175 REPLACE /RESET WITH /NODE
;200 LOAD REENTRANT OVERLAY HANDLER
;207 REDUCE SIZE OF OVERHEAD TABLES
;216 (13559) ADD ZSV ERROR CHECKS
;START OF VERSION 2B
;237 (13931) CHANGE RPR ERROR TO NBR
;245 MAKE OVERLAY FILE STAY ON SAME STRUCTURE ON SUPERSEDE
; MODIFY OC.OPN ROUTINE TO CHECK THIS CASE
;262 Force a /LINK on encountering /NODE, if needed
;300 Fix copy of permanent excludes on /OVERLAY
;331 Set size of segment correctly so don't loose
; EXTTAB and ENTTAB'S.
;352 LABEL EDIT 237
;404 Put edit 316 back in to LINK.
;407 Correct problem with /NODE:-1
;413 Fix some small bugs with ELN message.
;414 Make sure FUNCT. is loaded in the root link.
;416 Update GS.FR instead of GS.PT when creating bound globals.
;425 Improve FSN error detect to not bomb users unnecessarily.
;START OF VERSION 2C
;466 Avoid loop on /NODE when loading relocatable overlays.
;504 Get output IOWD right when putting symbols in overlay file.
;505 Fix absolute addresses after call to LNKCOR via SY.CHR.
;511 Overlap by 1 page when copying LS to overlay file for fixups.
;521 Zap MNSEEN and MNTYPE on /LINK.
;530 Get triplet flag definitions right.
;534 Make multiple /LINK switches work on one line.
;557 Clean up the listing for release.
;START OF VERSION 3A
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
;START OF VERSION 4
;605 Use OUTSTR in LNKRER message.
;623 Handle multiple /PLOT switches (delete data block)
;625 Print blank line after LNKELN message
;631 Print correct file spec with LNKEOV message.
;632 Implement $FIXUP.
;635 Add code to handle /ARSIZE switch, and count any
; ambiguous request table space in previous link.
;650 Use VM on TOPS-10 if available.
;651 Put the overlay file where the user wants it.
;660 Clear .LINK storage at the end of an overlay.
;664 Don't destroy last word of BG area on /NODE:0.
;665 Fix core management problem broken by edit 650.
;666 Fix edits 650 and 665, this time for sure.
;671 Don't leave junk in PH.ORL.
;677 Don't default to /SYMSEG:LOW if loading overlays.
;730 Check for /DEBUG, do it before /LINK.
;731 SEARCH MACTEN,UUOSYM
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
;START OF VERSION 4A
;1152 Set up RC.HL correctly on /LINK and /NODE.
;1172 Allocate PAT.. in the root.
;1174 Label and clean up all error messages.
;1201 Change $SEGxxx to $SSGxxx.
;1204 Say LNKPTL if /SPACE or /PATCHSIZE exceeds 777777.
;1205 Don't waste blocks in the overlay file.
;1214 Fix mismatched angle bracket bugs.
;1217 Clean up the listings for release.
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL ENTRY POINT
LNKOV1: JFCL .+1 ;NORMAL ENTRY
JRST LNKLOD
;IOWD FOR PREAMBLE SECTION
IFE FTKIONLY,<
PHIOWD: IOWD PH.ZZ,PH.HDR
0
>
IFN FTKIONLY,<EXTERN PHIOWD> ;BUG IN DMOVE MACRO
SUBTTL SWITCH ACTION -- /OVERLAY:key
.OVERLAY::
HRLZ T1,(P2) ;GET NEXT SWITCH
HLLM T1,1(P1) ;FIX LIST OF SWITCHES TO DO
JRST OVRLAY
%OVERLAY::
HRRZ T1,(P2) ;GET NEXT SWITCH
HRRM T1,1(P1) ;FIX LIST OF SWITCHES TO DO
; JRST OVRLAY
OVRLAY: MOVE T1,OVLTBL-1(T2) ;GET BIT
IORM T1,OVERLW ;SET IN MEMORY
SKIPE IO.PTR+%OC ;ALREADY SET ONCE?
JRST OVRLA1 ;YES, JUST RETURN
MOVSI T1,'OVL' ;FORCE EXTENSION
MOVEM T1,F.EXT(P1)
PUSHJ P,DVOUT.## ;SETUP DATA BLOCK
%OC,,.IODPR
HRLZI T1,2(P1) ;CLEAR ALL BUT LINK AND SWITCH
HRRI T1,3(P1)
SETZM 2(P1)
BLT T1,F.LEN-1(P1)
PUSHJ P,OVRTST ;PUT REQUEST IN SYMBOL TABLE
HLLZ T1,INCPTR ;SEE IF ANY VERY PERM INCLUDES
JUMPE T1,OVRLA0 ;NO INCLUDES, TRY EXCLUDES
MOVEI T2,.EXC ;YES, GET SPACE
PUSHJ P,DY.GET##
HRLZM T1,OVINEX ;SAVE START OF LIST
HLLZ T2,INCPTR ;START OF LIST
HRR T2,T1 ;WHERE TO PUT IT
BLT T2,.EXC-1(T1) ;DO MOVE
HRRZ T2,(T1) ;SEE IF MORE
JUMPE T2,OVRLA0 ;NO
PUSHJ P,OVRINX ;YES, COPY REST
;HERE TO SAVE SUPER-GLOBAL EXCLUDES, IF ANY EXIST.
OVRLA0: HLLZ T1,EXCPTR ;ANY EXCLUDES
JUMPE T1,OVRLA1 ;NO
MOVEI T2,.EXC ;YES, GET SPACE
PUSHJ P,DY.GET##
HRRM T1,OVINEX ;SAVE START OF LIST
HLLZ T2,EXCPTR ;START OF LIST
HRR T2,T1 ;WHERE TO PUT IT
BLT T2,.EXC-1(T1) ;DO MOVE
HRRZ T2,(T1) ;SEE IF MORE
JUMPE T2,OVRLA1 ;NO
PUSHJ P,OVRINX ;YES, COPY REST
OVRLA1: HRLS ARSIZE ;[635] STORE STICKY /ARSIZE
SUB P,[2,,2] ;ADJUST STACK
MOVE T1,P2 ;ADDRESS OF SWITCH BLOCK
HLRZ T2,(P2) ;SIZE
PUSHJ P,DY.RET## ;GIVE IT BACK
HLLZ T1,FL ;GET PERMANENT FLAGS TO DATE
IORM T1,FLAGS ;SAVE SO AS TO AFFECT ALL LINKS
JRST LNKWLD ;RETURN & TRY AGAIN
OVRTST: PUSHJ P,.SAVE4## ;SAVE THE P'S
MOVX W1,PT.SGN!PT.SYM
MOVE W2,['.OVRLA'] ;ENTRY POINT
SETZ W3,
PUSHJ P,TRYSYM## ;SEE IF DEFINED
PJRST SY.RQ## ;UNDEF, ENTER REQUEST
POPJ P, ;ALREADY UNDEFINED
POPJ P, ;ALREADY DEFINED
OVRINX: SPUSH <T2,T1> ;SAVE THE POINTERS
MOVEI T2,.EXC ;GET ANOTHER BLOCK
PUSHJ P,DY.GET##
POP P,T2 ;GET LAST NEW BLOCK
HRRM T1,(T2) ;LINK THIS TO IT
POP P,T2 ;NEXT BLOCK IN ORIGINAL LIST
HRLZ T3,T2 ;FROM
HRR T3,T1 ;TO
BLT T3,.EXC-1(T1)
HRRZ T2,(T1) ;GET NEXT
JUMPN T2,OVRINX ;YES THERE IS
POPJ P, ;RETURN
DEFINE KEYMAC (A,B)<
IFIDN <A><OVL>,<
A'TBL:
IRP B,<
EXP $OV'B
>>>
XALL
KEYWORDS
SALL
SUBTTL SWITCH ACTION -- /LINK:name
%LINK::
SKIPN T1,S.DEBG ;[730] HAVE WE SEEN A /DEBUG?
JRST %LINK1 ;[730] NO, JUMP
SETZM S.DEBG ;[730] YES, CLEAR FLAG
MOVEI T2,0(P2) ;[730] GET CURRENT /LINK SWITCH PTR
HRRM T2,1(T1) ;[730] CHAIN INTO /DEBUG FILE SPEC AS LOCAL SW
HRRZ T2,(P2) ;[730] MOVE PTR OF NEXT SWITCH INTO AN AC
HLLZS 0(P2) ;[730] BEFORE IT GET CLEARED
MOVE P2,T2 ;[730] UPDATE CURRENT SWTICH PTR WITH IT
POPJ P, ;[730] RETURN
%LINK1: ;[730]
JUMPN T2,.+3 ;NAME ALREADY SET?
SKIPGE LNKMAX ;NO, SO IS IT FIRST TIME?
MOVE T2,['ROOT '] ;YES, PREEMPT NAME "ROOT"
MOVEM T2,LNKNAM ;STORE NAME OR ZERO
MOVEI T1,LINKTO ;HERE ON TERMINATION
MOVEM T1,GOTO
SETOM S.INZR ;FLAG RETFSP TO END LINE IN LNKWLD
JUMPE T2,CPOPJ ;NO NAME
PUSHJ P,.SAVE2## ;NEED TWO SAFE ACCS
MOVE P1,T2 ;SAVE NAME
MOVS P2,LNMPTR ;GET START OF NAME CHAIN
JUMPE P2,LINKB ;NOT SETUP YET
LINKA: CAMN P1,(P2) ;SAME NAME
JRST LNKLNA ;YES, ERROR
HRRZ T1,1(P2) ;SEE IF ANY MORE
JUMPE T1,LINKB ;NO
MOVE P2,T1
JRST LINKA ;YES
LINKB: MOVEI T2,2 ;USE 2 WORDS
PUSHJ P,DY.GET##
JUMPE P2,[HRLZM T1,LNMPTR
JRST .+2]
HRRM T1,1(P2) ;LINK TO NEW BLOCK
MOVE P2,LNKMAX ;LINK NUMBER OF PREVIOUS
HRLZI P2,1(P2) ;ONE MORE IS # OF THIS ONE
DMOVEM P1,(T1) ;STORE
AOS LNMPTR ;COUNT ONE MORE
POPJ P,
LNKLNA: HLRZ P2,1(P2) ;GET LINK#
E$$LNA::.ERR. (MS,.EC,V%L,L%W,S%W,LNA,<Link name >) ;[1174]
.ETC. (SBX,.EC!.EP,,,,P1)
.ETC. (STR,.EC,,,,,< already assigned to link number >)
.ETC. (DEC,.EP,,,,P2)
POPJ P,
SUBTTL SWITCH ACTION -- /ARSIZE:n, /NOENTRY:sym, /NOREQUIRE:sym
%ARSIZE::
HRRM T2,ARSIZE ;[635] STORE VALUE FOR THIS LINK
POPJ P, ;[635] RETURN TO LNKWLD
%NOENTRY::
PUSHJ P,STRLSW## ;WAIT 'TIL FILE IS LOADED
.NOENTRY::
PUSHJ P,.SAVE4## ;SAVE P1-P4
MOVX W1,PT.SGN!PT.SYM ;FLAGS
SKIPN W2,T2 ;SYMBOL
JRST E$$ZSV## ;[1174] ZERO IS ILLEGAL
SETZ W3, ;VALUE
PUSHJ P,TRYSYM## ;SEE IF DEFINED
POPJ P, ;IGNORE
JFCL ;UNDEFINED
MOVX W1,PS.NOE ;NOT AN ENTRY FLAG
IORM W1,0(P1) ;SET IN SYMBOL TRIPLET
POPJ P,
%NOREQUEST::
PUSHJ P,STRLSW## ;WAIT 'TIL FILE IS LOADED
.NOREQUEST::
PUSHJ P,.SAVE4## ;SAVE P1-P4
MOVX W1,PT.SGN!PT.SYM ;FLAGS
SKIPN W2,T2 ;SYMBOL
JRST E$$ZSV## ;[1174] ZERO IS ILLEGAL
SETZ W3, ;VALUE
PUSHJ P,TRYSYM## ;SEE IF DEFINED
POPJ P, ;IGNORE
JFCL ;UNDEFINED
MOVX W1,PS.NRQ ;NOT A REQUEST FLAG
IORM W1,0(P1) ;SET IN SYMBOL TRIPLET
POPJ P,
SUBTTL SWITCH ACTION -- /PLOT:(INCHES:n,LEAVES:n,STEPS:n), /REGION, /SPACE:n
%PLOT::
SETOM PLOTSW ;MAKE SURE WE DO IT
SKIPE T1,3(P2) ;GET SWITCH VALUE
MOVEM T1,PLTTAB-1(T2) ;STORE FOR LNKPLT
SKIPE NULSPC ;[623] FIRST CALL THIS FILE SPEC?
POPJ P, ;NO
PUSHJ P,COPYP1## ;MAKE A NEW DATA BLOCK
PUSHJ P,DVOUT.## ;SETUP OUTPUT BLOCK
%PC,,-1 ;WILL BE EITHER ASCII LINE OR IMAGE AT RUN TIME
PJRST RESTP1## ;DELETE DATA BLOCK
%REGION::
JUMPE T2,CPOPJ ;ALLOW /REGION:0
E$$MRN::.ERR. (MS,0,V%L,L%I,S%I,MRN,<Multiple regions not yet implemented>) ;[1174]
POPJ P,
%SPACE::
MOVEM T2,SPACE ;SAVE VALUE
POPJ P,
SUBTTL LINK SWITCHES -- /REQUEST
%REQUEST::
PUSHJ P,STRLSW ;WAIT TIL AFTER FILE LOADED
.REQUEST::
MOVE T1,[PUSHJ P,REQNXT] ;[1174] SET UP NEXT SYMBOL ROUTINE
MOVEM T1,NXTGLB ;[1174] ..
MOVE W3,HT.PRM ;[1174] SET UP HASH TABLE INDEX
ADDI W3,1 ;[1174] START UP BY 1 FOR SOSGE BELOW
PUSHJ P,REQNXT ;[1174] GET NEXT (FIRST) ENTRY
PJRST E01RER ;[1174] NONE--GO SAY SO SPECIALLY
E$$RER::.ERR. (MS,.EC!.EN,V%L,L%F,S%I,RER) ;[1174]
.ETC. (STR,.EC,,,,,<Request external references (inter link entry points)>) ;[1174]
.ETC. (JMP,,,,,.ETSAV##) ;[1174] GO PRINT THE LIST
;REQNXT RETURNS THE NEXT INTER-LINK ENTRY POINT FOR USE BY THE ABOVE .ERR..
;
;CALL:
; W3/ NEXT HASH TABLE INDEX TO CHECK
;RETURNS WITH A NON-SKIP RETURN IF THERE ARE NO MORE SUCH SYMBOLS. OTHERWISE,
;GIVES A SKIP RETURN WITH:
; W1/ NEXT SYMBOL
; W2/ OCTAL VALUE
; W3/ UPDATED
REQNXT: PUSHJ P,.SAVE4## ;[1174] SAVE LNKLOG'S P ACS
REQLUP: SOSGE P2,W3 ;[1174] CHECK NEXT HASH TABLE ENTRY
POPJ P, ;[1174] NONE LEFT--GIVE NON-SKIP RETURN
SKIPN P3,@HT.PTR ;[1174] IGNORE IF NO SYMBOL HERE
JRST REQLUP ;[1174] ..
ADD P3,GS.LB ;[1174] RELOCATE IN CASE GS AREA MOVED
MOVE T1,0(P3) ;[1174] MUST BE UNDEFINED LINK ENTRY SYMBOL
TXNE T1,PT.SYM ;[1174] ..
TXNN T1,PS.ENT ;[1174] ..
JRST REQLUP ;[1174] NO--TRY NEXT
TXNN T1,PS.NRQ ;[1174] DID USER SAY NO FOR THIS SYMBOL?
SKIPN 2(P3) ;[1174] OR ZERO VALUE (I.E. NOT A CALL FOO)
JRST REQLUP ;[1174] YES--TRY NEXT
MOVE W1,1(P3) ;[1174] NO--A WINNER! LOAD UP SYMBOL AND VALUE
MOVE W2,2(P3) ;[1174] ..
JRST CPOPJ1 ;[1174] DONE--GIVE SKIP RETURN
E01RER::.ERR. (MS,.EC,V%L,L%F,S%I,RER) ;[1174]
.ETC. (STR,,,,,,<No request external references (inter-link entry points)>) ;[1174]
POPJ P, ;[1174]
REQHDR: ASCIZ \[LNKRER \
REQMES: ASCIZ \Request External References (Inter-Link Entry points)]
\
SUBTTL HERE TO TERMINATE LINK
LINKGO::SKIPN PRGNO ;LOAD ANYTHING?
JRST LNKOV2 ;NO, DO PASS2
PUSHJ P,LIBRARY## ;LOAD DEFAULT LIBS
PUSH P,.+1 ;LOAD RETURN ADDRESS
CAI LNKOV2
JRST LINKGT ;COMMON CODE
LINKTO::PUSHJ P,LIBRARY## ;LOAD DEFAULT LIBS
PUSH P,.+1 ;LOAD RETURN ADDRESS
CAI LNKOV1
LINKGT: SETOM LINKSEEN ;END OF SEGMENT SPECIFIED
AOS T1,LNKMAX ;INCREMENT NUMBER SEEN
MOVEM T1,CS.NUM ;STORE CURRENT IN HEADER
MOVE W2,STADDR ;IS START ADDRESS STILL SYMBOLIC?
TLNN W2,-1 ;NON-ZERO LEFT HALF IF SO
JRST LNKT0 ;NO
MOVX W1,PT.SGN!PT.SYM
SETZ W3,
PUSHJ P,TRYSYM## ;SEE IF DEFINED BY NOW
JRST LKSTER ;CANNOT HAPPEN
JRST LKSTER ;UNDEFINED
MOVE W3,2(P1) ;GET VALUE
HRRZM W3,STADDR ;STORE 18 BITS
LNKT0: SKIPE CS.NUM ;LINK 0?
JRST LNKT1 ;NO
MOVX W1,PT.SGN!PT.SYM ;FLAG BITS FOR A SYMBOL
MOVE W2,['FUNCT.'] ;THE SYMBOL'S NAME
SETZ W3,
PUSHJ P,TRYSYM ;IT MUST BE THERE OR OVRLAY
;WILL RECURSE HORRIBLY
SKIPA ;NOT NEEDED IS OK
JRST E$$FSN ;[1174] OVRLAY NEEDS IT, MUST BE THERE
MOVX W1,PT.SGN!PT.SYM
MOVE W2,['.OVRLA'] ;NEED TO KNOW WHERE IT IS
SETZ W3,
PUSHJ P,TRYSYM##
JRST E$$OHN ;[1174] MUST BE THERE
JRST E$$OHN ;[1174] BUT WARN USER
MOVE T1,2(P1) ;GET ADDRESS
HRLI T1,(JSP 1,) ;COMPLETE INST
MOVEM T1,EXTTRP ;AND STORE IN PROTOTYPE EXTTAB
HRRI W2,'RLU' ;WHERE UNDEFINED REQUESTS GO
PUSHJ P,TRYSYM##
JRST E$$OHN ;[1174]
JRST E$$OHN ;[1174]
;HERE TO SET UP FRONT OF OVERLAY FILE.
MOVE T1,2(P1) ;GET ADDRESS
MOVEM T1,ADDOVU ;SO WE CAN DO FIXUPS
PUSHJ P,OC.OPN ;SETUP OVERLAY FILE
MOVEI T2,^D128 ;START TABLE WITH 256 LINKS
MOVEM T2,L.MAX ;STORE NUMBER FOR CHECKS
PUSHJ P,DY.GET## ;GET SOME SPACE
HRLI T1,P1 ;PUT INDEX IN P1 FOR @
MOVEM T1,LNKTBL ;FOR DISC BLOCKS
MOVEI T1,LN.OVL/<.DBS*2> ;[650]
MOVEM T1,OVLBLK ;FIRST FREE BLOCK FOR LINKS
SKIPN LW.S1 ;SEE IF PAGING AND BASE NOT IN CORE
JRST LNKT0A ;OK IT IS
MOVEI P2,.JBVER ;HIGHEST ADDRESS WE NEED
SETZ P3, ;LOWER
PUSHJ P,PG.LSG## ;MAKE SURE WINDOW IS IN CORE
LNKT0A: MOVE T1,LC.LB ;BASE OF LOW SEG
MOVE T2,SYMSEG ;GET SYMSEG VALUE
CAIE T2,$SSGNONE ;[1201] USER SAYS NO?
SKIPE NOSYMS ;HOWEVER IF USER SAID NO
JRST [SETZM SYMSEG ;MAKE SURE NONE
JRST LNKT0C] ;[1172] CONTINUE
JUMPN T2,LNKT0B ;OK IF USER ALREADY SAID /SYMSEG
SKIPN .JBDDT(T1) ;IS DDT LOADED
JRST LNKT0C ;[1172] NO, CONTINUE
MOVEI T2,$SSGLOW ;[1201] SYMBOLS IN LOW SEG INDEX
MOVEM T2,SYMSEG ;SET VALUE SO WE CAN SAVE SYMBOLS
;HERE IF WE'RE GOING TO HAVE A RUNTIME SYMBOL TABLE. ALLOCATE PAT..
;AT THE END OF THE ROOT.
LNKT0B: MOVE T2,SYMSEG ;[1172] GET INDEX TO SYMBOL SEGMENT
SKIPN T3,PATSPC ;[1172] GET PATCHING SPACE
MOVEI T3,PATSP. ;[1172] DEFAULT
EXCH T3,HL.S0(T2) ;[1172] GET LOCATION OF PAT..
MOVEM T3,PATLOC ;[1172] SAVE FOR LSOVX
ADDM T3,HL.S0(T2) ;[1172] ALLOCATE THE PAT.. AREA
; ..
; ..
LNKT0C: MOVE T2,.JBVER(T1) ;[1172] GET VERSION N0.
SKIPN VERNUM
MOVEM T2,VERNUM ;SET FOR OVERLAY FILE
MOVX W1,PT.SGN!PT.SYM
MOVE W2,['.OVRLO']
SETO W3,
MOVE T1,OVERLW ;GET FLAGS
TXNE T1,$OVLOG ;WANT A LOG FILE?
PUSHJ P,SETVAL ;YES
SETZ W3,
TXNE T1,$OVNOLOG ;SPECIFICALLY NOT?
PUSHJ P,SETVAL
HRRI W2,'RWA' ;NOW FOR WARNINGS
TXNE T1,$OVWARN
PUSHJ P,SETVAL
SETO W3,
TXNE T1,$OVNOWARN
PUSHJ P,SETVAL
JRST LNKT1B
SETVAL: PUSHJ P,TRYSYM##
JRST E$$OHN ;[1174]
JRST E$$OHN ;[1174]
HRRZ P2,2(P1) ;GET ADDRESS
MOVE P3,P2 ;FOR ADDRESS CHECK
SKIPE PAG.S1 ;ON DSK
PUSHJ P,PG.LSG## ;YES
ADD P3,LC.LB
MOVEM W3,(P3) ;STORE BACK
MOVE T1,OVERLW ;RESET SWITCH
POPJ P,
LNKT1: SKIPN P1,LSTPTR ;FIRST TIME (LINK# 1)?
JRST [MOVEI T2,4 ;NEED 4 WORDS
PUSHJ P,DY.GET##
MOVEM T1,FSTPTR ;STORE START OF TREE
MOVSI T2,-4 ;-4 ,, 0
JRST LNKT1A]
SKIPN (P1) ;JUST DONE A RESET (0 WORD)
JRST [MOVS T2,CS.NUM
MOVEM T2,(P1)
JRST LNKT1B] ;REPLACE WITH LINK#
MOVEI T2,4 ;ASSUME AT LEAST 2 FORWARD PATHS FROM THIS LINK
PUSHJ P,DY.GET##
HRRM T1,(P1) ;LINK BACK TO PREVIOUS
HLRZ T2,P1 ;PTR TO START OF BLOCK
HRL T2,(T2) ;GET ITS LINK#
MOVEM T2,1(T1) ;STORE BACK POINTER
MOVSI T2,-4
HLR T2,(P1) ;THIS LINK#
LNKT1A: MOVEM T2,(T1)
MOVS T2,CS.NUM
MOVEM T2,2(T1) ;STORE LINK # WITH ZERO PTR
HRLI T1,2(T1) ;POINT TO NULL PTR
MOVSM T1,LSTPTR
LNKT1B: SKIPN T1,HL.S1 ;GET CURRENT HIGHEST LOC
JRST [SKIPN T1,PH.ADD ;NEVER SETUP, SO NO LOW SEG
MOVEI T1,.JBDA ;NOT POSSIBLE, BUT !!1
MOVEM T1,HL.S1 ;JUST STORE TABLES, ETC.
JRST .+1]
MOVEM T1,PH.CST ;WILL BE START OF HEADER SECTION
SKIPN CS.NUM ;IF ROOT
HRLM T1,ADDOVU ;STORE FOR UNDEF SYMBOL
HRL T1,CS.NUM ;PUT NUMBER IN LH
MOVEM T1,EXTCST ;ALSO IN EXTTAB
MOVE T1,PH.ADD ;GET THIS LINK'S ORIGIN
MOVEM T1,CS.COR ;SAVE AS START OF LINK
MOVEI T1,CS.ZZ ;ALLOCATE SPACE FOR HEADER
ADDB T1,HL.S1 ;AND ACCOUNT FOR IT
MOVE T1,[CS.HDR,,PH.HDR]
BLT T1,PH.NAM ;COPY COMMON INFO
MOVE T1,STADDR ;COPY START ADDRESS
HRRZM T1,CS.STA
SETZM CS.EXT ;INCASE NO UNDEFS
SKIPN P2,USYM ;NO. OF UNDEFS
JRST LNKT3 ;NONE
MOVN T1,P2 ;- NUMBER
HRL T1,HL.S1 ;,,ADDRESS
MOVSM T1,CS.EXT ;POINT TO TABLE
IMULI P2,ET.ZZ ;4 WORDS EACH
MOVE P3,HL.S1 ;LOWER BOUND
ADD P2,HL.S1 ;ACCOUNT FOR THEM
PUSHJ P,LNKTCK ;MAKE SURE IT'S IN CORE
;HERE TO SET EXTTAB
LNKT2: HRLI P3,EXTHDR ;FORM BLT PTR IN P3
MOVE P4,USYM ;GET UNDEFINED SYMBOL COUNT AGAIN
MOVE P2,HT.PRM ;GET INDEX INTO HASH TABLE
LNKT2A: SKIPN P1,@HT.PTR ;GET POINTER TO SYMBOL
JRST LNKT2B ;NO POINTER, NO SYMBOL
ADD P1,GS.LB ;ADD IN BASE
MOVE T1,0(P1) ;GET FLAGS
TXNE T1,PT.SYM ;WE ONLY WANT SYMBOLS
TXNN T1,PS.UDF!PS.REQ ;SEE IF UNDEFINED STILL
JRST LNKT2B ;NO
AOS EXTCNT ;COUNT ONE MORE
DMOVE T1,1(P1) ;GET SYMBOL AND VALUE (POINTER)
MOVEM T1,EXTNAM ;STORE NAME
MOVE T1,P3 ;GET BYTE PTR
ADDI P3,ET.ZZ ;INCR P3
BLT T1,-1(P3) ;MOVE PROTOTYPE BLOCK
MOVEI W3,ET.ZZ
ADD W3,HL.S1 ;NEW TOP
EXCH W3,HL.S1 ;OLD BASE
HRLI R,(1B1) ;RELOCATE RHS
SETZ P1, ;NOT SYMBOLIC THOUGH
SUB P3,LC.LB ;MAKE RELATIVE IN CASE CORE MOVES
PUSHJ P,SY.CHR## ;LINK ALL REQUESTS TO EXTTAB
ADD P3,LC.LB ;CAN HAPPEN IF PAGING LC AREA
SOJLE P4,LNKT3 ;DONE IF NO MORE UNDEFS
LNKT2B: SOJGE P2,LNKT2A ;LOOP IF MORE SYMBOLS TO LOOK AT
;HERE TO SET INTTAB
LNKT3: SETZM CS.INT ;INCASE 0 ENTRIES
SKIPN CS.NUM ;NOT REQUIRED IF LINK 0
JRST LNKT4
MOVEI T1,100 ;MAKE SURE ENOUGH SPACE FOR 100 ENTRIES
MOVEM T1,INTCNT
MOVE P3,HL.S1 ;LOWER BOUND
MOVEI P2,2*100(P3) ;ALLOCATE SPACE FOR WORD PAIRS
PUSHJ P,LNKTCK ;MAKE SURE IN CORE
MOVE P2,HT.PRM ;GET INDEX INTO HASH TABLE
LNKT3A: SKIPN T4,@HT.PTR ;GET POINTER TO SYMBOL
JRST LNKT3B ;NO POINTER, NO SYMBOL
ADD T4,GS.LB ;ADD IN BASE
MOVE T1,0(T4) ;GET FLAGS
TXNE T1,PT.SYM ;WE ONLY WANT SYMBOLS
TXNN T1,PS.ENT ;SEE IF AN ENTRY
JRST LNKT3B ;NOT AN ENTRY
TXNE T1,PS.BGS!PS.NOE ;BUT ONLY IF NOT BOUND AND USER DIDN'T SAY NO
JRST LNKT3B ;NO
SOSGE INTCNT ;ENOUGH SPACE
JRST [MOVEI T1,100 ;GET ANOTHER 100 WORDS WORTH
MOVEM T1,INTCNT
ADDB T1,CS.INT ;ACCOUNT FOR THEM
LSH T1,1 ;WORD PAIRS
PUSH P,P2 ;SAVE INDEX INTO HASH TABLE
MOVE P3,HL.S1 ;BASE AGAIN
MOVEI P2,2*100(P3)
ADD P2,T1 ;ADDRESS BOUNDS
PUSHJ P,LNKTCK ;ADDRESS CHECK IT
ADD P3,CS.INT ;ACCOUNT FOR PREVIOUS
ADD P3,CS.INT ; IN PAIRS
POP P,P2
JRST LNKT3A] ;KEEP ON TRYING
DMOVE T1,1(T4) ;GET NAME + VALUE
HRL T2,HL.S1 ;BASE OF TABLE
DMOVEM T1,(P3) ;STORE IN CORE
ADDI P3,2 ;INCREMENT
LNKT3B: SOJGE P2,LNKT3A ;LOOP IF MORE SYMBOLS TO LOOK AT
MOVEI T1,100
SUB T1,INTCNT ;SEE HOW MANY ENTRY POINTS
ADD T1,CS.INT ;INCASE MORE THAN 100
MOVN T2,T1 ;-NUMBER
HRL T2,HL.S1 ;,, ADDRESS
MOVSM T2,CS.INT ;POINTER TO TABLE
LSH T1,1 ;2 WORDS EACH
ADDM T1,HL.S1 ;ACCOUNT FOR THEM
; JRST LNKT4
LNKT4: DMOVE T1,OV.S1 ;SAVE CURRENT
HRR T1,PH.ADD ;HOWEVER LOW REALLY STARTS AFTER SPACE
DMOVEM T1,PV.S1 ;AS PREVIOUS SO MAP CAN COMPUTE LENGTHS
HRRZ T1,ARSIZE ;[635] RESERVE SPACE AFTER INTTAB FOR
ADDB T1,HL.S1 ;[635] ARL'S, PICK UP NEW HL.S1
MOVE T2,HL.S2 ;[635] NEED HI SEG HIGHEST ALSO
HRL T1,T1 ;MAKE THE HIGEST CODE THE
HRL T2,T2 ; HIGHEST SEEN TO HERE
DMOVEM T1,OV.S1 ;SAVE FOR MAP AND EXIT
MOVE T1,HL.S1 ;HIGHEST USED
MOVE T2,T1
SUB T2,PH.ADD ;REMOVE BASE
HRLM T2,CS.COR ;SAVE LENGTH REQUIRED
HRRZM T2,PH.LEN
MOVE P1,CS.NUM ;GET THIS LINK #
ROT P1,-1 ;CUT IN HALF AND MAKE REM SIGN BIT
HRLS T2,OVLBLK ;THIS TRICK PUTS RH(OVLBLK) INTO LH(OVLBLK)
;AND BOTH HALVES IN T2
JUMPL P1,[HRRM T2,@LNKTBL
JRST .+2]
HRLZM T2,@LNKTBL ;DISC BLOCK # OF PREAMBLE
AOS T1,OVLBLK ;ACCOUNT FOR PREAMBLE (OUTPUT IT LATER)
HRRZM T1,PH.OVL ;USE THIS BLOCK FOR CODE
LNKT4A: MOVE P3,PH.CST ;ADDRESS OF CONTROL SECTION
MOVEI P2,CS.ZZ-1(P3) ;UPPER BOUND
PUSHJ P,LNKTCK ;MAKE SURE ITS IN CORE
HRLI P3,CS.HDR ;FORM BLT PTR
MOVEI P2,CS.ZZ-1(P3) ;RESET UPPER BOUND
BLT P3,(P2) ;PUT HEADER IN CORE IMAGE
MOVE T1,HL.S1 ;TOP OF CORE
ADD T1,SPACE ;PLUS BUFFER SPACE
CAMLE T1,[1,,0] ;[1204] STILL IN BOUNDS?
PUSHJ P,E$$PTL## ;[1204] NO, COMPLAIN
MOVEM T1,PH.NFL ;FOR NEXT LINK
MOVN T2,PH.LEN ;TOTAL NO. OF WORDS
HRLM T2,PH.OVL ;IN IOWD FORM
PUSHJ P,LODFIX## ;DO ALL CORE FIXCUPS ETC.
SKIPN PAG.S1 ;PAGING?
JRST LNKT4B ;NO
HRLZ T1,LW.S1
HRR T1,UW.S1
PUSHJ P,LC.OUT## ;MAKE SURE FILE IS CORRECT
SETZM LW.S1 ;NOW START AT FRONT
MOVE T1,LC.UB ;GET TOP
MOVEM T1,LC.AB ;USE ALL SPAE WE CAN
SUB T1,LC.LB
MOVEM T1,UW.S1 ;MAKE IT UPPER BOUND
PUSHJ P,LC.IN## ;READ BACK
;HERE TO SETUP .JBOVL AND UPDATE OVERLAY FILE
LNKT4B: HRRZ T1,OVLBLK ;[666] BLOCK TO START STASHING CODE
USETO OC,(T1) ;SET ON IT
SKIPE CS.NUM ;IF LINK# 0
JRST LNKT4C ;NO
MOVE T1,LC.LB ;BASE
MOVE T2,PH.CST ;START OF CONTROL BLOCK
MOVEM T2,.JBOVL(T1) ;STORE INITIAL PTR
;HERE TO DUMP LC AREA IF NOT PAGING OR ON EACH BUFFER IF PAGING.
LNKT4C: MOVE T1,LC.AB ;[666] USUALLY WILL WANT TO DUMP
SUB T1,LC.LB ;[666] ENTIRE LC AREA, SO CALCULATE
ADDI T1,1 ;[666] SIZE TO DUMP
MOVE T3,PH.LEN ;[666] NUMBER OF WORDS TO DUMP TOTAL
SKIPN PAG.S1 ;[666] HAS LC AREA OVERFLOWED TO DISK?
SKIPA T1,T3 ;[666] NO, DUMP ALL WORDS AT ONCE
CAML T3,UW.S1 ;[666] YES, IF NOT LAST BUF DUMP ALL LC
JRST LNKT4G ;[666] T1 HAS CORRECT # WORDS TO DUMP
SUB T1,UW.S1 ;[666] LAST BUF WHEN PAGING, ONLY DUMP
SUBI T1,1 ;[666] LAST PARTIAL BUFFER
ADD T1,PH.LEN ;[666] GET LENGTH EXACT
LNKT4G: HRLZ T1,T1 ;[666] GENERATE IOWD TO DUMP LC AREA
SETCA T1, ;[666] ..
ADD T1,LC.LB ;[666] ..
SETZ T2, ;TERMINATOR
OUT OC,T1 ;OUTPUT WHOLE AREA
JRST LNKT4D ;OK
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
LNKT4D: SKIPE PAG.S1 ;[666] PAGING?
CAMG T3,UW.S1 ;[666] YES, FINISHED LAST BUFFER?
JRST LNKT4F ;[666] DON'T NEED TO DUMP ANOTHER BUF
MOVE T1,LC.AB ;GET TOP OF WHATS IN USE
SUB T1,LC.LB ;GET DIFF
MOVEI T1,1(T1) ;SO WE CAN ADD NO.
ADDM T1,LW.S1 ;ADJUST WINDOWS
ADDB T1,UW.S1
IORI T3,.IPM ;[666] MAKE SUB COME OUT EVEN .IPS'S
SUB T3,T1 ;[666] DO WE STILL NEED IT ALL?
JUMPGE T3,LNKT4E ;[666] YES, USE ALL OF SPACE AVAILABLE
ADDM T3,UW.S1 ;[666]
ADDB T3,LC.AB ;[666] REDUCE WINDOW NOW
HRLI T3,1(T3) ;[666] FORM BLT PTR
HRRI T3,2(T3) ;[666]
SETZM -1(T3) ;[666] CLEAR FROM (LC.AB)+1
BLT T3,@LC.UB ;[666] THROUGH ALL OF FREE SPACE
LNKT4E: HRLZ T1,LW.S1
HRR T1,UW.S1 ;SETUP NEW WINDOW
PUSHJ P,LC.IN## ;INPUT NEW AREA
JRST LNKT4C ;[666] AND OUTPUT IT
LNKT4F: MOVE T1,PH.LEN ;GET LENGTH WE NEED
ADDI T1,.DBM ;[650] FILL OUT BLOCK
LSH T1,-.DBS2W ;[650] INTO BLOCKS
ADDM T1,OVLBLK ;ACCOUNT FOR THEM
; JRST LNKT5
;HERE FOR LOCAL SYMBOLS
LNKT5: MOVN T1,LSYM ;[666] NEGATED # SYMBOLS FOR IOWD
HRL T1,OVLBLK ;GET FREE BLOCK
MOVS T1,T1
MOVEM T1,PH.SYM ;HOLD LOCAL IN THIS AREA
MOVE T1,LSYM ;CALCULATE # OF BLOCKS LS WILL USE
ADDI T1,.DBM ;[650] ROUND WORDS UP TO NEXT BLOCK
LSH T1,-.DBS2W ;[1214] WORDS TO BLOCKS
ADDM T1,OVLBLK ;UPDATE OVLBLK TO END OF SYMBOLS
SKIPN T1,PAG.LS ;PAGING?
JRST LNKT5B ;NO
JUMPG T1,LNKT5A ;IS UPPER WINDOW SET?
MOVE T1,LSYM ;NO
IORI T1,.DBM ;[666]
LNKT5A: HRL T1,LW.LS ;IOWD
PUSHJ P,LS.OUT## ;WRITE OUT SYMBOLS
MOVEI P1,LS.IX ;EXPAND LS AREA AS MUCH AS WE CAN
MOVE P2,LSYM ;HOW MUCH WE NEED
ADD P2,LS.LB ;MINUS HOW MUCH WE ALREADY HAVE
SUB P2,LS.AB ;GIVES HOW MUCH WE NEED
JUMPLE P2,LNKT5E ;SKIP LNKCOR CALL IF ALREADY ENUF
PUSHJ P,FR.CNT## ;SEE HOW MUCH IS FREE
CAMLE P2,T1 ;AS MUCH AS WE NEED?
MOVE P2,T1 ;NO, USE WHAT WE CAN
PUSHJ P,LNKCOR## ;NEED MORE - TRY FOR IT
PUSHJ P,E$$MEF## ;[1174] TOO BAD
LNKT5E: SETZM LW.LS ;START BACK AT FRONT OF FILE
MOVE T1,LS.AB ;CALCULATE THE
SUB T1,LS.LB ;LENGTH
IFL .IPS-2*.DBS,<
CAIGE T1,2*.DBS ;[650] MUST HAVE THIS MUCH FOR FIXUPS
PUSHJ P,E$$MEF## ;[1174] TOO BAD
> ;END IFL .IPS-2*.DBS
MOVEM T1,UW.LS ;OF WINDOW
PUSHJ P,LS.IN## ;INPUT IT
;HERE IF NOT PAGING OR ON EACH BUFFER OF SYMBOLS IF PAGING
LNKT5B: MOVE T1,LS.AB ;SAME AS FOR LC
SUB T1,LS.LB
ADDI T1,1 ;[666] WILL USUALLY WANT TO DUMP ALL LS
MOVE T3,LSYM ;[666] GET # WORDS TO DUMP TOTAL
SKIPE PAG.LS ;[666] IS LS AREA ON DISK?
JRST LNKT5F ;[666] YES, T1 MAY BE OK
MOVE T1,T3 ;[666] DO ONE DUMP, EXACT RIGHT # WORDS
JRST LNKT5H ;[666] GO DUMP THE LS AREA
LNKT5F: CAMG T3,UW.LS ;[666] IS THIS THE LAST BUF OF SYMBOLS?
JRST LNKT5G ;[666] YES, SPECIAL STUFF
SUBI T1,.DBS ;[666] NO, DON'T DUMP LAST WORDS TILL
JRST LNKT5H ;[666] NEXT TIME SO FIXUPS CAN BE DONE
LNKT5G: SUB T1,UW.LS ;[666] LAST BUF IF PAGING, REDUCE COUNT
SUBI T1,1 ;[666] DON'T BE OFF BY ONE
ADD T1,LSYM ;[666] WE DON'T WANT TO DUMP TOO MUCH
LNKT5H: HRLZ T1,T1 ;[666] GENERATE IOWD TO DUMP LS AREA
SETCA T1, ;[666] ..
ADD T1,LS.LB ;[666] ..
SETZ T2,
OUT OC,T1
JRST LNKT5C
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
LNKT5C: SKIPE PAG.LS ;PAGING?
CAMG T3,UW.LS ;YES, SEE IF MORE TO DO
JRST LNKT6 ;NO, ALL DONE
MOVE T1,LS.AB ;[666] WINDOW MOVES UP BY SIZE OF
SUB T1,LS.LB ;[666] LS AREA MINUS .DBM
ANDCMI T1,.DBM ;[666] FIGURE WINDOW OFFSET INTO T1
ADDM T1,LW.LS ;[666] MOVE THE WINDOW UP
ADDB T1,UW.LS ;[666] ..
IORI T3,.IPM ;[666] MAKE SUB BELOW COME OUT .IPS'S
SUB T3,T1 ;[666] ARE WE DUMPING FINAL PART WINDOW?
JUMPGE T3,LNKT5D ;[666] NO, PROCEED AS USUAL
SUBI T3,.DBS ;[666] YES, FIX ANDCMI .DBM ABOVE
ADDM T3,UW.LS ;[666] GET RID OF EXTRA LS SPACE
ADDB T3,LS.AB ;[666] ADJUST POINTERS, THEN BLT IT ZERO
HRLI T3,1(T3)
HRRI T3,2(T3) ;FORM BLT PTR
SETZM -1(T3)
BLT T3,@LS.UB ;TO CLEAR ALL EXCESS CORE
LNKT5D: HRLZ T1,LW.LS ;[666] LOWER WINDOW ADDR TO FILL
HRR T1,UW.LS ;[666] UPPER WINDOW ADDR
PUSHJ P,LS.IN## ;GET WINDOW
JRST LNKT5B ;AND OUTPUT IT
;HERE FOR RELOCATION TABLES
LNKT6: SETZM PH.REL ;[671] ASSUME NO RELOCATION
SETZM PH.ORL ;[671] AND NO "OTHER" RELOCATION
SKIPN RT.LB ;SETUP YET?
JRST LNKT7 ;NO
HRRZ P3,HL.S1 ;GET HIGHEST LOC USED
PUSHJ P,RT.P3## ;SETUP RT.PT TO IT
MOVE T1,RT.LB
HRRZ T2,RT.PT
SUBI T1,1(T2) ;- LENGTH ACTUALLY USED
HRL T1,OVLBLK
MOVSM T1,PH.REL ;-LENGTH ,, BLOCK NUMBER
MOVE T1,RT.AB
SUB T1,RT.LB ;LENGTH
AOS T2,T1 ;ACTUALLY ONE LARGER
LSH T2,-.DBS2W ;[650] NO. OF BLOCKS
ADDM T2,OVLBLK
MOVN T1,T1
HRLZ T1,T1
HRR T1,RT.LB
HRRI T1,-1(T1) ;IOWD AT LAST
SETZ T2,
OUT OC,T1
CAIA
PUSHJ P,E$$OOV## ;[1174]
SKIPN RBGPTR ;ANY OTHER RELOCATION
JRST LNKT7 ;NO
MOVE T1,RT.LB ;YES, GET AREA TO HOLD IT IN
MOVEM T1,RT.PT ;POINT TO FIRST FREE
HRL T1,T1
ADDI T1,1 ;BLT PTR
SETZM -1(T1) ;CLEAR FIRST WORD
BLT T1,@RT.AB ;AND REST
MOVE T1,RT.LB
IORI T1,.IPM
MOVEM T1,RT.AB ;ALLOCATE ONE BLOCK
SUB T1,RT.LB ;FREE SPACE
MOVEM T1,RT.FR ;IN THIS BLOCK
;USES ACCS AS FOLLOWS
;P1 = TO HOLD RBGPTR TO WHATS LEFT
;P2 = CURRENT LINK #
;P3 = TO HOLD LIST FOR THIS LINK
LNKT6A: MOVE P1,RBGPTR ;GET START OF LIST
HRRZ P3,P1 ;SET INITIAL PTR
SETZM RBGPTR ;WILL PUT BACK THOSE NOT REQUIRED
MOVE T1,P1 ;GET FIRST ITEM IN LIST
ADD T1,FX.LB ;FIX IN CORE
HLRZ P2,(T1) ;GET LINK#
HRRZ P1,(T1) ;GET NEXT ITEM PTR
HLLZS (T1) ;CLEAR THIS PTR
LNKT6B: SKIPN T1,P1 ;GET NEXT ITEM
JRST LNKT6L ;LIST EMPTY
ADD T1,FX.LB ;FIX IN CORE
HRRZ P1,(T1) ;GET PTR TO NEXT
HLLZS (T1) ;CLEAR PTR
HLRZ T2,(T1) ;GET LINK#
CAMN T2,P2 ;THIS THE ONE WE WANT?
JRST LNKT6C ;YES
MOVE T2,T1
SUB T2,FX.LB ;REMOVE BASE
EXCH T2,RBGPTR
HRRM T2,(T1) ;PUT BACK IN LIST
JUMPN P1,LNKT6B ;IF NOT END
JRST LNKT6L ;END OF THIS CHAIN
LNKT6C: HRRZ T2,1(T1) ;GET ADDRESS WE WANT TO ADD
MOVE T3,P3 ;START OF CHAIN
LNKT6M: ADD T3,FX.LB ;MAKE ABS
HRRZ T4,1(T3) ;ADDRESS IN CHAIN
CAML T2,T4 ;FOUND OUR PLACE YET?
JRST LNKT6G ;NO
HLRZ T3,T3 ;PUT LAST ADDRESS BACK
JUMPE T3,[HRRM P3,0(T1) ;PUT IN FRONT OF LIST
SUB T1,FX.LB
MOVE P3,T1 ;RESET BASE PTR
JRST LNKT6B] ;GET NEXT
MOVE T4,0(T3) ;GET FORWARD PTR
HRRM T4,0(T1) ;PUT INTO NEW BLOCK
LNKT6D: SUB T1,FX.LB ;MAKE REL
HRRM T1,0(T3) ;AND MAKE LAST POINT TO IT
JRST LNKT6B ;GET NEXT
LNKT6G: HRL T3,T3 ;SAVE LAST PTR
HRR T3,0(T3) ;GET NEXT
TRNE T3,-1 ;0 IS END OF LIST
JRST LNKT6M ;NO, MORE TO COME
MOVS T3,T3 ;SWAP BACK
JRST LNKT6D ;PUT LAST IN LIST
LNKT6L: MOVE T1,RT.PT ;GET PTR
SUB T1,RT.LB ;MAKE RELATIVE
PUSH P,T1 ;SAVE PTR SO WE CAN ADD COUNT LATER
AOS RT.PT
SOS RT.FR ;ACCOUNT FOR WORD
MOVE T1,BRNADD ;GET START OF ADDRESS TABLE
HRLI T1,-^D128 ;MAX SIZE?
MOVS T2,(T1) ;GET LINK#
CAIN P2,(T2) ;ONE WE WANT?
JRST .+3 ;YES
AOBJN T1,.-3 ;NO
HALT
MOVS P1,T2 ;LINK# ,, ADDRESS
SETZ T1, ;NO PREVIOUS
PUSHJ P,RT.DPB ;STORE IT
LNKT6K: SKIPN T1,P3 ;COPY OF PTR
JRST LNKT6R ;END OF LIST
ADD T1,FX.LB
HRRZ P3,0(T1) ;GET NEXT
JUMPE P1,[MOVE P1,1(T1) ;NO PREVIOUS
JRST LNKT6K] ;GET NEXT
HRRZ T2,1(T1) ;ADDRESS OF THIS RELOC WORD
SUBI T2,(P1) ;- PREVIOUS
CAIL T2,^D9 ;WITHIN RANGE?
JRST [PUSH P,1(T1) ;GET THIS VALUE
PUSHJ P,RT.DPB ;DUMP CURRENT
POP P,P1 ;RESET THIS ONE
JRST LNKT6K] ;GET NEXT
HLLZ T3,1(T1) ;GET RELOC BITS
IMULI T2,-2 ;2 BITS PER WORD
LSH T3,(T2) ;SHIFT INTO POSSITION
IOR P1,T3
JUMPN P3,LNKT6K ;TRY NEXT WORD
;HERE TO CHECK TO SEE IF MORE TO DO AND OUTPUT RT AREA IF NOT.
LNKT6R: SKIPE P1 ;PREVIOUS TO STORE STILL?
PUSHJ P,RT.DPB ;YES
POP P,P1 ;GET PTR TO START OF TABLE
ADD P1,RT.LB ;MAKE ABS
MOVE T1,RT.PT ;PTR TO END
SUBI T1,1(P1) ;LENGTH
MOVEM T1,(P1) ;PUT IT IN
SKIPE P1,RBGPTR ;MORE TO DO?
JRST LNKT6A ;YES
LNKT6Z: MOVE T1,RT.LB
HRRZ T2,RT.PT
SUBI T1,1(T2) ;- LENGTH ACTUALLY USED
HRL T1,OVLBLK
MOVSM T1,PH.ORL ;-LENGTH ,, BLOCK NUMBER
MOVE T1,RT.AB
SUB T1,RT.LB ;LENGTH
AOS T2,T1 ;ACTUALLY ONE LARGER
LSH T2,-.DBS2W ;[650] NO. OF BLOCKS
ADDM T2,OVLBLK
MOVN T1,T1
HRLZ T1,T1
HRR T1,RT.LB
HRRI T1,-1(T1) ;IOWD AT LAST
SETZ T2,
OUT OC,T1
JRST LNKT7
PUSHJ P,E$$OOV## ;[1174]
RT.DPB: SOSL RT.FR ;ANY ROOM
JRST RTDPB1 ;YES
SPUSH <T1,P1,P2>
MOVEI P1,RT.IX ;NEED MORE ROOM
MOVEI P2,.IPS
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
SPOP <P2,P1,T1>
RTDPB1: MOVEM P1,@RT.PT
AOS RT.PT
MOVE P1,T1 ;STORE NEW AS PREVIOUS
POPJ P,
;HERE FOR GLOBAL SYMBOLS
LNKT7: MOVE T1,HT.PTR ;ABS ADDRESS OF HASH TABLE
SUB T1,GS.LB ;RELATIVE
HRL T1,HT.PRM ;NEED TO SAVE THE HASH NUMBER
MOVEM T1,@GS.LB ;IN A SAFE PLACE
MOVE T1,OVLBLK
HRRZM T1,PH.GLB ;POINT TO BLOCK
MOVE T1,GS.AB ;SAME AS FOR LC
SUB T1,GS.LB
ADDI T1,1 ;[1205] SIZE REQUIRED
MOVEI T2,.DBM(T1) ;[1205] ROUND UP TO BLOCK BOUND
LSH T2,-.DBS2W ;[650]
ADDM T2,OVLBLK
MOVN T1,T1
HRLZ T1,T1
HRR T1,GS.LB
HRRI T1,-1(T1)
HLLM T1,PH.GLB
SETZ T2,
OUT OC,T1
JRST LNKT8
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
;HERE TO OUTPUT PREAMBLE - MUST BE LAST
LNKT8: HLRZ T1,OVLBLK ;GET BLOCK RESERVED FOR PREAMBLE
USETO OC,(T1) ;SET ON IT
DMOVE T1,PHIOWD ;SINCE IOWD CAN NOT BE IN HIGH SEG YET
OUT OC,T1
JRST LNKT9
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
LNKT9: MOVE T1,CS.NUM ;GET THIS LINK
MOVEM T1,PH.BPT ;AS BACK POINTER FOR NEXT LINK
;HERE TO ZERO VARIOUS AREAS
;HERE TO ZERO LOW CODE AREA
LNKZLC: MOVE T1,LC.LB ;BASE
HRL T1,T1
ADDI T1,1 ;BLT PTR
SETZM -1(T1) ;CLEAR FIRST WORD
BLT T1,@LC.AB ;AND REST
MOVE T1,LC.LB
IORI T1,.IPM ;PRE-ALLOCATE ONE BLOCK ONLY
MOVEM T1,LC.AB
SKIPN PAG.S1 ;PAGING?
JRST LNKZRT ;NO
MOVEI T1,LC ;CHAN# IF ON DSK
MOVEM T1,IO.CHN
PUSHJ P,DVDEL.## ;DELETE FILE
JFCL ;INCASE OF ERRORS
PUSHJ P,DVZAP.## ;GET RID OF DATA BLOCK
SETZM LW.S1 ;ZERO ALL PAGING INFO
SETZM UW.S1
SETZM HB.S1
;HERE TO ZERO THE RELOCATION TABLE
LNKZRT: SKIPN T1,RT.LB ;DO WE HAVE SPACE ALLOCATED?
JRST LNKZLS ;NO
HRL T1,T1
ADDI T1,1 ;BLT PTR
SETZM -1(T1) ;CLEAR FIRST WORD
BLT T1,@RT.AB ;AND REST
MOVE T1,RT.LB
IORI T1,.IPM ;PRE-ALLOCATE ONE BLOCK ONLY
MOVEM T1,RT.AB
SKIPN PAG.RT ;PAGING
JRST LNKZLS ;NO
HALT
;HERE TO ZERO LOCAL SYMBOL AREA
LNKZLS: MOVE T1,LS.LB ;BASE
HRL T1,T1
ADDI T1,1 ;BLT PTR
SETZM -1(T1) ;CLEAR FIRST WORD
BLT T1,@LS.AB ;AND REST
MOVE T1,LS.LB
ADDI T1,1 ;PRE-ALLOCATE FIRST WORD
MOVEM T1,LS.PT ;SO USER CAN NOT GET IT
IORI T1,.IPM ;PRE-ALLOCATE ONE BLOCK ONLY
MOVEM T1,LS.AB
MOVEI T1,.IPM ;NO. OF WORDS FREE
MOVEM T1,LS.FR ;IN THIS BLOCK
SKIPN PAG.LS ;PAGING?
JRST LNKZFX ;NO
MOVEI T1,SC ;CHAN# IF ON DSK
MOVEM T1,IO.CHN
PUSHJ P,DVDEL.## ;DELETE FILE
JFCL ;INCASE OF ERRORS
PUSHJ P,DVZAP.## ;GET RID OF DATA BLOCK
SETZM LW.LS ;ZERO ALL PAGING INFO
SETZM UW.LS
SETZM HB.LS
;HERE TO ZERO AND REMOVE THE FIXUP AREA
LNKZFX: MOVEI T1,FX.IX ;AREA#
SKIPE TAB.LB(T1) ;SET UP?
PUSHJ P,XX.ZAP## ;YES, DELETE WHOLE AREA
MOVE T1,[FX.S1,,FX.S2]
SETZM FX.S1
BLT T1,FXC.SS ;CLEAR ALL POINTERS
;HERE TO ADD GS TO BG AND ZERO GS
LNKZBG: SKIPE BG.LB ;BOUND GLOBAL TABLE SET UP
JRST LNKZGS ;YES
SETOM BG.SCH ;WILL BE ALLOWED TO SEARCH THEM
MOVEI T2,^D128 ;SETUP BRANCH TABLES
PUSHJ P,DY.GET##
HRLI T1,P1 ;PUT INDEX IN P1 FOR @
MOVEM T1,BRNTBL ;LINK # ,, REL ADDRESS
MOVEI T2,^D128
PUSHJ P,DY.GET##
HRLI T1,P1 ;PUT INDEX IN P1 FOR @
MOVEM T1,BRNADD ;LINK# ,, LOWEST ADDRESS
MOVEI T2,^D128
PUSHJ P,DY.GET##
HRLI T1,P1 ;PUT INDEX IN P1 FOR @
MOVEM T1,BRNDSK ;LENGTH ,, DSK BLOCK #
MOVE T2,GS.PT ;LAST LOC USED
SUB T2,GS.LB ;- FIRST = LENGTH
MOVSM T2,(T1) ;STORE LENGTH
MOVSI T1,-^D127 ;AOBJN WORD FOR NUMBER LEFT
MOVEM T1,BRNLEN
MOVE T1,GS.AB ;TOP IN ACTUAL USE
CAML T1,GS.UB ;ANY FREE?
JRST [MOVEI P1,GS.IX ;EASIEST WAY IS TO EXPAND
MOVEI P2,.IPS ;BY ONE BLOCK
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
MOVNI T1,.IPS ;NOW TAKE BACK EXTRA
ADDM T1,GS.FR ;NO MORE FREE THAN BEFORE
ADDB T1,GS.AB
JRST .+1] ;AND CONTINUE
MOVEM T1,BG.AB ;MOVE AREA
MOVEM T1,BG.UB ; BY MOVING THE POINTERS
MOVE T2,GS.LB
MOVEM T2,BG.LB
MOVE T2,GS.PT
MOVEM T2,BG.PT ;POINT TO NEXT FREE
MOVE T2,GS.FR
MOVEM T2,BG.FR ;AND FREE SPACE IN IT
ADDI T1,1 ;NEXT FREE WILL BE START OF NEW GS
MOVEM T1,GS.LB
JRST LNKZHT ;NOW SET UP HASH TABLES ETC.
LNKZGS: MOVE T1,BG.UB ;SEE IF ENOUGH CORE
SUB T1,BG.PT
ADD T1,GS.UB ;IN GS +BG
SUB T1,GS.PT
CAIL T1,.IPS ;SO WE CAN MOVE AND ALLOCATE 1 BLOCK
JRST LNKZG1 ;OK, NO PROBLEM
MOVEI P1,BG.IX
MOVEI P2,.IPS
PUSHJ P,LNKCOR## ;EXPAND
PUSHJ P,E$$MEF## ;[1174] TOO BAD
MOVNI T1,.IPS
ADDM T1,BG.AB ;DON'T REALLY WANT IT
LNKZG1: MOVE P1,BRNLEN ;GET NO. OF LINKS IN BRANCH
AOBJP P1,[HALT]
MOVEM P1,BRNLEN ;ALL OK
HRRZ P1,P1 ;INDEX ONLY
CAMLE P1,BRNMAX ;DEEPEST YET?
MOVEM P1,BRNMAX ;YES, STORE FOR LATER
MOVE T2,BG.PT ;NEXT FREE LOC
SUB T2,BG.LB ;REMOVE BASE
HRL T2,CS.NUM ;LINK # IN LEFT
MOVEM T2,@BRNTBL
HLLZ T3,T2 ;LINK#
HRR T3,PH.ADD ;STARTING ADDRESS
MOVEM T3,@BRNADD ;IN CASE RELOCATABLE
MOVE T3,GS.PT ;NOW FOR LENGTH OF NEW GLOBAL
SUB T3,GS.LB
ADDM T3,BG.PT ;ACCOUNT FOR IT
MOVSM T3,@BRNDSK
ADD T2,BG.LB ;PUT BACK BASE
HRL T2,GS.LB ;FORM BLT PTR
BLT T2,@BG.PT ;MOVE ALL WORDS
HRRZ T1,BG.PT ;NOW CLEAN UP
SETZM (T1)
HRL T1,T1
ADDI T1,1
BLT T1,@GS.AB ;ALL OF GS AREA
MOVE T1,BG.PT
MOVE T2,T1
IORI T1,.IPM ;THIS IS TOP
MOVEM T1,BG.AB
MOVEM T1,BG.UB ;NO WASTED SPACE
SUB T2,T1 ;SEE WHATS LEFT
MOVMM T2,BG.FR
ADDI T1,1 ;START OF GS
MOVEM T1,GS.LB
;HERE TO SET UP HASH TABLE
LNKZHT: IORI T1,.IPM ;MUST ALLOCATE 1 BLOCK
MOVEM T1,GS.AB ;TO KEEP LNKCOR HAPPY
ANDCMI T1,.IPM-1 ;PRE-ALLOCATE FIRST WORD
HRLI T1,P2 ;USES P2 AS INDEX
MOVEM T1,HT.PTR ;START OF NEW HASH TABLE
MOVEI T2,I.PRM ;INITIAL HASH TABLE
MOVEM T2,HT.PRM ; PRIME NUMBER
HRRZI T1,I.PRM(T1) ;SEE IF ENOUGH SPACE FOR WHAT WE NEED
CAMG T1,GS.UB ;WELL?
JRST LNKZB1
SUB T1,GS.UB ;EXTRA WE NEED
MOVEI P1,GS.IX
MOVE P2,T1
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174] FAILED
LNKZB1: MOVE T1,GS.LB ;GET BASE
SETOM (T1) ;MAKE NON-ZERO SO WE DON'T LOAD JOBDAT AGAIN
ADDI T1,1+<I.PRM+.L-1>/.L*.L ;SPACE RESERVED FOR HASH TABLE
MOVEM T1,GS.PT ;MAKE SURE CORRECT
MOVE T2,T1
IORI T2,.IPM ;NOW RESET TO WHAT IT SHOULD BE
MOVEM T2,GS.AB ;INCASE MORE THAN ONE BLOCK LONG
SUB T1,T2 ;- WHATS FREE
MOVNM T1,GS.FR ;IN GS BLOCK
MOVEI T1,I.PRM*.HS%/^D100 ;INITIAL AMOUNT FREE
MOVEM T1,HSPACE ;BEFORE WE REHASH
MOVSI T1,(POINT 18,0)
MOVEM T1,PRMPTR ;START HASH POINTER AT REL 0
SETZM GS.LNK ;NO FREE SPACE IN LINKED LISTS
SETZM GS.FSP
;HERE TO INITIALIZE THE REST OF LOW CORE
E$$ELN::.ERR. (MS,.EC,V%L,L%I6,S%I,ELN,<End of>) ;[1174]
.ETC. (JMP,.EC,,,,.ETLNN##) ;[1174]
.ETC. (BKL) ;[1174] BLANK LINE IN THE LOG FILE
LNKZA: MOVEI R,1 ;POINT TO RELOC TABLE 1
MOVE R,@RC.TB
MOVE T1,PH.NFL ;NEXT FREE LOC
MOVEM T1,PH.ADD ;SET ORIGIN OF NEXT LINK
MOVEM T1,RC.CV(R) ;SET AS NEW CURRENT VALUE
MOVEM T1,RC.HL(R) ;[1152] AND AS NEW FIRST FREE
PUSHJ P,Z.INEX## ;CLEAR INCLUDE/EXCLUDE STORAGE
MOVSS INCPTR ;BOTH HALVES
MOVSS EXCPTR
PUSHJ P,Z.INEX##
MOVE T1,[OV1.Z0,,OV1.Z0+1]
SETZM OV1.Z0 ;CLEAR PASS1 DATA
BLT T1,OV1.ZE
MOVE T1,[CS.NUM,,CS.NUM+1]
SETZM CS.NUM
BLT T1,CS.HDR+CS.ZZ-1
SKIPN T1,LINKTB ;[660] .LINK TABLE SET UP?
JRST LNKZA0 ;[660] NO
SETZM LINKTB ;[660] YES, DELETE IT
HRRZ T1,T1 ;[660] ADDRESS TO GIVE BACK ONLY
MOVEI T2,LN.12 ;[660] LENGTH
PUSHJ P,DY.RET## ;[660] RETURN THE BLOCK
LNKZA0: SETZM %OWN ;[660] CANNOT LINK ALGOL OWN YET
SETZM HL.S1
SETZM MNSEEN ;NO MAIN PROGRAMS SEEN YET
SETZM MNTYPE ;SO DON'T KNOW LIBRARIES, CPU ETC.
SETZM NOLIBS
SETZM NAMPTR
SETZM PRGNAM
SETZM LSTSYM
;CONTINUED ON NEXT PAGE
;FALL IN FROM PREVIOUS PAGE
SETZM GOTO ;SO WE DON'T LOOP
HLRS ARSIZE ;[635] RESET STICKY SIZE FOR ARL TABLE
MOVEI T1,.SPL ;SET DEFAULT SPACE
MOVEM T1,SPACE ;[635] FOR NON-ROOT LINKS
AOS LSYM ;ALLOCATE FIRST WORD
HLLZ T1,OVINEX ;SEE IF ANY INCLUDES TO SETUP
JUMPE T1,LNKZA1 ;NO
MOVEI T2,.EXC ;GET SPACE
PUSHJ P,DY.GET##
HRLZM T1,INCPTR ;SET IT UP
HLLZ T2,OVINEX ;FROM
HRR T2,T1 ;TO
BLT T2,.EXC-1(T1) ;MOVE
HRRZ T2,(T1) ;SEE IF MORE
SKIPE T2 ;NO
PUSHJ P,OVRINX ;YES
LNKZA1: HRRZ T1,OVINEX ;SEE IF EXCLUDES
JUMPE T1,LNKZA2 ;NO
MOVEI T2,.EXC ;GET SPACE
PUSHJ P,DY.GET##
HRLZM T1,EXCPTR ;SET IT UP
HRLZ T2,OVINEX ;FROM
HRR T2,T1 ;TO
BLT T2,.EXC-1(T1) ;MOVE
HRRZ T2,(T1) ;GET NEXT
SKIPE T2 ;IF NONE
PUSHJ P,OVRINX ;OTHERWISE MOVE REST
LNKZA2: MOVE T1,OVERLW ;GET OVERLAY SWITCHES
SKIPN RT.LB ;ALREADY SETUP?
TXNN T1,$OVRELOC ;NO, BUT DO WE NEED IT
POPJ P, ;NO, RETURN TO EITHER LNKOV1 OR LNKOV2
MOVEI P1,RT.IX ;AREA WE WANT
PJRST XX.INI## ;SET IT UP
LNKTCK: SKIPE RT.LB ;RELOCATABLE?
PUSHJ P,RT.P2## ;YES, SETUP BYTE PTR
SUB P2,PH.ADD ;REMOVE BASE ADDRESS INCASE ABS
SUB P3,PH.ADD ;...
SKIPE PAG.S1 ;PAGING?
JRST LNKTC2 ;YES
ADD P2,LC.LB ;RELOCATE
CAMG P2,LC.AB ;FIT IN WHAT WE HAVE?
JRST LNKTC1 ;YES
SUB P2,LC.AB ;GET EXTRA REQUIRED
MOVEI P1,LC.IX
PUSHJ P,LNKCOR##
JRST LNKTC2 ;MUST BE ON DSK NOW
SUB P3,LW.S1 ;INCASE WE DUMPED CORE
LNKTC1: ADD P3,LC.LB ;RELOCATE
POPJ P,
LNKTC2: PUSHJ P,PG.LSG## ;MAKE SURE IN CORE
JRST LNKTC1 ;IS BY NOW
LKSTER: PUSHJ P,E$$USA## ;[1174] UNDEFINED MESSAGE
SETZM STADDR ;CLEAR ADDRESS
POPJ P,
SUBTTL DO OPEN & ENTER FOR OV FILE
OC.OPN::MOVEI T2,LN.IO ;GET SPACE FOR LOOKUP/ENTER BLOCK
PUSHJ P,DY.GET##
MOVEM T1,IO.PTR+OC ;STORE POINTER
MOVE T3,IO.PTR+%OC ;GET PTR TO REAL BLOCK
MOVEI T2,.IODPR ;MODE 16
MOVEM T2,I.MOD(T1)
SKIPN T2,I.DEV(T3) ;USE WHAT USER SPECIFIED
MOVSI T2,'DSK'
MOVEM T2,I.DEV(T1)
MOVEI T2,LN.RIB-1 ;SIZE OF EXTENDED RIB
MOVEM T2,I.RIB(T1)
MOVE T2,I.EXT(T3) ;GET USER EXT OR DEFAULT
MOVEM T2,I.EXT(T1) ;USE IT FOR LOOKUP
MOVE T2,I.PPN(T3) ;[651] COPY PPN SPECIFIED
MOVEM T2,I.PPN(T1) ;[651] TO TMP FILE DATA BLOCK
HRLZI T2,I.PTH(T3) ;[651] COPY ALL SFD'S ALSO
HRRI T2,I.PTH(T1) ;[651] VIA STANDARD BLT
BLT T2,I.PTH+LN.SFD-1(T1) ;[651] BUT NOT TOO FAR
MOVEI T1,OC ;SET CURRENT CHAN #
MOVEM T1,IO.CHN
PUSHJ P,DVNAM.## ;SET UP OUTPUT NAME
PUSHJ P,DVSUP.## ;DETERMINE STRUCTURE
PJRST E$$OFS ;[1174] DEV IS NOT A DSK, DIE
MOVE T1,IO.PTR+OC ;RESTORE THE I/O DATA
MOVE T3,IO.PTR+%OC ; BLOCK POINTERS
MOVE T2,JOBNUM ;SIXBIT JOB NUMBER
HRRI T2,'OVL'
MOVEM T2,I.NAM(T1) ;AS FILE NAME
MOVSI T2,'TMP' ;EXT
MOVEM T2,I.EXT(T1)
MOVSI T2,077000 ;PROTECTION
MOVEM T2,I.PRV(T1)
SKIPN T2,I.EST(T3) ;SEE IF USER SUPPLIED
MOVEI T2,1000 ;REAL JOBS ARE BIG
MOVEM T2,I.EST(T1)
MOVEI T1,OC ;CHAN#
PUSHJ P,DVUPD.## ;OPEN IN UPDATE MODE
JRST E$$EOV ;[1174] FAILED
POPJ P,
E$$OFS::.ERR. (MS,0,V%M,L%F,S%F,OFS,<Overlay file must be created on a file structure>) ;[1174]
E$$EOV::PUSH P,IO.CHN ;[1174] TELL ERROR ROUTINE CHANNEL NUMBER
.ERR. (LRE,.EC,V%L,L%F,S%F,EOV,<Error creating overlay file>) ;[1174]
SUBTTL SWITCH ACTION -- /NODE:name
%NODE::
%RESET::
PUSHJ P,.SAVE4##
SKIPN LINKSEEN ;PREVIOUS SEGMENT COMPLETED?
PUSHJ P,[PUSHJ P,.SAVE4## ;WILL NEED P2
MOVE P2,LNKMAX ;OVERLAY COUNT
ADDI P2,1 ;OVERLAY NUMBER
E$$LSM::.ERR. (MS,.EC,V%L,L%W,S%W,LSM,</LINK switch missing while loading link number >) ;[1174]
.ETC. (DEC,.EC!.EP,,,,P2) ;LINK NUM
.ETC. (STR,,,,,,< -- assumed>)
PUSHJ P,SYSLB1## ;SEARCH LIBRARIES
SETZM LNKNAM ;/LINK:<LNKNAM>
PJRST LINKGT] ;FORCE /LINK
SETZM LINKSEEN ;STARTING NEW SEGMENT
MOVE T2,2(P2) ;RESTORE /NODE VALUE
TLNN T2,-1 ;TEST FOR NAME
JRST RSTA ;CERTAINLY NOT
TLC T2,-1 ;BUT MIGHT BE NEGATIVE NO.
TLCE T2,-1
JRST RSTL ;NO, ITS A NAME
RSTA: CAMN T2,LNKMAX ;TEST FOR TRIVIAL CASE
POPJ P, ;IT WAS, LEAVE AS IS
CAMLE T2,LNKMAX ;IS IT IN RANGE?
JRST E$$LNL ;[1174] NO
MOVEM T2,CS.NUM ;NO, STORE SO WE KNOW WHO TO LINK TO
MOVE P2,T2 ;SAFER PLACE FOR LINK#
JUMPE P2,RESET0 ;RESET TO ROOT IS SPECIAL
JUMPL P2,RSTN ;STILL A NEGATIVE NO.?
MOVS T1,LSTPTR ;SEE IF SPECIAL CASE
MOVE T2,(T1) ;OF WANTING PENULTIMATE LINK
CAIE P2,(T2)
JRST RST2 ;NO, GENERAL CASE
;HERE ON A /NODE TO THE ROOT LINK.
RSTB: HLL T1,(T1) ;FORM AOBJN PTR
ADD T1,[2,,2] ;BYPASS LINK# AND BACK PTR
SKIPN (T1) ;BLANK?
JRST RST1 ;YES
AOBJN T1,.-2
HLRZ T1,LSTPTR ;GET NODE BLOCK
HLRE T2,(T1) ;GET LENGTH
MOVM T2,T2
ADDI T2,1 ;MAKE ONE MORE
PUSHJ P,DY.GET##
HLLZ T3,LSTPTR ;FROM
HRR T3,T1 ;TO, BLT PTR
MOVN T4,T2 ;- LENGTH
HLL T2,LSTPTR ;SAVE START OF OLD BLOCK
HRLM T1,LSTPTR
ADDI T1,-2(T2) ;END OF BLT
BLT T3,(T1) ;MOVE DATA
HRRM T1,LSTPTR ;RESET LAST POINTER
SUBI T1,-2(T2) ;BACKUP
HRLM T4,(T1) ;SET NEW COUNT
HLRZ T1,T2 ;OLD ORIGIN
HRRZI T2,-1(T2) ;OLD BLOCK SIZE
PUSHJ P,DY.RET##
HLRZ T1,LSTPTR ;GET NEW BLOCK AGAIN
HRRZ T2,(T1) ;THIS LINK#
SKIPN T3,1(T1) ;BACK POINTER
JRST [MOVEM T1,FSTPTR ;MUST BE LINK# 0
JRST RSTBB]
MOVS T4,2(T3) ;GET LINK#
CAIE T2,(T4) ;ONE WE WANT
AOJA T3,.-2 ;MUST BE THERE
HRRM T1,2(T3) ;MAKE IT POINT TO NEW BLOCK
RSTBB: MOVEI T3,2(T1) ;NOW LOOK AT POSSIBLE FORWARD PTRS
RSTC: SKIPN T2,(T3) ;GET POINTER
JRST RST1 ;ALL DONE
TRNE T2,-1 ;FORWARD PTR?
HRRM T1,1(T2) ;YES
AOJA T3,RSTC
;THIS CASE IS SPECIAL IN THAT ALL THAT HAS TO BE DONE IS TO DELETE
;THE LAST LINK STORED AND ADJUST THE POINTERS ACCORDINGLY
RST1: AOS LSTPTR ;MAKE ROOM IN CURRENT BLOCK
RST1A: HRRZ P1,BRNLEN ;GET POINTER TO LAST LINK STORED
PUSHJ P,CHKBRN ;SEE IF LINK AS AT TOP OF TABLE
JRST RST1C ;ON DSK SO NOTHING TO DO
RST1B: SETZM (T1) ;ZERO FIRST WORD
HRLZ T2,T1
HRRI T2,1(T1) ;BLT PTR
BLT T2,@BG.AB ;DELETE ALL AREA
MOVEM T1,BG.PT ;NEW TOP OF AREA USED
IORI T1,.IPM ;PUT ON BLOCK BOUND
MOVEM T1,BG.AB ;MAKE NEW TOP
MOVEM T1,BG.UB
ADDI T1,1 ;NEW START OF GS AREA
HRLZ T2,GS.LB
HRR T2,T1 ;BLT PTR
SUB T1,GS.LB ;- DIFF
JUMPE T1,RST1C ;SHOULD NOT HAPPEN
ADDM T1,GS.LB ;FIXUP PTR
ADDM T1,GS.AB
ADDM T1,GS.PT
ADDM T1,HT.PTR
BLT T2,@GS.AB ;MOVE AREA DOWN
MOVM T1,T1 ;+ DIFF
ADD T1,GS.AB ;GET OLD END AGAIN
HRRZ T2,GS.AB
HRLI T2,1(T2)
HRRI T2,2(T2) ;BLT PTR
SETZM -1(T2)
BLT T2,(T1) ;CLEAR ALL OF AREA LEFT
RST1C: MOVE T1,BRNLEN ;GET OLD LENGTH
HRRZ P1,T1 ;INDEX INTO BRANCH TABLES
SETZM @BRNTBL ;AVIODS CONFUSION
SETZM @BRNDSK
SETZM @BRNADD
SUB T1,[1,,1] ;BACKUP
MOVEM T1,BRNLEN ;AND RESET IT
MOVE P1,CS.NUM ;GET NUMBER WE WANT
JRST RST06 ;AND READ IN THE PREAMBLE
;HERE TO RESET TO SOME LINK ON THE CURRENT PATH
;THE LINKS ABOVE THE REQUIRED ONE MUST BE DELETED
;AND ALL POINTERS ADJUSTED
RST2: PUSHJ P,DLTDSK ;DELETE POSSIBLE DSK FILE
PUSHJ P,MRKLNK ;MARK IT AS REQUIRED
JRST RST3 ;NOT IN BRANCH
PUSHJ P,.SAVE2## ;NEED P2
MOVS P1,LSTPTR ;WALK BACKWARDS THROUGH TREE
HRRZ T1,(P1) ;GET LINK#
MOVE P1,1(P1) ;AND NEXT PTR
CAME P2,T1 ;BACK TO ONE WE WANT?
JRST .-3 ;NOT YET
RST2A: HRRZ P2,(P1) ;LINK#
PUSHJ P,MRKLNK ;WE NEED THIS ONE
PUSHJ P,E$$LNM## ;[1174] MUST BE IN MEMORY
MOVE P1,1(P1) ;GET PREVIOUS
JUMPN P2,RST2A ;END AT 0
PUSHJ P,ADJBRN ;NOW REMOVE WHATS NOT NEEDED
RST2B: PUSHJ P,BKPBRN ;DELETE AREA AND BACKUP BRNTBL
SUBI P1,1
CAME P1,P2 ;DONE THEM ALL YET?
JRST RST2B ;NO, LOOP
HLRZ P2,@BRNTBL ;GET LINK# WE REALLY WANTED
MOVS T1,LSTPTR ;GET NODE PTR
HRRZ T2,(T1) ;GET NUMBER
CAMN T2,P2 ;WHAT WE WANTED?
JRST RST2D ;YES
HLL T1,(T1) ;AOBJN
ADD T1,[2,,2] ;BYPASS HEADER & BACK PTR
MOVS T2,(T1) ;GET LINK#
CAIN P2,(T2) ;ONE WE WANTED?
JRST .+3
AOBJN T1,.-3 ;NOT YET
PUSHJ P,E$$LNM## ;[1174] MUST BE IN MEMORY
TLNN T2,-1 ;FORWARD PTR?
JRST RST2D ;NO?
MOVS T2,T2 ;GET PTR
HRLM T2,LSTPTR ;POINT TO NEW
HLL T2,(T2) ;AOBJN PTR
ADD T2,[2,,2] ;BYPASS LINK# AND BACK PTR
SKIPE (T2) ;LOOK FOR BLANK
AOBJN T2,.-1 ;OR END OF LIST
SUBI T2,1 ;BACKUP 1 TO POINT TO LAST USED
HRRM T2,LSTPTR
RST2D: MOVE T1,[1,,1] ;FAKE OUT BRNLEN
ADDM T1,BRNLEN ;SO WE CAN REMOVE NON-EXISTENT TOP
MOVS T1,LSTPTR
JRST RSTB ;YES, NOW MOVE GS DOWN
;HERE TO RESET TO SOME LINK NOT ON THE CURRENT PATH
;ALL THE LINKS NOT REQUIRED MUST BE DELETED
;THEN ALL OTHER LINKS ON THE PATH READ IN
RST3: MOVE P1,P2 ;WE WANTED THIS LINK
PUSHJ P,TR.WLK## ;FIND NODE
HLRZ T1,P1 ;GET ADDRESS OF START OF NODE
HRRZ T2,(T1) ;GET LINK#
CAIN T2,(P1) ;ONE WE WANTED?
JRST RST3A ;YES, AS EXPECTED
MOVEI T2,4 ;NO, MUST BE A NEW NODE
PUSHJ P,DY.GET## ;SO GET SPACE FOR IT
HRRZ T2,P1 ;LINK #
HRLI T2,-4 ;LENGTH
MOVEM T2,(T1) ;HEADER WORD
HLRZM P1,1(T1) ;BACK POINTER
HRLI T1,1(T1) ;MAKE LSTPTR
MOVSM T1,LSTPTR
HLRZ T2,P1 ;NOW LOOK BACK TO FIND FATHER
HLRZ T3,2(T2)
CAIE T3,(P1) ;MATCHING ONE WE WANT?
AOJA T2,.-2 ;MUST BE THERE
HRRM T1,2(T2) ;POINT TO IT
JRST RST3B ;NOW CONTINUE
RST3A: HRLM T1,LSTPTR ;START OF NODE
ADD T1,[2,,2] ;BYPASS LINK# AND BACK PTR
HLL T1,(T1) ;FORM AOBJN PTR
SKIPN (T1) ;LOOK FOR BLANK
JRST .+3
AOBJN T1,.-2 ;OR END OF LIST
SUBI T1,1 ;END SO BACKUP TO LAST
HRRM T1,LSTPTR ;LSTPTR IS NOW POINTING TO NODE WE WANT
RST3B: MOVS P1,LSTPTR
PUSH P,P2 ;DEPTH WE FINALLY WANT
CAIA
RST3C: MOVE P1,1(P1) ;GET BACK PTR
HRRZ P2,(P1) ;GET LINK #
PUSHJ P,MRKLNK ;MARK AS REQUIRED
JFCL ;TOO BAD, WILL HAVE TO READ IT IN LATER
JUMPN P2,RST3C ;FINISH ON 0
PUSHJ P,ADJBRN ;REMOVE WHATS NOT NEEDED
RST3D: CAMN P1,P2 ;NOTHING TO REMOVE?
JRST RST3E
PUSHJ P,DLTBRN ;REMOVE SYMBOL TABLE
SOJA P1,RST3D ;SEE IF DONE
;HERE WHEN ALL OLD SYMBOL TABLES DELETED. READ IN NEW ONES.
RST3E: POP P,P2 ;RECOVER DEPTH
MOVE T1,BRNLEN ;DEPTH WE NOW HAVE
SUBI P2,(T1) ;DIFFERENCE
HRL P2,P2 ;IN BOTH HALVES
ADDB P2,BRNLEN ;MAKE IT WHAT WE WANT
HRRZS P1,P2
HLRZ T1,LSTPTR ;START OF BACK PATH
RST3F: HRRZ T2,(T1) ;GET LINK#
SKIPE @BRNDSK ;IF 0 THEN ITS NOT YET SETUP
JRST RST3G ;ALL DONE
HRLZM T2,@BRNTBL ;STORE # WE NEED
MOVE T1,1(T1) ;GET NEXT PTR
SOJG P1,RST3F ;LINK# IS ALWAYS IN CORE
;HERE TO READ IN ALL REQUIRED SYMBOL TABLES
RST3G: MOVNI P2,1(P2)
HRLZ P2,P2 ;FORM AOBJN WORD
RST3H: HRRZ P1,P2 ;INDEX FOR TABLE LOOKUPS
SKIPE @BRNDSK ;SEE IF ALREADY SET
AOBJN P2,.-2 ;WILL EVENTUALLY SKIP
HLRZ P1,@BRNTBL ;GET LINK#
ROT P1,-1 ;USUAL METHOD TO PICK CORRECT HALF
JUMPL P1,[HRRZ T1,@LNKTBL
JRST .+2]
HLRZ T1,@LNKTBL ;FOR USETI TO GET PREAMBLE
USETI OC,(T1) ;SET ON BLOCK
DMOVE T1,PHIOWD
IN OC,T1 ;READ IT IN
CAIA ;OK
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
HRRZ P1,P2 ;INDEX INTO BRANCH TABLES
HRRZ T1,PH.ADD ;LOWER ADDRESS
HLL T1,@BRNTBL ;LINK #
MOVEM T1,@BRNADD ;INCASE RELOCATED
RST3I: MOVE T1,PH.GLB ;POINTER TO GLOBAL SYMBOLS
HLRE T2,T1 ;WORD COUNT (FROM IOWD)
MOVM T2,T2
ADD T2,BG.PT ;TOP WE NEED
CAMG T2,BG.AB ;IS THERE ENOUGH?
JRST RST3J ;YES
SUB T2,BG.AB ;EXCESS
PUSH P,P2 ;SAVE AOBJN COUNTER
MOVEI P1,BG.IX
MOVE P2,T2 ;WHAT WE NEED
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
POP P,P2
JRST RST3I ;TRY AGAIN
;HERE WHEN ENOUGH ROOM. READ IN REQUIRED GLOBAL TABLE.
RST3J: USETI OC,(T1) ;SET ON BLOCK
HRR T1,BG.PT ;IOWD (ALMOST)
HRRI T1,-1(T1)
SETZ T2,
IN OC,T1 ;READ IN GLOBAL TABLE
CAIA
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
HRRZ P1,P2 ;TO HOLD BRN DEPTH
HRRZI T2,1(T1) ;GET LOWER ADDRESS BACK
SUB T2,BG.LB ;MAKE RELATIVE
HRRM T2,@BRNTBL ;START OF SYMBOL AREA
HLRE T2,T1 ;- LENGTH
MOVM T2,T2
HRLM T2,@BRNDSK ;STORE LENGTH
ADDM T2,BG.PT ;ACCOUNT FOR AREA
AOBJN P2,RST3H ;GET NEXT
JRST RST2D ;NOW CORRECT PTRS
RSTN0: PUSHJ P,BKPBRN ;BACKUP ONE LINK
AOS P2,CS.NUM ;GET ITS FATHER
; JRST RSTN ;AND SEE IF ALL DONE
RSTN: MOVN T1,LNKMAX ;CHECK FOR INRANGE LINK
CAMGE P2,T1 ;NODE REQUESTED BEFORE ROOT?
JRST E$$NBR ;[1174] YES - ERROR
MOVS T1,LSTPTR ;MUST BACKUP BY ONE LEVEL
CAME P2,[-1] ;BACK TO LAST YET?
JRST RSTN0 ;NO, KEEP TRYING
HRRZ P2,(T1) ;GET LINK#
MOVEM P2,CS.NUM ;SET IT
JUMPE P2,RESET0 ;ROOT IS SPECIAL
JRST RST2 ;DO IT
RSTL: MOVS T1,LNMPTR ;GET POINTER
JUMPE T1,E$$LNN ;[1174] ERROR
RSTLA: CAMN T2,(T1) ;IS THIS IT
JRST RSTLF ;YES
HRRZ T1,1(T1) ;GET FORWARD PTR
JUMPN T1,RSTLA ;TRY AGAIN
E$$LNN::.ERR. (MS,.EC,V%L,L%W,S%W,LNN,<Link name >) ;[1174]
.ETC. (SBX,.EC!.EP,,,,T2)
.ETC. (STR,,,,,,< not assigned>)
POPJ P,
E$$LNL::.ERR. (MS,.EC,V%L,L%W,S%W,LNL,<Link number >) ;[1174]
.ETC. (DEC,.EC!.EP,,,,T2)
.ETC. (STR,,,,,,< not loaded>)
POPJ P,
RSTLF: HLRZ T2,1(T1) ;GET NUMBER
JRST RSTA ;AND RETURN
E$$NBR::.ERR. (MS,,V%L,L%F,S%F,NBR,<Attempt to position to node before the root>) ;[1174]
;HERE IF RESET IS ALL THE WAY BACK TO THE ROOT
RESET0: MOVE T1,FSTPTR
HLL T1,(T1) ;FORM AOBJN
ADD T1,[2,,2] ;BYPASS LINK# AND BACK PTR
SKIPN (T1) ;LOOK FOR NULL IN CURRENT BLOCK
JRST RST0A ;FOUND IT
AOBJN T1,.-2
HLRE T2,@FSTPTR ;GET LENGTH
MOVM T2,T2
ADDI T2,1 ;MAKE ONE MORE
PUSHJ P,DY.GET##
HRLZ T3,FSTPTR ;FROM
HRR T3,T1 ;TO, BLT PTR
MOVN T4,T2 ;- LENGTH
ADDI T1,-2(T2) ;END OF BLT
BLT T3,(T1) ;MOVE DATA
SUBI T1,-2(T2) ;BACKUP
HRLM T4,(T1) ;SET NEW COUNT
EXCH T1,FSTPTR ;EXCH OLD WITH NEW
HRRZI T2,-1(T2) ;OLD BLOCK SIZE
PUSHJ P,DY.RET##
HRRZ T3,FSTPTR ;GET NEW BLOCK AGAIN
MOVEI T1,2(T3) ;NOW LOOK AT POSSIBLE FORWARD PTRS
RST0C: SKIPN T2,(T1) ;GET POINTER
JRST RST0A ;ALL DONE
TRNE T2,-1 ;FORWARD PTR?
HRRM T3,1(T2) ;YES
AOJA T1,RST0C
RST0A: HRL T1,FSTPTR
MOVEM T1,LSTPTR ;RESET TREE PTR
PUSHJ P,DLTDSK ;DELETE DSK FILE, MARK LINKS NOT IN CORE
HRRZ P1,BRNLEN ;NO. OF LINKS TO SCAN
RST01: HLRZ T2,@BRNTBL ;GET LINK #
JUMPE T2,RST02 ;FOUND IT
SETZM @BRNTBL ;ZERO THE TABLE SLOTS
SETZM @BRNDSK
SETZM @BRNADD
SOJGE P1,RST01 ;LOOP
PUSHJ P,E$$LNM## ;[1174] MUST BE IN MEMORY
RST02: HRRZ T1,@BRNTBL ;GET ORIGIN OF TABLE
JUMPE T1,RST03 ;ALREADY AT BOTTOM
HRLZ T2,T1
HRR T2,BG.LB ;BLT PTR
HLRZ T3,@BRNDSK ;GET LENGTH OF THIS TABLE
ADDB T1,T3 ;NEXT FREE WORD
MOVEM T1,BG.PT ;RESET NEXT FREE PTR
BLT T2,-1(T2) ;MOVE DOWN
JRST RST04 ;NOW ZERO THE REST AND GIVE IT AWAY
RST03: HLRZ T3,@BRNDSK ;GET LENGTH
ADD T3,BG.LB ;+ BASE
MOVEM T3,BG.PT ;NEW PTR TO NEXT FREE
RST04: HRLZ T1,T3
HRRI T1,1(T3) ;BLT PTR
SETZM -1(T1) ;[664] CLEAR CORE
BLT T1,@BG.AB ;BEFORE WE GIVE IT AWAY
MOVE T1,T3
IORI T1,.IPM
MOVEM T1,BG.AB ;HIGHEST IN ACTUAL USE
SUBM T1,T3 ;GET FREE SPACE
MOVEM T3,BG.FR ;NO. OF WORDS FREE IN LAST BLOCK
CAML T1,BG.UB ;JUST INCASE NOTHING TO GIVE AWAY
JRST RST05 ;NOT VERY LIKELY!
MOVEM T1,BG.UB
AOS T3,T1 ;WHERE IT WILL GO
HRL T1,GS.LB ;FROM
SUB T3,GS.LB ;- NEGATIVE DIFF
ADDM T3,GS.LB ;FIXUP ALL GS PTR
ADDM T3,GS.PT
ADDM T3,HT.PTR
MOVE T2,GS.PT ;NEXT FREE
HRLI T2,1(T2) ;BLT PTR (SWAPPED)
BLT T1,-1(T2) ;MOVE DOWN
SETZM (T2) ;CLEAR REST
MOVS T2,T2 ;PUT BLT PTR RIGHT WAY ROUND
BLT T2,@GS.AB ;CLEAR CORE
ADDM T3,GS.AB ;SET LOWER
RST05: MOVE T1,BRNLEN ;GET AOBJN POINTER
HRLS T2,BRNLEN ;PUTINDEX IN BOTH SIDES
SUB T1,T2 ;GET ORIGINAL PTR
HLLZM T1,BRNLEN ;ONLY LINK 0 IN TABLE
SETZ P1, ;INDEX FOR LINK # 0
RST06: ROT P1,-1 ;CUT IN HALF
JUMPL P1,[HRRZ T1,@LNKTBL
JRST .+2]
HLRZ T1,@LNKTBL ;GET BLOCK
USETI OC,(T1) ;OF PREAMBLE
DMOVE T1,PHIOWD
IN OC,T1
PJRST LNKZA ;NOW ZERO WHAT WE DON'T NEED
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
SUBTTL COMMON SUBROUTINES
;CHKBRN - CHECKS TO SEE IF LINK IS AT TOP OF BG AREA
;IF NOT IT MOVES ALL LINKS ABOVE DOWN AND PUTS ADDRESS OF
;THIS LINK AT TOP. NOTE ACTUAL LINK IS NOT MOVED UP.
;IF LINK IS ON DSK NOTHING IS DONE
;ENTERS WITH
; P1 CONTAINS DEPTH IN BRANCH OF REQUIRED LINK #
;RETURNS
;+1 LINK IS ON DSK
;+2 LINK IS NOW AT TOP OF BG
CHKBRN: HRRZ T1,@BRNTBL ;GET ITS ADDRESS
ADD T1,BG.LB ;FIX IT
MOVS T2,@BRNDSK ;GET LENGTH
SKIPE T2 ;DOES NOT REALLY EXIST IF 0
TLNE T2,-1 ;IS CURRENTLY ON DSK
POPJ P, ;JUST BACKUP PTR
ADD T2,T1 ;GET END
CAMN T2,BG.PT ;MAKE SURE ITS THE LAST ITEM
JRST CPOPJ1 ;YES, SIMPLE CASE
HRL T1,T2
MOVS T1,T1 ;FORM BLT PTR
HRRZ T3,T2 ;ALL AT OR ABOVE THIS ADDRESS MUST BE ADJUSTED
SUB T2,BG.LB
MOVN T2,T2 ;- NO. OF WORDS TO REMOVE
ADD T2,BG.PT ;TOP OF SYMBOLS LEFT
HRRM T2,@BRNTBL ;SO POINT TO WHERE IT WOULD BE MOVED TO
BLT T1,(T2) ;MOVE REQUIRED SYMBOLS DOWN
SUB T2,BG.PT ;GET - COUNT BACK
PUSH P,P1
SUBI P1,1 ;NOW FIXUP POINTERS
HRRZ T1,@BRNTBL ;GET POINTER
CAIL T3,(T1) ;NEED TO ADJUST?
ADDM T2,@BRNTBL ;YES
SOJGE P1,.-3
POP P,P1
JRST CHKBRN ;NOW TRY
MRKLNK: PUSHJ P,.SAVE1##
HRRZ P1,BRNLEN ;NO. OF LINKS TO SCAN
MRKLN1: HLRZ T1,@BRNTBL ;GET LINK#
CAMN T1,P2 ;ONE WE WANT
JRST MRKLN2 ;FOUND IT
SOJGE P1,MRKLN1 ;NO
POPJ P, ;NOT IN BRANCH
MRKLN2: HLLOS @BRNDSK ;MARK BY -1 IN RIGHT HALF
JRST CPOPJ1 ;FOUND IT
DLTDSK: PUSHJ P,.SAVE1## ;NEED P1
HRRZ P1,BRNLEN ;NO. OF LINKS IN BRANCH
HLLZS @BRNDSK ;ZERO RH MEANS NOT NEEDED YET
SOJGE P1,.-1
POPJ P,
ADJBRN: HRRZ T4,BRNLEN ;MAX NO. WE HAVE
SETZ P1, ;START AT ZERO
SETO P2, ;SAFE SINCE LINK# 0 IS ALWAYS WANTED
ADJBR1: MOVE T1,@BRNDSK
TRNN T1,-1 ;DO WE NEED IT?
JRST ADJBR2 ;NO, SEE IF ALL DONE
ADDI P2,1 ;INCRENENT SINCE WE NEED TO STORE THIS ONE
MOVE T2,@BRNTBL ;GET ADDRESS AND NUMBER
MOVE T3,@BRNADD ;LINK # AND LOWER BOUND
EXCH P1,P2 ;SWAP PTRS
HLLZM T1,@BRNDSK
MOVEM T2,@BRNTBL ;MOVE BACK
MOVEM T3,@BRNADD
EXCH P1,P2
ADJBR2: CAMGE P1,T4 ;DONE THEM ALL?
AOJA P1,ADJBR1 ;NOT YET
POPJ P,
BKPBRN: MOVS T1,LSTPTR
HRRZ T2,(T1) ;GET FATHER LINK
SKIPN T1,1(T1) ;BACK POINTER
JRST E$$NBR ;[1174] ERROR
HRLM T1,LSTPTR ;BACK UP
HLL T1,(T1) ;FORM AOBJN POINTER
ADD T1,[2,,2] ;BYPASS LINK# AND BACK PTR
SKIPN (T1) ;BLANK YET?
JRST BKPB1 ;YES
AOBJN T1,.-2
SUBI T1,1 ;NO SPACE, SO BACKUP
BKPB1: HRRM T1,LSTPTR ;RESET NOW
; JRST DLTBRN
DLTBRN: HRRZ P1,BRNLEN ;GET DEPTH IN BRANCH
PUSHJ P,CHKBRN ;MAKE SURE ITS AT TOP
JFCL ;OK IF ON DSK
HLRZ T1,@BRNDSK ;GET LENGTH
MOVN T1,T1
ADDM T1,BG.PT ;AND BACK UP
MOVE T1,BRNLEN ;ONE LESS BRANCH IN CORE
SUB T1,[1,,1] ;SO BACKUP
MOVEM T1,BRNLEN
SETZM @BRNTBL ;AVOIDS CONFUSION
SETZM @BRNDSK
SETZM @BRNADD
JUMPL T1,CPOPJ ;STILL VALID POINTER
PUSHJ P,E$$LNM## ;[1174] MUST BE IN MEMORY
SUBTTL SEARCH BOUND GLOBALS
TRY.BG::SPUSH <P1,P2,P3> ;SAVE HASH ACCS
SPUSH <NAMLOC,HSPACE,HT.PRM,HT.PTR> ;GS PARAMETERS
.JDDT LNKOV1,TRY.BG,<<CAMN W2,$SYMBOL##>>
SETZM HSPACE ;PREVENT REHASHING
HRRZ T1,BRNLEN ; NO. OF BOUND GLOBAL TABLES
MOVEM T1,BG.SCH ;SAFE PLACE TO PUT IT
TRYBG1: ;START AT LINK 0 AND READ IN ASCENDING ORDER
; SINCE MOST GLOBALS WILL BE IN ROOT
HRRZ T1,BRNLEN ;TOTAL
SUB T1,BG.SCH ;MINUS WHATS LEFT GIVES INDEX
ADD T1,BRNTBL ;INDEX INTO TABLE
SKIPN T2,(T1) ;GET LINK #,,ADDRESS
JRST .+3 ;LINK 0 IS ALWAYS IN CORE
TRNN T2,-1 ;ON DSK?
PUSHJ P,E$$LNM## ;[1174] MUST BE IN MEMORY
ADD T2,BG.LB ;ADD IN BASE
HRRZM T2,NAMLOC ;WHERE IT IS
MOVE T1,(T2) ;FIRST WORD IS SPECIAL
HLRZM T1,HT.PRM ;CONTAINS HASH SIZE
ADDI T2,(T1) ;ADD OFFSET FOR HASH TABLE
HRRM T2,HT.PTR
PUSHJ P,TRYSYM## ;TRY AGAIN
JRST TRYBG3 ;FAILED
JRST TRYBG3 ;ALSO FAILED
SPOP <HT.PTR,HT.PRM,HSPACE,NAMLOC>
MOVE P4,P1 ;SAVE POINTER TO THIS SYMBOL
MOVE W1,0(P1) ;GET FLAGS
TXO W1,PS.BGS ;TURN ON BOUND BIT
TXZ W1,PS.ENT ;MAKE SURE ENTRY FLAG OFF IN COPY
; ALSO NOT RELOC WRT THIS LINK
SPOP <P3,P2,P1> ;PREV VALUES
PUSH P,W3 ;SAVE CURRENT VALUE (REQUEST CHAIN)
MOVE W3,2(P4) ;GET BOUND VALUE
HRRZ T1,BRNLEN ;NO. OF POSSIBLE LINKS
SUB T1,BG.SCH ;CURRENT INDEX
TXZN W1,PS.REL ;IS THE SYMBOL RELOCATABLE
JRST .+3 ;NO, SO NO RELOC PROBLEM
SKIPE RT.LB ;LINK RELOCATABLE?
JUMPN T1,TRYBG4 ;YES, UNLESS LINK 0
TXNN W1,PT.EXT ;IS IT EXTENDED?
JRST TRYBG2 ;NO
EXCH P1,P4 ;PTR BACK IN P1
PUSHJ P,SY.CHK## ;SEE HOW LONG
SUB P1,BG.LB ;IN CASE CORE MOVES
PUSHJ P,GS.GET## ;GET SPACE
ADDI T2,-1(T1) ;END OF BLT
ADD P1,BG.LB
MOVE W3,T1 ;SYMBOL LOCATION
HRL T1,P1 ;BLT PTR
BLT T1,(T2) ;COPY SYMBOL
MOVEM W1,0(W3) ;RESET POSSIBLE CHANGED VALUE OF FLAGS
SUB W3,GS.LB ;RELATIVE
EXCH P1,P4 ;RESTORE P1
TRYBG2: PUSHJ P,INSRT## ;PUT IN CURRENT TABLE
SOS GSYM ;NOT REALLY A NEW GLOBAL SO REDUCE COUNT
AOS BSYM ;INCREASE COUNT FROM BOUND TABLES
POP P,W3 ;GET REQUEST CHAIN BACK
HRRZ P1,@HT.PTR ;GET REL ADDRESS OF SYMBOL
ADD P1,NAMLOC ;MAKE ABS
SETOM BG.SCH ;PUT BACK NORMAL VALUE
HRRZ R,R ;NOT RELOCATABLE WITH RESPECT TO THIS LINK
CPOPJ2: AOS (P)
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
TRYBG3: SOSL T1,BG.SCH ;MORE TO LOOK AT?
JRST TRYBG1 ;YES
SPOP <HT.PTR,HT.PRM,HSPACE,NAMLOC> ;PUT THINGS BACK
SPOP <P3,P2,P1>
SETOM BG.SCH ;AS IT WAS
POPJ P, ;NOT FOUND RETURN
TRYBG4: TXO W1,PS.RBG ;TURN ON REL BOUND GLOBAL
EXCH P1,P4 ;GET POINTER BACK
PUSHJ P,SY.CHK## ;SEE HOW LONG
SUB P1,BG.LB ;IN CASE CORE MOVES
ADDI T2,.L ;NEED EXTRA BLOCK
PUSHJ P,GS.GET## ;GET SPACE FOR COPY
ADDI T2,-<1+.L>(T1) ;END OF BLT
ADD P1,BG.LB
MOVE W3,T1 ;SYMBOL LOCATION
HRL T1,P1 ;FORM BLT PTR
BLT T1,(T2) ;MOVE IT
MOVEM W1,0(W3) ;SET NEW FLAGS
MOVX T1,PT.EXT ;MUST BE EXTENDED BY NOW
IORM T1,(W3) ;SET BIT
SUB W3,GS.LB ;RELATIVE
MOVX T1,S.LST ;CLEAR LAST TRIPLET BIT IF SET
TXOE W1,PT.EXT ;SET AS EXTENDED
ANDCAM T1,-.L+1(T2) ;IT WAS
MOVX T1,S.SYM!S.LST!S.RBG
MOVEM T1,1(T2) ;STORE NEW TRIPLET
MOVEM W2,2(T2) ;STORE NAME FOR NOW
HRRZ T1,BRNLEN ;GET POSSIBLE MAX INDEX
SUB T1,BG.SCH ;GET INDEX INTO TABLE
ADD T1,BRNTBL ;PLUS BASE
HLRZ T1,(T1) ;LINK#
MOVEM T1,3(T2) ;CRUCIAL ITEM IN THIS TRIPLET
JRST TRYBG2 ;PUT IN TABLE
SUBTTL STORE INTO USER CORE IMAGE
;HERE TO STORE BLOCK TYPE 1 (AND 21)
;ENTER WITH DATA IN W1 (RESULT FROM RB.1)
;STORE ADDRESS IN P3
;THIS BLOCK IS NOT GENERALIZED BECAUSE OF SPEED CONSIDERATIONS
;CALLED BY
; MOVE W1,DATA WORD
; CSTORE
;WHICH IS
; JSP T1,CS.RHS##
;
CS.LHS==:(JSP T1,) ;BUILD THE INSTRUCTION UP
CS.RHS::MOVEM W1,(P3) ;STORE IN CORE
SKIPN RT.LB ;LOADING RELOCATABLE OVERLAYS?
JRSTF (T1) ;NO
ROT R,2 ;PUT RELOC BITS IN 34-35
IDPB R,RT.PT ;STORE
ROT R,-2 ;PUT BACK
JRSTF (T1) ;RETURN
SUBTTL RELOCATABLE OVERLAY ROUTINES
;RT.FX - ROUTINE TO STORE RELOCATION FOR BOUND GLOBAL IN A RELOCATABLE LINK
;ENTER WITH
;P1 = POINTER TO SYMBOL
;W1 = FIXUP FLAGS (WHICH HALF)
;W3 = FIXUP VALUE
;USES T1-T4
RT.FX:: MOVEI T2,2 ;USES 2 WORDS
SUB P1,GS.LB ;IN CASE CORE MOVES
PUSHJ P,FX.GET## ;IN FIXUP AREA
ADD P1,GS.LB
MOVE T2,P1 ;COPY PTR TO SYMBOL
MOVE T3,0(T2) ;GET PRIMARY FLAGS
TXNN T3,PT.EXT ;IT BETTER BE EXTENDED
HALT
RT.FX1: ADDI T2,.L ;GET NEXT TRIPLET
MOVE T3,0(T2) ;GET SECONDARY FLAGS
TXNE T3,S.RBG ;BOUND GLOBAL?
JRST RT.FX2 ;YES
TXNN T3,S.LST ;LAST TRIPLET?
JRST RT.FX1 ;NOT YET
HALT
RT.FX2: MOVS T2,2(T2) ;GET LINK#
HRR T2,RBGPTR ;LAST ONE TO LINK IN
SETZ T3, ;START WITH NO RELOCATION
TXNE W1,FS.FXR ;RIGHT ONLY?
TXO T3,1B1 ;YES
TXNE W1,FS.FXL ;OR LEFT ONLY?
TXO T3,1B0 ;YES
TXNE W1,FS.FXF ;OR BOTH?
TXO T3,3B1 ;YES
TXNE W1,FS.FXS ;SYMBOL TABLE?
HALT ;NOT YET
HRR T3,W3 ;VALUE
DMOVEM T2,(T1) ;STORE
SUB T1,FX.LB ;REMOVE BASE
.JDDT LNKOV1,RT.FX2,<<CAMN T1,$FIXUP##>> ;[632]
MOVEM T1,RBGPTR ;POINT TO IT
POPJ P,
;RT.FXC - ROUTINE SAME AS RT.FX BUT USES PREVIOUS RELOCATION
;I.E. FOR CHAINED REFERENCES
;ENTER WITH
;P1 = POINTER TO SYMBOL
;W1 = FIXUP FLAGS (WHICH HALF)
;W3 = FIXUP VALUE
;USES T1-T4
RT.FXC::MOVEI T2,2 ;SAME 2 WORDS AS ABOVE
PUSHJ P,FX.GET##
MOVE T2,RBGPTR ;GET ADDRESS OF LAST
ADD T2,FX.LB ;FIX IN CORE
DMOVE T3,(T2) ;GET LAST
HRR T3,RBGPTR ;LINK TO LAST ADDRESS
HRR T4,W3 ;CHANGE VALUE
DMOVEM T3,(T1) ;STORE IN NEW BLOCK
SUB T1,FX.LB ;REMOVE BASE
.JDDT LNKOV1,RT.FXC,<<CAMN T1,$FIXUP##>> ;[632]
MOVEM T1,RBGPTR ;STORE POINTER TO LIST
POPJ P,
;RT.T2R - ROUTINE TO SET RELOC BITS CORRECT FOR RIGHT HALF CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R = RELOC BITS (BITS 0 & 1)
;P1 = PTR TO SYMBOL
;W1 = FLAGS OF PRIMARY SYMBOL
RT.T2R::PUSHJ P,RT.T2H ;CHECK NOT IN HISEG
POPJ P, ;IN HIGH
PUSH P,P3 ;NEED P3 FOR ADDRESS CHECK
MOVE P3,T2
PUSHJ P,RT.P3## ;SETUP RT.PT
TXNN R,1B1 ;IS IT RELOCATED?
TDZA T2,T2 ;NO
MOVEI T2,1 ;YES
MOVE T1,RT.PT ;GET BYTE PTR
TLC T1,(<POINT 3,>-<POINT 0,>)
IBP T1 ;BYPASS LHS
IDPB T2,T1 ;NEW BYTE
JUMPE P1,POPP3 ;NOT SYMBOLIC
PUSH P,W1 ;SAVE FLAGS
MOVX W1,FS.FXR ;RH IN CASE BOUND
RT.T2Z: MOVE T2,0(P1) ;GET FLAGS
TXNN T2,PS.RBG ;BOUND?
JRST .+4 ;NO
EXCH W3,P3 ;PUT ADDRESS IN W3
PUSHJ P,RT.FX ;STORE FIXUP
EXCH W3,P3
POP P,W1 ;RESTORE FLAGS
POPP3: MOVE T2,P3 ;RESET T2
POP P,P3
POPJ P,
;RT.T2H - ROUTINE TO CHECK ADDRESS NOT IN HISEG
;ENTER WITH
;T2 = ADDRESS
;RETURNS
;+1 IN HISEG
;+2 IN LOW SEG
RT.T2H: SKIPE HC.LB ;NO HIGH SEG
CAMGE T2,LL.S2 ;IS IT IN HIGH?
AOS (P) ;NO
POPJ P,
;RT.T2L - ROUTINE TO SET RELOC BITS CORRECT FOR LEFT HALF CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R = RELOC BITS (BITS 0 & 1)
RT.T2L::PUSHJ P,RT.T2H ;CHECK NOT IN HISEG
POPJ P, ;IN HIGH
PUSH P,P3 ;NEED P3 FOR ADDRESS CHECK
MOVE P3,T2
PUSHJ P,RT.P3## ;SETUP RT.PT
TXNN R,1B0 ;IS IT RELOCATED?
TDZA T2,T2 ;NO
MOVEI T2,1 ;YES
MOVE T1,RT.PT ;GET BYTE PTR
TLC T1,(<POINT 3,>-<POINT 0,>)
IDPB T2,T1 ;NEW BYTE
JUMPE P1,POPP3 ;NOT SYMBOLIC
PUSH P,W1 ;SAVE FLAGS
MOVX W1,FS.FXL ;LH IN CASE BOUND
JRST RT.T2Z ;RESET T2,P3, AND RETURN
;RT.T2F - ROUTINE TO SET RELOC BITS CORRECT FOR FULL WORD CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R = RELOC BITS (BITS 0 & 1)
RT.T2F::PUSHJ P,RT.T2H ;CHECK NOT IN HISEG
POPJ P, ;IN HIGH
PUSH P,P3 ;NEED P3 FOR ADDRESS CHECK
MOVE P3,T2
PUSHJ P,RT.P3## ;SETUP RT.PT
TXNN R,3B1 ;IS IT RELOCATED?
TDZA T2,T2 ;NO
MOVEI T2,1 ;YES
MOVE T1,RT.PT ;GET BYTE PTR
IDPB T2,T1 ;NEW BYTE
JUMPE P1,POPP3 ;NOT SYMBOLIC
PUSH P,W1 ;SAVE FLAGS
MOVX W1,FS.FXF ;FULL WORD IN CASE BOUND
JRST RT.T2Z ;RESET T2,P3, AND RETURN
E$$OHN::.ERR. (MS,,V%L,L%F,S%F,OHN,<Overlay handler not loaded>) ;[1174]
E$$FSN::.ERR. (MS,,V%L,L%F,S%F,FSN,<FUNCT. subroutine not loaded>) ;[1174]
SUBTTL THE END
OV1LIT: END LNKOV1