Trailing-Edge
-
PDP-10 Archives
-
tops10_703a_sys_ap115_bb-ju01b-bb
-
lnkov1.x14
There are 4 other files named lnkov1.x14 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/PY/PAH/HD 28-May-86
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986. ALL RIGHTS RESERVED.
;[2403]
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH LNKPAR,LNKLOW,OVRPAR,MACTEN,UUOSYM,SCNMAC
IFN TOPS20,< SEARCH MONSYM > ;[1506]
SALL
ENTRY LNKOV1
EXTERN LNKLOD,LNKWLD,LNKOV2
CUSTVR==0 ;CUSTOMER VERSION
DECVER==6 ;DEC VERSION
DECMVR==0 ;DEC MINOR VERSION
DECEVR==2403 ;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).
;START OF VERSION 4B
;1226 Default /SEGMENT:LOW after loading the root.
;1230 Really put the overlay file where the user wants it (see edit 651).
;1232 Handle symbolic start address in LINKGT.
;1247 Add check for /SYMSEG:HIGH or /SYMSEG:PSECT: with overlays.
;1257 Store RC.HL from absolute code after loading root node.
;1263 Don't change LSTSYM if not new symbol.
;1265 Put .SYM file name in OWN block in Algol program.
;1266 Fix loop when local symbols can't all be read in at once.
;1310 Make LNKOFS message use long error text.
;START OF VERSION 5
;1400 Use OVRPAR.MAC and implement writable overlays.
;1424 Implement /MAXNODE.
;1447 Move /MAXNODE support into LNKWLD.
;START OF VERSION 5.1
;1506 Conditionalize TOPS-10 specific code and nativize LS overflow area
;1514 Unmap, don't BLT to zero the LC area excess when shrinking LC
;1537 Remove unnecessary AOSA when setting up PMAP arguments.
;1541 Unmap overflow windows before deleting overflow files (TOPS-20)
;1704 Writable overlay support work.
;1710 Don't miss last writable overlay link.
;2002 Implement /PLTTYP switch.
;2007 Give LNKTML a long message.
;2011 Remove /PLTTYP code, put it in LNKWLD.
;2026 Update copyright notices, cleanup listing.
;2033 Keep LW.LS page aligned on TOPS-20.
;2053 Argcheck the BG area, and build deferred character fixups.
;2076 Check IO.PTR+%PC not NULSPC for previously seen file spec in %PLOT.
;Start of version 6
;2202 Use 30 bit addresses when calling xx.IN and xx.OUT, remove bare PMAPs.
;2214 Add 30 bit fixups, which relocate like halfwords in overlays.
;2235 Give error if overlays used with extended addressing.
;2247 Use inferior fork on TOPS-20.
;2251 Set PM%CNT before mapping out pages.
;2255 Use LSTLCL and LSTGBL instead of LSTSYM.
;2262 Check for PG.LSG returning all memory asked for.
;2316 Don't check lower bound after PG.LSG, just upper. Lower is always OK.
;2366 Check for overlays outside section zero on TOPS-10.
;2403 New corporate copywrite statement.
SUBTTL ENTRY POINT
LNKOV1: JFCL .+1 ;NORMAL ENTRY
JRST LNKLOD
;IOWD FOR PREAMBLE SECTION
IFE FTKIONLY,<
PHIOWD: IOWD PH.ZZ,PH ;[1400]
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:
IFN TOPS20,< ;[2366]
MOVE T1,FXSBIT ;[2235] GET THE SECTION BITS
TDNE T1,[^-1B0] ;[2235] ANY NON-ZERO SECTIONS?
PUSHJ P,E$$CBO## ;[2235] YES, GIVE ERROR
>;[2366] IFN TOPS20
IFE TOPS20,< ;[2366]
MOVE T1,HL.S1 ;[2366] GET THE HIGHEST LOADED
TLNE T1,-1 ;[2366] OUTSIDE OF SECTION ZERO?
PUSHJ P,E$$CBO## ;[2366] YES, GIVE ERROR
>;[2366] IFE TOPS20
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
MOVEI T1,.DBS ;[1424] SET MAXIMUM LINK NUMBER
SKIPN L.MAX ;[1424] UNLESS ALREADY SET
MOVEM T1,L.MAX ;[1424] ...
MOVE T1,SYMSEG ;[1247] GET SYMBOL SEGMENT LOCATION
JUMPL T1,.+3 ;[1247] /SYMSEG:PSECT?
CAIE T1,$SSGHIGH ;[1247] /SYMSEG:HIGH?
JRST OVSYMS ;[1247] NO - IT'S OK
E01OSL::.ERR. (MS,,V%L,L%W,S%W,OSL,) ;[1247]
MOVEI T1,$SSGLOW ;[1247] GET /SYMSEG:LOW
MOVEM T1,SYMSEG ;[1247] FORCE SYMBOLS THERE
OVSYMS: MOVSI T1,'OVL' ;[1247] FORCE EXTENSION
MOVEM T1,F.EXT(P1)
PUSHJ P,DVOUT.## ;SETUP DATA BLOCK
%OC,,.IODPR
MOVE T1,IO.CHR ;[1230] MAKE SURE DEVICE IS A DISK
TLC T1,-1-<(DV.TTA)>;[1230] ..
TLCE T1,-1-<(DV.TTA)>;[1230] ..
TXNN T1,DV.DSK ;[1230] ..
JRST E$$OFS ;[1230] OVERLAY HANDLER ASSUMES A DISK
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
E$$OFS::.ERR. (MS,0,V%L,L%F,S%F,OFS,<Overlay file must be created on a file structure>) ;[1310]
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
SKIPL WRTDAT ;[1704] LINK MARKED WRITABLE?
POPJ P, ;[1704] NO, FINISHED
HRLOI T1,377777 ;[1704] CLEAR MARKER BIT NOW
ANDM T1,WRTDAT ;[1704]
HLRZ T1,P2 ;[1704] CURRENT LINK IS WRITABLE
PUSHJ P,WRTPTR## ;[1704] GET BYTE PTR TO LINK DATA
MOVX T2,OW.WRT ;[1704] MARK IT WRITABLE
DPB T2,T1 ;[1704] ...
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,
E$$TML::.ERR. (MS,,V%L,L%F,S%F,TML,<Too many links, use /MAXNODE >) ;[2007]
POPJ P, ;[1424]
SUBTTL SWITCH ACTION -- /ARSIZE:n, /MAXNODE: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)
%PLOT::
SETOM PLOTSW ;MAKE SURE WE DO IT
SKIPE T1,3(P2) ;GET SWITCH VALUE
MOVEM T1,PLTTAB-1(T2) ;STORE FOR LNKPLT
SKIPE IO.PTR+%PC ;[2076] 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
SUBTTL SWITCH ACTION -- /REGION, /SPACE:n
%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:
IFE TOPS20,<
MOVE T1,HL.S1 ;[2366] GET THE HIGHEST LOADED
TLNE T1,-1 ;[2366] OUTSIDE OF SECTION ZERO?
PUSHJ P,E$$CBO## ;[2235] YES, GIVE ERROR
>;[2366] IFE TOPS20
SETOM LINKSEEN ;END OF SEGMENT SPECIFIED
AOS T1,LNKMAX ;INCREMENT NUMBER SEEN
MOVEM T1,CS+CS.NUM ;[1400]STORE CURRENT IN HEADER
CAMLE T1,L.MAX ;[1424] TOO MANY?
PUSHJ P,E$$TML ;[1424] TOO MANY
SKIPL WRTDAT ;[1710] LINK MARKED WRITABLE?
JRST LNKGT0 ;[1710]
HRLOI T2,377777 ;[1710] CLEAR MARKER BIT NOW
ANDM T2,WRTDAT ;[1710]
PUSHJ P,WRTPTR## ;[1710] GET BYTE PTR TO LINK DATA
MOVX T2,OW.WRT ;[1710] MARK IT WRITABLE
DPB T2,T1 ;[1710] ...
LNKGT0: SKIPN W2,STADDR+1 ;[1232] IS START ADDRESS STILL SYMBOLIC?
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
ADDM W3,STADDR ;[1232] CALCULATE VALUE
LNKT0: SKIPE CS+CS.NUM ;[1400]LINK 0?
JRST LNKT1 ;NO
PUSHJ P,ALGCHK## ;[1265] DO SPECIAL CHECK FOR ALGOL
HRRZ T1,RC.TB ;[1257] GET POINTER
MOVE T1,0(T1) ;[1257] GET POINTER TO .ABS. BLOCK
MOVE T1,RC.HL(T1) ;[1257] GET ROOT NODE HIGH ABS LOC.
MOVEM T1,ROOTAB ;[1257] STORE IT FOR EXIT TIME
MOVSI T1,L.FNS!L.FHS ;[1226] TURN OFF /SEG:DEF AND /SEG:HIGH
ANDCAM T1,FLAGS ;[1226] IN GLOBAL (ACCROSS LINES) SWITCHES
ANDCAM T1,S.LHFL ;[1226] AND GLOBAL KLUDGE FLAGS
MOVSI T1,L.FLS ;[1226] TURN ON /SEGMENT:LOW FOR DURATION
IORM T1,FLAGS ;[1226] ..
IORM T1,S.LHFL ;[1226] ..
TXZ FL,<L.FNS!L.FHS,,R.FNS!R.FHS> ;[1226] FIX /SEG:LOW NOW TOO
TXO FL,<L.FLS,,R.FLS> ;[1226] ..
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,ET+ET.OVL ;[1400] 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,.DBS ;[1424] START TABLE WITH 256 LINKS
SKIPN T2,L.MAX ;[1424] BUT NOT IF SET BY /MAXNODE
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,
LKSTER: PUSHJ P,E$$USA## ;[1232] UNDEFINED MESSAGE
JRST LNKT0 ;[1232] CONTINUE END-OF-LINK PROCESSING
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+CS.NUM ;[1400]
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+CS.NUM ;[1400]
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+PH.ADD ;[1400] 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+PH.CST ;[1400] WILL BE START OF HEADER SECTION
SKIPN CS+CS.NUM ;[1400] IF ROOT
HRLM T1,ADDOVU ;STORE FOR UNDEF SYMBOL
HRL T1,CS+CS.NUM ;[1400] PUT NUMBER IN LH
MOVEM T1,ET+ET.CST ;[1400] ALSO IN EXTTAB
MOVE T1,PH+PH.ADD ;[1400] GET THIS LINK'S ORIGIN
MOVEM T1,CS+CS.COR ;[1400] SAVE AS START OF LINK
MOVEI T1,CS.LEN ;[1400] ALLOCATE SPACE FOR HEADER
ADDB T1,HL.S1 ;AND ACCOUNT FOR IT
MOVE T1,[CS+CS.HDR,,PH+PH.HDR] ;[1400]
BLT T1,PH+PH.NAM ;[1400] COPY COMMON INFO
MOVE T1,STADDR ;COPY START ADDRESS
HRRZM T1,CS+CS.STA ;[1400]
SETZM CS+CS.EXT ;[1400] INCASE NO UNDEFS
SKIPN P2,USYM ;NO. OF UNDEFS
JRST LNKT3 ;NONE
MOVN T1,P2 ;- NUMBER
HRL T1,HL.S1 ;,,ADDRESS
MOVSM T1,CS+CS.EXT ;[1400] POINT TO TABLE
IMULI P2,ET.LEN ;[1400] 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,ET ;[1400] 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,ET+ET.NAM ;[1400] STORE NAME
MOVE T1,P3 ;GET BYTE PTR
ADDI P3,ET.LEN ;[1400] INCR P3
BLT T1,-1(P3) ;MOVE PROTOTYPE BLOCK
MOVEI W3,ET.LEN ;[1400]
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+CS.INT ;[1400] INCASE 0 ENTRIES
SKIPN CS+CS.NUM ;[1400] 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+CS.INT ;[1400] 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+CS.INT ;[1400] ACCOUNT FOR PREVIOUS
ADD P3,CS+CS.INT ;[1400] 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+CS.INT ;[1400] INCASE MORE THAN 100
MOVN T2,T1 ;-NUMBER
HRL T2,HL.S1 ;,, ADDRESS
MOVSM T2,CS+CS.INT ;[1400] 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+PH.ADD ;[1400] 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+PH.ADD ;[1400] REMOVE BASE
HRLM T2,CS+CS.COR ;[1400] SAVE LENGTH REQUIRED
HRRZM T2,PH+PH.LLN ;[1400]
MOVE P1,CS+CS.NUM ;[1400] 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+PH.OVL ;[1400] USE THIS BLOCK FOR CODE
LNKT4A: MOVE P3,PH+PH.CST ;[1400] ADDRESS OF CONTROL SECTION
MOVEI P2,CS.LEN-1(P3) ;[1400] UPPER BOUND
PUSHJ P,LNKTCK ;MAKE SURE ITS IN CORE
MOVN T2,PH+PH.LLN ;[1400] TOTAL NO. OF WORDS
HRLM T2,PH+PH.OVL ;[1400] IN IOWD FORM
MOVE T2,PH+PH.OVL ;[1400] COPY POINTER TO CS FOR SPEED
MOVEM T2,CS+CS.OVL ;[1400] AT RUNTIME WITH WRITABLE OVERLAYS
HRLI P3,CS ;[1400] COPY FINAL CONTROL SECTION TO
MOVEI P2,CS.LEN-1(P3) ;[1400] THE MEMORY IMAGE
BLT P3,(P2) ;[1400] ..
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+PH.NFL ;[1400] FOR NEXT LINK
PUSHJ P,LODFIX## ;DO ALL CORE FIXCUPS ETC.
SKIPN PAG.S1 ;PAGING?
JRST LNKT4B ;NO
MOVE T1,LW.S1 ;[2202] LOWER BOUND
MOVE T2,UW.S1 ;[2202] UPPER BOUND
PUSHJ P,LC.OUT## ;MAKE SURE FILE IS CORRECT
SETZB T1,LW.S1 ;[2202] NOW START AT FRONT
MOVE T2,LC.UB ;[2202] GET TOP
MOVEM T2,LC.AB ;[2202] USE ALL SPACE WE CAN
SUB T2,LC.LB ;[2202] GET THE SIZE
MOVEM T2,UW.S1 ;[2202] 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+CS.NUM ;[1400] IF LINK# 0
JRST LNKT4C ;NO
MOVE T1,LC.LB ;BASE
MOVE T2,PH+PH.CST ;[1400] 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+PH.LLN ;[1400] 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+PH.LLN ;[1400] 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]
IFE TOPS20,<
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
> ;[1514]IFE TOPS20
IFN TOPS20,<
MOVE T2,LC.AB ;[2202] Get upper bound
SUB T2,LC.LB ;[2202] Get the current size
ADD T2,LW.LC ;[2202] Current window area
MOVE T1,T2 ;[2202] Get the upper window
ADD T1,T3 ;[2202] Get new upper window (T3 is negative)
ADDI T1,1 ;[2202] Start of piece to remove
ADDM T3,LC.AB ;[1514] Set new upper limit
PUSHJ P,LC.OUT## ;[2202] Unmap excess area
> ;[1514] IFN TOPS20
LNKT4E: MOVE T1,LW.S1 ;[2202] GET LOWER BOUND
MOVE T2,UW.S1 ;[2202] SETUP NEW WINDOW
PUSHJ P,LC.IN## ;INPUT NEW AREA
JRST LNKT4C ;[666] AND OUTPUT IT
LNKT4F: MOVE T1,PH+PH.LLN ;[1400] 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+PH.SYM ;[1400] 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 T2,LSYM ;[2202] NO
;**;[2033] Replace at LNKT5+12 Lines PY 14-Feb-83
IFN TOPS20,< ;[2033]
IORI T2,.IPM ;[2202] PUT ON PAGE BOUND
>;[2033] IFN TOPS20
IFE TOPS20,< ;[2033]
IORI T2,.DBM ;[2202] PUT ON BLOCK BOUND
>;[2033] IFE TOPS20
LNKT5A: MOVE T1,LW.LS ;[2202] GET LOWER BOUND
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: SETZB T1,LW.LS ;[2202] START BACK AT FRONT OF FILE
MOVE T2,LS.AB ;[2202] CALCULATE THE
SUB T2,LS.LB ;[2202] LENGTH
IFL .IPS-2*.DBS,<
CAIGE T2,2*.DBS ;[650] MUST HAVE THIS MUCH FOR FIXUPS
PUSHJ P,E$$MEF## ;[1174] TOO BAD
> ;END IFL .IPS-2*.DBS
MOVEM T2,UW.LS ;[2202] NEW END 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
;**;[2033] Replace at LNKT5F+2 Lines PY 14-Feb-83
IFN TOPS20,< ;[2033]
SUBI T1,.IPS ;[2033] NO, DON'T DUMP LAST WORDS TILL
>;[2033] IFN TOPS20
IFE TOPS20,< ;[2033]
SUBI T1,.DBS ;[666] NO, DON'T DUMP LAST WORDS TILL
>;[2033] IFE TOPS20
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
;**;[2033] Replace at LNKT5C+5 Lines PY 14-Feb-83
IFN TOPS20,< ;[2033]
ANDCMI T1,.IPM ;[2033] FIGURE WINDOW OFFSET INTO T1
>;[2033] IFN TOPS20
IFE TOPS20,< ;[2033]
ANDCMI T1,.DBM ;[666] FIGURE WINDOW OFFSET INTO T1
>;[2033] IFE TOPS20
ADDM T1,LW.LS ;[666] MOVE THE WINDOW UP
ADDB T1,UW.LS ;[666] ..
IFE TOPS20,<
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
MOVE T3,LSYM ;[1266] GET NUMBER OF SYMBOLS
MOVEM T3,UW.LS ;[1266] SINCE LAST BUFFER, MUST BE TOP
SUB T3,LW.LS ;[1266] FIGURE SIZE OF CURRENT BUFFER
ADD T3,LS.LB ;[1266] GET TOP OF NEW BUFFER
IORI T3,.IPM ;[1266] MUST BE ON END OF PAGE
MOVEM T3,LS.AB ;[1266] SET HIGHEST ADDRESS IN USE
HRLI T3,1(T3)
HRRI T3,2(T3) ;FORM BLT PTR
SETZM -1(T3)
BLT T3,@LS.UB ;TO CLEAR ALL EXCESS CORE
> ;[1506] IFE TOPS20
LNKT5D: MOVE T1,LW.LS ;[2202] LOWER WINDOW ADDR TO FILL
MOVE T2,UW.LS ;[2202] UPPER WINDOW ADDR
PUSHJ P,LS.IN## ;GET WINDOW
JRST LNKT5B ;AND OUTPUT IT
;HERE FOR RELOCATION TABLES
LNKT6: SETZM PH+PH.REL ;[1400] ASSUME NO RELOCATION
SETZM PH+PH.ORL ;[1400] 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+PH.REL ;[1400] -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+PH.ORL ;[1400] -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+PH.GLB ;[1400] 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+PH.GLB ;[1400]
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+CS.NUM ;[1400] GET THIS LINK
MOVEM T1,PH+PH.BPT ;[1400] AS BACK POINTER FOR NEXT LINK
;HERE TO ZERO VARIOUS AREAS
;HERE TO ZERO LOW CODE AREA
LNKZLC:
IFE TOPS20,< ;[2247]
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
>;[2247] IFE TOPS20
IFN TOPS20,< ;[1541]
MOVE T1,LW.LC ;[2202] GET THE BOTTOM
MOVE T2,UW.LC ;[2202] AND THE TOP
PUSHJ P,LC.OUT## ;[1541] UNMAP IT SO IT CAN CLOSE
MOVE T3,HL.S1 ;[2247] GET THE UPPER BOUND
LSH T3,-9 ;[2247] IN PAGES
ADDI T3,1 ;[2247] NEED COUNT OF PAGES
TXO T3,PM%CNT ;[2251] TELL THE MONITOR ABOUT IT
HRLZ T2,LC.JF ;[2247] GET THE FORK HANDLE
SETO T1, ;[2247] WANT TO UNMAP THE PAGES
PMAP% ;[2247] MAKE THEM GO AWAY
ERCAL E$$OLC## ;[2247] UNEXPECTED FAILURE
MOVE T1,LC.LB
IORI T1,.IPM ;PRE-ALLOCATE ONE BLOCK ONLY
MOVEM T1,LC.AB
SETZB T1,LW.S1 ;[2247] RESET LOWER WINDOW
MOVEI T2,.IPM ;[2247] NEED ONE PAGE
MOVEM T2,UW.S1 ;[2247] MAPPED IN FOR WINDOW
PUSHJ P,LC.IN## ;[2247] MAP IT IN
> ;[1541] IFN TOPS20
;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:
IFN TOPS20,< ;[2202]
SKIPE PAG.LS ;[2202] Paging?
JRST LSNPAG ;[2202] Yes, Don't bother to BLT
> ;[2202] IFN TOPS20
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
LSNPAG: ;[1506]
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
IFN TOPS20,< ;[1541]
MOVE T1,LW.LS ;[2202] GET THE BOTTOM
MOVE T2,UW.LS ;[2202] AND THE TOP
PUSHJ P,LS.OUT## ;[1541] UNMAP IT SO IT CAN CLOSE
> ;[1541] IFN TOPS20
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+CS.NUM ;[1400] LINK # IN LEFT
MOVEM T2,@BRNTBL
HLLZ T3,T2 ;LINK#
HRR T3,PH+PH.ADD ;[1400] 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+PH.NFL ;[1400] NEXT FREE LOC
MOVEM T1,PH+PH.ADD ;[1400] 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+CS.NUM,,CS+CS.NUM+1] ;[1400]
SETZM CS+CS.NUM ;[1400]
BLT T1,CS+CS.LEN-1 ;[1400]
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 LSTGBL ;[2255] ZERO GLOBAL POINTER
SETZM LSTLCL ;[2255] AND LOCAL POINTER
;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+PH.ADD ;[1400] REMOVE BASE ADDRESS INCASE ABS
SUB P3,PH+PH.ADD ;[1400] ...
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
CAMLE P2,UW.LC ;[2262] HIGH ADDRESS IN WINDOW?
PUSHJ P,E$$MEF ;[2262] NO, NOT ENOUGH MEMORY
JRST LNKTC1 ;IS BY NOW
SUBTTL DO OPEN & ENTER FOR OV FILE
OC.OPN: MOVEI T1,%OC ;[1230] NOW THAT ROOT IS DONE, FIND OUT
MOVEM T1,IO.CHN ;[1230] WHAT TO CALL THE OVERLAY FILE
PUSHJ P,DVNAM.## ;[1230] ..
MOVEI T2,LN.IO ;[1230] GET SPACE FOR OVERFLOW SPEC'S
PUSHJ P,DY.GET## ;[1230] BLOCK
MOVEM T1,IO.PTR+OC ;[1230] SAVE ITS ADDRESS FOR LATER
MOVE T2,T1 ;[1230] POINTER TO OVERFLOW BLOCK IN T2
MOVE T1,IO.PTR+%OC ;[1230] POINTER TO USER'S BLOCK IN T1
MOVEI T3,.IODPR ;[1230] SET UP OVERFLOW BLOCK WITH
MOVEM T3,I.MOD(T2) ;[1230] PROPER DATA--FIRST, DATA MODE
MOVEI T3,LN.RIB-1 ;[1230] SIZE OF EXTENDED RIB
MOVEM T3,I.RIB+.RBCNT(T2) ;[1230] ..
MOVE T3,JOBNUM ;[1230] FILE NAME nnnOVL
HRRI T3,'OVL' ;[1230] ..
MOVEM T3,I.RIB+.RBNAM(T2) ;[1230] ..
MOVSI T3,'TMP' ;[1230] EXTENSION .TMP
MOVEM T3,I.RIB+.RBEXT(T2) ;[1230] ..
MOVX T3,<INSVL. 077,RB.PRV> ;[1230] HIGH PROT FOR OVERFLOW FILES
MOVEM T3,I.RIB+.RBPRV(T2) ;[1230] ..
SKIPN T3,I.RIB+.RBEST(T1) ;[1230] USE USER'S ESTIMATE
MOVEI T3,1000 ;[1230] OR LARGE DEFAULT (REAL PROGS
MOVEM T3,I.RIB+.RBEST(T2) ;[1230] ARE BIG)
MOVEI T1,%OC ;[1230] CHANNEL OF USER'S OVERLAY FILE
MOVEI T2,OC ;[1230] CHANNEL OF LINK'S OVERFLOW FILE
PUSHJ P,DVSUP.## ;[1230] PUT OVERFLOW FILE IN RIGHT PLACE
JRST E$$EOV ;[1230] FAILED
POPJ P, ;[1230] DONE
E$$EOV::PUSH P,[OC] ;[1230] 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+CS.NUM ;[1400] 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+CS.NUM ;[1400] 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+PH.ADD ;[1400] LOWER ADDRESS
HLL T1,@BRNTBL ;LINK #
MOVEM T1,@BRNADD ;INCASE RELOCATED
RST3I: MOVE T1,PH+PH.GLB ;[1400] 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+CS.NUM ;[1400] 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+CS.NUM ;[1400] 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: PUSH P,LSTGBL ;[2255] SAVE GLOBAL PTR IN CASE PART OF FIXUP
PUSH P,LSTLCL ;[2255] SAVE LOCAL POINTER TOO
PUSHJ P,INSRT## ;PUT IN CURRENT TABLE
POP P,LSTLCL ;[2255] RESTORE POINTERS
POP P,LSTGBL ;[2255] THIS SYMBOL ALREADY EXISTS
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
;**;[2053] Insert after TRYBG4+26 Lines PY 8-Nov-83
SUBTTL Argument check the BG area [2053]
TYP.BG::SKIPL BG.SCH ;[2053] Any bound globals we can look at?
POPJ P, ;[2053] No, return
SPUSH <NAMLOC,HSPACE,HT.PRM,HT.PTR,BG.SCH> ;[2053] GS Parameters
SETOM ARGOVL ;[2053] Remember that BG area is being checked
.JDDT LNKOV1,TYP.BG,<<CAMN W2,$SYMBOL##>> ;[2053]
SETZM HSPACE ;[2053] Prevent rehashing
HRRZ T1,BRNLEN ;[2053] No. of bound global tables
MOVEM T1,BG.SCH ;[2053] Safe place to put it
PUSH P,W3 ;[2053] Save the arg block pointer
TYPBG1: ;[2053] Start at link 0 so typout will
;[2053] be in correct order
HRRZ T1,BRNLEN ;[2053] Total
SUB T1,BG.SCH ;[2053] Minus whats left gives index
ADD T1,BRNTBL ;[2053] Index into table
SKIPN T2,(T1) ;[2053] Get LINK #,,ADDRESS
JRST TYPBG2 ;[2053] Link 0 is always in core
TRNN T2,-1 ;[2053] On DSK?
PUSHJ P,E$$LNM## ;[2053] Must be in memory
TYPBG2: ADD T2,BG.LB ;[2053] Add in base
HRRZM T2,NAMLOC ;[2053] Where it is
MOVE T1,(T2) ;[2053] First word is special
HLRZM T1,HT.PRM ;[2053] Contains hash size
ADDI T2,(T1) ;[2053] Add offset for hash table
HRRM T2,HT.PTR ;[2053]
MOVE W3,0(P) ;[2053] Get the callee argblock pointer
PUSHJ P,SYTYP## ;[2053] Typecheck this table
SOSL T1,BG.SCH ;[2053] More to look at?
JRST TYPBG1 ;[2053] Yes
SETZM ARGOVL ;[2053] Back to typechecking GS area
POP P,W3 ;[2053] Recover the arg block pointer
SPOP <BG.SCH,HT.PTR,HT.PRM,HSPACE,NAMLOC> ;[2053] Put things back
POPJ P, ;[2053] Return to process current overlay
;[2053] Here to build a deferred fixup block. The block is two words
;[2053] long, and looks like:
;
; -----------------------------
; ! Pointer to next !
; -----------------------------
; !overlay index,,user address!
; -----------------------------
;
;[2053] These blocks are stored in ascending order by overlay index
;[2053] and address. Note that the address is 18 bits because this
;[2053] only occur in the overlay case, and that is restricted to
;[2053] section zero. On entry, P3 contains the user address.
COEOVL::HRRZ T2,BRNLEN ;[2053] Total
SUB T2,BG.SCH ;[2053] Minus whats left gives index
JUMPN T2,COEOV0 ;[2053] Check for not root node
HRRZ P2,LL.S2 ;[2053] Get the root node highseg origin
JUMPE P2,COEOV0 ;[2053] No root node high segment
CAML P3,P2 ;[2053] In the high segment?
JRST COESP0## ;[2053] Yes, do this fixup now. SGCHK.
;[2053] will use the root node high seg.
COEOV0: HRL P3,T2 ;[2053] Put the index with the address
MOVEI T2,TPCBK ;[2053] Get the length
PUSH P,T4 ;[2053] Save over DY.GET call
PUSHJ P,DY.GET## ;[2053] Get a block
POP P,T4 ;[2053] Restore AC
MOVEM P3,TPCAD(T1) ;[2053] Store the address info
MOVEI P1,ARGFXP ;[2053] Get the pointer to the chain
COEOV1: MOVE T2,TPCLK(P1) ;[2053] Get the new pointer
JUMPE T2,COEOV2 ;[2053] At end of chain?
CAMG P3,TPCAD(T2) ;[2053] Is this one bigger than last?
JRST COEOV2 ;[2053] Yes, link it in here
MOVE P1,T2 ;[2053] Point to the current block
JRST COEOV1 ;[2053] Try the next block
COEOV2: MOVEM T2,TPCLK(T1) ;[2053] Link this one into the chain
MOVEM T1,TPCLK(P1) ;[2053] Complete the chain
PJRST COESP1## ;[2053] Return to coersion code
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
TXNN W1,FS.FXR ;[2214] RIGHT ONLY?
TXNE W1,FS.FXE ;[2214] OR THIRTY BIT?
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
SETZ T1, ;[2214] ZERO SECTION FOR CHAINED FIXUPS
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
;RT.T2E - Routine to set reloc bits correct for thirty bit chained references
;Enter with
;T2 = Address
;R = Reloc bits (BITS 0 & 1)
RT.T2E::PUSHJ P,RT.T2H ;[2214] Check not in hiseg
POPJ P, ;[2214] In high
PUSH P,P3 ;[2214] NEED P3 FOR ADDRESS CHECK
MOVE P3,T2 ;[2214]
PUSHJ P,RT.P3## ;[2214] Setup RT.PT
TXNN R,3B1 ;[2214] Is it relocated?
TDZA T2,T2 ;[2214] No
MOVEI T2,1 ;[2214] Yes
MOVE T1,RT.PT ;[2214] Get byte ptr
IDPB T2,T1 ;[2214] New byte
JUMPE P1,POPP3 ;[2214] Not symbolic
PUSH P,W1 ;[2214] Save flags
MOVX W1,FS.FXE ;[2214] Full word in case bound
JRST RT.T2Z ;[2214] 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