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, ;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,) ;[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,;[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 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 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,) ;[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,) ;[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 JRST OVR6CE ;AND MAKE IT UNDEFINED AT RUN TIME ;HERE ON A MULTIPLY-DEFINED ENTRY POINT OVR6M: SPUSH 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 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,) ;[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 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 ;[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 ;[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,) ;[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,) ;[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,(+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