1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 09:21:15 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

2410 lines
76 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE LNKOV1 - PHASE 1 OVERLAY MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC/DZN/PY/PAH/HD/RJF 5-Feb-88
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986,1988.
; ALL RIGHTS RESERVED.
;
;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==2420 ;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.
;2417 Update copywrite statement to 1988.
;2420 Reset LC.UP when a .TMP file is discarded.
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
SETZM LC.UP ;[2420] RESET HIGHEST BLOCK NUMBER
>;[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