mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-01 17:26:38 +00:00
1352 lines
45 KiB
Plaintext
1352 lines
45 KiB
Plaintext
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
|