Trailing-Edge
-
PDP-10 Archives
-
bb-d868c-bm_tops20_v4_2020_distr
-
language-sources/lnkov2.mac
There are 39 other files named lnkov2.mac in the archive. Click here to see a list.
TITLE LNKOV2 - PHASE 2 OVERLAY MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/RKH/JNG/MCHC/DZN 24-Aug-79
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973, 1979 BY DIGITAL EQUIPMENT CORPORATION
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL
ENTRY LNKOV2
EXTERN LNKMAP,LNKXIT
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==1 ;DEC MINOR VERSION
DECEVR==1220 ;DEC EDIT VERSION
VERSION
SEGMENT
SUBTTL REVISION HISTORY
;START OF VERSION 2
;135 ADD OVERLAY FACILITY
;136 FIX VARIOUS BUGS
;174 FIX BUGS IN RELOCATABLE OVERLAYS
;203 GET DDT SYMBOLS INTO ALL LINKS
;207 REDUCE SIZE OF OVERHEAD TABLES
;START OF VERSION 2B
;261 Allow loading of null structures (root only)
;322 Set up LSYM correctly to prevent confusing LNKCOR
;332 Restore base of GS area before processing
;362 Always set up the preamble area at OVR8, since edit
; 322 made LNKXIT not set it up. [15706] (JNG).
;410 Avoid ?LNKISN on a node with no internal symbols.
;415 Set up LSYM and NAMPTR to avoid ?ILL MEM REF in LNKCOR
;423 Return RT area when done with it to avoid LNKXIT problems.
;START OF VERSION 2C
;460 Fix bug if multiple multiply-defined references in 1 link.
;461 Prevent loop in LNKCOR by requesting 0 words in rdcst
;467 Prevent ?ADDRESS CHECK by keeping RT.PT at relative
; (not absolute) zero when the RT area is empty.
;530 Get triplet flag definitions right.
;536 Get IT.??? flag definitions right.
;557 Clean up 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
;573 Prevent random USETO when root of relocatable overlay
; structure has no INTTAB or EXTTAB
;576 Correct usage of PT.SGN and PT.OTH in INTTAB hash table.
;621 Generate an EXE file.
;627 Fix LNKARL message when list of links is long.
;635 Use /ARSIZE area for ARL tables, and give intelligent
; error messages if /ARSIZE area is too small.
;650 Use VM on TOPS-10 if available.
;677 Don't default to /SYMSEG:LOW when loading overlays.
;731 SEARCH MACTEN,UUOSYM
;743 Fix bug with offset calculation of link intab pointer.
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
;START OF VERSION 4A
;1172 Call LSLOOP correctly.
;1174 Label and clean up all error messages.
;1201 Change references to $SEGxxx to $SSGxxx.
;1217 Clean up the listings for release.
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL DEFINITIONS
EI.ZZ==4 ;NO. OF WORDS IN EXT/INT HASH BLOCKS
;INDEX TO ITEMS IN EXT/INT TABLE
EI.FLG==0 ;FLAGS,,LINK#
EI.SYM==1 ;SYMBOL
EI.VAL==2 ;VALUE
EI.INT==3 ;INTTAB ENTRY
EI.LEN==4 ;LENGTH OF SYMBOL BLOCK
;TEMP "SYMBOL" FLAGS
IT.DEF==PS.GLB ;SYMBOL IS DEFINED IN OTHER LINK
IT.MDF==PS.MDF ;SYMBOL IS DEFINED IN MORE THAN 1 LINK
IT.UDF==PS.UDF ;SYMBOL IS NOT YET DEFINED
IT.LST==PS.DDT ;LAST SYMBOL IF EXTENDED
;FLAGS IN OVERLAY BLOCK (JSP CALL)
F.LIC==1B0 ;LINK IN CORE (ONLY USED FOR UNDEFS)
F.MDL==1B1 ;LINK IS MULTIPLY-DEFINED
F.RLC==1B2 ;LINK IS RELOCATED (NOT USED)
;IOWD FOR PREAMBLE SECTION
IFE FTKIONLY,<
PHIOWD: IOWD PH.ZZ,PH.HDR
0
>
IFN FTKIONLY,<EXTERN PHIOWD> ;BUG IN DMOVE MACRO
DEFINE SETBIT (BIT,%ADD)<
SKIPE T1,RT.PT ;;NEED TO SET RELOC TABLE?
CAMN T1,RT.LB ;;MAYBE, DO WE?
JRST %ADD ;;NO
%BIT==0
IRP BIT,<
IFE BIT,<
IBP RT.PT ;;LEAVE 0 THERE
>
IFN BIT,<
IFN BIT-%BIT,<
MOVEI T1,BIT ;;BIT PATTERN WE WANT
%BIT==BIT
>
IDPB T1,RT.PT ;;STORE BIT PATTERN
>>
%ADD: PURGE %BIT
>
SUBTTL ENTRY POINT
LNKOV2: JFCL .+1 ;NORMAL ENTRY
E$$OS2::.ERR. (MS,,V%L,L%I,S%I,OS2,<Overlay segment phase 2>) ;[1174]
MOVE T1,SYMSEG ;GET /SYMSEG VALUE
CAIE T1,$SSGNONE ;[1201] USER SAY NO?
SKIPE NOSYMS ; . . . ?
SETZM SYMSEG ;YES, DON'T LOAD SYMBOLS
RELEASE DC, ;CLOSE INPUT I/O
MOVEI T1,DC ;FINISHED WITH INPUT BUFFERS NOW
MOVEM T1,IO.CHN
PUSHJ P,DVRET.## ;RETURN TO FREE POOL
SETZM IO.PTR+DC
MOVE T1,IO.PTR+%OC ;PSEUDO CHAN#
MOVE T2,LODNAM ;GET DEFAULT NAME
SKIPN I.NAM(T1) ;DID USER SUPPLY?
MOVEM T2,I.NAM(T1) ;NO, USE DEFAULT
MOVE T2,VERNUM ;GET VERSION#
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
MOVEM T2,I.VER(T1)
OVR2: MOVEI T1,BG.IX ;DONE WITH BOUND GLOBALS
PUSHJ P,XX.ZAP## ;SO REMOVE THEM
SETZM BG.SCH ;CERTAINLY CAN NOT SEARCH THEM NOW
HRRZ T2,BRNLEN ;HIGHEST USED
HLRE T1,BRNLEN ;-COUNT OF WHATS LEFT
SUB T2,T1 ;INITIAL SIZE
ADDI T2,1
HRRZ T1,BRNTBL ;START ADDRESS
PUSHJ P,DY.RET## ;GIVE IT BACK
HRRZ T1,BRNDSK
PUSHJ P,DY.RET## ;PARALLEL TABLE
MOVN T1,LNKMAX ;HIGHEST LINK# ASSIGNED
HRLI T1,2 ;BLOCK NUMBER OF LINK TABLE
MOVSM T1,DI.LPT ;PUT IOWD/USETI PTR IN DIRECTORY
HRRZ T2,LNMPTR ;NO. OF LINK NAMES
MOVN T1,T2 ;- FOR IOWD PART
LSH T1,1+^D18 ;WORD PAIRS IN LEFT HALF
LSH T2,1
ADD T2,L.MAX ;NO. USED BY LINK #'S
CAIL T2,LN.OVL/2 ;ENOUGH SPACE LEFT?
JRST [HALT] ;NO
MOVE T2,L.MAX ;NO. OF WORDS USED
LSH T2,-.DBS2W ;[650] BLOCKS
HRRI T1,2(T2) ;START BLOCK FOR NAMES
MOVEM T1,DI.NPT ;STORE IN DIRECTORY
MOVSI T1,(POINT 18)
MOVEM T1,PRMPTR ;MAKE SURE ITS SET TO INITIAL VALUE
MOVE T1,EXTCNT ;THIS MANY EXTERN REQUESTS
ADDI T1,^D50 ;A FEW SPARE
IMULI T1,^D100 ;MAKE SURE HASH TABLE NEVER FILLS
IDIVI T1,.HS% ;SO WE WOULD HAVE TO REHASH
MOVEM T1,HT.PRM
PUSHJ P,NPRIME## ;GET NEAREST PRIME#
MOVE T1,GS.LB ;GET BASE
SETZM (T1) ;PROBABLY JUNK THERE
HRRM T1,HT.PTR ;PUT HASH TABLE THERE
ADD T1,HT.PRM ;ACCOUNT FOR IT
MOVEM T1,GS.PT
IORI T1,.IPM ;ROUND UP
CAMG T1,GS.AB ;FIT IN WHAT WE HAVE?
JRST OVR2A ;YES
SUB T1,GS.AB ;NO, GET DIFF
MOVM P2,T1 ;WHAT WE NEED
MOVEI P1,GS.IX ;FROM WHERE
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
SKIPA T1,GS.AB ;GS.AB IS NOW SETUP CORRECTLY
OVR2A: MOVEM T1,GS.AB
SUB T1,GS.PT ;SEE WHATS LEFT
MOVEM T1,GS.FR
AOS LS.FR ;RESET LS AREA TO USE WORD 0'
SOS LS.PT
SETZM LSYM ;LS AREA IS NOW EMPTY
SETZM NAMPTR ;SO NO TITLES IN IT
OVR3: SETOM LNKNO. ;SO WE WILL START BACK AT 0
MOVE P2,LC.AB ;MAKE SURE ENOUGH CORE FOR 2 BLOCKS
SUB P2,LC.LB
CAIL P2,2*.DBS-1
JRST OVR3A ;OK
MOVEI P1,LC.IX
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
OVR3A: AOS P1,LNKNO. ;PICKUP LINK #
CAMLE P1,LNKMAX ;SEE IF FINISHED
JRST OVR4 ;YES, NOW RATIONALIZE TABLES
PUSH P,LSYM ;SAVE LSYM, SINCE RDCST READS IN
;AN OLD COPY FROM THE OVL FILE
PUSHJ P,RDCST ;READ IN BLOCK CONTAINING CONTROL SEC.
JRST [POP P,LSYM ;RESTORE LSYM
JRST OVR3A] ;GIVE UP -- NO EXTTAB OR INTTAB
POP P,LSYM ;BRING BACK LSYM
OVR3C: SETZB W1,W3 ;NO FLAGS YET
HLL R2,CS.EXT ;FORM AOBJN PTR.
JUMPGE R2,OVR3I ;DONE IF NONE THERE
OVR3D: HRRZ T1,R2 ;GET REL ADDRESS
ADD T1,LC.LB ;LOCATE
MOVE W2,ET.NAM(T1) ;GET NAME
PUSHJ P,TRYSYM## ;SEE IF IN TABLE
JRST OVR3F ;NO
JFCL ;YES
OVR3E: ADDI R2,ET.ZZ-1 ;ACCOUNT FOR MULTIPLE WORDS
AOBJN R2,OVR3D ;LOOP FOR ALL TABLE
JRST OVR3I ;NOW FOR INTTAB
OVR3F: MOVEI T2,EI.ZZ ;4 WORD TABLES
PUSHJ P,GS.GET##
MOVX W1,PT.SGN!PT.OTH!IT.UDF ;[576] NOT YET DEFINED FLAG
DMOVEM W1,EI.FLG(T1) ;STORE FLAG & NAME (REST IS ZERO)
SUB T1,GS.LB ;REMOVE BASE
HRL T1,P3 ;HASH TOTAL IN LEFT
MOVEM T1,@HT.PTR ;HASH TOTAL ,, REL ADDRESS
JRST OVR3E
OVR3I: HLRE T2,CS.INT ;GET NO OF WORDS
JUMPE T2,OVR3A ;NONE
IMUL T2,[-2] ;ACTUALLY 2 WORDS PER ENTRY
ADDI T2,1 ;PLUS ONE FOR LINK#
MOVE T1,LS.FR ;NUMBER OF WORDS FREE
SUBI T1,(T2) ;MINUS WHAT WE NEED
JUMPL T1,OVR3X ;MUST EXPAND
MOVEM T1,LS.FR ;STORE NEW COUNT
ADDM T2,LSYM ;COUNT EXTRA WORDS
MOVE T3,LS.PT ;GET NEXT FREE
ADDB T2,LS.PT
MOVE T1,CS.INT
HRR T1,CS.NUM ;-COUNT ,, LINK #
MOVEM T1,(T3) ;STORE FIRST WORD
HRRZI T1,1(T3) ;ACCOUNT FOR IT
ADD R2,LC.LB ;FIX SOURCE
HRL T1,R2 ;FORM BLT PTR
BLT T1,-1(T2) ;MOVE ALL WORDS
JRST OVR3A ;GET NEXT
OVR3X: MOVEI P1,LS.IX
MOVE P2,T2
SUB P2,LS.FR ;WHAT WE REALLY NEED
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
JRST OVR3I ;TRY AGAIN
;FIRST MAKE SURE THE POINTERS IN THE LS AREA TERMINATE
;WITH A ZERO, THEN GO PROCESS THEM.
OVR4: SKIPN LS.FR ;ANY FREE SPACE AT ALL?
JRST [MOVEI P1,LS.IX ;NO (SIGH), NEED 1 WORD
MOVEI P2,1 ;ONLY ONE LONELY WORD
PUSHJ P,LNKCOR## ;GET IT
PUSHJ P,E$$MEF## ;[1174] NOT 1 WORD ????!!!!!!
JRST .+1] ;REJOIN MAIN STREAM
SOS LS.FR ;WE NEED ONE WORD
AOS LSYM ;FOR OUR ZERO POINTER
AOS T1,LS.PT ;SO UPDATE ALL THE RIGHT POINTERS
SETZM -1(T1) ;AND CLEAR OUR LONELY LITTLE WORD
SETZ R2, ;START ON FIRST WORD
OVR4A: HRRZ T1,R2 ;GET REL ADDRESS
ADD T1,LS.LB
SKIPN T1,(T1) ;GET NEXT -LEN,,LINK #
JRST OVR5 ;TABLE EXHAUSTED, STOP
HLL R2,T1 ;AOBJN LH
HRRZM T1,LNKNO. ;STORE WHO WE ARE
HRRI R2,1(R2) ;ACCOUNT FOR WORD
SETOM INTCNT ;START AT -1 SO AOS WORKS
OVR4B: HRRZ T1,R2
ADD T1,LS.LB
DMOVE W2,(T1) ;GET NAME AND VALUE
PUSHJ P,TRYSYM## ;SEE IF REQUIRED
JRST OVR4C ;NO
JFCL
MOVE T1,0(P1) ;GET FLAGS
TXOE T1,IT.DEF ;SEE IF ALREADY DEFINED
JRST OVR4D ;YES, STORE ALL DEFINITIONS
TXZ T1,IT.UDF ;NOW DEFINED
HRR T1,LNKNO. ;WHICH LINK
MOVEM T1,EI.FLG(P1) ;PUT BACK
HRRZM W3,EI.VAL(P1) ;VALUE
AOS T1,INTCNT ;COUNT NO. IN INTTAB
HLL T1,W3 ;START OF TABLE
MOVSM T1,EI.INT(P1)
OVR4C: ADDI R2,1 ;WORDS COME IN 2S
AOBJN R2,OVR4B ;LOOP FOR ALL THIS LINK
MOVE T1,LNKNO. ;GET THIS LINK #
CAMGE T1,LNKMAX ;ALL DONE?
JRST OVR4A ;NO, GET NEXT LINK
JRST OVR5 ;YES
;HERE TO HANDLE GLOBAL DEFINED IN MORE THAN 1 LINK
OVR4D: TXON T1,IT.MDF ;SIGNAL SO
MOVEM T1,0(P1) ;AND STORE BACK
;NOW MOVE SYMBOL TO NEW LOCATION
PUSHJ P,EI.CNT ;SEE HOW LONG IT IS
ADDI T2,4 ;EXTRA WE NEED
PUSHJ P,GS.GET## ;GET NEW BLOCK
HRRZ P1,@HT.PTR ;INCASE WE MOVED
ADD P1,GS.LB
EXCH P1,T1 ;PUT NEW BLOCK IN P1 OLD IN T1
SUBI T2,EI.LEN ;LENGTH BACK AS IT WAS
HRLZ T3,T1
HRR T3,P1 ;BLT PTR
HRRZ T4,P1
ADDI T4,(T2) ;END OF BLT +1
BLT T3,-1(T4) ;MOVE SYMBOL TO NEW HOME
MOVE T3,P1
SUB T3,GS.LB ;OFFSET ONLY
HRRM T3,@HT.PTR ;MAKE HASH TABLE POINT TO NEW BLOCK
MOVX T3,PT.EXT
IORB T3,EI.FLG-EI.LEN(T4) ;SET LAST BLOCK EXTENDED
TXZ T3,PT.EXT ;NEW LAST NOT EXTENDED
HRR T3,LNKNO. ;WHICH LINK
MOVEM T3,EI.FLG(T4) ;SET FLAGS FOR NEW LAST BLOCK
MOVEM W2,EI.SYM(T4) ;STORE SYMBOL NAME AGAIN
HRRZM W3,EI.VAL(T4) ;VALUE
AOS T3,INTCNT ;COUNT NO. IN TABLE
HLL T3,W3 ;START OF TABLE
MOVSM T3,EI.INT(T4)
PUSHJ P,GS.RET## ;GIVE BACK OLD BLOCK
JRST OVR4C ;AND RETURN
;ROUTINE EI.CNT - TO COUNT LENGTH OF EI SYMBOL BLOCK
;ENTER WITH
;P1 = POINTS TO SYMBOL
;RETURNS
;LENGTH IN T2
;USES T1
EI.CNT: MOVE T3,P1 ;GET A COPY
MOVEI T2,EI.LEN ;LENGTH OF SYMBOL
EICNT1: MOVE T1,0(T3) ;GET FLAGS
TXNN T1,PT.EXT ;IS IT EXTENDED?
POPJ P, ;NO, ALL DONE
ADDI T2,EI.LEN ;YES
ADDI T3,EI.LEN
JRST EICNT1 ;ACCOUNT FOR IT AND TRY AGAIN
OVR5: MOVE T1,LS.LB ;GET BASE
SETZM (T1)
MOVEM T1,LS.PT ;MAKE IT ALL FREE
HRLZ T2,T1
HRRI T2,1(T1)
BLT T2,@LS.AB ;CLEAR ALL OF CORE
IORI T1,.IPM
MOVEM T1,LS.AB ;ALLOCATE ONE BLOCK
MOVEI T1,.IPS
MOVEM T1,LS.FR ;KEEP FREE SPACE COUNT RIGHT
SETOM LNKNO. ;START BACK ON LINK 0
AOS T2,BRNMAX ;NEED TABLE OF 1/2 WORD PER LINK ON PATH
LSH T2,-1
ADDI T2,PH.ZZ ;PLUS SPACE FOR PREAMBLE
MOVEM T2,BRNLEN
PUSHJ P,DY.GET##
HRLI T1,(POINT 18)
MOVEM T1,BRNTBL ;STORE ORIGINAL PTR
OVR6: AOS P1,LNKNO. ;GET NEXT LINK
CAMLE P1,LNKMAX ;SEE IF FINISHED
JRST OVR7 ;YES
PUSHJ P,RDCST ;READ IN BLOCK CONTAINING CONTROL SEC.
JRST [PUSHJ P,RDREL ;[573] NEITHER EXTTAB NOR INTTAB
JRST OVR6G] ;[573] SO SETUP RT AREA & SKIP ON
PUSHJ P,RDREL ;IF RELOCATABLE SETUP RT.PT
ADD R2,LC.LB ;CORE WILL NOT MOVE NOW
SETZB W1,W3 ;SAVE CONFUSION
HLL R2,CS.EXT
JUMPGE R2,OVR6D ;NO EXTTAB
HRRZ P3,CS.EXT ;GET START ADDRESS
SKIPE T2,RT.PT ;IS IT RELOCATABLE?
CAMN T2,RT.LB ;NOT IF AREA IS EMPTY
CAIA ;EMPTY, DON'T CALL RT.P3
PUSHJ P,RT.P3## ;SET UP RT.PT
OVR6C: MOVE W2,ET.NAM(R2) ;GET NAME
PUSHJ P,TRYSYM## ;LOOK IT UP
JRST E$$USC ;[1174]
JRST E$$USC ;[1174]
MOVE T2,EI.FLG(P1) ;GET LINK#
TXNE T2,IT.MDF ;MULTIPLY-DEFINED?
JRST OVR6M ;YES
SPUSH <FSTPTR,P3>
MOVE P3,P1 ;SAVE SYMBOL PTR
SKIPN P1,CS.NUM ;ONLY WANT TO LOOK AT TREE ABOVE US
JRST OVR6CA ;ALL IS ABOVE ROOT
PUSHJ P,TR.WLK## ;THESE ARE ONLY LINKS WE CAN REACH
JUMPE P2,[MOVE P2,CS.NUM ;SHOULD NOT HAPPEN
PUSHJ P,E$$LNM##] ;[1174] BUT!!!
HLRZ T1,P1 ;GET POINTER
HRRZ T1,(T1) ;GET LINK# OF HEAD OF NODE
CAIE T1,(P1) ;IF NOT EQUAL THEN REQUIRED NODE IS A TERMINAL ONE
JRST OVR6CN ; IN WHICH CASE IT HAS NO SONS
HLRZM P1,FSTPTR ;CREATE SUB-TREE PTR
HRRZ P1,EI.FLG(P3) ;LINK# WE WANT
PUSHJ P,TR.WLK## ;SEE IF WE CAN SEE IT
JUMPE P2,OVR6CN ;NOT VISIBLE
;HERE IF DESIRED LINK IS VISIBLE
OVR6CA: MOVE P1,P3 ;PUT P1 BACK
SPOP <P3,FSTPTR>
OVR6CB: MOVE T2,EI.FLG(P1) ;GET LINK #
HRLM T2,ET.CST(R2) ;SAVE IT
HLRZ T1,EI.INT(P1) ;GET ITEM NO. IN INTTAB
LSH T1,1 ;2 WORDS PER ITEM
ADD T1,EI.INT(P1) ;FIX IT
HRRZM T1,ET.INC(R2) ;STORE IT WITH 0 FLAGS
OVR6CC: SETZM ET.NAM(R2) ;CLEAR NAME NOW
OVR6CD: SETBIT <0,0,1,0>
ADDI R2,ET.ZZ-1
AOBJN R2,OVR6C ;LOOP FOR ALL OF EXTTAB
JRST OVR6D
E$$USC::.ERR. (MS,.EC,V%L,L%F,S%W,USC,<Undefined subroutine >) ;[1174]
.ETC. (SBX,.EC!.EP,,,,W2)
.ETC. (STR,.EC,,,,,< called from>) ;[1174]
.ETC. (JMP,,,,,.ETLNN##) ;[1174]
OVR6CE: MOVE T1,ADDOVU ;ADDRESS OF UNDEFINED ROUTINE
HLRZM T1,ET.CST(R2) ; AND ROOT CST
HRLI T1,(F.LIC) ;ALWAYS IN CORE
MOVEM T1,ET.INC(R2) ;TO SAVE TIME AND EFFORT
JRST OVR6CD ;IN OVERLAY HANDLER
OVR6CN: HRRZ P1,EI.FLG(P3) ;GET LINK #
E$$SNP::.ERR. (MS,.EC,V%L,L%W,S%W,SNP,<Subroutine >) ;[1174]
.ETC. (SBX,.EC!.EP,,,,W2)
.ETC. (STR,.EC,,,,,< in link number >)
.ETC. (DEC,.EC!.EP,,,,P1)
.ETC. (STR,.EC,,,,,< not on path for call from>) ;[1174]
.ETC. (JMP,,,,,.ETLNN##) ;[1174]
MOVE P1,P3 ;RESTORE P1
SPOP <P3,FSTPTR>
JRST OVR6CE ;AND MAKE IT UNDEFINED AT RUN TIME
;HERE ON A MULTIPLY-DEFINED ENTRY POINT
OVR6M: SPUSH <FSTPTR,P3,P4>
MOVE P3,P1 ;SAVE SYMBOL PTR
SETZ P4, ;KEEP POINTER TO FIRST AVAILABLE SYMBOL
SKIPN P1,CS.NUM ;WE ONLY WANT TO LOOK AT TREE ABOVE US
JRST OVR6MA ;ALL OF TREE IS ABOVE ROOT
PUSHJ P,TR.WLK## ;SINCE THESE ARE THE ONLY LINKS WE
;CAN REACH, ALL OTHERS ARE NOT AVAILABLE
JUMPE P2,[MOVE P2,CS.NUM ;CANNOT HAPPEN
PUSHJ P,E$$LNM##] ;[1174] BUT!
HLRZ T1,P1 ;GET POINTER
HRRZ T1,(T1) ;GET LINK# OF HEAD OF NODE
CAIE T1,(P1) ;IF NOT EQUAL THEN REQUIRED NODE IS A TERMINAL ONE
SETZB P1,P2 ; IN WHICH CASE IT HAS NO SONS
HLRZM P1,FSTPTR ;USE THIS AS START OF SUB TREE
OVR6MA: HRRZ P1,EI.FLG(P3) ;GET LINK#
SKIPE FSTPTR ;INDICATES NO POSSIBLE SONS
PUSHJ P,TR.WLK## ;SEE IF WE CAN GET TO IT
JUMPE P2,OVR6MB ;NO, TRY NEXT
JUMPN P4,OVR6MC ;NOT FIRST, SO ERROR
MOVE P4,P3 ;SAVE PTR TO FIRST AVAILABLE
OVR6MB: MOVE T1,EI.FLG(P3) ;GET FLAGS
TXNN T1,PT.EXT ;MORE TO COME?
JRST OVR6MZ ;NO, ITS THE END
ADDI P3,4 ;GET NEXT
JRST OVR6MA
OVR6MZ: MOVE P1,P4 ;UNIQUE SYMBOL
POP P,P4
JUMPE P1,OVR6CN ;NONE CAN BE REACHED
SPOP <P3,FSTPTR>
JRST OVR6CB ;RETURN WITH P1 SETUP
OVR6MC: MOVX T1,F.MDL ;MARK IT MULTIPLY DEFINED
IORM T1,ET.INC(R2) ;IN EXTTAB
SUB P4,GS.LB ;INCASE WE MOVE
SUB P3,GS.LB
PUSH P,P4 ;SAVE ORIGINAL
PUSH P,P3 ;SAVE SECOND DEF
ADD P3,GS.LB ;PUT BASE BACK
MOVEI P4,2 ;COUNT NUMBER IN P4
JRST OVR6ME ;GET NEXT
OVR6MD: HRRZ P1,EI.FLG(P3) ;GET LINK#
PUSHJ P,TR.WLK## ;SEE IF WE CAN GET TO IT
JUMPE P2,OVR6ME ;NO, TRY NEXT
SUB P3,GS.LB
PUSH P,P3 ;SAVE IT
ADD P3,GS.LB ;RESTORE GS BASE
ADDI P4,1 ;ONE MORE
OVR6ME: MOVE T1,EI.FLG(P3) ;GET FLAGS
TXNN T1,PT.EXT ;MORE TO COME?
JRST OVR6MF ;NO, ITS THE END
ADDI P3,4 ;GET NEXT
JRST OVR6MD
OVR6MF: SUB R2,LC.LB ;CORE MIGHT MOVE
MOVE T2,P4 ;NO. OF DEFINITIONS
LSH T2,1 ;2 WORDS EACH
ADDI T2,2 ;PLUS LINK TO NEXT & NAME
PUSHJ P,DY.GET## ;SPACE TO BUILD THE TABLE
MOVN P3,P4
HRLZ P3,P3
HRR P3,T1 ;AOBJN WORD
HRRZ T1,CS.RLC ;USE THIS TO POINT TO LIST
HRL T1,R2 ;POINT TO WHICH ONE
MOVEM T1,(P3) ;STORE IN FIRST WORD
HRRZM P3,CS.RLC ;RESET TO POINT TO THIS FIRST
ADDI P3,2 ;BYPASS FIRST TWO WORD
MOVE T2,P4 ;ALSO NEED SPACE TO STORE ERROR MESSAGE
IMULI T2,7 ;6 CHAR NAME PLUS COMMA
IDIVI T2,5 ;STORED AS ASCII
ADDI T2,1 ;FOR PARTIAL WORD
PUSHJ P,DY.GET## ;GET SPACE
;HERE TO PRINT ERROR MESSAGE. GENERATE PART OF MESSAGE IN DY AREA.
MOVE P1,T1 ;PUT IN SAFE PLACE (CANNOT USE STACK)
HRLI P1,(POINT 7,) ;FORM BYTE PTR
HRLZ P2,T2
HRR P2,T1 ;SO WE CAN GIVE IT BACK
ADD R2,LC.LB ;PUT BASE BACK
HLLM P3,ET.CST(R2) ;STORE COUNT BACK IN EXTTAB
MOVE T2,ET.NAM(R2) ;GET NAME
MOVEM T2,-1(P3) ;STORE IN SECOND WORD
OVR6MG: POP P,T4 ;GET ADDRESS BACK
ADD T4,GS.LB ;FIX IN CORE
HRL T1,EI.FLG(T4) ;GET LINK #
HRR T1,ET.CST(R2) ;AND CONTROL SECTION (WILL GET DESTROYED)
HLRZ T2,T1 ;GET LINK #
PUSHJ P,[IDIVI T2,^D10 ;USUAL RADIX PRINTER
HRLM T3,0(P) ;STORE ON STACK
SKIPE T2 ;DONE?
PUSHJ P,@. ;NOT YET
HLRZ T2,0(P) ;RECOVER CHAR
ADDI T2,"0" ;MAKE ASCII
IDPB T2,P1 ;STORE
POPJ P,] ;RETURN
MOVEI T2,","
IDPB T2,P1 ;SEPARATOR
HLRZ T2,EI.INT(T4) ;GET ITEM NO. IN INTTAB
LSH T2,1 ;2 WORDS PER ITEM
ADD T2,EI.INT(T4) ;FIX IT
HLL T2,ET.INC(R2) ;COPY FLAGS
MOVEM T2,0(P3) ;STORE
MOVEM T1,1(P3) ;...
ADDI P3,1
AOBJN P3,OVR6MG ;MORE TO DO
SETZ T1, ;STORE A NULL
DPB T1,P1 ;AT END OF STRING
HRRZ P1,P2 ;[627] POINT BACK TO START OF STRING
E$$ARL::.ERR. (MS,.EC,V%L,L%W,S%W,ARL,<Ambiguous request in>) ;[1174]
.ETC. (JMP,.EC,,,,.ETLNN##) ;[1174]
.ETC. (STR,.EC,,,,,< for symbol >) ;[1174]
.ETC. (SBX,.EC!.EP,,,,W2)
.ETC. (STR,.EC,,,,,<, defined in links >)
.ETC. (STR,.EP,,,,P1)
HRRZ T1,P2
HLRZ T2,P2
PUSHJ P,DY.RET## ;GIVE SPACE BACK
SPOP <P4,P3,FSTPTR>
JRST OVR6CC ;GET NEXT SYMBOL
OVR6D: HLRE R3,CS.INT ;[635] GET NO. OF INTTAB ENTRIES
IMUL R3,[-2] ;[635] CONVERT TO WORDS
ADD R3,CS.INT ;[635] MAKE FIRST FREE AFTER INTTAB
JUMPN R3,OVR6DA ;[635] USE IT IF INTTAB EXISTS
HLRE R3,CS.EXT ;[635] OTHERWISE USE END OF EXTTAB
IMUL R3,[-ET.ZZ] ;[635] WORDS IN EXTTAB
ADD R3,CS.EXT ;[635] THENCE TO FIRST WORD BEYOND IT
OVR6DA: HRRZ T1,OV.S1 ;[635] FIRST FREE BEYOND /ARSIZE
SUBI T1,0(R3) ;[635] MINUS FIRST WORD OF /ARSIZE AREA
HRRM T1,ARSIZE ;[635] IS THIS LINK'S ARSIZE
HLL R2,CS.INT ;GET NO. OF INTTABS
JUMPGE R2,OVR6FA ;NONE
HRRZ R3,R2 ;USED TO STORE BACK IF REQUIRED
HRRZ P3,CS.INT ;GET START ADDRESS
SKIPE T1,RT.PT ;IS IT RELOCATABLE?
CAMN T1,RT.LB ;MAYBE, IS IT?
CAIA ;NO
PUSHJ P,RT.P3## ;SET UP RT.PT
OVR6E: DMOVE W2,(R2) ;GET SYMBOL & VALUE
PUSHJ P,TRYSYM## ;SEE IF WANTED
JRST OVR6F ;NOT IN TABLE SO NOT WANTED
HALT
MOVE T1,0(P1) ;GET FLAGS
TXNN T1,IT.DEF ;SEE IF ITS WANTED
JRST OVR6F ;NO
HRRZM W3,0(R3) ;STORE PTR AS VALUE
SETZM 1(R3) ;NO REFS YET
ADDI R3,2
SETBIT <1,0>,OVR6F
OVR6F: ADDI R2,1
AOBJN R2,OVR6E ;LOOP
HRRZ R2,R2
CAML R3,R2 ;DID WE REDUCE?
JRST OVR6FA ;NO
HRLZI T1,0(R3)
HRRI T1,1(R3) ;FORM BLT PTR
SETZM (R3) ;CLEAR FIRST WORD
BLT T1,-1(R2) ;AND REST
SUB R3,R2 ;SEE BY HOW MUCH WE REDUCED
MOVM T1,R3 ;+DIFF
ADD R2,R3 ;BACKUP NEXT FREE PTR
LSH T1,^D17 ;CUT IN HALF AND PUT IN LHS
ADDM T1,CS.INT ;MAKE THIS RIGHT
OVR6FA: SKIPN P1,CS.RLC ;ANY MULTIPLY DEF GLOBALS?
JRST OVR6G ;NO
SETZ P3, ;[635] INDICATE NO TMA ERROR YET
HLRE R3,CS.INT ;THESE WILL GO AT END OF TABLES
IMUL R3,[-2]
ADD R3,CS.INT
JUMPN R3,OVR6FB ;BUT IF NO INTTAB
HLRE R3,CS.EXT ; USE EXTTAB
IMUL R3,[-ET.ZZ]
ADD R3,CS.EXT
OVR6FB: MOVE T1,0(P1) ;GET NEXT PTR
HRRZM T1,CS.RLC ;AND SET IT
HLRZ P2,T1 ;PTR TO EXTTAB BLOCK
ADD P2,LC.LB ;IN CORE
HRRM R3,ET.CST(P2) ;POINT TO BLOCK OF DEFINITIONS
HLRE T1,ET.CST(P2) ;GET LENGTH
MOVM T2,T1 ;+ LENGTH
LSH T2,1 ;WORD PAIRS
ADDI T2,1 ;PLUS ONE FOR NAME
JUMPE P3,OVR6FD ;[635] IF NO ERROR YET, CHECK IF ONE NOW
ADD P3,T2 ;[635] ERROR--JUST ACCUMULATE TOTAL NEED
JRST OVR6FG ;[635] GO FREE THIS BLOCK & CHECK NEXT
;HERE IF ARL TABLE STILL WITHIN OVERLAY. SEE IF OVERFLOW IMMINENT.
OVR6FD: HRRZ T1,OV.S1 ;[635] GET FIRST FREE AFTER LINK
SUB T1,T2 ;[635] COMPUTE MAX FF AFTER ARL TABLE
CAIL T1,(R3) ;[635] STILL WITHIN LIMITS?
JRST OVR6FE ;[635] YES, GO BLT INFO INTO TABLE
SUBI T1,(R3) ;[635] NO, FIND OUT HOW MUCH OVER
HRRZ P3,ARSIZE ;[635] FLAG ERROR, START WITH /ARSIZE
SUB P3,T1 ;[635] ADD THIS OVERAGE (IS NEGATIVE)
JRST OVR6FG ;[635] GO RETURN BLOCK WITHOUT BLT
;HERE WHEN THIS BLOCK WILL FIT TOO. COPY IT ONTO END OF OVERLAY.
OVR6FE: HRLZI T1,1(P1) ;[635] FROM (EXCLUDING PTR WORD)
HRR T1,R2 ; TO
ADD R2,T2
HRRZ T3,LC.AB ;[635] HIGHEST WORD ALLOCATED TO LC
CAIL T3,-1(R2) ;[635] IS BLT GOING BEYOND LC?
JRST OVR6FF ;[635] NO, PROCEED
SUB T1,LC.LB ;[635] CORE MIGHT MOVE
SUB P2,LC.LB ;[635] ..
SUB R2,LC.LB ;[635] ..
SPUSH <T1,T2,P1,P2> ;[635] SAVE ACCS LNKCOR WILL USE
MOVEI P1,LC.IX ;[635] EXPAND LC AREA
MOVEI P2,.IPS ;[635] ONE BLOCK IS ENOUGH FOR NOW
PUSHJ P,LNKCOR## ;[635] EXPAND LC AREA
PUSHJ P,E$$MEF## ;[1174] TOO BAD
SPOP <P2,P1,T2,T1> ;[635] RESTORE NEEDED ACCS
ADD R2,LC.LB ;[635] FIX ADDRESSES AGAIN
ADD P2,LC.LB ;[635] ..
ADD T1,LC.LB ;[635] ..
OVR6FF: BLT T1,-1(R2) ;[635] BLT BLOCK
OVR6FG: MOVE T1,P1 ;[635]
ADD R3,T2 ;SET FOR NEXT BLOCK
ADDI T2,1 ;PTR WORD IN FRONT ALSO
PUSHJ P,DY.RET## ;RETURN SPACE
SUBI T2,1
JUMPN P3,OVR6FC ;[635] IF HAD AN ERROR, DON'T SETUP RT
SKIPE T1,RT.PT ;RELOCATABLE?
CAMN T1,RT.LB ;NOT IF AREA IS EMPTY
JRST OVR6FC ;NO
MOVEI T1,1 ;SET BIT
HLRE T2,ET.CST(P2) ;NO. OF PAIRS
IBP RT.PT ;ACCOUNT FOR NAME
IBP RT.PT ;INTTAB
IDPB T1,RT.PT ;CS IS RELOCATABLE
AOJL T2,.-2 ;LOOP FOR ALL TABLE
OVR6FC: SKIPE P1,CS.RLC ;MORE TO DO?
JRST OVR6FB ;TRY AGAIN
JUMPE P3,OVR6G ;[635] PROCEED IF NO ERROR DETECTED
E$$TMA::.ERR. (MS,.EC,V%L,L%F,S%W,TMA,<Too many ambiguous requests in>) ;[1174]
.ETC. (JMP,.EC,,,,.ETLNN##) ;[1174]
.ETC. (STR,.EC,,,,,<, use /ARSIZE:>)
.ETC. (DEC,.EP,,,,P3)
CAMLE P3,TMAMAX ;[635] LARGEST SEEN YET?
MOVEM P3,TMAMAX ;[635] YES, SAVE FOR FATAL ERROR AT END
; JRST OVR6G ;[635] CONTINUE TO NEXT LINK
OVR6G: MOVE T1,PH.LEN ;GET LENGTH
HRLM T1,CS.COR ;INTO CONTROL SECTION
MOVE T1,PH.CST ;NOW TO COPY CS BACK
SUB T1,PH.ADD
ANDI T1,.DBM ;[743] MAKE REL TO THIS BLOCK
ADD T1,LC.LB ;FIX IN CORE
MOVEI T2,CS.ZZ-1(T1) ;END OF BLT
HRLI T1,CS.HDR
BLT T1,(T2) ;MOVE IT ALL
SKIPN P1,CS.NUM ;NOW SET TO WRITE BACK THIS LINK
JRST OVR6GC ;DON'T BOTHER IF LINK 0
PUSHJ P,TR.WLK## ;GET PATH
JUMPE P2,OVR6GC ;DONE IF NONE LINKED TO IT
ROT P2,-1 ;STORE 2 LINK# PER WORD
SKIPGE P2 ;IF A REMAINDER
ADDI P2,1 ;ADD ONE FOR IT
MOVEI T1,PH.ZZ
HLL T1,OVLBLK ;AND BLOCK#
ADDI P2,-1(T1) ;GET BYTE POINTER TO END
MOVSM T1,PH.FPT ;LIST IN FORWARDS DIRECTION
HRLZM P2,PH.BPT ;AND IN BACKWARDS DIRECTION
ADD P2,BRNTBL ;SO WE CAN STORE BACKWARDS
TLOE P2,(1B0) ;SEE WHICH HALF WORD TO START WITH
IBP P2 ;STORE IN RIGHT HALF ON EVEN P2
MOVS T1,P1 ;GET POINTER BACK
HRRZ T2,(T1) ;GET LINK #
CAIN T2,(P1) ;POINTING TO NON-TERMINAL LINK?
MOVE T1,1(T1) ;YES, GET BACK POINTER
SETZM (P2) ;MAKE SURE LAST LINK IS 0
OVR6GA: HRRZ T2,(T1) ;LINK#
JUMPE T2,OVR6GB ;DONE WHEN BACK TO 0
IDPB T2,P2 ;STORE IT
MOVE T1,1(T1) ;GET BACK POINTER
SOJA P2,OVR6GA ;LOOP
OVR6GB: HLRZ T2,PH.BPT ;REL START IN BACK DIRECTION
LSH T2,-.DBS2W ;[650] IN BLOCKS
HLRZ T1,OVLBLK ;GET STARTING BLOCK#
ADDI T2,(T1) ;ACCOUNT FOR EXTRA BLOCKS USED (PERHAPS)
HRRM T2,PH.BPT ;AND STORE BLOCK#
OVR6GC: USETO OC,(R1) ;RESET BACK TO BLOCK WE NEED
MOVE T1,LC.LB
SUBI T1,1
MOVE T2,PH.CST ;[635] ADDR OF CONTROL SECTION
SUB T2,PH.ADD ;[635] OFFSET FROM START OF LINK
ANDI T2,.DBM ;[635] # WORDS BEFORE CS IN LC AREA
ADD T2,PH.ADD ;[635] PLUS LENGTH OF CS, INTTAB,
ADD T2,PH.LEN ;[635] EXTTAB, AND ARL TABLE
SUB T2,PH.CST ;[635] ..
IORI T2,.DBM ;[635] TOTAL SIZE IN LC AREA TO OUTPUT
MOVNI T2,1(T2) ;[635] NEGATIVE FOR IOWD
HRL T1,T2 ;IOWD
SETZ T2,
OUT OC,T1 ;OUTPUT IT
JRST OVR6H
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
OVR6H: SKIPE T1,RT.PT ;RELOC TABLE TO PUT OUT?
CAMN T1,RT.LB ;..?
JRST OVR6S ;NO
HRRZ P3,PH.CST
ADDI P3,CS.PTR-CS.HDR+1 ;BYPASS KNOWN ZEROS AND FIRST IBP
PUSHJ P,RT.P3## ;RESET IT
MOVEI T1,1 ;RELOC BIT
MOVE T2,[CS.PTR-CS.HDR+1-CS.ZZ,,CS.PTR] ;AOBJN PTR
SKIPE 0(T2) ;NEED TO RELOC
DPB T1,RT.PT ;YES
IBP RT.PT ;ADVANCE
AOBJN T2,.-3 ;FOR ALL TABLE
MOVE T1,PH.ADD ;WHERE ADDRESS WOULD BE
MOVE T2,PH.CST ;BUT THIS IS LOWEST ADDRESS WE CARE ABOUT
SUB T2,T1 ;I.E CST PLUS TABLES
IDIVI T2,.DBS*^D18 ;[650] BYTES PER DSK BLOCK
MOVE T3,T2 ;NO. OF WHOLE BLOCKS TO SKIP
ADD T3,PH.REL ;PLUS FIRST
USETO OC,(T3) ;SET ON IT
IMULI T2,.DBS ;[650] NO. OF WORDS TO SKIP
HLRE T1,PH.REL ;NO. OF WORDS ORIGINALLY
ADD T1,T2 ;NO. LEFT
HRLZ T1,T1 ;LHS OF IOWD
HRR T1,RT.LB
HRRI T1,-1(T1) ;IOWD AT LAST
SETZ T2,
OUT OC,T1
JRST OVR6S ;OK
PUSHJ P,E$$OOV## ;[1174] THIS IS AN OUTPUT ERROR
;HERE TO CHECK IF SYMBOLS NEEDED, AND READ THEM IN IF SO.
;WE DO THIS BY FILLING THE LS AREA WITH TRIPLETS, CLEARING THE LC AREA,
;AND CALLING LSLOOP IN LNKXIT TO GENERATE A RUNTIME SYMBOL TABLE IN THE
;LC AREA. WE DON'T ALLOW EITHER AREA TO PAGE.
OVR6S: SKIPE R,SYMSEG ;WANT TO KEEP SYMBOLS?
SKIPN T1,PH.SYM ;YES, BUT MAKE SURE THERE ARE SOME
JRST OVR6P ;NO
SETZM USYM ;THERE ARE NO UNDEFINED SYMBOLS IN THIS TABLE
SETZM NAMPTR ;THIS COULN'T BE VALID
SETOM LS.PP ;CAN'T PAGE LS NOW
USETI OC,(T1) ;SET ON SYMBOL BLOCK
HLRE T1,T1 ;SIZE WE NEED
MOVE P2,LS.UB
MOVEM P2,LS.AB ;USE IT ALL
SUB P2,LS.LB ;SIZE WE HAVE
ADD P2,T1 ;GET DIFF
JUMPGE P2,OVR6S1 ;IS IT ENOUGH
MOVEI P1,LS.IX ;NO, GET AREA
MOVM P2,P2 ;AND SIZE
PUSHJ P,LNKCOR## ;EXPAND
PUSHJ P,E$$MEF## ;[1174] TOO BAD
OVR6S1: HLRE T1,PH.SYM ;GET -LENGTH AGAIN
MOVM T1,T1
MOVE T2,LS.UB ;TOP
MOVEM T2,LS.AB ;MAKE SURE THE SAME
IORI T1,.IPM ;ROUND UP
SUB T2,T1 ;FIND WHERE LOWER BOUND SHOULD BE
CAMN T2,LS.LB ;ARE WE USING IT ALL
JRST .+3 ;YES
MOVEI T1,-1(T2) ;HIGHEST TO GIVE BACK
PUSHJ P,GBCK.L## ;WILL RESET LS.LB
SETZM LS.PP ;LSLOOP KNOWS HOW TO PAGE
MOVE T1,LS.LB ;WHERE TO READ INTO
SUBI T1,1
HLL T1,PH.SYM ;IOWD
SETZ T2,
IN OC,T1 ;READ BACK SYMBOLS
SKIPA T1,LSYM ;OK, NOW TO RESET LAST SYM PTR
PUSHJ P,E$$IOV## ;[1174] ERROR
SUB T1,LW.LS ;SHOULD BE 0
ADD T1,LS.LB ;OFFSET IN CORE
MOVEM T1,LS.PT
;NOW FOR LC AREA
;WE ACTUALLY NEED ABOUT 2/3 THE LS SPACE
;JUST ALLOCATE 1 BLOCK WE WILL EXPAND AS REQUIRED
HRRZ T1,TAB.LB(R)
HRL T1,T1
HRRI T1,1(T1) ;FORM BLT PTR
SETZM -1(T1)
BLT T1,@TAB.AB(R) ;ZERO AREA
MOVE T1,TAB.LB(R) ;NOW RESET ACTUAL BOUND
MOVEM T1,TAB.PT(R) ;ALSO FREE POINTER
IORI T1,.IPM ;USING ONLY ONE BLOCK
MOVEM T1,TAB.AB(R)
MOVE P3,PH.ADD ;SYMBOL TABLE STARTS AT REL 0
SETZM OVLOFF ; TO FAKE OUT RT.P3
SKIPE T1,RT.PT ;RELOCATABLE?
CAMN T1,RT.LB ;..
JRST OVR6L ;NO
PUSHJ P,RT.P3## ;YES, SETUP PTR
MOVE T1,RT.LB ;YES, MUST ZERO PREVIOUS JUNK
HRL T1,T1
ADDI T1,1
SETZM -1(T1)
BLT T1,@RT.AB ;AT LAST ITS DONE
OVR6L: PUSHJ P,LSOVX## ;[1172] INITIALIZE LNKXIT FOR LSLOOP CALL
PUSHJ P,LSLOOP## ;YES
MOVE T2,TAB.PT(R) ;FINAL LENGTH
SUB T2,TAB.LB(R)
MOVN T1,T2 ;- LENGTH OF SYMBOLS
HRLZ T1,T1 ; IN LHS FOR IOWD
HRR T1,OVLBLK ;BLOCK NUMBER
MOVEM T1,PH.RDX ;POINTER TO RADIX-50 SYMBOLS
USETO OC,(T1) ;SET ON IT
ADDI T2,.IPS
LSH T2,-.DBS2W ;[650] NO. OF BLOCKS
ADDM T2,OVLBLK ;ACCOUNT FOR THEM
HRR T1,TAB.LB(R) ;START OF CORE TO OUTPUT
HRRI T1,-1(T1) ;-1 OF COURSE
SETZ T2, ;TERMINATOR
OUT OC,T1 ;OUTPUT IT
JRST OVR6R ;OK
PUSHJ P,E$$OOV## ;[1174] FAILED
OVR6R: SKIPE T1,RT.PT ;ANY RELOCATION TABLES?
CAMN T1,RT.LB ;..
JRST OVR6P ;NO
MOVEI T1,1(T1) ;TOP
SUB T1,RT.LB ;- BOTTOM
MOVEI T2,.DBS(T1) ;[650] MAKE INTO BLOCKS (+ REMAINDER)
MOVN T1,T1 ;-LENGTH
HRLZ T1,T1 ; IN LHS FOR IOWD
HRR T1,OVLBLK ;POINT TO NEXT FREE BLOCK
MOVEM T1,PH.RDR ;STORE PTR
USETO OC,(T1) ;SET ON IT
LSH T2,-.DBS2W ;[650] INTO BLOCKS
ADDM T2,OVLBLK ;ACCOUNT FOR THEM
HRR T1,RT.LB ;BASE
HRRI T1,-1(T1) ;IOWD
SETZ T2,
OUT OC,T1 ;OUTPUT
JRST OVR6P ;FINISHED
PUSHJ P,E$$OOV## ;[1174] ERROR
OVR6P: HLRZ T1,OVLBLK ;BLOCK # OF PREAMBLE
USETO OC,(T1) ;SET BACK TO IT
DMOVE T1,PHIOWD
SKIPN T3,PH.BPT ;DO WE HAVE TO OUTPUT THE PATH?
JRST OVR6Z ;NO
MOVN T1,T3 ;NEGATE
HRLI T3,PH.HDR ;SINCE GATHER WRITE DOESN'T WORK
HRR T3,BRNTBL ;WE MUST BLT THE STUFF TOGETHER
HRRI T1,-1(T3) ;COMPLETE IOWD
BLT T3,PH.ZZ(T1)
OVR6Z: OUT OC,T1
JRST OVR6X ;NOW FIXUP CS.DDT IF REQUIRED
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
OVR6X: SKIPN PH.RDX ;ANY RADIX-50 SYMBOLS
JRST OVR6 ;NO, LOOP FOR ALL LINKS
HRRZ R1,PH.OVL ;BLOCK# OF CODE SECTION
MOVE T3,PH.CST ;ADDRESS OF HEADER
SUB T3,PH.ADD ;MINUS BASE
ROT T3,-.DBS2W ;[650] CONVERT TO BLOCKS
ADDI R1,(T3) ;POINT TO IT
USETI OC,(R1) ;SET ON IT
LSH T3,.DBS2W-^D36 ;ANDI 177 WITH ORIGINAL T3
MOVEI T1,CS.DDT-CS.HDR(T3) ;GET NO. OF WORDS TO END
IORI T1,.DBM ;[650] INCASE IT CROSSES BLOCK BOUND
MOVNI T1,1(T1) ;IOWD
HRL T1,T1
HRR T1,LC.LB
HRRI T1,-1(T1) ;AT LAST
SETZ T2,
IN OC,T1
TDOA T3,LC.LB ;ADDRESS OF CS.HDR
PUSHJ P,E$$IOV## ;[1174]
MOVE T2,PH.RDX ;GET SYMBOL TABLE PTR
MOVEM T2,CS.DDT-CS.HDR(T3) ;STORE
USETO OC,(R1) ;SET BACK
SETZ T2,
OUT OC,T1 ;WRITE IT BACK
JRST OVR6 ;LOOP
PUSHJ P,E$$OOV## ;[1174]
OVR7: SKIPN TMAMAX ;[635] ANY %LNKTMA MESSAGES OUTPUT?
JRST OVR7C ;[635] NO, CONTINUE
E$$ABT::.ERR. (MS,.EC,V%L,L%F,S%F,ABT,<Load aborted due to %LNKTMA errors, max. /ARSIZE: needed was >) ;[1174]
.ETC. (DEC,.EP,,,,TMAMAX)
;HERE TO OUTPUT THE DIRECTORY BLOCK
OVR7C: MOVE T1,[0,,DI.ZZ] ;[635] CODE ,, LENGTH
MOVEM T1,DI.HDR
MOVE T1,VERNUM ;GET VERSION#
MOVEM T1,DI.VER ;INTO DIRECTORY
USETO OC,1 ;NOW FOR DIRECTORY BLOCK
SKIPA T1,.+1
IOWD DI.ZZ,DI.HDR ;VERY LOCAL CODE
SETZ T2,
OUT OC,T1
CAIA
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
MOVN T1,L.MAX ;GET MAX LINKS ALLOWED
HRLZ T1,T1
HRR T1,LNKTBL ;ADDRESS OF IT
HRRI T1,-1(T1) ;IOWD
SETZ T2,
OUT OC,T1
CAIA
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
;NOW FOR LINK NAMES, THERE WILL BE AT LEAST ONE (ROOT)
MOVE T1,DI.NPT ;GET AOBJN/USETO PTR
USETO OC,(T1) ;WHERE WE WILL START OUTPUT
HLRE T1,T1 ;- NO. OF WORDS
MOVM T2,T1
PUSHJ P,DY.GET## ;GET BUFFER
SUBI T1,1 ;BACKUP
HLL T1,DI.NPT ;FORM IOWD
PUSH P,T1 ;SAVE I/O WORD FOR LATER
MOVS T2,LNMPTR ;GET INITIAL PTR TO NAMES
OVR7A: DMOVE T3,(T2) ;GET NAME AND LINK #
HRRZ T2,T4 ;GET NEXT
HLRZM T4,1(T1) ;STORE NUMBER
MOVEM T3,2(T1) ; AND NAME
JUMPE T2,OVR7B ;END
AOBJN T1,.+1 ;INCREMENT
AOBJN T1,OVR7A ;TWICE
HALT ;ERROR
OVR7B: POP P,T1 ;GET BACK IOWD
SETZ T2,
OUT OC,T1 ;OUTPUT IT
CAIA ;OK
PUSHJ P,E$$OOV## ;[1174] ERROR
HLRE T2,T1 ;GET BACK LENGTH
MOVM T2,T2
HRRZI T1,1(T1) ;ADDRESS
PUSHJ P,DY.RET##
SKIPE IO.PTR+%VC ;SAVE SWITCH SEEN?
JRST OVR8 ;YES
MOVEI T2,F.LEN ;NO, FAKE IT
PUSHJ P,DY.GET## ;SPACE FOR FILE SPEC
MOVEM T1,IO.PTR+%VC
HRLZ T2,IO.PTR+%OC
HRR T2,T1
BLT T2,F.LEN-1(T1) ;COPY OVERLAY SPEC
IFN FTEXE,< MOVSI T2,'EXE'>
IFE FTEXE,< MOVSI T2,'HGH'> ;ASSUME NOT SHAREABLE
MOVEM T2,I.EXT(T1) ; BUT MIGHT BE TWO SEG
MOVEM T2,SSEXT
MOVE T2,I.NAM(T1) ;GET OVERLAY NAME
MOVEM T2,SSNAME
SETZM I.EST(T1)
OVR8: MOVE T2,BRNLEN
HRRZ T1,BRNTBL
PUSHJ P,DY.RET## ;GIVE SPACE BACK
MOVEI T1,RT.IX ;DESTROY RT AREA NOW
PUSHJ P,XX.ZAP ;SO LNKMAP WILL HAVE MORE ROOM
MOVE T1,MAPSW ;SEE IF WE WANT A MAP
CAMN T1,[$MAPEND] ;AT THE END
PUSHJ P,LNKMAP ;YES
MOVEI T1,GS.IX ;WE CAN NOW REDUCE CORE
PUSHJ P,XX.ZAP## ;DELETE GLOBALS
MOVEI T1,FX.IX
PUSHJ P,XX.ZAP## ;AND FIXUP SPACE
SETZ P1, ;ALWAYS READ BACK
PUSHJ P,INPH ;ROOT PREAMBLE
SKIPE R,SYMSEG ;SAVING DDT SYMBOLS?
SKIPN T1,PH.RDX ;MAKE SURE ITS SETUP
JRST OVR8B ;NO?
USETI OC,(T1) ;SET ON BLOCK
HLRE T1,T1 ;-SIZE WE NEED
MOVE P2,LS.UB
MOVEM P2,LS.AB ;USE IT ALL
SUB P2,LS.LB ;SIZE WE HAVE
ADD P2,T1 ;GET DIFF
JUMPGE P2,OVR8A ;IS IT ENOUGH
MOVEI P1,LS.IX ;NO, GET AREA
MOVM P2,P2 ;AND SIZE
PUSHJ P,LNKCOR## ;EXPAND
PUSHJ P,E$$MEF## ;[1174] TOO BAD
OVR8A: MOVE T2,LS.UB ;GET TOP
MOVEM T2,LS.AB ;ALLOCATE IT ALL
HLRE T1,PH.RDX ;GET -LENGTH
MOVM T1,T1 ;+
MOVEM T1,LSYM ;SET SIZE OF SYMBOL AREA
MOVEM T1,NAMPTR ;SET START OF CURRENT SYM
IORI T1,.IPM ;ROUND UP
SUB T2,T1 ;FIND WHERE BOUND SHOULD BE
CAMN T2,LS.LB ;USED IT ALL?
JRST .+3 ;YES
MOVEI T1,-1(T2) ;HIGHEST TO GIVE BACK
PUSHJ P,GBCK.L##
MOVE T1,LSYM ;LENGTH OF SYMBOLS
SUB T1,LW.LS ; - PART NOT IN CORE
ADD T1,LS.LB ; + BASE OF AREA
MOVEM T1,LS.PT ; YIELDS POINTER TO END
SUB T1,LS.AB ;= -AMOUNT LEFT TO TOP
MOVMM T1,LS.FR ;POSITIVE AMT FREE
MOVE T1,LS.LB ;BASE
SUBI T1,1
HLL T1,PH.RDX ;IOWD
SETZ T2,
IN OC,T1
JRST LNKXIT ;OK, NOW EXIT
PUSHJ P,E$$IOV## ;[1174] ERROR
OVR8B: MOVEI T1,LS.IX ;NOW DELETE LOCAL SYMBOLS
PUSHJ P,XX.ZAP## ;TO GET AS MUCH SPACE AS POSSIBLE
JRST LNKXIT ;EXIT
RDCST:: PUSHJ P,INPH ;READ IN PREAMBLE
HRRZ R1,PH.OVL ;BLOCK# OF CODE SECTION
MOVE T3,PH.CST ;ADDRESS OF CONTROL SECTION
SUB T3,PH.ADD ;MINUS BASE
ROT T3,-.DBS2W ;[650] CONVERT INTO BLOCKS
ADDI R1,(T3) ;POINT TO BLOCK CONTAINING THE CONTROL SECTION
USETI OC,(R1) ;SET ON IT
LSH T3,.DBS2W-^D36 ;EQUIVALENT TO ANDI 177 WITH ORIGINAL T3
MOVEI T1,CS.ZZ(T3) ;GET NO. OF WORDS TO END
IORI T1,.DBM ;[650] INCASE CROSSES BLOCK BOUND
HRLI R1,1(T1) ;HOW MANY WORDS WE WILL READ
MOVNI T1,1(T1)
HRL T1,T1 ;LH OF IOWD
HRR T1,LC.LB ;SAFE PLACE TO READ IT INTO
HRRI T1,-1(T1) ;AN IOWD AT LAST
SETZ T2,
IN OC,T1 ;NOW FOR DATA
CAIA
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
ADD T3,LC.LB ;POINT TO FIRST CS WORD
HRLZ T1,T3
HRRI T1,CS.HDR ;FORM BLT WORD
BLT T1,CS.HDR+CS.ZZ-1
HLRE T1,CS.EXT ;NO. OF EXTTAB
HLRE T2,CS.INT ;SAME FOR INTTAB
IMUL T1,[-ET.ZZ] ;+ NUMBER OF WORDS
IMUL T2,[-2]
ADD T1,T2 ;TOTAL NO. WE NEED
HRRZ T2,CS.EXT ;START OF EXTTABS
JUMPN T2,.+3 ;MIGHT BE ZERO IF END OF PATH
HRRZ T2,CS.INT ;SO TRY INTTAB
JUMPE T2,CPOPJ ;GIVE UP IF NEITHER!
SUB T2,PH.ADD ;REL TO START OF FIRST BLOCK
MOVE R2,T2 ;REL START OF EXTTAB
ADD T1,T2 ;TOTAL WORDS WE NEED
IORI T1,.DBM ;[650] UPTO DSK BLOCK BOUND
MOVE T2,PH.CST ;NOW GET ADDRESS OF CS
SUB T2,PH.ADD ;REL TO LINK ORIGIN
ANDCMI T2,.DBM ;[650] ADDRESS OF FIRST LOC IN CORE
SUB R2,T2 ;THENCE OFFSET TO EXTTAB
HLRZ T3,R1 ;WORDS ALREADY READ
ADDI T2,-1(T3) ;WE HAVE THIS MUCH IN CORE ALREADY
SUB T1,T2 ;SEE IF WE HAVE IT ALL
JUMPE T1,CPOPJ1 ;YES
ADD T3,T1 ;NEW WORDS COUNT
HLRZ P3,R1 ;SAVE PREVIOUS SIZE
HRL R1,T3 ;SAVE EXCESS
MOVE P2,LC.AB ;NOW SEE IF WE HAVE ENOUGH ROOM
SUB P2,LC.LB
SUBI P2,-1(P3) ;NOT COUNTING ALREADY USED
CAMG T1,P2 ;WILL IT FIT?
JRST RDCST1 ;YES
SUBB T1,P2 ;NO, PUT DIFF IN P2 FOR LNKCOR
MOVEI P1,LC.IX
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
HLRZ T1,R1 ;RESET EXCESS SIZE
SUBI T1,(P3) ;ONLY WANT EXTRA NEEDED
RDCST1: MOVN T1,T1 ;USUAL CODE TO MAKE IOWD PTR
HRL T1,T1
HRR T1,LC.LB
ADDI T1,-1(P3) ;BYPASS WHAT WE ALREADY HAVE
SETZ T2,
IN OC,T1 ;INPUT EXTTAB & INTTAB
CPOPJ1: AOSA (P)
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
CPOPJ: POPJ P,
INPH:: ROT P1,-1 ;CUT IN HALF
MOVE T1,@LNKTBL ;PICKUP BLOCK #
SKIPL P1 ;PICK CORRECT HALF
MOVS T1,T1
ROT P1,1 ;PUT IT BACK
USETI OC,(T1)
HRLM T1,OVLBLK ;STORE BLOCK# OF PREAMBLE
DMOVE T1,PHIOWD
IN OC,T1 ;INPUT PREAMBLE
POPJ P,
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
RDREL: MOVE T1,RT.LB ;MAKE RT.PT SAME AS RT.LB
MOVEM T1,RT.PT ;TO INDICATE RT AREA EMPTY
SKIPN PH.REL ;IS IT RELOCATABLE?
POPJ P, ;NO
MOVE T1,PH.ADD ;WHERE ADDRESS WOULD BE
MOVE T2,PH.CST ;BUT THIS IS LOWEST ADDRESS WE CARE ABOUT
SUB T2,T1 ;I.E CST PLUS TABLES
IDIVI T2,.DBS*^D18 ;[650] BYTES PER DSK BLOCK
MOVE T3,T2 ;NO. OF WHOLE BLOCKS TO SKIP
ADD T3,PH.REL ;PLUS FIRST
USETI OC,(T3) ;SET ON IT
IMULI T2,.DBS ;[650] NO. OF WORDS TO SKIP
MOVEM T2,OVLOFF ;SET BASE OFFSET
HLRE T1,PH.REL ;NO. OF WORDS ORIGINALLY
ADD T1,T2 ;NO. LEFT
JUMPGE T1,[HALT .] ;ERROR
MOVM T2,T1 ;+ NO.
ADDM T2,RT.PT ;UPDATE RT.PT TO SIZE USED
HRLZ T1,T1 ;LHS OF IOWD
SUB T2,RT.AB
ADD T2,RT.LB ;SEE IF ENOUGH SPACE
JUMPLE T2,RDREL1 ;YES
DMOVE P1,T1 ;SAFE PLACE FOR IOWD & COUNT
PUSHJ P,RT.INC## ;EXPAND BY 1 BLOCK
SUBI P2,.IPS ;SHOULD BE ENOUGH
JUMPG P2,.-2 ;LOOP IF NOT
MOVE T1,P1 ;RECOVER IOWD
RDREL1: HRR T1,RT.LB
HRRI T1,-1(T1) ;IOWD AT LAST
SETZ T2,
IN OC,T1
POPJ P, ;AREA IS NOW SETUP
PJRST E$$IOV## ;[1174] I/O ERROR
SUBTTL THE END
OV2LIT: END LNKOV2