Trailing-Edge
-
PDP-10 Archives
-
bb-bt99m-bb
-
lnkov2.x19
There are 2 other files named lnkov2.x19 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/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
SALL
ENTRY LNKOV2
EXTERN LNKMAP,LNKXIT
CUSTVR==0 ;CUSTOMER VERSION
DECVER==6 ;DEC VERSION
DECMVR==0 ;DEC MINOR VERSION
DECEVR==2417 ;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).
;START OF VERSION 5
;1316 Add code to set up RC.HL for low and high segs from HP.S1 and HP.S2
;1400 Use OVRPAR.MAC and implement writable overlays.
;START OF VERSION 5.1
;1704 Writable overlay support.
;2026 Update copyright notice.
;2042 Protect pointers to GS and LC when calling TR.WLK.
;2053 Process deferred character fixups.
;Start of version 6
;2247 Use inferior fork on TOPS-20.
;2270 Remove the argument typechecking area to gain space.
;2403 New corporate copywrite statement.
;2416 IOWD size calculation wrong at OVR6GC+11.
;2417 Update copywrite statement to 1988.
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
;IOWD FOR PREAMBLE SECTION
IFE FTKIONLY,<
PHIOWD: IOWD PH.ZZ,PH ;[1400]
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]
MOVEI T1,TP.IX ;[2270] NOW DELETE TYPECHECKING AREA
PUSHJ P,XX.ZAP## ;[2270] GET RID OF IT
IFN TOPS20,< ;[2247]
MOVE T1,LW.LC ;[2247] GET THE BOTTOM OF THE WINDOW
SKIPE T2,UW.LC ;[2247] AND THE TOP. IS IT PAGING?
PUSHJ P,LC.OUT## ;[2247] YES, DON'T WANT IT TO HERE
SETZM UW.LC ;[2247] SET NOT PAGING
>;[2247] IFN TOPS20
MOVEI R,1 ;[1316] SET UP FOR LOW SEG
MOVE R,@SG.TB ;[1316]
MOVE T1,HP.S1 ;[1316] GET .LOW. PSECT BREAK
CAMLE T1,RC.HL(R) ;[1316] IS IT HIGHER?
MOVEM T1,RC.HL(R) ;[1316] PUT IT IN THE PSECT BLOCK
SKIPN LL.S2 ;[1316] IS THERE A HIGH SEG?
JRST OVR1 ;[1316] NO - IGNORE HP.S2
MOVEI R,2 ;[1316] SET UP FOR HIGH SEG
MOVE R,@SG.TB ;[1316]
MOVE T1,HP.S2 ;[1316] GET .HIGH. PSECT BREAK
CAMLE T1,RC.HL(R) ;[1316] IS IT HIGHER?
MOVEM T1,RC.HL(R) ;[1316] PUT IT IN THE PSECT BLOCK
OVR1: MOVE T1,SYMSEG ;[1316] 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+DI.LPT ;[1400] 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+DI.NPT ;[1400] STORE IN DIRECTORY
MOVE T2,<WR.LEN/.DBS>;[1704] CALC NEXT FREE BLOCK
HRRZS T1 ;[1704]
ADD T1,T2 ;[1704]
HRLI T1,-WR.LEN ;[1704] LENGTH OF TABLE
SKIPE WRTDAT ;[1704] BUT ONLY IF WRITABLE
MOVEM T1,DI+DI.WPT ;[1704]
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,INPH ;[2053] READ IN PREAMBLE
SKIPE P1,ARGFXP ;[2053] ANY CHARACTER FIXUPS?
PUSHJ P,FIXARG ;[2053] YES, DO ANY FOR THIS OVERLAY
PUSHJ P,RDCST0 ;[2053] 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+CS.EXT ;[1400] 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.LEN-1 ;[1400] 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+CS.INT ;[1400] 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+CS.INT ;[1400]
HRR T1,CS+CS.NUM ;[1400] -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+CS.EXT
JUMPGE R2,OVR6D ;[1400] NO EXTTAB
HRRZ P3,CS+CS.EXT ;[1400] 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+CS.NUM ;[1400] ONLY WANT TO LOOK AT TREE ABOVE US
JRST OVR6CA ;ALL IS ABOVE ROOT
PUSHJ P,OVR6TW ;[2042] THESE ARE ONLY LINKS WE CAN REACH
JUMPE P2,[MOVE P2,CS+CS.NUM ;[1400] 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,OVR6TW ;[2042] 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.ADR(R2) ;[1400] STORE IT WITH 0 FLAGS
OVR6CC: SETZM ET.NAM(R2) ;CLEAR NAME NOW
OVR6CD: SETBIT <0,0,1,0>
ADDI R2,ET.LEN-1 ;[1400]
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.ADR(R2) ;[1400] 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+CS.NUM ;[1400] WE ONLY WANT TO LOOK AT TREE ABOVE US
JRST OVR6MA ;ALL OF TREE IS ABOVE ROOT
PUSHJ P,OVR6TW ;[2042] SINCE THESE ARE THE ONLY LINKS WE
;CAN REACH, ALL OTHERS ARE NOT AVAILABLE
JUMPE P2,[MOVE P2,CS+CS.NUM ;[1400] 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,OVR6TW ;[2042] 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.ADR(R2) ;[1400] 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,OVR6TW ;[2042] 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+CS.RLC ;[1400] USE THIS TO POINT TO LIST
HRL T1,R2 ;POINT TO WHICH ONE
MOVEM T1,(P3) ;STORE IN FIRST WORD
HRRZM P3,CS+CS.RLC ;[1400] 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.ADR(R2) ;[1400] 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
OVR6TW: SUB P3,GS.LB ;[2042] Subtract the base addresses
SUB R2,LC.LB ;[2042] Because TR.WLK calls DY.GET
PUSHJ P,TR.WLK## ;[2042] Walk the tree
ADD P3,GS.LB ;[2042] Add the base addresses back
ADD R2,LC.LB ;[2042] LC better not be paging!
POPJ P, ;[2042] And return
OVR6D: HLRE R3,CS+CS.INT ;[1400] GET NO. OF INTTAB ENTRIES
IMUL R3,[-2] ;[635] CONVERT TO WORDS
ADD R3,CS+CS.INT ;[1400] MAKE FIRST FREE AFTER INTTAB
JUMPN R3,OVR6DA ;[635] USE IT IF INTTAB EXISTS
HLRE R3,CS+CS.EXT ;[1400] OTHERWISE USE END OF EXTTAB
IMUL R3,[-ET.LEN] ;[1400] WORDS IN EXTTAB
ADD R3,CS+CS.EXT ;[1400] 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+CS.INT ;[1400] GET NO. OF INTTABS
JUMPGE R2,OVR6FA ;NONE
HRRZ R3,R2 ;USED TO STORE BACK IF REQUIRED
HRRZ P3,CS+CS.INT ;[1400] 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+CS.INT ;[1400] MAKE THIS RIGHT
OVR6FA: SKIPN P1,CS+CS.RLC ;[1400] ANY MULTIPLY DEF GLOBALS?
JRST OVR6G ;NO
SETZ P3, ;[635] INDICATE NO TMA ERROR YET
HLRE R3,CS+CS.INT ;[1400] THESE WILL GO AT END OF TABLES
IMUL R3,[-2]
ADD R3,CS+CS.INT ;[1400]
JUMPN R3,OVR6FB ;BUT IF NO INTTAB
HLRE R3,CS+CS.EXT ;[1400] USE EXTTAB
IMUL R3,[-ET.LEN] ;[1400]
ADD R3,CS+CS.EXT ;[1400]
OVR6FB: MOVE T1,0(P1) ;GET NEXT PTR
HRRZM T1,CS+CS.RLC ;[1400] 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+CS.RLC ;[1400] 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+PH.LLN ;[1400] GET LENGTH
HRLM T1,CS+CS.COR ;[1400] INTO CONTROL SECTION
MOVE T1,PH+PH.CST ;[1400] NOW TO COPY CS BACK
SUB T1,PH+PH.ADD ;[1400]
ANDI T1,.DBM ;[743] MAKE REL TO THIS BLOCK
ADD T1,LC.LB ;FIX IN CORE
MOVEI T2,CS.LEN-1(T1) ;[1400] END OF BLT
HRLI T1,CS ;[1400]
BLT T1,(T2) ;MOVE IT ALL
SKIPN P1,CS+CS.NUM ;[1400] 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+PH.FPT ;[1400] LIST IN FORWARDS DIRECTION
HRLZM P2,PH+PH.BPT ;[1400] 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+PH.BPT ;[1400] 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+PH.BPT ;[1400] AND STORE BLOCK#
OVR6GC: USETO OC,(R1) ;RESET BACK TO BLOCK WE NEED
MOVE T1,LC.LB
SUBI T1,1
MOVE T2,PH+PH.CST ;[1400] ADDR OF CONTROL SECTION
SUB T2,PH+PH.ADD ;[1400] OFFSET FROM START OF LINK
ANDI T2,.DBM ;[635] # WORDS BEFORE CS IN LC AREA
ADD T2,PH+PH.ADD ;[1400] PLUS LENGTH OF CS, INTTAB,
ADD T2,PH+PH.LLN ;[1400] EXTTAB, AND ARL TABLE
SUB T2,PH+PH.CST ;[1400] ..
MOVNS T2 ;[2416] NEGATIVE FOR IOWD
TRZ T2,.DBM ;[2416] NEGATIVE SIZE IN FULL BLOCKS
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+PH.CST ;[1400]
ADDI P3,CS.PTR+1 ;[1400] BYPASS KNOWN ZEROS AND FIRST IBP
PUSHJ P,RT.P3## ;RESET IT
MOVEI T1,1 ;RELOC BIT
MOVE T2,[CS.PTR+1-CS.LEN,,CS+CS.PTR] ;[1400] 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+PH.ADD ;[1400] WHERE ADDRESS WOULD BE
MOVE T2,PH+PH.CST ;[1400] 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+PH.REL ;[1400] PLUS FIRST
USETO OC,(T3) ;SET ON IT
IMULI T2,.DBS ;[650] NO. OF WORDS TO SKIP
HLRE T1,PH+PH.REL ;[1400] 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+PH.SYM ;[1400] 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+PH.SYM ;[1400] 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+PH.SYM ;[1400] 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+PH.ADD ;[1400] 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+PH.RDX ;[1400] 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+PH.RDR ;[1400] 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+PH.BPT ;[1400] DO WE HAVE TO OUTPUT THE PATH?
JRST OVR6Z ;NO
MOVN T1,T3 ;NEGATE
HRLI T3,PH ;[1400] 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-1(T1)
OVR6Z: OUT OC,T1
JRST OVR6X ;NOW FIXUP CS.DDT IF REQUIRED
PUSHJ P,E$$OOV## ;[1174] OUTPUT ERROR
OVR6X: SKIPN PH+PH.RDX ;[1400] ANY RADIX-50 SYMBOLS
JRST OVR6 ;NO, LOOP FOR ALL LINKS
HRRZ R1,PH+PH.OVL ;[1400] BLOCK# OF CODE SECTION
MOVE T3,PH+PH.CST ;[1400] ADDRESS OF HEADER
SUB T3,PH+PH.ADD ;[1400] 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(T3) ;[1400] 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 ;[1400] ADDRESS OF CONTROL SECTION
PUSHJ P,E$$IOV## ;[1174]
MOVE T2,PH+PH.RDX ;[1400] GET SYMBOL TABLE PTR
MOVEM T2,CS.DDT(T3) ;[1400] 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,[700,,DI.LEN];[1400] CODE ,, LENGTH
MOVEM T1,DI+DI.HDR ;[1400]
MOVE T1,VERNUM ;GET VERSION#
MOVEM T1,DI+DI.VER ;[1400] INTO DIRECTORY
MOVE T1,OVERLW ;[1400] COPY IMPORTANT FLAGS TO DIRECTORY
SETZ T2, ;[1400] ..
TXNE T1,$OVRELOCATABL;[1400] RELOCATABLE OVERLAYS
TXO T2,OD.RLC ;[1400] ..
TXNE T1,$OVWRITABLE ;[1400] WRITABLE OVERLAYS
TXO T2,OD.WRT ;[1400] ..
MOVEM T2,DI+DI.FLG ;[1400] ..
USETO OC,1 ;NOW FOR DIRECTORY BLOCK
SKIPA T1,.+1
IOWD DI.LEN,DI ;[1400] 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+DI.NPT ;[1400] 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+DI.NPT ;[1400] 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##
OVR7D: SKIPN T1,DI+DI.WPT ;[1704] WRITABLE OVERLAYS INVOLVED?
JRST OVR7E ;[1704] NO, GO ON
USETO OC,(T1) ;[1704] GET TO BLOCKBOUND
SETZ T2, ;[1704] TERMINATE IOWD LIST
HRR T1,WRTDAT ;[1704] CONSTRUCT IOWD
SUBI T1,1 ;[1704]
OUT OC,T1 ;[1704] WRITE IT
CAIA ;[1704] OKAY
PUSHJ P,E$$OOV## ;[1704] ERROR
HRRZ T1,WRTDAT ;[1704] RETURN THE BLOCK NOW
MOVEI T2,WR.LEN ;[1704]
PUSHJ P,DY.RET## ;[1704] ...
OVR7E: 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+PH.RDX ;[1400] 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+PH.RDX ;[1400] 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+PH.RDX ;[1400] 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
RDCST0: HRRZ R1,PH+PH.OVL ;[2053] BLOCK# OF CODE SECTION
MOVE T3,PH+PH.CST ;[1400] ADDRESS OF CONTROL SECTION
SUB T3,PH+PH.ADD ;[1400] 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.LEN(T3) ;[1400] 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 ;[1400] FORM BLT WORD
BLT T1,CS+CS.LEN-1 ;[1400]
HLRE T1,CS+CS.EXT ;[1400] NO. OF EXTTAB
HLRE T2,CS+CS.INT ;[1400] SAME FOR INTTAB
IMUL T1,[-ET.LEN] ;[1400] + NUMBER OF WORDS
IMUL T2,[-2]
ADD T1,T2 ;TOTAL NO. WE NEED
HRRZ T2,CS+CS.EXT ;[1400] START OF EXTTABS
JUMPN T2,.+3 ;MIGHT BE ZERO IF END OF PATH
HRRZ T2,CS+CS.INT ;[1400] SO TRY INTTAB
JUMPE T2,CPOPJ ;GIVE UP IF NEITHER!
SUB T2,PH+PH.ADD ;[1400] 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+PH.CST ;[1400] NOW GET ADDRESS OF CS
SUB T2,PH+PH.ADD ;[1400] 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+PH.REL ;[1400] IS IT RELOCATABLE?
POPJ P, ;NO
MOVE T1,PH+PH.ADD ;[1400] WHERE ADDRESS WOULD BE
MOVE T2,PH+PH.CST ;[1400] 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+PH.REL ;[1400] 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+PH.REL ;[1400] 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
;[2053] Here to do the deferred character fixups.
;[2053] P1 contains the pointer to the first character fixup block.
;[2053] Each character fixup requires two addresses. To minimize
;[2053] disk I/O, there are two buffers kept. The block number of
;[2053] the argument descriptor is in R1, and the block of the
;[2053] character string descriptor is in R2, unless they are the
;[2053] same block. The character fixup blocks are built at COEOVL
;[2053] in LNKOV1.
FIXARG: HLRZ T1,TPCAD(P1) ;[2053] Get the overlay number
CAME T1,LNKNO. ;[2053] Fixups for this overlay?
POPJ P, ;[2053] No
SETZB R1,R2 ;[2053] Remember no blocks read yet
FXARG1: HRRZ T1,TPCAD(P1) ;[2053] Get the address
PUSHJ P,FIXAD1 ;[2053] Get it into memory
MOVE P2,T1 ;[2053] Keep it safe
HRRZ T1,(T1) ;[2053] Get the address of the
;[2053] string descriptor
PUSHJ P,FIXAD2 ;[2053] Get it into memory
HRRZ T1,(T1) ;[2053] Get the start address of the string
HRLI T1,(<Z 17,>+1B0);[2053] Make it an ascii descriptor
MOVEM T1,(P2) ;[2053] Put it back in memory
MOVE T1,P1 ;[2053] Get the address of this block
MOVEI T2,TPCBK ;[2053] And the size
HRRZ P1,TPCLK(P1) ;[2053] Get the next block
PUSHJ P,DY.RET## ;[2053] Return this block
JUMPE P1,FXARG2 ;[2053] Check for no more blocks
HLRZ T1,TPCAD(P1) ;[2053] Get the overlay number
CAMN T1,LNKNO. ;[2053] For this overlay?
JRST FXARG1 ;[2053] Yes, do another
FXARG2: MOVEM P1,ARGFXP ;[2053] Put the chain back
USETO OC,(R1) ;[2053] Set to output last block
MOVE T1,LC.LB ;[2053] Get the location in memory
SUBI T1,1 ;[2053] As an IOWD
HRLI T1,-.DBS ;[2053] One block
SETZ T2, ;[2053] Terminate the IO list
OUT OC,T1 ;[2053] Write it
POPJ P, ;[2053] OK, Return
PUSHJ P,E$$OOV## ;[2053] Error
;[2053] FIXAD1 brings a location in the overlay into a read/write
;[2053] block of memory. If the block contains another page of the
;[2053] overlay file, it writes the block back into the file first.
;[2053] Accepts an address in T1. Returns with updated address
;[2053] in T1.
FIXAD1: HRRZ T3,PH+PH.OVL ;[2053] Block number of code section
SUB T1,PH+PH.ADD ;[2053] Minus base
PUSH P,T1 ;[2053] Save the offset
ROT T1,-.DBS2W ;[2053] Convert into blocks
ADDI T3,(T1) ;[2053] Point to block desired code
JUMPE R1,FXAD1A ;[2053] Always read if nothing in yet
CAIN R1,(T3) ;[2053] Is it already in memory?
JRST FXAD1B ;[2053] Yes, don't read it again
USETO OC,(R1) ;[2053] Set on it
MOVE T1,LC.LB ;[2053] Get the location in memory
SUBI T1,1 ;[2053] As an IOWD
HRLI T1,-.DBS ;[2053] One block
SETZ T2, ;[2053] Terminate the IO list
OUT OC,T1 ;[2053] Write it
CAIA ;[2053] Okay
PUSHJ P,E$$OOV## ;[2053] Error
FXAD1A: HRRZ R1,T3 ;[2053] Remember the new block
USETI OC,(R1) ;[2053] Set on it
MOVE T1,LC.LB ;[2053] Get the location in memory
SUBI T1,1 ;[2053] As an IOWD
HRLI T1,-.DBS ;[2053] One block
SETZ T2, ;[2053] Terminate the IO list
IN OC,T1 ;[2053] Read it
CAIA ;[2053] Okay
PUSHJ P,E$$IOV## ;[2053] Error
FXAD1B: POP P,T1 ;[2053] Get back the offset
ANDI T1,.DBM ;[2053] Get the offset within the block
ADD T1,LC.LB ;[2053] The block is in the LC area
POPJ P, ;[2053] Done
;[2053] FIXAD2 brings a location in the overlay into memory.
;[2053] If the desired location is already in the read/write
;[2053] block, it uses that, otherwise it reads it into a
;[2053] read only block if it is not there yet. Accepts an
;[2053] address in T1. Returns with updated address in T1.
FIXAD2: HRRZ T3,PH+PH.OVL ;[2053] Block number of code section
SUB T1,PH+PH.ADD ;[2053] Minus base
PUSH P,T1 ;[2053] Save the offset
ROT T1,-.DBS2W ;[2053] Convert into blocks
ADDI T3,(T1) ;[2053] Point to block desired code
CAIN R1,(T3) ;[2053] Is it already in memory?
JRST FXAD1B ;[2053] Yes, in the read/write block
JUMPE R2,FXAD2A ;[2053] Always read if nothing in yet
CAIN R2,(T3) ;[2053] Is it already in memory?
JRST FXAD2B ;[2053] Yes, don't read it again
FXAD2A: MOVE R2,T3 ;[2053] Remember the new block
USETI OC,(R2) ;[2053] Set on it
MOVE T1,LC.LB ;[2053] Get the location in memory
ADDI T1,.DBS-1 ;[2053] Second block of LC, as an IOWD
HRLI T1,-.DBS ;[2053] One block
SETZ T2, ;[2053] Terminate the IO list
IN OC,T1 ;[2053] Read it
CAIA ;[2053] Okay
PUSHJ P,E$$IOV## ;[2053] Error
FXAD2B: POP P,T1 ;[2053] Get back the offset
ANDI T1,.DBM ;[2053] Get the offset within the block
ADD T1,LC.LB ;[2053] The block is in the LC area
ADDI T1,.DBS ;[2053] In the second block
POPJ P, ;[2053] Done
SUBTTL THE END
OV2LIT: END LNKOV2