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

1352 lines
45 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE 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