mirror of
https://github.com/PDP-10/stacken.git
synced 2026-02-28 17:09:15 +00:00
4598 lines
163 KiB
Plaintext
4598 lines
163 KiB
Plaintext
TITLE LNKLOD - LOAD MODULE FOR LINK
|
||
SUBTTL D.M.NIXON/DMN/JLd/JBC/RKH/JNG/DCE/MCHC/DZN/PAH/PY/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,OVRPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
|
||
IFN TOPS20,< SEARCH MONSYM > ;[1401]
|
||
SALL
|
||
|
||
ENTRY LNKLOD
|
||
EXTERN LNKSCN,LNKCOR,LNKWLD,LNKLOG,LNKF40,LNKMAP,LNKXIT
|
||
|
||
|
||
CUSTVR==0 ;CUSTOMER VERSION
|
||
DECVER==6 ;DEC VERSION
|
||
DECMVR==0 ;DEC MINOR VERSION
|
||
DECEVR==2417 ;DEC EDIT VERSION
|
||
|
||
VERSION
|
||
|
||
|
||
SEGMENT
|
||
|
||
|
||
;LOCAL ACC DEFINITIONS
|
||
INTERN R,RB,WC
|
||
|
||
R=R1 ;CURRENT RELOCATION COUNTER
|
||
RB=R+1 ;RELOCATION BYTE WORD
|
||
WC=R3 ;WORD COUNT
|
||
|
||
;[1477] USEFUL MACROS FROM MACSYM
|
||
|
||
DEFINE WID(MASK)<<^L<-<<MASK>_<^L<MASK>>>-1>>> ; WIDTH OF MASK
|
||
|
||
DEFINE POS(MASK)<<^L<<MASK>&<-<MASK>>>>> ; POSITION OF MASK
|
||
|
||
DEFINE POINTR(LOC,MASK)<<POINT WID(MASK),LOC,POS(MASK)>>
|
||
; BYTE POINTER TO MASK
|
||
|
||
SUBTTL REVISION HISTORY
|
||
|
||
|
||
;START OF VERSION 1A
|
||
;44 ADD ASCIZ TEXT BLOCK
|
||
;45 HASH INITIAL SYMBOLS AT ASSEMBLY TIME
|
||
;46 ADD KLUDGE FEATURE
|
||
;52 ADD ASCII TEXT BLOCK
|
||
;54 ADD KIONLY D.P. INST.
|
||
;61 ADD STORE CODE IN FX AREA FOR TWOSEG FORCED HIGH/LOW
|
||
;63 STORE MULTIPLY-DEFINED SYMBOLS IN SYMBOL TABLE FOR MAP
|
||
;75 ADD ROUTINE TO ADDRESS CHECK A SINGLE WORD
|
||
;101 FIXES FOR FAIL CODE WITH UNDEF GLOBALS IN BLOCK 11
|
||
;102 ADD TEST FOR END BLOCK NOT SEEN BEFORE EOF
|
||
;106 REMOVE HIORG, REPLACE WITH LL.S2 OR SO.S2 AS REQUIRED
|
||
;107 REPLACE KLUDGE BY MIXFOR
|
||
;111 MAKE MIXFOR WORK EVEN IF NOT IN SEARCH MODE
|
||
;112 CHECK PER FILE /SEARCH SWITCH @LODTST
|
||
;113 MAKE MIXFOR KNOW ABOUT ARRAY REFERENCES IN ARGS
|
||
;115 MAKE /NOSYMS WORK CORRECTLY
|
||
|
||
;START OF VERSION 1B
|
||
;117 (12058) ADD MISSING POPJ P, AT FORKI+2
|
||
;130 (12315) PREVIOULY REQUESTED COMMON IS NOT PUT IN LOCAL SYMBOL TABLE CORRECTLY
|
||
|
||
;START OF VERSION 2
|
||
;135 ADD OVERLAY FACILITY
|
||
;143 ADD TEST FOR /INCLUDE MODE
|
||
;145 IMPLEMENT USER LIBRARIES
|
||
;147 TURN ON MIXFOR FEATURE
|
||
;152 FIX LOOP IF /NOINIT AND UNDEF SYMBOLS
|
||
;157 (12640) ONLY PRINT FSI MESSAGE IF /FORSE GIVEN EXPLICITLY
|
||
;161 ADD LANGUAGE SPECIFICATION TO /USERLIB
|
||
;163 IF /ONLY IS ON DON'T LOAD F-10 CODE INTO LOW SEG BY DEFAULT
|
||
;164 MAKE CPU TEST OF REL FILES MORE GENERAL
|
||
;166 READ BACK RADIX50 SYMBOL FILES
|
||
;167 CHANGE ARGS TO /OTS SWITCH
|
||
;172 (13243) BUG IF MORE THAN 1 BLOCK TYPE 16 (OR 17) SEEN
|
||
;173 TEST ASCIZ BLOCK TYPE FOR VALID FIRST CHAR
|
||
;174 FIX BUGS IN RELOCATABLE OVERLAYS
|
||
;176 MAKE START BLOCK (7) BE TWO WORDS LONG
|
||
;200 LOAD REENTRANT OVERLAY HANDLER
|
||
;204 FIX CORE EXPANSION BUG IN SYMBOL TABLE FIXUPS
|
||
;206 FIX RH CHAINED GLOBAL IF NOT ALL OF CHAIN IN CORE
|
||
;210 (13461) MORE OF #172, HANDLE TYPE 16 CORRECTLY
|
||
;220 HANDLE COMMON REFERENCED BEFORE BEING DEFINED CORRECTLY
|
||
;START OF VERSION 2B
|
||
;223 FIXUP PRIMARY TRIPLET AFTER ADDITIVE FIXUPS HAVE BEN DONE
|
||
;232 (13920) UNRELOCATE POLISH POINTER BEFORE CALL TO T.11EV
|
||
;233 (13932) INFINITE LOOP IF UNDEF SYMBOLS AND TYPE 16 BLOCKS
|
||
;251 Setup FX before using for temp storage when /SEG:LOW
|
||
; and no high seg size in REL file
|
||
;275 ADD CODE TO LOAD SIMULA LIBRARY
|
||
;305 Correct the test for CPU type so it works.
|
||
;325 Don't ever eliminate block 3 when saving TWOSEG REL
|
||
; block in DY and FX during force to single segment when
|
||
; high segment break is unknown.
|
||
;327 Save 2 locations in F40NAM
|
||
;341 INCLUDE EDIT 327 IN MAINTENANCE SOURCES. LABEL EDITS 223,232,233
|
||
;367 KEEP CORRECT W3 ON POLISH FIXUPS WHEN SYMBOL JUST DEFINED
|
||
;375 Make LS.ADE internal for use in LNKOLD.
|
||
;376 Give error message if trying to overlay F40 code.
|
||
;405 Add routine D.RED1, like D.IN1 but POPJ's on EOF.
|
||
;412 Preserve W3 when doing fixups.
|
||
;422 Shut off /SEG:??? when processing fixups.
|
||
;START OF VERSION 2C
|
||
;450 Correct code at F40NAM to give error message if illegal
|
||
; mixing of F40 and FORTRAN CODE
|
||
;451 Change message for illegal mixing of F40 and Fortran code
|
||
;456 Setup P1 in ADCHK. before calling LNKCOR.
|
||
;457 REQUEST FORSE. as soon as both FORTRAN's seen so
|
||
; library searching will work. Don't wipe out PROCSN when
|
||
; searching libraries.
|
||
;462 Set up R in .MXFOR after calling SY.RQ, which destroys it.
|
||
;464 Implement /MISSING and LNKIMM
|
||
;465 Redo some of block type dispatch for block type 100.
|
||
;470 Preserve left half of R at SY.FHS for overlays.
|
||
;471 Add code for ALGOL debugging system.
|
||
;510 Generate correct fixups for relocatable symbols in LS area.
|
||
;512 Handle chained fixups (PS.FXC) correctly.
|
||
;515 Teach fixup processor about PH.ADD
|
||
;517 Change ABLLEN to LN.ABL
|
||
;522 Set relocation bit correctly when following paged fixups.
|
||
;526 Don't set relocation bits unless loading overlays. fix to 522.
|
||
;530 Define triplet flags correctly.
|
||
;532 Don't search FORLIB too many times.
|
||
;535 Always search user libraries for all links.
|
||
;541 Fixup F40 subroutine prologue correctly under /MIXFOR.
|
||
;542 Define entry points correctly when paging in MIXFOR processor.
|
||
;543 Catch multiple definition for additive second definition.
|
||
;544 SOUP in LINK version 3 stuff for TOPS-20.
|
||
;555 Always load global symbols into ALGOL programs.
|
||
;557 Clean up the listing for release.
|
||
|
||
;START OF VERSION 3
|
||
;445 INSERT OLD EDITS TO POLISH SYMBOL FIXUPS
|
||
|
||
;START OF VERSION 3A
|
||
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
|
||
;START OF VERSION 4
|
||
;561 Fix the MIXFOR code for F10 subroutines
|
||
;572 Make sure LS addr in core before doing fixups
|
||
;574 Load OTS into low seg if no high seg and low seg .GT. 128K
|
||
;605 Use OUTSTR for ?LNKUGS message.
|
||
;611 Support COBOL-74
|
||
;612 Fix various polish bugs
|
||
;613 Load user libs before system libs to avoid FOROTS screwup.
|
||
;614 Re-search a system lib if more modules that want it are seen.
|
||
;630 Don't forget INCLUDE/EXCLUDE specs after editing an error.
|
||
;632 Fix $LOCATION to always work, add $FIXUP.
|
||
;650 Use VM on TOPS-10 if available.
|
||
;654 Accept a relative address in LS.ADE incase shuffling.
|
||
;661 Make the %LNKMDS message be L%W.
|
||
;667 Call correct paging routine to move hi seg up.
|
||
;672 Set FX.DIR correctly in PRGLIB.
|
||
;673 Change the FON and ILI messages to MSR and IRB.
|
||
;677 Don't default to /SYMSEG:LOW if loading overlays.
|
||
;704 Order psect reloc table by order of origin before doing map.
|
||
;712 Add check for psect index when a global is defined.
|
||
;716 Read in smaller of LN.WD or current size when moving window down.
|
||
;731 SEARCH MACTEN,UUOSYM
|
||
;734 Don't allow mixing of KL & KA, or KL & KI compiled code.
|
||
;737 Clear link list pointer after it's given back.
|
||
;741 Check fixup address against window range.
|
||
;746 Add CHKBND routine to check PSECT overlap after reloc table sort.
|
||
;747 Update LOWLOC after reloc table sorted and before going to LNKXIT.
|
||
;751 Fix bug with calculation of space to give back in PG.SD.
|
||
;752 JFFO cpu-code from Block 6 before dispatching to inconsistancy check.
|
||
;760 Expand PSECT overlap checks to check each PSECT with all others.
|
||
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
|
||
;START OF LINK 4A
|
||
;766 Return cpu table offset in P2 from routine CPUTST.
|
||
;777 Comment SY.RF as destroying P1-P4.
|
||
;1101 Keep LSTBLK (last block read from current file) up to date.
|
||
;1102 Keep window into overflow file in section 0.
|
||
;1103 Zero the .REQUEST/.REQUIRE list pointer after freeing its contents.
|
||
;1106 Update HL.S1 from RC.CV of the highest PSECT loaded.
|
||
;1114 Don't clear COBOL symbols and ALGOL OWNs in LODTST (moved to T.5A).
|
||
;1116 When expanding a window in PG.SX, read in any data already in the
|
||
; overflow file for the region being created. Broken by 716.
|
||
;1120 Remove CPUTST routine (T.6 does it now) and all calls to it.
|
||
;1131 Force non-reentrant OTS sooner, if low segment is within 40 pages of 400000.
|
||
;1132 Teach SEGCHK about PSECTs above the high segment.
|
||
;1135 Make PG.SU expand anyway if request crosses page and window only a page.
|
||
;1143 Fake a module name if LS.ADD called with a symbol before a module seen.
|
||
;1165 Zero LSTSYM in SY.RLS if the symbol was rejected.
|
||
;1174 Label and clean up all error messages.
|
||
;1175 Fix /UPTO with a symbolic argument.
|
||
;1200 If loading reentrant FOROTS, search SYS:FORLIB/SEGMENT:LOW.
|
||
;1201 Change reference to $SEGLOW to LC.IX.
|
||
;1203 Support extended FORTRAN.
|
||
;1204 Complain if any Psects are too long.
|
||
;1207 Make the LNKCMX message continue loading.
|
||
;1212 Make LNKIVC and LNKPOV consistent with other messages.
|
||
;1213 Respect the FS.MDC bit.
|
||
;1215 Use RC.HL instead of RC.CV for the LOWLOC check at CHKLLC.
|
||
;1217 Clean up the listings for release.
|
||
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
|
||
|
||
;START OF VERSION 4B
|
||
;1225 Force /UPTO: if GETSEGging OTS, and make OTS origin compiler-specific.
|
||
;1226 Remove now redundant test for non-root link in FORNAM.
|
||
;1227 Allow multiple COBOL-74 modules to be loaded without LNKCMC.
|
||
;1230 Use correct I/O channel for ALGOL symbol file.
|
||
;1232 Make E$$USA be a subroutine called also from LNKOV1.
|
||
;1234 Fix munged T1 which prints garbage if multiple LNKPOV errors.
|
||
;1246 Set up high segment in GO: if /SYMSEG:HIGH was seen.
|
||
;1251 Fix test in PG.SU so it doesn't request more core than available.
|
||
;1256 Put processor type in P4 before calling QREENT if overlaid.
|
||
;1262 Make LNKCMX message print out once only.
|
||
;1265 Make ALGCHK label global.
|
||
;1271 Cause FORLIB to load /SEG:LOW if main program is not FORTRAN.
|
||
;1277 If /LINK is not followed by /NODE, print LNKNSM error.
|
||
;1300 Don't do chained fixups if BADCORE is non-zero.
|
||
;1305 Use HP.S1 and HP.S2 before sorting psects.
|
||
;1312 Load a nonsharable OTS if /SYMSEG:HIGH and edit 1246
|
||
;1315 Fix user libraries to use bits for compiler type.
|
||
;1320 Fix T3HOLD to know about new rel blocks and ASCII text blocks.
|
||
|
||
|
||
;START OF VERSION 5
|
||
;1400 Use OVRPAR.MAC.
|
||
;1401 Nativize overflow file handling, fix ?LNKMEF bug in PG.LSG/PG.HSG
|
||
;1402 Nativize REL file handling.
|
||
;1412 Make SY.CHR,SY.CHL warn user before truncating fullword value.
|
||
;1420 Save T2 across error in SY.CHR,SY.CHL, and include missing POPJ.
|
||
;1432 Make ?LNKNSM only a warning.
|
||
;1433 Distinguish COBOL,COBOL-68 and COBOL-74.
|
||
;1434 Support for byte initialization.
|
||
;1435 PASCAL support.
|
||
;1441 Make sure E$$NSM returns properly.
|
||
;1442 Remove hard-wired section-1 limit on PSECT boundaries.
|
||
;1450 Fix typo in edit 1442, also ext addr patch in PG.MOV.
|
||
;1451 PASCAL support -- force library to lowseg as default.
|
||
;1463 Redo deferred fixup handling for nonzero sections.
|
||
|
||
;Start of Version 5A
|
||
|
||
;1467 Make D.CNT global for calling from LNKNEW.
|
||
;1474 Fix bad test for caller/callee block in SY.TYP.
|
||
;1475 Rewrite coercion block processing.
|
||
;1476 Fixes to type mismatch checking, char fixup handling.
|
||
; Rewrite SY.TY2 to pick up the right descriptors.
|
||
; Don't mark unknown functions as global requests.
|
||
;1477 Fix miscount of 2ndary arg descriptors in ARGSCN.
|
||
;1523 Don't define PASDT% as zero if undefined before library search.
|
||
;1545 Set continuation bit for errors which will print module names.
|
||
;1702 Remove call to LS.ADD in typechecking code.
|
||
;1703 Add RTSECT routine to release unneeded 2ndary triplets
|
||
; after typechecking, and don't inhibit bound global searches.
|
||
;1711 Put CHKCHX code under FTFRK2 conditional.
|
||
;1723 If arg count for caller and function doesn't match, typecheck
|
||
; only the args that exist.
|
||
;1724 Add a new action code to the set accepted in the coercion block.
|
||
;1725 Change error message E$$CMX to say "GFloating" Fortran.
|
||
;1732 Don't clear FXSPTR as a hint to CHKCHN that it should call CHKCHX.
|
||
; Just recurse to CHKCHN from CHKCHX after the check.
|
||
;1733 Don't complain about truncation of section number in section-local
|
||
; halfword fixups, but do complain about negative numbers being
|
||
; truncated if they're large ones.
|
||
;1734 Fix edit 1733, which breaks deferred right half fixups.
|
||
;1735 Fix typo introduced when installing edit 1733.
|
||
;1736 Strip unsupported FMXFOR code.
|
||
;1737 Don't lose deferred fixups in nonzero sections.
|
||
;1740 Don't create the lower section if the window straddles sections
|
||
; while doing fixups.
|
||
;1741 Don't add in section numbers unnecessarily.
|
||
;1743 Correct typo in edit 1724 that breaks char fixups.
|
||
;1751 Type out argument number in decimal, not octal.
|
||
;1753 Make LNKCMX a warning, not a fatal error.
|
||
;1777 Fix type checking code to handle nonresident argument blocks.
|
||
;2001 Pass the right typechecking triplet pointer to RTSECT.
|
||
;2005 Fix some typechecking bugs.
|
||
;2007 Give LNKFTH a long error message.
|
||
;2012 Fix function return to use arg checking in correct order.
|
||
;2013 Fix /NOSYSLIB - Don't insert instructions after a skip.
|
||
;2015 Preserve function name length accross TMATCH call.
|
||
;2020 Use a linked list to keep track of typechecking blocks.
|
||
;2025 Define FOROT% as 400010 for sharable OTS so 5a libraries work.
|
||
;2026 Update copyright and cleanup listings.
|
||
;2037 Check more carefully for last triplet in SY.RF1
|
||
;2045 Fix typechecking to not clobber other secondary triplets.
|
||
;2046 Garbage collect the DY area occasionally if many typecheck blocks.
|
||
;2053 Argcheck the BG area and defer fixups accross overlays.
|
||
;2065 Check .ABS. against zero when computing LOWLOC.
|
||
;2074 Calculate page size correctly in PG.MOV.
|
||
;2103 Typecheck structure mismatches.
|
||
|
||
;Start of Version 6
|
||
;2200 Use 30 bit addresses in fixups.
|
||
;2202 Call xx.IN and xx.OUT with 30 bit addresses, remove NONZER and FTFRK2.
|
||
;2203 Handle new style store and halfword fetch operators in type 11 blocks.
|
||
;2212 Handle deferred type 1072 polish fixups.
|
||
;2214 Add 30 bit fixups, change section default for fullword chained fixups.
|
||
;2215 Tell GBCK.L not to BLT areas which have been unmapped.
|
||
;2216 Fix long symbols in INSRT and LS.ADD.
|
||
;2217 Check for word alligned byte ptrs and fix lost sect numbers at COESPC.
|
||
;2220 Handle long symbols in psect names and /UPTO.
|
||
;2221 Fix edit 2217 so that it gets section right at SEGCHK. call in COESP2.
|
||
;2224 Get ots reentrancy correct if extended addressing or /PVBLOCK:HIGH.
|
||
;2226 Remove long /INCLUDE and /EXCLUDE blocks properly.
|
||
;2227 Return /PSCOMMON blocks at end of load.
|
||
;2242 Make sure all sections in all psects exist.
|
||
;2243 Fix off by one, make sure RC.HL not less than RC.CV.
|
||
;2247 Don't use LOWLOC, don't LNKPOV .LOW. if it does not exist.
|
||
;2255 Use 30 bit addresses for the LS area for symbol fixups.
|
||
;2262 Allow PG.xSG to return less than request, don't create extra sections.
|
||
;2263 Fix 30 bit additive deferred, set additive bit not chained.
|
||
;2264 Fix typo in LNKPMA message which caused it to type out as PMC.
|
||
;2266 Don't pass short symbols to TYP.BG as long, overlays can't handle them.
|
||
;2267 Remove part of edit 2266, proper fix is in LNKHSH.
|
||
;2270 Allow argument typechecking to page, fix conditionals in edit 2262.
|
||
;2273 Use 30 bit addresses for type 12 LNKEND blocks.
|
||
;2300 Remove F40 code.
|
||
;2301 Fix up TOPS-20 errors.
|
||
;2305 Add code to support 1070 blocks.
|
||
;2310 Rewrite LS.ADE to support long symbols.
|
||
;2322 Make LNKCCE a fatal error.
|
||
;2331 Always return the last secondary triplet after fixups.
|
||
;2342 Fix problems if TP overflows or GS area moves during typechecking.
|
||
;2343 Give LNKMMF, not LNKMEF on core manager error.
|
||
;2356 Remove unnecessary TOPS20 conditionals.
|
||
;2366 Implement extended addressing rules on TOPS-10.
|
||
;2374 Use TPPTR for TP.PT in typchecking code and fix TP paging problem.
|
||
;2376 Correct calculation for BLTing long symbol.
|
||
;2403 New corporate Copywrite statement.
|
||
;2405 Preserve W3 across calls that move mem in TP code.
|
||
;2406 Correct code for section changes in RDBACK
|
||
;2407 Edit 2406 not good enouhg
|
||
;2417 Update Copywrite statement to 1988.
|
||
SUBTTL LOAD CONTROL
|
||
|
||
|
||
;ENTER HERE FROM LNKSCN
|
||
;LNKWLD READS A FILE SPEC FROM LIST POINTED TO BY F.INZR
|
||
;NON-SKIP RETURN IS END OF LIST
|
||
;SKIP RETURN WITH DEVICE INITED AND FILE OPEN OR ENTERED
|
||
|
||
LNKLOD: JFCL .+1 ;IN CASE CCL ENTRY
|
||
IFN .ASBLK,<
|
||
SKIPE F.ASCI ;READING INCORE TEXT?
|
||
JRST LNKWLD## ;YES, SEE IF ANY SWITCHES FOR CURRENT SPEC
|
||
>
|
||
HLLZ FL,FLAGS ;RESET GLOBAL DEFAULTS
|
||
E$$LDS::.ERR. (MS,0,V%L,L%I,S%I,LDS,<LOAD segment>) ;[1174]
|
||
LODNXT: HLR FL,FL ;CLEAR TEMP FLAGS AND SET FROM GLOBAL ONES
|
||
SKIPN F.EDIT ;[630] DON'T IF EDITING AN ERROR
|
||
PUSHJ P,Z.INER ;CLEAR LOCAL STORAGE, GIVE ERRORS
|
||
PUSHJ P,LNKWLD ;GET NEXT FILE SPEC
|
||
JRST LNKSCN ;LIST EMPTY GET MORE
|
||
LODTST::JFCL ;INCASE FROM /SYSLIB
|
||
IFN FTOVERLAY,< ;[1277]
|
||
SKIPE LINKSEEN ;[1277] IN LIMBO BETWEEN OVERLAYS?
|
||
PUSHJ P,E$$NSM ;[1277] YES, GO PRINT AN ERROR
|
||
> ;[1277]
|
||
HRRM FL,FLAGS ;SAVE LOCAL FLAGS AT START OF FILE
|
||
TRNN FL,R.LIB!R.INC ;IN LIBRARY SEARCH MODE OR /INC MODE?
|
||
JRST LOAD ;NO
|
||
SKIPN USYM ;ANY UNDEFINED SYMBOLS
|
||
SKIPE INCPTR ;OR SOME INCLUDES STILL TO DO?
|
||
CAIA ;YES
|
||
JRST EOF1 ;NO, GET NEXT FILE
|
||
SKIPE XBUF ;YES, INDEX IN CORE FOR THIS FILE?
|
||
JRST T.14B## ;YES, USE IT TO FIND PROG TO LOAD
|
||
JRST LOAD
|
||
|
||
E$$NSM::.ERR. (MS,0,V%L,L%W,S%W,NSM,</NODE switch missing after /LINK switch>) ;[1277]
|
||
POPJ P, ;[1441] RETURN TO CALLER
|
||
|
||
T.LOAD::HRR FL,FLAGS ;RESTORE LOCAL FLAGS
|
||
TRNE FL,R.LIB!R.INC ;IN LIBRARY SEARCH MODE OR /INC MODE?
|
||
JRST LODTST ;YES,
|
||
; JRST LOAD
|
||
SUBTTL READ BLOCK TYPE AND DISPATCH
|
||
|
||
|
||
;LOAD READS THE FIRST WORD OF A BLOCK
|
||
;IT PUTS THE LENGTH (NEGATIVE) IN WC AND DISPATCHES TO HANDLING ROUTINE
|
||
|
||
LOAD:: PUSHJ P,D.IN1 ;READ ONE WORD
|
||
MOVNI WC,400000(W1) ;GET NEG BLOCK LENGTH
|
||
HLRZ T1,W1 ;GET BLOCK TYPE
|
||
MOVEM T1,CURTYP ;[1434] SAVE CURRENT TYPE FOR ERROR RECOVERY
|
||
CAIG T1,377 ;IS IT OLD BLOCK TYPES
|
||
JRST LNKOLD## ;YES, HANDLE THERE
|
||
CAIG T1,003777 ;IN RANGE FOR NEW?
|
||
CAIGE T1,1000
|
||
JRST T.ERR1 ;NO
|
||
JRST LNKNEW## ;YES
|
||
|
||
|
||
;UNKNOWN BLOCK TYPES
|
||
|
||
T.ERR1:
|
||
CAILE T1,777 ;IN LNKOLD OR LNKCST?
|
||
JRST T.ERR2 ;NO, MUST BE ASCII TEXT
|
||
CAIL T1,700 ;DEC-DEFINED SPEC. FILE TYPES?
|
||
JRST LNKOLD## ;YES, GO HANDLE
|
||
CAIL T1,402 ;402-677 (CUSTOMER TYPES) ?
|
||
JRST LNKCST## ;YES, LET CUSTOMER HANDLE
|
||
CAIE T1,400 ;ONLY CHOICE LEFT IS F40
|
||
JRST T.401## ;SO ITS T.401 IF NOT T.400
|
||
JRST T.400## ;USUALLY IS 400
|
||
|
||
T.ERR2: ;HERE FOR ASCII TEXT OR ILLEGAL
|
||
IFN .ASBLK,<
|
||
CAIL T1,(<ASCII / />&<-1,,0>)
|
||
CAILE T1,(<ASCII /zzz/>&<-1,,0>)
|
||
CAIA ;NO
|
||
JRST LNKASC## ;VALID ASCIZ BLOCK
|
||
>
|
||
E$$IRB::.ERR. (MS,.EC,V%L,L%F,S%F,IRB,<Illegal REL block type >) ;[1174]
|
||
.ETC. (OCT,.EP!.EC,,,,T1)
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1174]
|
||
SUBTTL CLEAR INCLUDE/EXCLUDE STORAGE
|
||
|
||
|
||
Z.INER: HRRZ P1,INCPTR ;GET POINTER TO FIRST BLOCK
|
||
JUMPE P1,Z.EXIN ;NONE, GIVE UP
|
||
MOVEI T1,[ASCIZ \?LNKIMM \] ;GET PREFIX
|
||
PUSHJ P,MISNG1## ;TYPE IT AND REST OF MESSAGE
|
||
Z.INEX::HRRZ P1,INCPTR ;GET FIRST
|
||
JUMPE P1,Z.EXIN ;NONE, TRY EXCLUDES
|
||
HLLZS INCPTR ;ZERO POINTER SINCE LIST GONE
|
||
PUSHJ P,Z.ZAP ;WIPE OUT THIS LIST
|
||
;FALL INTO Z.EXIN
|
||
|
||
Z.EXIN: HRRZ P1,EXCPTR ;GET POINTER TO EXCLUDE LIST
|
||
JUMPE P1,CPOPJ ;ALL DONE
|
||
HLLZS EXCPTR ;INDICATE LIST ZEROED
|
||
Z.ZAP:
|
||
ADD P1,[-.EXC+1,,1] ;MAKE AOBJN POINTER TO BLOCK
|
||
Z.ZAP1: SKIPE P2,(P1) ;GET NEXT WORD
|
||
TLNE P2,770000 ;MUST BE A POINTER
|
||
JRST Z.ZAP2 ;NOTHING THERE
|
||
HRRZ T1,P1 ;[2226] LONG SYMBOL, T1=ADDRESS
|
||
HLRZ T2,P2 ;[2226] T2=SIZE
|
||
PUSHJ P,DY.RET## ;RETURN THE BLOCK
|
||
Z.ZAP2: AOBJN P1,Z.ZAP1 ;LOOP OVER ENTIRE BLOCK
|
||
SUBI P1,.EXC ;POINT BACK TO 1ST WORD
|
||
MOVEI T1,(P1) ;POINT TO FIRST WORD
|
||
MOVEI T2,.EXC ;STANDARD SIZE
|
||
HRRZ P1,(P1) ;SAVE POINTER WORD
|
||
PUSHJ P,DY.RET## ;FREE UP THE CORE
|
||
JUMPN P1,Z.ZAP ;LOOP IF MORE
|
||
POPJ P, ;ELSE FINISHED
|
||
SUBTTL ADDRESS CHECK A SINGLE WORD
|
||
|
||
|
||
;HERE TO MAKE SURE LOCATION IS IN CORE
|
||
;ENTER WITH ADDRESS IN P3
|
||
;RETURNS NEW ADDRESS (MAYBE) IN P3
|
||
;MAY USE P2 (IF PAGING)
|
||
;CALLED BY
|
||
; MOVE P3,ADDRESS
|
||
; MOVEI R,SEGMENT NO.
|
||
; PUSHJ P,ADCHK.##
|
||
|
||
SGCHK.::TRNN FL,R.FLS!R.FHS ;[2203] Forced loading?
|
||
PJRST SGCHK0 ;[2053] No, no problem
|
||
TRNN FL,R.FLS ;[2053] Which segment has been faked?
|
||
SKIPA T1,[1] ;[2053] Low seg has been faked
|
||
MOVEI T1,2 ;[2053] High seg faked if /SEG:LOW
|
||
HRR R,T1 ;[2053] Setup R For SG.TB; Preserve LH
|
||
MOVE T1,@SG.TB ;[2053] Get real value for RC table
|
||
EXCH T1,@RC.TB ;[2053] Restore it, get fake value
|
||
PUSH P,T1 ;[2053] Save fake value to restore later
|
||
PUSH P,R ;[2053] Remember which segment
|
||
PUSH P,LL.S2 ;[2053] LL.S2 Was also faked by T.3
|
||
HRRZS LL.S2 ;[2053] If we are loading F10, that is
|
||
PUSHJ P,SGCHK0 ;[2053] Now do the fixup
|
||
POP P,LL.S2 ;[2053] Restore LL.S2
|
||
POP P,R ;[2053] Remember which counter we grabbed
|
||
POP P,@RC.TB ;[2053] And restore it
|
||
POPJ P, ;[2053] Return From SY.RF
|
||
|
||
SGCHK0: HRRI R,2 ;[2053] ASSUME HIGH SEG
|
||
SKIPE LL.S2 ;[1777] MUST BE LOW SWG IF ONLY ONE SEG
|
||
CAMGE P3,LL.S2 ;[1777] BELOW BOTTOM OF HIGH SEG?
|
||
SOJA R,ADCHK.
|
||
SUB P3,LL.S2 ;[1777] FORM OFFSET TO HIGH SEG
|
||
CAMGE P3,HL.S2 ;[1777] BEFORE END OF HIGH SEG?
|
||
JRST ADCHK.
|
||
MOVE P3,0(P) ;[1777] RESTORE ADDRESS
|
||
HRRI R,1
|
||
|
||
ADCHK.::
|
||
IFN FTOVERLAY,<
|
||
SKIPE RT.LB ;RELOCATION TABLE SETUP?
|
||
PUSHJ P,RT.P3## ;YES, SET BYTE PTR
|
||
CAIN R,1 ;LOW SEG?
|
||
SUB P3,PH+PH.ADD ;[1400] REMOVE LINK ORIGIN
|
||
>
|
||
MOVE P2,P3 ;GET A COPY
|
||
IFE TOPS20,< ;[2262]
|
||
SKIPE PAG.S0(R) ;PAGING?
|
||
JRST ADCHK2 ;YES, SEE IF IN CORE
|
||
ADD P2,LC.LB-1(R) ;RELOCATE RELATIVE ADDRESS
|
||
CAMG P2,LC.AB-1(R) ;WILL IT FIT IN EXISTING SPACE?
|
||
JRST ADCHK1 ;YES
|
||
SUB P2,LC.AB-1(R) ;GET EXTRA REQUIRED
|
||
MOVEI P1,LC.IX-1(R) ;POINT TO PROPER AREA
|
||
PUSHJ P,LNKCOR## ;TRY TO GET MORE SPACE
|
||
JRST ADCHK2 ;FAILED BUT MUST BE ON DSK
|
||
SUB P3,LW.S0(R) ;INCASE WE DUMPED CORE FOR FIRST TIME
|
||
>;[2262] IFE TOPS20
|
||
IFN TOPS20,< ;[2270]
|
||
PUSHJ P,@[EXP PG.LSG,PG.HSG]-1(R) ;[2270] MAKE SURE IN MEMORY
|
||
>;[2270] IFN TOPS20
|
||
ADCHK1: ADD P3,LC.LB-1(R) ;FINALLY FIX IN CORE
|
||
POPJ P, ;RETURN WITH P3 SETUP
|
||
IFE TOPS20,< ;[2270]
|
||
ADCHK2:
|
||
PUSHJ P,@[EXP PG.LSG,PG.HSG]-1(R)
|
||
JRST ADCHK1 ;NOW TRY
|
||
>;[2270] IFE TOPS20
|
||
SUBTTL PAGING CORE CONTROL
|
||
|
||
|
||
IFE TOPS20,<
|
||
;HERE TO CHECK TO SEE IF LOW SEG ADDRESS IS INCORE
|
||
;IF NOT CHANGE CORE WINDOW TO INCLUDE NEW ADDRESS
|
||
|
||
PG.LSG::CAMGE P3,LW.S1 ;IS LOWER ADDRESS IN CORE
|
||
PUSHJ P,PG.LSD ;NO, MOVE WINDOW DOWN
|
||
CAMLE P2,UW.S1 ;AND UPPER ALSO
|
||
PUSHJ P,PG.LSU ;NO, NEED TO MOVE WINDOW UP
|
||
SUB P3,LW.S1 ;REMOVE BASE
|
||
POPJ P, ;AND CONTINUE
|
||
|
||
;HERE FOR LOW SEG TO MOVE DOWN
|
||
|
||
PG.LSD: PUSH P,R ;SAVE R
|
||
MOVEI R,LC.IX ;INDEX TO LOW SEG
|
||
JRST PG.SD ;GENERAL MOVER DOWN
|
||
|
||
|
||
PG.LSU: PUSH P,R ;SAVE R
|
||
MOVEI R,LC.IX ;INDEX TO LOW SEG
|
||
JRST PG.SU ;GENERAL MOVER UP
|
||
;HERE TO MOVE THE WINDOW EITHER UP OR DOWN, BUT WITH NO OVERLAPING. FIRST,
|
||
;OUTPUT CURRENT WINDOW, THEN READ BACK THE PORTION WE WILL NEED. WINDOW
|
||
;(POTENTIALLY) SHRINKS TO SMALLER OF LN.WD OR ITS CURRENT SIZE. IF NEW WINDOW
|
||
;ORIGIN PLUS LENGTH EXCEEDS 512P IN THE FILE'S ADDRESS SPACE, SLIDE THE WINDOW
|
||
;DOWN JUST ENOUGH SO IT ENDS AT 512P.
|
||
|
||
PG.SD: MOVE T1,LW.S0(R) ;[2202] SETUP CONTROL WORD
|
||
MOVE T2,UW.S0(R) ;[2202] FIRST,,LAST WORD TO MOVE
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R)
|
||
MOVE T1,P3 ;LOWER ADDRESS WE NEED
|
||
ANDCMI T1,.IPM ;MAKE INTO BLOCK BOUND
|
||
EXCH T1,LW.S0(R) ;RESET WINDOW
|
||
SUB T1,UW.S0(R) ;OLD BASE - OLD UPPER
|
||
MOVM T2,T1 ;+LENGTH -1
|
||
MOVE T1,T2 ;[751] SPACE TO GIVE BACK
|
||
SUBI T1,LN.WD ;[751] IN CASE CURRENT SIZE BIGGER
|
||
CAILE T2,LN.WD-1 ;[717] CURRENT SIZE SMALLER?
|
||
MOVEI T2,LN.WD-1 ;[717] NO, USE LN.WD
|
||
ADD T2,LW.S0(R) ;[717] GET US TO END
|
||
MOVEM T2,UW.S0(R) ;[717]
|
||
JUMPL T1,PG.SD2 ;[717] JUMP IF NOTHING TO GIVE BACK
|
||
ADD T1,TAB.LB(R) ;FIX IN CORE
|
||
IFN TOPS20,< ;[2215] DON'T HAVE GBCK.L ZERO THE AREA
|
||
HRLI T1,1 ;[2215] SINCE IT'S PAGES WERE REMOVED
|
||
> ;[2215] IFN TOPS20
|
||
PUSHJ P,GBCK.L## ;GIVE BACK TO NEXT LOWER
|
||
PG.SD2: MOVE T1,LW.S0(R) ;[2202] RESET CONTROL WORD
|
||
MOVE T2,UW.S0(R) ;[2202] TO DESIRED AREA
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
|
||
PJRST FIXUP ;FIXUP ALL POSSIBLE CORE CHAINS
|
||
;HERE TO MOVE THE WINDOW UP IN MEMORY. IF NECESSARY, DUMP THE LOWER PART OF THE
|
||
;WINDOW AND MOVE DOWN THE REST. THEN EXPAND THE END OF THE WINDOW IF NECESSARY
|
||
;AND READ IN THE UPPER PART WHICH IS USUALLY ZERO. TRY TO KEEP THE SIZE OF THE
|
||
;WINDOW REASONABLE AS A FIRST APPROXIMATION.
|
||
|
||
PG.SU: MOVE T1,P2 ;[1135] SEE IF REQUEST CROSSES A PAGE BOUNDARY
|
||
XOR T1,P3 ;[1135] ..
|
||
TXNN T1,^-<.IPS-1> ;[1135] ..
|
||
JRST PG.SU1 ;[1135] NO--NO SWEAT
|
||
MOVE T1,TAB.AB(R) ;[1135] YES--THEN MAKE SURE AT LEAST 2 PAGES
|
||
SUB T1,TAB.LB(R) ;[1135] IN THE WINDOW
|
||
CAIGE T1,.IPS ;[1135] ..
|
||
JRST PG.SU2 ;[1135] ONLY 1 PAGE--MUST EXPAND
|
||
PG.SU1: CAMG P2,TAB.HB(R) ;[1135] THE HIGH ADDR ALREADY OUT ON DISK?
|
||
JRST PG.SD ;[716] YES, DON'T BOTHER TO EXPAND
|
||
PG.SU2: PUSHJ P,FR.CNT## ;[1135] SEE HOW MUCH FREE SPACE WE HAVE
|
||
ADD T1,UW.S0(R) ;IF WE GIVE IT ALL TO THIS AREA
|
||
SUB T1,LW.S0(R) ;[1251] UPPER BOUND - LOWER BOUND
|
||
SUB T1,FRECOR ;[1251] MINUS WHAT MUST BE KEPT FREE
|
||
CAMG P2,T1 ;WILL IT NOW FIT?
|
||
JRST PG.SX ;YES, JUST EXPAND
|
||
|
||
;SEE IF BY GIVING AWAY LESSER OF LN.WD OR HALF OF EXISTING AREA
|
||
;WE CAN FIT THIS REQUEST IN, IF SO
|
||
;DELETE LOWER PART (WRITE OUT FIRST)
|
||
;IF NOT, MOVE WINDOW UP AS FAR AS POSSIBLE VIA PG.SD, THEN EXPAND
|
||
;AS MUCH AS NEEDED VIA PG.SX
|
||
|
||
MOVE T2,UW.S0(R) ;TOP OF AREA
|
||
SUB T2,LW.S0(R) ;MINUS BOTTOM
|
||
ADDI T2,1 ;GET EVEN
|
||
LSH T2,-1 ;HALF
|
||
ANDCMI T2,.IPM ;KEEP IN BLOCKS
|
||
CAILE T2,LN.WD ;USE THE LESSER
|
||
MOVEI T2,LN.WD
|
||
ADD T1,T2 ;ADD TO PREVIOUS ACCUMULATION
|
||
CAMLE P2,T1 ;WIL IT NOW FIT?
|
||
JRST PG.SS ;[650] NO, CENTER MINIMAL WINDOW
|
||
PUSH P,T2 ;SAVE THE EXCESS
|
||
MOVE T1,LW.S0(R) ;CURRENT LOWEST
|
||
ADD T2,T1 ;FIRST TO KEEP
|
||
SUBI T2,1 ;[2202] HIGHEST TO GET RID OF
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R)
|
||
POP P,T1 ;GET EXCESS BACK
|
||
ADDM T1,LW.S0(R) ;NEW LOWER BOUND
|
||
ADD T1,TAB.LB(R) ;ADD BASE IN CORE
|
||
SUBI T1,1 ;HIGHEST LOC TO GIVE AWAY
|
||
IFN TOPS20,< ;[2215] DON'T HAVE GBCK.L ZERO THE AREA
|
||
HRLI T1,1 ;[2215] SINCE IT'S PAGES WERE REMOVED
|
||
> ;[2215] IFN TOPS20
|
||
PUSHJ P,GBCK.L## ;GIVE EXCESS AWAY
|
||
JRST PG.SU ;SHOULD NOW FIT (AFTER A SHUFFLE
|
||
;HERE IF WE CAN'T FIT THIS REQUEST INTO CURRENT WINDOW.
|
||
;MAKE SURE P3 POINTS INTO BOTTOM PAGE OF WINDOW VIA PG.SD, THEN
|
||
;EXPAND WINDOW TO ENCOMPASS P2 VIA PG.SX IF NECESSARY.
|
||
|
||
PG.SS: MOVE T1,P3 ;[650] LOWEST LOCATION WANTED
|
||
ANDCMI T1,.IPM ;[650] WHAT LW WOULD BE AT BEST
|
||
CAME T1,LW.S0(R) ;[650] WINDOW AS HIGH AS POSSIBLE?
|
||
PUSHJ P,@[EXP PG.LSD,PG.HSD]-1(R) ;[667] NO, MOVE UP
|
||
CAMLE P2,UW.S0(R) ;[650] WINDOW BIG ENOUGH?
|
||
JRST PG.SX ;[650] NO, EXPAND VIA LNKCOR
|
||
JRST RPOPJ ;[650] YES, GOOD ENOUGH
|
||
;HERE TO EXPAND CORE BY AS MUCH AS WE NEED
|
||
;ALSO CHECK INCASE OVERFLOW FILE ALREADY CONTAINS THE NEW AREA
|
||
;IF SO READ IT IN
|
||
|
||
PG.SX: PUSH P,P1 ;SAVE ACCS USED BY LNKCOR
|
||
PUSH P,P2
|
||
MOVEI P1,(R) ;WHO WE WANT TO EXPAND
|
||
SUB P2,UW.S0(R) ;BY HOW MUCH
|
||
PUSHJ P,LNKCOR## ;GET IT
|
||
PUSHJ P,PGMOV2 ;[2366] CAN'T DO IT, TAKE WHAT'S AVAILABLE
|
||
POP P,P2 ;RESTORE
|
||
POP P,P1
|
||
MOVE T1,TAB.AB(R) ;HIGHEST BLOCK IN CORE
|
||
SUB T1,TAB.LB(R) ;LENGTH OF INCORE AREA
|
||
ADD T1,LW.S0(R) ;LENGTH FROM ORIGIN
|
||
EXCH T1,UW.S0(R) ;IS NEW UPPER BOUND
|
||
CAML T1,HB.S0(R) ;[1116] HOWEVER IF EVEN BIGGER HAS BEEN SEEN?
|
||
JRST RPOPJ ;NO, RESTORE R AND RETURN
|
||
ADDI T1,1 ;[2202] IT MUST BE ON THE DSK
|
||
MOVE T2,UW.S0(R) ;[2202] SO SETUP TRANSFER REQUEST
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;[1116]
|
||
PJRST FIXUP ;[1116] AND DO ANY FIXUPS
|
||
;SIMILARLY FOR HIGH SEG
|
||
|
||
PG.HSG::CAMGE P3,LW.S2 ;SAME AS FOR LOW SEG
|
||
PUSHJ P,PG.HSD
|
||
CAMLE P2,UW.S2
|
||
PUSHJ P,PG.HSU
|
||
SUB P3,LW.S2 ;REMOVE BASE
|
||
POPJ P, ;CONTINUE
|
||
|
||
;HERE TO CHANGE WINDOW TO HIGH SEG
|
||
;HERE TO MOVE WINDOW DOWN
|
||
;FIRST OUTPUT THE WINDOW, THEN READ BACK WHAT WE NEED
|
||
PG.HSD: PUSH P,R ;SAVE R
|
||
MOVEI R,HC.IX ;INDEX TO HIGH
|
||
JRST PG.SD ;MOVE DOWN
|
||
|
||
|
||
;HERE TO MOVE WINDOW UP IN CORE
|
||
;DUMP LOWER PART OF WINDOW, BLT DOWN AND READ IN TOP PART
|
||
;THIS PART IS MOST LIKELY ZERO
|
||
PG.HSU: PUSH P,R ;SAVE R
|
||
MOVEI R,HC.IX ;INDEX TO HIGH
|
||
JRST PG.SU ;MOVE UP
|
||
> ;[1401] IFE TOPS20
|
||
|
||
IFN TOPS20,<
|
||
|
||
;[1401] THIS CODE FIXES OCCASIONAL ?LNKMEF.
|
||
;HERE TO CHANGE WINDOW TO LOW SEG
|
||
|
||
PG.LSG::
|
||
CAMGE P3,LW.S1 ;[1401] IS LOWER ADDRESS IN CORE?
|
||
SKIPA ;[1401] NO
|
||
CAMLE P2,UW.S1 ;[1401] IS UPPER ADDRESS IN CORE?
|
||
PUSHJ P,PG.LSX ;[1401] NO, MOVE THE WINDOW
|
||
SUB P3,LW.S1 ;[1401] REMOVE BASE
|
||
POPJ P, ;[1401] AND CONTINUE
|
||
|
||
PG.LSX: PUSH P,R ;[1401] SAVE CURRENT R
|
||
MOVEI R,LC.IX ;[1401] INDEX TO LOW SEG
|
||
CAML P3,LW.S1 ;[1401] SIMPLE EXPANSION POSSIBLE?
|
||
JRST PG.XPN ;[1401] YES, TRY THAT FIRST
|
||
JRST PG.MOV ;[1401] GENERAL MOVER
|
||
|
||
;[1401] SIMILARLY FOR HIGH SEG
|
||
|
||
PG.HSG::CAMGE P3,LW.S2 ;[1401] SAME AS FOR LOW SEG
|
||
SKIPA
|
||
CAMLE P2,UW.S2
|
||
PUSHJ P,PG.HSX
|
||
SUB P3,LW.S2 ;[1401] REMOVE BASE
|
||
POPJ P, ;[1401] CONTINUE
|
||
|
||
;[1401] HERE TO CHANGE WINDOW TO HIGH SEG
|
||
|
||
PG.HSX: PUSH P,R ;[1401] SAVE R
|
||
MOVEI R,HC.IX ;[1401] INDEX TO HIGH
|
||
CAML P3,LW.S2 ;[1401] SIMPLE EXPANSION POSSIBLE?
|
||
JRST PG.XPN ;[1401] YES, TRY THAT FIRST
|
||
JRST PG.MOV ;[1401] MOVE DOWN
|
||
|
||
;[1401] MINOR NOTE: THE STACK IS CLEANED UP AT RETURN FROM "FIXUP".
|
||
|
||
;[1401] HERE TO TRY EXPANDING THE WINDOW.
|
||
|
||
PG.XPN:
|
||
MOVE T1,TAB.UB(R)
|
||
SUB T1,TAB.AB(R) ;[1401] WHAT'S AVAILABLE
|
||
MOVE T2,P2
|
||
SUB T2,UW.S0(R) ;[1401] HOW MUCH MORE WE WANT
|
||
CAMGE T1,T2 ;[1401] ENOUGH TO SIMPLY EXPAND?
|
||
JRST PG.MOV ;[1401] NO, DO GENERAL PURPOSE MOVE
|
||
PUSH P,P1 ;[1401] SAVE ACS
|
||
PUSH P,P2
|
||
MOVEI P1,(R) ;[1401] NOTE INDEX
|
||
MOVE P2,T2 ;[1401] AND AMOUNT TO EXPAND BY
|
||
PUSHJ P,LNKCOR ;[1401] ASK
|
||
PUSHJ P,E$$MEF ;[1401] NOT ALWAYS GIVEN...
|
||
POP P,P2 ;[1401] RESTORE
|
||
POP P,P1
|
||
JRST PGDONE ;[1401] ALL SET.
|
||
|
||
;[1401] HERE TO MOVE THE WINDOW. OUTPUT THE EXISTING WINDOW AND THEN
|
||
;[1401] BRING IN THE REQUESTED DATA.
|
||
|
||
PG.MOV:
|
||
MOVE T1,LW.S0(R) ;[2202] RETURN CURRENT SPAN
|
||
MOVE T2,UW.S0(R) ;[2202] FIRST,,LAST
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R)
|
||
;[1401] IS THERE ENOUGH STORAGE IN THIS AREA TO FIT THE REQUEST?
|
||
MOVE T1,UW.S0(R) ;[1401] LAST
|
||
SUB T1,LW.S0(R) ;[1401] -FIRST
|
||
MOVE T2,P2 ;[1401] UPPERBOUND
|
||
TRO T2,.IPM ;[2074] AT TOP OF A PAGE
|
||
SUB T2,P3 ;[1401] LOWERBOUND
|
||
CAMGE T1,T2 ;[1401] AREA GTRE REQUEST?
|
||
JRST PGMOV1 ;[1401] NO
|
||
MOVE T1,P3 ;[1401] LOWER ADDRESS WE NEED
|
||
ANDCMI T1,.IPM ;[1401] MAKE INTO BLOCK BOUNDARY
|
||
MOVEM T1,LW.S0(R) ;[1401] RESET LOWER WINDOWBOUND
|
||
MOVE T2,P2 ;[1401] HIGHEST ADDRESS WE NEED
|
||
ANDCMI T2,.IPM ;[1401] MAKE INTO BLOCK BOUNDARY
|
||
ADDI T2,.IPS-1 ;[1401] INCLUDE THE PAGE
|
||
MOVEM T2,UW.S0(R) ;[1401] RESET UPPER WINDOWBOUND
|
||
SUB T2,T1 ;[1401] GET WINDOW LENGTH
|
||
MOVE T1,TAB.LB(R) ;[1401] RESET AREA BOUNDS
|
||
ADD T1,T2
|
||
MOVEM T1,TAB.AB(R)
|
||
MOVE T1,LW.S0(R) ;[2202] BRING IN THE WINDOW
|
||
MOVE T2,UW.S0(R) ;[2202]
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
|
||
JRST PGDONE
|
||
;[1401] HERE IF MEMORY MUST BE REQUESTED
|
||
|
||
PGMOV1:
|
||
|
||
;[1401]
|
||
; THERE IS NOT ENOUGH ROOM CURRENTLY ALLOCATED IN MEMORY. BRING IN ONE
|
||
; PAGE'S WORTH OF THE REQUEST, AND ASK LNKCOR TO EXPAND ON IT TO PROVIDE
|
||
; THE REST.
|
||
MOVE T2,TAB.LB(R) ;[2202] GET THE LOWER BOUND
|
||
ADDI T2,.IPS-1 ;[2202] ALLOW ONE PAGE
|
||
MOVEM T2,TAB.AB(R) ;[2202] NEW UPPER BOUND
|
||
MOVE T1,P3 ;[1401] LOWER END OF REQUEST
|
||
ANDCMI T1,.IPM ;[1401] MAKE INTO BLOCKBOUND
|
||
MOVEM T1,LW.S0(R) ;[1401] SET LOWER WINDOWBOUND
|
||
MOVE T2,T1 ;[2202] GET LOWER BOUND
|
||
ADDI T2,.IPS-1 ;[2202] END OF PAGE
|
||
MOVEM T2,UW.S0(R) ;[2202] SET UPPER WINDOWBOUND
|
||
PUSHJ P,@[EXP LC.IN,HC.IN]-1(R)
|
||
MOVE T2,P2 ;[1401] UPPER END OF REQUEST
|
||
ANDCMI T2,.IPM ;[1401] MAKE INTO BLOCKBOUND
|
||
ADDI T2,.IPS-1 ;[1401] THROUGH END OF PAGE
|
||
SUB T2,UW.S0(R) ;[2202] ADDITIONAL SPACE NEEDED
|
||
PUSH P,P1 ;[1401] SAVE ACS USED BY LNKCOR
|
||
PUSH P,P2 ;[1401]
|
||
MOVEI P1,(R) ;[1401] WHAT TO EXPAND
|
||
MOVE P2,T2 ;[1401] BY HOW MUCH
|
||
PUSHJ P,LNKCOR##
|
||
PUSHJ P,PGMOV2 ;[2262] CAN'T DO IT
|
||
POP P,P2 ;[1401] RESTORE ACS
|
||
POP P,P1
|
||
;[1401] THE WINDOW HAS BEEN RESET TO COVER THE REQUEST.
|
||
PGDONE:
|
||
PJRST FIXUP ;[1401] DO ANY FIXUPS POSSIBLE
|
||
> ;[1401] IFN TOPS20
|
||
;HERE TO SEE IF ANY FIXUPS CAN BE DONE FOR LOW SEG JUST READ IN
|
||
;MUST NOT CHANGE P1-P4 & MUST SAVE R
|
||
;USES T1-T4
|
||
|
||
|
||
FIXUPL: PUSH P,R ;NEED TO SAVE IT
|
||
MOVEI R,LC.IX ;LOAD INDEX TO LOW
|
||
JRST FIXUP ;DO THE FIXUPS
|
||
|
||
;HERE TO SEE IF ANY FIXUPS CAN BE DONE FOR HIGH SEG JUST READ IN
|
||
;MUST NOT CHANGE P1-P4 & MUST SAVE R
|
||
;USES T1-T4
|
||
|
||
FIXUPH: PUSH P,R ;NEED TO SAVE IT
|
||
MOVEI R,HC.IX
|
||
|
||
|
||
FIXUP: PUSHJ P,CHKCHN ;SEE IF ANYTHING TO DO
|
||
RPOPJ: POP P,R ;RESTORE R
|
||
POPJ P,
|
||
|
||
;[2262] Here if unable to get requested memory. Get whatever is
|
||
;[2262] available. The calling routine will have to check to see
|
||
;[2262] if it got what it needed. Note that routines which need
|
||
;[2262] only one page will not have to check as they always get it.
|
||
PGMOV2: PUSHJ P,FR.CNT## ;[2262] FIND OUT WHAT IS AVAILABLE
|
||
SUB T1,FRECOR ;[2262] MINUS WHAT LNKCOR WILL PRESERVE
|
||
MOVE P2,T1 ;[2262] THAT'S HOW MUCH TO ASK FOR
|
||
PUSHJ P,LNKCOR## ;[2262] GO GET IT
|
||
PUSHJ P,E$$MMF## ;[2343] NOT EXPECTED TO FAIL
|
||
POPJ P, ;[2262] DONE
|
||
|
||
SUBTTL PROCESS FIXUPS FOR NEW WINDOW
|
||
;CHKCHN - SEE IF ANY FIXUPS EXIST FOR THE NEW CORE WINDOW
|
||
;IF SO LINK THEM INTO FXT.S0
|
||
;AND DO THEM
|
||
;R=2*N+1 FOR LOW, R=2*N+2 FOR HIGH
|
||
;DESTROYS R
|
||
;USES T1-T4
|
||
|
||
CHKCHN:
|
||
PUSHJ P,.SAVE1## ;[1737] Save P1 - will point to fixup chain head
|
||
MOVEI P1,FX.S0(R) ;[1737] Point to the Rth section's fixup header
|
||
CAIE R,1 ;[2200] Low segment fixups?
|
||
JRST CHKCHE ;[1737] No, go on and use FX.S0(R)
|
||
HLRZ P1,LW.LC ;[2200] Get the section number of the window
|
||
MOVEI P1,FXSPTR(P1) ;[2200] Set the head pointer and process
|
||
CHKCHE: SKIPN (P1) ;[1737] Anything to do?
|
||
POPJ P, ;NO
|
||
SETZM FXT.S0 ;CLEAR TEMP PTR
|
||
HRRZ T1,(P1) ;[1737] Get pointer to fixup for lowest address
|
||
ADD T1,FX.LB ;+OFFSET
|
||
LDB T2,[ADDRESS 1(T1)] ;[2200] GET ADDRESS
|
||
SUB T2,LL.S0(R) ;REMOVE ORIGIN
|
||
IFN FTOVERLAY,<
|
||
CAIN R,1 ;LOW SEGMENT?
|
||
SUB T2,PH+PH.ADD ;[1400] YES, REMOVE OVERLAY START ADDR
|
||
> ;END OF IFN FTOVERLAY
|
||
HLRZ T1,(P1) ;[1737] Pointer to fixup for highest address
|
||
ADD T1,FX.LB ;+OFFSET
|
||
LDB T3,[ADDRESS 1(T1)] ;[2200] ADDRESS
|
||
SUB T3,LL.S0(R) ;REMOVE ORIGIN
|
||
IFN FTOVERLAY,<
|
||
CAIN R,1 ;LOW SEGMENT?
|
||
SUB T3,PH+PH.ADD ;[1400] YES, REMOVE OVERLAY START ADDR
|
||
> ;END OF IFN FTOVERLAY
|
||
CAMG T2,UW.S0(R) ;IS LOWEST ADDRESS TOO HIGH?
|
||
CAMGE T3,LW.S0(R) ;OR HIGHEST TOO LOW?
|
||
POPJ P, ;YES, JUST GIVE UP
|
||
;MAKE QUICK TEST INCASE ALL CHAIN IN CORE
|
||
;IN WHICH CASE WE NEED NOT CHASE THE CHAIN
|
||
CAML T2,LW.S0(R) ;IS LOWEST ADDRESS .GT. LOW WINDOW?
|
||
CAMLE T3,UW.S0(R) ;AND HIGHEST ADDRESS .LE. HIGH WINDOW
|
||
JRST .+5 ;NO, DO THE SLOW WAY
|
||
MOVE T1,(P1) ;[1737] Get pointer word
|
||
MOVEM T1,FXT.S0 ;MOVE IT ALL OVER
|
||
SETZM (P1) ;[1737] Remove from list to consider
|
||
JRST FXTLUP ;AND DO IT
|
||
MOVE T1,P1 ;[1737] Get initial pointer
|
||
;Start at back since most usual case
|
||
;is to read file backwards
|
||
CHKCHL: HLRZ T1,(T1) ;GET NEXT
|
||
JUMPE T1,CPOPJ ;NOTHING TO DO
|
||
ADD T1,FX.LB ;OFFSET
|
||
LDB T2,[ADDRESS 1(T1)] ;[2200] GET 30 BIT ADDRESS
|
||
SUB T2,LL.S0(R) ;REMOVE ORIGIN
|
||
IFN FTOVERLAY,<
|
||
CAIN R,1 ;LOW SEGMENT?
|
||
SUB T2,PH+PH.ADD ;[1400] YES, REMOVE OVERLAY START ADDR
|
||
> ;END OF IFN FTOVERLAY
|
||
CAMG T2,UW.S0(R) ;[741] INCORE?
|
||
CAMGE T2,LW.S0(R) ;[741] CHECK AGAINST WINDOW RANGE
|
||
JRST CHKCHL ;NO, LOOP
|
||
HRRZ T3,(T1) ;GET FORWARD LINK
|
||
JUMPE T3,[MOVE T3,P1 ;[1737] If link is zero, this is
|
||
JRST CHKCHM] ;[1737] the top of the chain
|
||
HRL T3,T3 ;STORE UNRELOCATED IN LEFT HALF
|
||
ADD T3,FX.LB ;RELOCATED IN RIGHT
|
||
HLLZS (T1) ;CLEAR FORWARD PTR OF REMOVED PART
|
||
CHKCHM: SUB T1,FX.LB ;-OFFSET
|
||
MOVSM T1,FXT.S0 ;TEMP PTR TO HIGHEST TO DO
|
||
ADD T1,FX.LB ;+OFFSET
|
||
CHKCHH: HLRZ T1,(T1) ;GET NEXT
|
||
JUMPE T1,[MOVE T1,P1 ;[1737] Point to the header if we have
|
||
JRST CHKFIN] ;[1737] reached the end of the chain
|
||
ADD T1,FX.LB ;+OFFSET
|
||
LDB T2,[ADDRESS 1(T1)] ;[2200] ADDRESS
|
||
SUB T2,LL.S0(R) ;REMOVE ORIGIN
|
||
IFN FTOVERLAY,<
|
||
CAIN R,1 ;LOW SEGMENT?
|
||
SUB T2,PH+PH.ADD ;[1400] YES, REMOVE OVERLAY START ADDR
|
||
> ;END OF IFN FTOVERLAY
|
||
CAML T2,LW.S0(R) ;STILL IN COREE?
|
||
JRST CHKCHH ;YES
|
||
MOVE T2,T1 ;GET ABS ADDRESS
|
||
SUB T2,FX.LB ;REMOVE OFFSET
|
||
HRL T1,T2 ;STORE LINK IN LEFT HALF FOR LATER
|
||
CHKFIN: HRRZ T2,(T1) ;GET 1ST FIXUP WE CAN DO
|
||
HRRM T2,FXT.S0 ;STORE IN PTR
|
||
ADD T2,FX.LB ;RELOCATE IN FIXUP BLOCK
|
||
HRRZS (T2) ;AND CLEAR BACK LINK
|
||
;NOW CLOSE PTRS OVER HOLE
|
||
HLRM T3,(T1) ;LINK TOP TO BOTTOM
|
||
HLLM T1,(T3) ;AND BOTTOM TO TOP
|
||
;NOW TO EXECUTE THE FIXUPS
|
||
;STORE R IN LEFT OF FXT.S0 (NOT USED FOR CHAIN PROCESSING)
|
||
FXTLUP: PUSH P,W3 ;KEEP W3 INTACT
|
||
FXTLP1: SOS FXC.S0(R) ;COUNT 1 LESS
|
||
HRRZ T1,FXT.S0 ;GET NEXT PTR
|
||
JUMPE T1,[POP P,W3 ;RESTORE W3
|
||
POPJ P,] ;ALL DONE FOR THIS LIST
|
||
.JDDT LNKLOD,FXTLP1,<<CAMN T1,$FIXUP##>> ;[632]
|
||
ADD T1,FX.LB ;+OFFSET
|
||
PUSH P,1(T1) ;GET ADDRESS (EXPECTED IN T2)
|
||
MOVE W3,2(T1) ;VALUE
|
||
HRRZ T2,(T1) ;NEXT PTR
|
||
HRRM T2,FXT.S0 ;STORED
|
||
MOVEI T2,3 ;SIZE OF BLOCK
|
||
PUSHJ P,FX.RET## ;RESTORE NOW (INCASE REQUIRED AGAIN)
|
||
POP P,T2 ;ADDRESS IN T2
|
||
LDB T1,[HIGH6 T2] ;[2200] GET INDEX
|
||
TLZ T2,770000 ;[2200] AND 30 BIT ADDRESS (CLEAR HIGH 6 BITS)
|
||
HRLM R,FXT.S0 ;SAVE R SINCE IT WILL POINT TO DATA BLOCK ON RETURN
|
||
PUSHJ P,@CHNTAB(T1) ;GO TO RIGHT ROUTINE
|
||
HLRZ R,FXT.S0 ;RESTORE R
|
||
JRST FXTLP1 ;AND CONTINUE
|
||
|
||
IFE FTOVERLAY,<
|
||
PFF.CR==SY.CHR ;USE NORMAL CHAIN-CHASING ROUTINES
|
||
PFF.CL==SY.CHL
|
||
PFF.CF==SY.CHF
|
||
PFF.CE==SY.CHE ;[2214]
|
||
> ;END IFE FTOVERLAY
|
||
|
||
DEFINE X (A)<
|
||
EXP PFF.'A
|
||
>
|
||
|
||
CHNTAB: CFIXUPS
|
||
SUBTTL FIND HIGHEST LOCATION TO FIXUP
|
||
;ROUTINE TO FIND HIGHEST LOCATION TO FIXUP IN EITHER LOW OR HIGH SEG
|
||
;CALLED BY
|
||
; PUSHJ P,FHA.L/FHA.H
|
||
;RETURNS
|
||
;T1 = HIGHEST LOC, 0 IF NONE TO DO
|
||
;USES T1,T2
|
||
|
||
FHA.L: MOVEI T1,MAXSEC ;[2200] Number of sections
|
||
FHALX1: JUMPE T1,CPOPJ ;[2200] Done if below table
|
||
SKIPN FXSPTR-1(T1) ;[2200] Check for nonzero entry
|
||
SOJA T1,FHALX1 ;[2200] Get another if zero
|
||
HLRZ T1,FXSPTR-1(T1) ;[2200] Check the highest loc
|
||
SETZ T2, ;[2200] 0 for low segment
|
||
JRST FHALH1 ;[2200] Join common code
|
||
|
||
FHA.H: MOVEI T2,1 ;1 FOR HIGH
|
||
HLRZ T1,FX.S1(T2) ;GET PTR TO HIGHEST LOC THIS CHAIN
|
||
JUMPE T1,CPOPJ ;NOTHING THERE
|
||
FHALH1: ADD T1,FX.LB ;[2200] +OFFSET
|
||
LDB T1,[ADDRESS 1(T1)] ;[2200] AND NOTE ADDR TO BE FIXED
|
||
IFN FTOVERLAY,<
|
||
JUMPN T2,CPOPJ ;LOW SEGMENT?
|
||
SUB T1,PH+PH.ADD ;[1400] YES, REMOVE OVERLAY START ADDR
|
||
> ;END OF IFN FTOVERLAY
|
||
POPJ P, ;RETURN
|
||
|
||
SUBTTL SCAN WHOLE PROGRAM FOR FIXUPS
|
||
;ROUTINE TO READ OVERFLOW FILES BACKWARDS AND DO ALL POSSIBLE CODE FIXUPS
|
||
|
||
COR.FX::
|
||
SKIPE FX.S2 ;[2200] High seg fixups?
|
||
JRST CORFX0 ;[2200] Yes, must do fixups
|
||
MOVEI T1,MAXSEC ;[2200] Get the number of sections
|
||
CORFX1: SKIPE FXSPTR-1(T1) ;[2200] Fixups for this section?
|
||
JRST CORFX0 ;[2200] Yes
|
||
SOJG T1,CORFX1 ;[2200] No, try the next section
|
||
POPJ P,
|
||
CORFX0: PUSH P,R ;[1463] SAVE R
|
||
E$$FCF::.ERR. (MS,0,V%L,L%I,S%I,FCF,<Final code fixups>) ;[1174]
|
||
CORFXL: ;HERE FOR LOW SEGMENT
|
||
PUSHJ P,FHA.L ;FIND ADDRESS
|
||
JUMPE T1,CORFXH ;TRY HIGH
|
||
IORI T1,.IPM ;ROUNDED UP TO BLOCK BOUND
|
||
MOVEI R,LC.IX ;SET INDEX
|
||
PUSHJ P,RDBACK ;READ IN REQUIRED CORE IMAGE
|
||
;AND DO ALL FIXUPS WE CAN
|
||
JRST CORFXL ;TRY AGAIN
|
||
|
||
CORFXH: ;HERE FOR HIGH
|
||
PUSHJ P,FHA.H ;SEE IF ANY HIGH
|
||
JUMPE T1,CORFXT ;TEST TO SEE IF ANY MORE LOW
|
||
SUB T1,LL.S2 ;REMOVE ORIGIN
|
||
IORI T1,.IPM
|
||
MOVEI R,HC.IX ;SET INDEX FOR HIGH
|
||
PUSHJ P,RDBACK ;READ IN AND FIXUP
|
||
JRST CORFXH ;LOOP
|
||
|
||
CORFXT: PUSHJ P,FHA.L ;ANY LOW
|
||
JUMPN T1,CORFXL ;YES, RECYCLE
|
||
POP P,R ;RESTORE R
|
||
POPJ P, ;RETURN
|
||
;HERE TO DO ACTUAL READ BACK
|
||
;ENTER WITH
|
||
;R = 1 FOR LOW
|
||
;R = 2 FOR HIGH
|
||
|
||
RDBACK: MOVE T2,UW.S0(R) ;[2202] GET THE OLD BOUNDARY
|
||
MOVEM T1,UW.S0(R) ;[2202] STORE THE NEW UPPER LIMIT
|
||
MOVE T1,LW.S0(R) ;[2202] WRITE OUT CURRENT IMMAGE
|
||
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R)
|
||
MOVE T1,UW.S0(R) ;NOW FIND BOTTOM
|
||
HLLZM T1,LW.S0(R) ;[2407] SECTION,,0 OF NEW BOTTOM
|
||
HRRZS T1 ;[2407] UW ADDRESS IN SECTION
|
||
ADD T1,TAB.LB(R)
|
||
SUB T1,TAB.AB(R) ;FOR NEW LW.S0(R)
|
||
HRRM T1,LW.S0(R) ;[2407] SET BASE IN THIS SECTION
|
||
JUMPGE T1,RDBCK1 ;OK IF NOT TOO MUCH
|
||
ADDM T1,TAB.AB(R) ;TOO MUCH, CUT BACK TOP
|
||
HLLZS LW.S0(R) ;[2407] GET SECTION,,0 AS LOWER WINDOW
|
||
;[2407] WINDOW NOW ALL IN CORE
|
||
IFE TOPS20,< ;[2202] DON'T BLT ON THE -20, IT'S MAPPED AWAY
|
||
MOVE T1,TAB.LB(R) ;TOP WE WILL FILL
|
||
HRLI T1,1(T1) ;FORM BLT PTR
|
||
HRRI T1,2(T1)
|
||
SETZM -1(T1) ;AND CLEAR UP TO .UB
|
||
BLT T1,@TAB.UB(R) ;SO WE DON'T LEAVE JUNK BEHIND
|
||
> ;[2202] IFE TOPS20
|
||
RDBCK1: MOVE T1,LW.S0(R) ;[2202] NOW FOR READIN
|
||
MOVE T2,UW.S0(R) ;[2202]
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
|
||
PJRST @[EXP FIXUPL,FIXUPH]-1(R) ;AND DO FIXUPS
|
||
;HERE TO DO PAGE FAULT FIXUPS
|
||
|
||
;ADDITIVE FIXUPS
|
||
PFF.AR: JUMPE T2,CPOPJ ;DONE IF ZERO
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
HRRZ T1,(T2) ;GET RIGHT HALF VALUE
|
||
ADD T1,W3 ;PLUS DEFINED SYMBOL
|
||
HRRM T1,(T2) ;STORE NEW VALUE
|
||
POPJ P,
|
||
|
||
PFF.AL: JUMPE T2,CPOPJ ;DONE IF ZERO
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
HLRZ T1,(T2) ;GET LEFT HALF VALUE
|
||
ADD T1,W3 ;PLUS DEFINED SYMBOL
|
||
HRLM T1,(T2) ;STORE NEW VALUE
|
||
POPJ P,
|
||
|
||
PFF.AF: JUMPE T2,CPOPJ ;DONE IF ZERO
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
ADDM W3,(T3) ;[2214] PLUS DEFINED SYMBOL
|
||
POPJ P,
|
||
|
||
PFF.AE: JUMPE T2,CPOPJ ;[2214] Done if zero
|
||
PUSHJ P,SEGCHK ;[2214] Setup incore address
|
||
PUSHJ P,E$$ANM ;[2214] We only get here when page is in core
|
||
LDB T1,[ADDRESS(T2)] ;[2214] Get 30 bit half value
|
||
ADD T1,W3 ;[2214] Plus defined symbol
|
||
DPB T1,[ADDRESS(T2)] ;[2214] Store new value
|
||
POPJ P, ;[2214]
|
||
|
||
;CHAINED FIXUPS
|
||
IFN FTOVERLAY,<
|
||
PFF.CR: SKIPE T1,RT.PT ;IS RT AREA SET UP?
|
||
CAMN T1,RT.LB ;MAYBE, IS IT?
|
||
PJRST SY.CHR ;NO, NO RELOC BITS TO SET
|
||
PUSH P,P3 ;SAVE P3 OVER RT.P3
|
||
MOVE P3,T2 ;ADDRESS OF CURRENT FIXUP
|
||
PUSHJ P,RT.P3## ;SETUP BYTE POINTER
|
||
ILDB T1,RT.PT ;PICK UP RELOCATION BITS
|
||
TRNE T1,1 ;RH RELOCATABLE?
|
||
TXO R,1B1 ;YES, TELL RT.T2R
|
||
MOVE T2,P3 ;RESTORE CHAIN ADDRESS
|
||
POP P,P3 ;AND PRESERVED AC
|
||
PJRST SY.CHR ;GO CHASE CHAIN
|
||
|
||
|
||
PFF.CL: SKIPE T1,RT.PT ;ANY RELOC BITS TO WORRY ABOUT?
|
||
CAMN T1,RT.LB ;MAYBE, ARE THERE?
|
||
PJRST SY.CHL ;NO, GO FOLLOW CHAINS
|
||
PUSH P,P3 ;SAVE P3 OVER RT.P3
|
||
MOVE P3,T2 ;ADDRESS OF CURRENT FIXUP
|
||
PUSHJ P,RT.P3## ;SETUP BYTE POINTER
|
||
ILDB T1,RT.PT ;PICK UP RELOCATION BITS
|
||
TRNE T1,2 ;LH RELOCATABLE?
|
||
TXO R,1B0 ;YES, TELL RT.T2L
|
||
MOVE T2,P3 ;RESTORE CHAIN ADDRESS
|
||
POP P,P3 ;AND PRESERVED AC
|
||
PJRST SY.CHL ;GO CHASE CHAIN
|
||
|
||
|
||
PFF.CF: SKIPE T1,RT.PT ;RELOC BITS?
|
||
CAMN T1,RT.LB ;OR IS RT AREA EMPTY?
|
||
PJRST SY.CHF ;EMPTY, DON'T WORRY ABOUT IT
|
||
PUSH P,P3 ;SAVE P3 OVER RT.P3
|
||
MOVE P3,T2 ;ADDRESS OF CURRENT FIXUP
|
||
PUSHJ P,RT.P3## ;SETUP BYTE POINTER
|
||
ILDB T1,RT.PT ;PICK UP RELOCATION BITS
|
||
LSH T1,-^D34 ;MOVE TO LEFT JUSTIFY
|
||
IOR R,T1 ;SET WHERE RT.T2F CAN FIND IT
|
||
MOVE T2,P3 ;RESTORE CHAIN ADDRESS
|
||
POP P,P3 ;AND PRESERVED AC
|
||
PJRST SY.CHF ;GO CHASE CHAIN
|
||
|
||
|
||
PFF.CE: SKIPE T1,RT.PT ;[2214] Reloc bits?
|
||
CAMN T1,RT.LB ;[2214] Or is RT area empty?
|
||
PJRST SY.CHE ;[2214] Empty, don't worry about it
|
||
PUSH P,P3 ;[2214] Save P3 over RT.P3
|
||
MOVE P3,T2 ;[2214] Address of current fixup
|
||
PUSHJ P,RT.P3## ;[2214] Setup byte pointer
|
||
ILDB T1,RT.PT ;[2214] Pick up relocation bits
|
||
LSH T1,-^D34 ;[2214] Move to left justify
|
||
IOR R,T1 ;[2214] Set where RT.T2E can find it
|
||
MOVE T2,P3 ;[2214] Restore chain address
|
||
POP P,P3 ;[2214] And preserved ac
|
||
PJRST SY.CHE ;[2214] Go chase chain
|
||
|
||
|
||
> ;END IFN FTOVERLAY
|
||
|
||
|
||
|
||
E$$ANM::.ERR. (MS,,V%L,L%F,S%F,ANM,<Address not in memory>)
|
||
;REPLACEMENTS
|
||
|
||
;RIGHT HALF
|
||
PFF.RR: JUMPE T2,CPOPJ
|
||
PUSHJ P,SEGCHK
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
HRRM W3,(T2) ;JUST REPLACE WHATS THERE
|
||
POPJ P,
|
||
|
||
;LEFT HALF
|
||
PFF.RL: JUMPE T2,CPOPJ
|
||
PUSHJ P,SEGCHK
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
HRLM W3,(T2)
|
||
POPJ P,
|
||
|
||
;FULLWORD
|
||
PFF.RF: JUMPE T2,CPOPJ ;DONE IF ZERO
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
PUSHJ P,E$$ANM ;[1174] WE ONLY GET HERE WHEN PAGE IS IN CORE
|
||
MOVEM W3,(T2) ;REPLACE VALUE
|
||
POPJ P,
|
||
|
||
;[2214] Thirty bit
|
||
PFF.RE: JUMPE T2,CPOPJ ;[2214] Done if zero
|
||
PUSHJ P,SEGCHK ;[2214] Setup incore address
|
||
PUSHJ P,E$$ANM ;[2214] We only get here when page is in core
|
||
DPB W3,[ADDRESS(T2)] ;[2214] Replace value
|
||
POPJ P,
|
||
|
||
SUBTTL LOCAL SYMBOL STORE
|
||
|
||
|
||
;ROUTINE TO ADD CONTENTS OF W1, W2, W3 TO LOCAL SYMBOLTABLE
|
||
;ALSO USED TO PUT GLOBALS AND OTHER STUFF THERE
|
||
;CHECKS FOR DSK OVERFLOW ETC
|
||
|
||
|
||
;THIS IS WHERE IT ALL GETS DONE
|
||
|
||
LSADDX: PUSHJ P,LS.XPN ;NEED TO EXPAND FIRST
|
||
LS.ADD::SKIPN @GS.LB ;[1143] USER TYPE /NOINITIAL?
|
||
PUSHJ P,LS.CHK ;[1143] YES, SEE IF NEED A DUMMY MODULE NAME
|
||
LSADD: MOVE T1,LSYM ;[1143] GET SYMBOL TABLE POINTER
|
||
MOVEM T1,LSTLCL ;[2255] STORE REL POINTER TO NEXT LOCAL SYMBOL
|
||
TXNN W1,PS.GLB ;IF NOT GLOBAL
|
||
SETZM LSTGBL ;[2255] CLEAR SPURIOUS GLOBAL POINTER
|
||
TXC W1,PT.TTL!PT.PSC ;[2220] Could be a long psect
|
||
TXCE W1,PT.TTL!PT.PSC ;[2220] Was it?
|
||
TXNE W1,PT.SYM ;[2216] Is it a symbol?
|
||
TLNE W2,770000 ;[2216] And long?
|
||
CAIA ;[2216] No, short or non-symbl
|
||
JRST [PUSH P,W2 ;[2216] Yes, save the length and pointer
|
||
PUSH P,[LSADDL] ;[2216] Where to go to do long symbol
|
||
MOVE W2,(W2) ;[2216] Get the first six characters
|
||
JRST .+1] ;[2216]
|
||
MOVEI T2,.L ;[2216] Short symbol, need one triplet
|
||
MOVE T1,LS.FR ;NUMBER OF WORDS FREE
|
||
SUBI T1,(T2) ;WE NEED SOME MORE FOR THIS ENTRY
|
||
JUMPL T1,LSADDX ;NOT ENOUGH
|
||
MOVEM T1,LS.FR ;STORE NEW COUNT
|
||
MOVE T1,T2 ;SAME NUMBER OF WORDS
|
||
ADDM T2,LSYM ;COUNT EXTRA WORDS
|
||
ADDB T1,LS.PT ;NEW ACTUAL BOUND
|
||
TMOVEM W1,-3(T1) ;FLAGS, NAME, VALUE
|
||
POPJ P,
|
||
|
||
;[2216] Here on a long symbol to store the secondaries
|
||
LSADDL: MOVE W2,(P) ;[2216] Get back the pointer
|
||
HLR T2,W2 ;[2216] Get the count
|
||
CAILE T2,1 ;[2216] Check for only one word
|
||
SKIPN 1(W2) ;[2216] Or second word blank
|
||
JRST LSADLZ ;[2216] Only one word - Done
|
||
MOVX T3,PS.EXO ;[2216] Get the bit indicating extended triplet
|
||
IORM T3,-3(T1) ;[2216] Set it
|
||
MOVNI T1,-1(T2) ;[2216] Negate it, account for first word
|
||
HRL W2,T1 ;[2216] Build AOBJN pointer (low by one word)
|
||
|
||
;[2216] Get another word, and generate a secondary LS triplet for it
|
||
LSADL1: SKIPN 1(W2) ;[2216] Is this blank?
|
||
JRST LSADLD ;[2216] Yes, done
|
||
LSADL2: MOVEI T2,.L ;[2216] Need another triplet
|
||
MOVE T1,LS.FR ;[2216] Number of words free
|
||
SUBI T1,(T2) ;[2216] We need some more for this entry
|
||
JUMPL T1,[PUSHJ P,LS.XPN ;[2216] Get more memory
|
||
JRST LSADL2] ;[2216] Go back
|
||
MOVEM T1,LS.FR ;[2216] Store new count
|
||
MOVE T1,T2 ;[2216] Same number of words
|
||
ADDM T2,LSYM ;[2216] Count extra words
|
||
ADDB T1,LS.PT ;[2216] New actual bound
|
||
TXNE W1,PT.TTL ;[2220] A title block?
|
||
MOVX T2,S.TTL!S.PSN ;[2220] Yes, this is a psect name
|
||
TXNE W1,PT.SYM ;[2220] Symbol?
|
||
MOVX T2,S.SYM!S.LNM ;[2220] Yes, Get the flags for long symbol name
|
||
MOVEM T2,-3(T1) ;[2216] Store the flags
|
||
MOVE T2,1(W2) ;[2216] Get a name word
|
||
MOVEM T2,-2(T1) ;[2216] Store the name word
|
||
AOBJP W2,LSADLD ;[2216] Check for more
|
||
SKIPN T2,1(W2) ;[2216] There's more, get the next one
|
||
JRST LSADLD ;[2216] Null word, done
|
||
MOVEM T2,-1(T1) ;[2216] Store another word
|
||
AOBJN W2,LSADL1 ;[2216] Continue
|
||
LSADLD: MOVX T2,S.LST ;[2216] Get flag indicating end
|
||
IORM T2,-3(T1) ;[2216] Indicate end
|
||
LSADLZ: POP P,W2 ;[2216] Restore count and pointer
|
||
POPJ P, ;[2216] Done
|
||
;HERE IF WE HAVE TO EXPAND
|
||
|
||
LS.XPN: PUSHJ P,.SAVE2## ;SAVE PRESERVED ACCS
|
||
PUSH P,T2 ;SAVE WORD COUNT
|
||
MOVEI P1,LS.IX ;LOCAL SYMBOL AREA
|
||
MOVE P2,T2 ;NUMBER OF WORDS REQUIRED
|
||
SUB P2,LS.FR ;LESS WHAT WE HAVE
|
||
PUSHJ P,LNKCOR ;GENERAL CORE EXPANDER
|
||
PUSHJ P,E$$MEF## ;[1174] CANNOT EXPAND ANY MORE
|
||
POP P,T2
|
||
POPJ P,
|
||
;HERE TO ADD EXTENDED SYMBOL TRIPLETS (COMMON FOR INSTANCE)
|
||
;ENTER WITH P1 CONTAINING A RELATIVE POINTER INTO THE GS AREA
|
||
;RETURNS WITH P1 FIXED IN CORE.
|
||
|
||
;[2310] NOTE - CURRENTLY ONLY HANDLES ONE EXTENDED SECONDARY
|
||
|
||
LS.ADE::SPUSH <W1,W2,W3> ;[2310] Save symbol ACs
|
||
ADD P1,GS.LB ;[2310] Find the global symbol
|
||
MOVE W3,2(P1) ;[2310] Get GS area value
|
||
SUB P1,GS.LB ;[2310] Relocate pointer
|
||
PUSHJ P,LS.ADD ;[2310] Put in the symbol
|
||
ADD P1,GS.LB ;[2310] Find the global symbol
|
||
TMOVE W1,.L(P1) ;[2310] Get the secondary
|
||
TLNN W2,770000 ;[2310] Long symbol?
|
||
MOVE W2,(W2) ;[2310] Yes, make short
|
||
PUSHJ P,LS.ADD ;[2310] Insert it too
|
||
SPOP <W3,W2,W1> ;[2310] Restore symbol ACs
|
||
POPJ P, ;[2310] Done
|
||
|
||
;HERE IF USER TYPED /NOINITIAL. IF USER TYPES /SET, /COMMON, ETC. BEFORE
|
||
;LOADING ANYTHING, THEN WE NEED TO INSERT A MODULE NAME SO SYMBOLS WILL
|
||
;NOT OCCUR OUTSIDE OF A MODULE. USE THE SYMBOL NAME FOR THE MODULE NAME.
|
||
|
||
LS.CHK: MOVE T1,LSYM ;[1143] GET SIZE OF LS AREA SO FAR
|
||
CAIN T1,1 ;[1143] EMPTY?
|
||
TXNN W1,PT.SYM ;[1143] YES, BUT IS THIS A SYMBOL?
|
||
POPJ P, ;[1143] NO, NOT THE SPECIAL CASE
|
||
MOVEM T1,NAMPTR ;[1143] CREATING A NEW MODULE
|
||
AOS PRGNO ;[1143] REMEMBER ONE MORE
|
||
SPUSH <W1,W3,T2> ;[1143] SAVE CALLER'S ARGS
|
||
MOVX W1,PT.SGN!PT.TTL ;[1143] THIS IS A TITLE
|
||
SETZ W3, ;[1143] NO PREVIOUS PTR
|
||
PUSHJ P,LSADD ;[1143] INSERT IN LS AREA
|
||
SPOP <T2,W3,W1> ;[1143] RESTORE ACS
|
||
SETZM LSTGBL ;[2255] SINCE NOT REALLY A SYMBOL
|
||
SETZM LSTLCL ;[2255] ZERO THE LAST SYMBOL POINTERS
|
||
POPJ P, ;[1143] RETURN TO LS.ADD OR LS.ADE
|
||
SUBTTL GLOBAL SYMBOL STORE
|
||
|
||
|
||
;HERE WHEN SYMBOL MUST BE PUT IN TABLE
|
||
;POINTERS IN P1 _ P4
|
||
;SYMBOL STILL IN W1, W2, W3
|
||
|
||
SY.GS0::PUSHJ P,INSRT ;PUT CURRENT SYMBOL IN GLOBAL TABLE
|
||
MOVEI T2,.L ;ONLY 3 WORDS LONG
|
||
IFN FTOVERLAY,<
|
||
TXNN W1,PS.BGS ;A BOUND SYMBOL?
|
||
>
|
||
SKIPE NOSYMS ;NOT IN LOCAL IF NOT WANTED
|
||
POPJ P,
|
||
PJRST LS.ADD ;PUT IN LOCAL SYMBOL FILE
|
||
|
||
INSRT:: SKIPE @HT.PTR ;IS THERE A ZERO IN TABLE
|
||
JRST E$$SIF ;[1174] NO, ERROR, SHOULD NEVER HAPPEN
|
||
|
||
INSRT0: AOS GSYM ;COUNT SYMBOL
|
||
SOS HSPACE ;AND DECREMENT SPACE IN HASH TABLE
|
||
.JDDT LNKLOD,INSRT0,<<CAMN W2,$SYMBOL>> ;ARE WE LOOKING FOR THIS SYMBOL?
|
||
TLNN W2,770000 ;[2216] Do we have a long symbol name?
|
||
JRST INSRTE ;[2216] Yes so let's set it up
|
||
INSRTS: TXNE W1,PT.EXT ;[2216] Triplet has secondaries?
|
||
JRST INSRTL ;[2216] Yes, just move pointers
|
||
MOVEI T2,.L ;[2216] Number of words required
|
||
PUSHJ P,GS.GET## ;GO GET THEM
|
||
TMOVEM W1,0(T1) ;STORE TRIPLET SYMBOL
|
||
INSRT1: SUB T1,NAMLOC ;GET OFFSET TO NAMTAB
|
||
HRL T1,P3 ;HASH TOTAL IN LEFT HALF
|
||
MOVEM T1,@HT.PTR ;HASH TOTAL,,REL ADDRESS OF SYMBOL
|
||
TXNN W1,PS.GLB ;[2255] DEFINING A GLOBAL?
|
||
POPJ P, ;[2255] NO, RETURN
|
||
HRRZM T1,LSTGBL ;[2255] YES, STORE POINTER TO IT
|
||
SETZM LSTLCL ;[2255] NO LAST LOCAL (YET)
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
;HERE IF SYMBOL IS EXTENDED
|
||
;SYMBOL IS ALREADY IN CORE POINTER NEED ADJUSTING AND W3 RESET
|
||
|
||
INSRTL: MOVE T1,W3 ;W3 POINTS TO INCORE BLOCK
|
||
ADD T1,NAMLOC ;RELATIVE TO GS.LB
|
||
MOVE W3,2(T1) ;RESTORE W3 (VALUE)
|
||
JRST INSRT1 ;PUT IN HASH TABLE
|
||
|
||
;[2216] Here for long symbol. Put it in memory
|
||
INSRTE: HLR T1,W2 ;[2216] Count of words in symbol name
|
||
MOVNS T1 ;[2216] Make it negative for aobjn pointer
|
||
HRLS T1 ;[2216] Into the left half
|
||
HRR T1,W2 ;[2216] Address of symbol in the right half
|
||
INSRTZ: SKIPE (T1) ;[2216] Zero word?
|
||
AOBJN T1,INSRTZ ;[2216] No look at the next
|
||
HLRES T1 ;[2216] See it they were all contained sym name
|
||
HLRZ T2,W2 ;[2216] Get the original word count
|
||
ADD T2,T1 ;[2216] Add (neg) count left from the aobjn
|
||
CAIG T2,1 ;[2216] Actually a short symbol?
|
||
JRST [MOVE W2,(W2) ;[2216] Yes, get the symbol
|
||
JRST INSRTS] ;[2216] Use the short symbol code
|
||
HRL W2,T2 ;[2216] Put the count of non-zero words in w2
|
||
PUSHJ P,GS.GET## ;[2216] Get that many words from the gs area
|
||
HRL T3,W2 ;[2216] BLT source address
|
||
HRR T3,T1 ;[2216] BLT dest address
|
||
ADD T2,T1 ;[2376] Add number of word to dest address
|
||
SUBI T2,1 ;[2376] Last location to load into
|
||
BLT T3,(T2) ;[2216] Go ahead and move it
|
||
SUB T1,GS.LB ;[2216] Make gs address relative
|
||
HLL T1,W2 ;[2216] Put in the size
|
||
PUSH P,T1 ;[2216] Save the size,,GS pointer
|
||
TXNE W1,PT.EXT ;[2216] Triplet has secondaries?
|
||
JRST INSRTM ;[2216] Yes, just move pointers
|
||
MOVEI T2,.L ;[2216] Number of words required
|
||
PUSHJ P,GS.GET## ;[2216] Go get them
|
||
MOVEM W1,0(T1) ;[2216] Store triplet symbol flags
|
||
POP P,1(T1) ;[2216] And the size,,GS pointer
|
||
MOVEM W3,2(T1) ;[2216] And the value
|
||
JRST INSRT1 ;[2216] Remember this symbol
|
||
|
||
;[2216] Here for long symbol in extended triplet. The triplets are
|
||
;[2216] already in the GS area, but the name pointer points to the
|
||
;[2216] DY area or static memory. Fix the pointer in the primary
|
||
;[2216] triplet.
|
||
INSRTM: MOVE T1,W3 ;[2216] W3 Points to incore block
|
||
ADD T1,GS.LB ;[2216] Relative to gs.lb
|
||
POP P,1(T1) ;[2216] Insert the pointer to the symbol
|
||
MOVE W3,2(T1) ;[2216] Restore W3 (value)
|
||
JRST INSRT1 ;[2216] PUT IN HASH TABLE
|
||
|
||
E$$SIF::.ERR. (MS,0,V%L,L%F,S%F,SIF,<Symbol insert failure, non-zero hole found>) ;[1174]
|
||
SUBTTL SATISFY GLOBAL REQUESTS
|
||
|
||
|
||
;HERE TO SATISFY GLOBAL REQUESTS WITH DEFINED VALUE
|
||
;FLAGS IN W1
|
||
;VALUE IN W3
|
||
;ALL CHAINED REQUESTS ARE RIGHT-HALF FIXUPS
|
||
;P1-P4 ARE NOT SAVED BY THIS ROUTINE
|
||
|
||
SY.RF:: SOSGE USYM ;DECREMENT UNDEFINED GLOBAL COUNT
|
||
PUSHJ P,E$$DUZ ;[1174] BUT NOT TOO FAR
|
||
TRNE FL,R.FHS ;ARE RC TABLES SCREWED UP?
|
||
JRST SY.FHS ;YES, RESTORE THEM FOR FIXUPS
|
||
TRNE FL,R.FLS ;BUT MUST SAVE THEM IF RESTORED
|
||
JRST SY.FLS ;SINCE OTHERS DEPEND ON THEM
|
||
;BOTH SY.FHS & SY.FLS RETURN HERE WITH A PUSHJ
|
||
SY.FXX: IORM W1,0(P1) ;SEE WHAT WE HAVE IN FLAGS
|
||
MOVX W1,PS.UDF!PS.REQ ;DON'T NEED THESE NOW
|
||
ANDCAB W1,0(P1) ;SO CLEAR FROM MEMORY
|
||
MOVE T2,2(P1) ;PICKUP ADDRESS
|
||
MOVEM W3,2(P1) ;STORE VALUE
|
||
PUSHJ P,SY.CHR ;CHAIN THROUGH RIGHT HALF
|
||
MOVEI T2,.L ;STORE SYMBOL BEFORE WE LOSE IT
|
||
TXNE W1,PS.COM ;IF COMMON NEED TWO TRIPLETS
|
||
JRST [ADDI T2,.L
|
||
SUB P1,GS.LB ;[654] MAKE POINTER RELATIVE
|
||
PUSHJ P,LS.ADE ;STORE MULTIPLE WORD
|
||
JRST .+2] ;SKIP NEXT INST.
|
||
PUSHJ P,LS.ADD ;IN LOCAL TABLE
|
||
TXNN W1,PS.FXP ;ANY FIXUPS FOR THIS SYMBOL?
|
||
POPJ P, ;NO
|
||
JRST SY.RF1 ;YES
|
||
|
||
E$$DUZ::.ERR. (MS,,V%L,L%F,S%F,DUZ,<Decreasing undefined symbol count below zero>) ;[1174]
|
||
|
||
SY.FHS: SKIPA T1,[1] ;LOW SEG HAS BEEN FAKED
|
||
SY.FLS: MOVEI T1,2 ;HI SEG FAKED IF /SEG:LOW
|
||
HRR R,T1 ;SETUP R FOR SG.TB; PRESERVE LH
|
||
MOVE T1,@SG.TB ;GET REAL VALUE FOR RC TABLE
|
||
EXCH T1,@RC.TB ;RESTORE IT, GET FAKE VALUE
|
||
PUSH P,T1 ;SAVE FAKE VALUE TO RESTORE LATER
|
||
PUSH P,R ;REMEMBER WHICH SEGMENT
|
||
PUSH P,LL.S2 ;LL.S2 WAS ALSO FAKED BY T.3
|
||
HRRZS LL.S2 ;IF WE ARE LOADING F10, THAT IS
|
||
PUSHJ P,SY.FXX ;RE-JOIN SY.RF TILL IT POPJS
|
||
|
||
;HERE WHEN SY.RF RETURNS. RESTORE FORCED LOADING MODE.
|
||
POP P,LL.S2 ;RESTORE LL.S2
|
||
POP P,R ;REMEMBER WHICH COUNTER WE GRABBED
|
||
POP P,@RC.TB ;AND RESTORE IT
|
||
POPJ P, ;RETURN FROM SY.RF
|
||
SUBTTL SATISFY ADDDITIVE GLOBALS
|
||
|
||
|
||
;HERE FOR ADDITIVE GLOBALS
|
||
;THE ADDDITIVE GLOBAL REQUESTS ARE STORED IN LINKED LISTS IN AREA FX
|
||
;THE INITIAL POINTER TO THEM IS IN AN EXTENDED TRIPLET IN AREA GS
|
||
|
||
SY.RF1: HRRZ P1,@HT.PTR ;SETUP P1 AGAIN
|
||
ADD P1,NAMLOC ;ABSOLUTE
|
||
SY.RF2: HLLZ T1,0(P1) ;GET FLAGS AGAIN
|
||
TXNN T1,PS.REL ;IF THIS SYMBOL IS RELOCATABLE
|
||
TDZA T1,T1 ;NO
|
||
ANDX T1,PS.REL ;ALL THOSE DEPENDING ON IT ARE TOO
|
||
MOVEM T1,SYMFLG ;STORE INCASE SYMBOL TABLE FIXUPS
|
||
SYRF2A: ADDI P1,.L ;POINT TO EXTENDED SYMBOL
|
||
MOVE T1,0(P1) ;GET FLAGS
|
||
JUMPL T1,CPOPJ ;FINISHED IF PRIMARY SYMBOL
|
||
TXNE T1,S.FXP ;[2037] This triplet a fixup request?
|
||
JRST SYRF2B ;[2037] Yes
|
||
TXNN T1,S.LST ;[2037] Is this the last secondary?
|
||
JRST SYRF2A ;[2037] No, try next
|
||
POPJ P, ;[2037] Yes, no additive fixups here
|
||
SYRF2B: MOVE T1,P1 ;[2037] Remember where we are
|
||
SUB T1,NAMLOC
|
||
PUSH P,T1 ;SO WE CAN DELETE FIXUP REQUEST WHEN DONE
|
||
MOVE P1,2(P1) ;GET POINTER TO FIXUP
|
||
SY.RF3: .JDDT LNKLOD,SY.RF3,<<CAMN P1,$FIXUP##>> ;[632]
|
||
PUSH P,P1 ;SAVE ADD OF FIXUP BLOCK
|
||
ADD P1,FX.LB ;IN CORE
|
||
MOVE W1,(P1) ;GET FLAGS AND NEXT POINTER
|
||
TXNE W1,FP.POL ;POLISH FIXUP (TYPE 11)?
|
||
JRST [PUSHJ P,SY.PF0 ;YES, SEE IF FIXUP CAN BE DONE
|
||
POP P,P1 ;RESTORE POINTER
|
||
ADD P1,FX.LB ;FIX IN CORE
|
||
JRST SY.RF4] ;AND DELETE THIS REQUEST
|
||
EXCH W2,1(P1) ;[2255] SWAP NAME WITH REQUEST
|
||
EXCH W3,2(P1) ;SWAP VALUE WITH REQUEST
|
||
PUSHJ P,SY.ADG ;DO THIS FIXUP
|
||
POP P,P1 ;RESTORE P1
|
||
ADD P1,FX.LB ;INCASE CORE MOVED
|
||
MOVE W2,1(P1) ;[2255] RESTORE W2
|
||
MOVE W3,2(P1) ;RESTORE W3
|
||
SY.RF4: MOVE T1,P1 ;FINISHED WITH IT NOW
|
||
MOVEI T2,.L
|
||
PUSHJ P,FX.RET## ;RETURN SPACE
|
||
HRRZ P1,W1 ;GET NEXT REL POINTER
|
||
JUMPE P1,SY.RF5 ;ZERO MARKS END OF CHAIN
|
||
TXNE W1,FP.SYM
|
||
JRST SY.RF3 ;DO THIS ONE
|
||
E$$ISP::.ERR. (MS,,V%L,L%F,S%F,ISP,<Incorrect symbol pointer>) ;[1174]
|
||
|
||
SY.RF5: POP P,T1 ;[2331] GET THE SYMBOL POINTER
|
||
ADD T1,NAMLOC ;[2331] IN CASE MOVED
|
||
PJRST SY.ZST ;[2331] REMOVE THE SECONDARY AND RETURN
|
||
;HERE FOR ADDITIVE GLOBAL REQUEST WITH VALUE ALREADY DEFINED
|
||
|
||
SY.ADG: TXNN W1,FS.FXS ;SYMBOL TABLE FIXUP?
|
||
JRST SY.AD0 ;NO
|
||
OR W1,SYMFLG ;STORE EXTRA FLAGS (PS.REL)
|
||
JRST SY.STF ;YES
|
||
|
||
;HERE TO FILL IN SINGLE ADDITIVE GLOBAL REQUEST
|
||
|
||
SY.AD0::
|
||
TXNE W1,FS.FXC ;RH CHAINED FIXUP?
|
||
JRST SY.ADC ;YES, HANDLE SEPERATELY
|
||
IFN FTOVERLAY,<
|
||
MOVE T1,0(P1) ;GET INCORE FLAGS
|
||
TXNE T1,PS.RBG ;FROM A RELOCATABLE LINK?
|
||
PUSHJ P,RT.FX## ;YES, STORE FIXUP FOR RELOCATION
|
||
>;END OF IFN FTOVERLAY
|
||
TLZ W3,770000 ;[2200] Remove any leftover radix 50 bits
|
||
MOVE T2,W3 ;[2200] GET 30 BIT REL ADDRESS OF FIXUP
|
||
PUSHJ P,SEGCHK ;GET CORE LOCATION
|
||
JRST SY.ADP ;OUT ON DSK (PAGED)
|
||
TXNE W1,FS.FXL ;LEFT HALF FIXUP?
|
||
JRST SY.ADL ;YES
|
||
TXNE W1,FS.FXF ;OR FULL WORD?
|
||
JRST SY.ADF ;YES
|
||
TXNE W1,FS.FXE ;[2214] OR THIRTY BIT?
|
||
JRST SY.ADE ;[2214] YES
|
||
SY.ADR:
|
||
IFN FTOVERLAY,<
|
||
TXNE W1,FS.REL ;RELOCATABLE?
|
||
TXO R,1B1 ;YES, RESET BIT IN R
|
||
PUSHJ P,SY.ADT ;RELOCATABLE OVERLAY?
|
||
JFCL RT.T2R## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
HRRZ T1,(T2) ;GET RIGHT HALF VALUE
|
||
ADD T1,2(P1) ;PLUS DEFINED SYMBOL
|
||
HRRM T1,(T2) ;STORE NEW VALUE
|
||
POPJ P,
|
||
SY.ADL:
|
||
IFN FTOVERLAY,<
|
||
TXNE W1,FS.REL ;RELOCATABLE?
|
||
TXO R,1B0 ;YES, RESET BIT IN R
|
||
PUSHJ P,SY.ADT ;RELOCATABLE OVERLAY?
|
||
JFCL RT.T2L## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
HLRZ T1,(T2) ;GET LEFT HALF VALUE
|
||
ADD T1,2(P1) ;PLUS DEFINED SYMBOL
|
||
HRLM T1,(T2) ;STORE NEW VALUE
|
||
POPJ P,
|
||
|
||
SY.ADF:
|
||
IFN FTOVERLAY,<
|
||
TXNE W1,FS.REL ;RELOCATABLE?
|
||
TXO R,3B1 ;YES, RESET BITS IN R
|
||
PUSHJ P,SY.ADT ;RELOCATABLE OVERLAY?
|
||
JFCL RT.T2F## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
MOVE T1,(T2) ;GET FULL WORD VALUE
|
||
ADD T1,2(P1) ;PLUS DEFINED SYMBOL
|
||
MOVEM T1,(T2) ;STORE NEW VALUE
|
||
POPJ P,
|
||
|
||
SY.ADE: ;[2214] Thirty bit
|
||
IFN FTOVERLAY,< ;[2214]
|
||
TXNE W1,FS.REL ;[2214] Relocatable?
|
||
TXO R,1B1 ;[2214] Yes, reset bits in R
|
||
PUSHJ P,SY.ADT ;[2214] Relocatable overlay?
|
||
JFCL RT.T2E## ;[2214] Yes, set reloc bit correctly
|
||
> ;[2214]
|
||
LDB T1,[ADDRESS(T2)] ;[2214] Get full word value
|
||
ADD T1,2(P1) ;[2214] Plus defined symbol
|
||
DPB T1,[ADDRESS(T2)] ;[2214] Store new value
|
||
POPJ P, ;[2214] Done
|
||
|
||
SY.ADC: MOVE T2,W3 ;RETRIEVE ADDRESS OF CHAIN
|
||
MOVE W3,2(P1) ;GET VALUE TO STORE FOR SY.CHR
|
||
TXNE W1,FS.FXL ;[2305] is it a left half chain?
|
||
PJRST SY.CHL ;[2305] yes - go do it
|
||
TXNE W1,FS.FXE ;[2305] is it a 30 bit chained fixup
|
||
PJRST SY.CHE ;[2305] yes - go do it
|
||
TXNE W1,FS.FXF ;[2305] is it a full word chained fixup
|
||
PJRST SY.CHF ;[2305] yes - go do it
|
||
PJRST SY.CHR ;[2305] must be right half chain GO CHASE CHAIN
|
||
;SY.CHR WILL DO RIGHT THING FOR
|
||
;RELOCATABLE OVERLAYS
|
||
;HERE WHEN REQUIRED ADDRESS IS NOT IN CORE
|
||
;STORE AS A FIXUP REQUEST FOR ADDITIVES, EITHER RH ,LH, OR FULL
|
||
;ENTER WITH R = 1 (LOW), OR R = 2 (HIGH)
|
||
;W1 = FIXUP FLAGS
|
||
;W3 = ADDITIVE REQUEST
|
||
;2(P1) = SYMBOL VALUE
|
||
|
||
;PUT T2 =W3 AND W3 = 2(P1)
|
||
|
||
SY.ADP: MOVE T2,W3 ;EXPECTS ADDRESS IN T2
|
||
MOVE W3,2(P1) ;TRUE VALUE IN W3
|
||
TXNE W1,FS.FXR ;RIGHT HALF FIXUP?
|
||
TXO T2,CPF.AR ;[2200] YES
|
||
TXNE W1,FS.FXL ;LEFT HALF FIXUP
|
||
TXO T2,CPF.AL ;[2200] YES
|
||
TXNE W1,FS.FXF ;FULL WORD?
|
||
TXO T2,CPF.AF ;[2200] YES
|
||
TXNE W1,FS.FXE ;[2214] THIRTY BIT FIXUP?
|
||
TXO T2,CPF.AE ;[2263] YES
|
||
TXNE W1,FS.FXC ;RIGHT HALF CHAINED?
|
||
TXO T2,CPF.CR ;[2200] YES
|
||
PJRST SY.CHP ;LINK IN
|
||
|
||
IFN FTOVERLAY,<
|
||
SY.ADT: SKIPN RT.LB ;IS IT RELOCATABLE
|
||
POPJ P, ;NO
|
||
PUSH P,P1 ;SAVE SYMBOL TABLE PTR
|
||
MOVSI P1,(Z @) ;TURN ON @ IN STACK
|
||
IORM P1,-1(P) ;THERE MUST BE AN EASIER WAY?
|
||
SETZ P1, ;SIGNAL NOT A SYMBOL FIXUP
|
||
HRRZ T2,W3 ;RESET ADDRESS
|
||
PUSHJ P,@-1(P) ;GO TO CORRECT ROUTINE
|
||
POP P,P1 ;RESTORE
|
||
HRRZ T2,W3 ;RESET ADDRESS
|
||
PUSHJ P,SEGCHK ;GET CORE LOCATION
|
||
HALT . ;CAN NOT HAPPEN
|
||
POPJ P, ;AND RETURN
|
||
>
|
||
;HERE FOR SYMBOL TABLE FIXUP
|
||
;CALLED BY
|
||
; MOVE W1,FLAGS
|
||
; MOVE W2,GLOBAL SYMBOL TABLE POINTER [2255]
|
||
; MOVE W3,LOCAL SYMBOL TABLE POINTER [2255]
|
||
; MOVE P1,POINTER TO DEFINING TRIPLET (GS OR FX)
|
||
; PUSHJ P,SY.STF
|
||
;USES T1 - T4
|
||
|
||
SY.STF::SPUSH <W3,W2,W1,P1> ;SAVE ALL VALUES NEEDED LATER
|
||
SYSTF1: MOVE T1,W2 ;[2255] GET GLOBAL ADDRESS
|
||
JUMPE T1,SYSTFL ;NO GLOBAL FIXUP REQUIRED
|
||
TXNE W1,FS.MDC ;[1213] ONLY WANT TO COMPARE VALUES?
|
||
JRST [MOVE T1,P1 ;[1213] YES, USE DEFINING TRIPLET AS VALUE
|
||
JRST SYSTFC] ;[1213] SKIP SEARCH FOR S.PVS TRIPLET
|
||
ADD T1,NAMLOC ;RELOCATE
|
||
MOVE T3,0(T1) ;GET FLAGS
|
||
TXNN T3,PT.OTH ;NOT SYMBOL?
|
||
JRST SYSTF3 ;YES IT IS
|
||
TXNN T3,PO.IND ;INDIRECT POINTER PERHAPS?
|
||
PUSHJ P,E$$ISP ;[1174] NO???
|
||
MOVE W2,2(T1) ;[2255] RESET REAL POINTER
|
||
MOVEM W2,-2(P) ;[2255] KEEP STACK UP TO DATE
|
||
MOVEI T2,.L ;AND GET RID OF THIS DUMMY BLOCK
|
||
PUSHJ P,GS.RET##
|
||
JRST SYSTF1 ;TRY AGAIN
|
||
|
||
SYSTF2: TXNE T3,S.LST ;MORE TO COME?
|
||
PUSHJ P,E$$ISP ;[1174] NO, NO PVS TRIPLET???
|
||
|
||
SYSTF3: ADDI T1,.L ;LOOK AT NEXT TRIPLET
|
||
SKIPG T3,0(T1) ;PICK UP FLAGS
|
||
PUSHJ P,E$$ISP ;[1174] MUSN'T BE PRIMARY
|
||
TXNN T3,S.PVS ;FOUND THE PVS TRIPLET?
|
||
JRST SYSTF2 ;NO, KEEP LOOKING
|
||
|
||
;FALL THROUGH TO NEXT PAGE
|
||
;HERE WITH ABSOLUTE POINTER TO PVS TRIPLET IN T1. DEFINE GLOBAL SYMBOL.
|
||
|
||
MOVE T2,W1 ;GET FIXUP FLAGS FOR SY.AST
|
||
MOVE W3,2(P1) ;[572] AND FIXUP VALUE
|
||
PUSHJ P,SY.AST ;SET 2(T1) TO REAL VALUE
|
||
SYSTFC: MOVX T3,PS.UDR ;[1213] ASSUME RH FIXUP
|
||
TXNE W1,FS.FXL ;LEFT HALF?
|
||
TXC T3,PS.UDF ;YES, MAKE DEFINITION LH TOO
|
||
TXNN W1,FS.FXF ;[2214] UNLESS FULL WORD
|
||
TXNE W1,FS.FXE ;[2214] OR 30 BIT
|
||
TXO T3,PS.UDF ;IN WHICH CASE WE'RE DEFINING ALL
|
||
MOVE T2,-2(P) ;[2255] RESTORE PRIMARY TRIPLET ADDR
|
||
ADD T2,NAMLOC ;MAKE ABSOLUTE
|
||
MOVE T4,T3 ;[612] COPY OF BITS BEING DEFINED
|
||
AND T4,0(T2) ;[612] WHICH OF THOSE ARE NOW UNDEFINED
|
||
CAME T3,T4 ;[612] ANYTHING WE'RE DEFINING KNOWN?
|
||
JRST SYSTFM ;YES, MULTIPLE DEFINITION
|
||
PUSHJ P,SYSTFF ;SET FLAGS AT 0(T2) PROPERLY
|
||
TXNE T3,PS.UDF ;STILL UNDEFINED ANYWHERE?
|
||
JRST SYSTFL ;YES, GIVE UP FOR NOW
|
||
SOSGE USYM ;NO, DECREMENT USYM
|
||
PUSHJ P,E$$DUZ ;[1174] BUT NOT TOO FAR
|
||
MOVE W3,2(T1) ;GET NOW-DEFINED VALUE
|
||
MOVE P1,T2 ;POINT TO PRIMARY OF NEW SYMBOL
|
||
TXNN W1,FS.MDC ;[1213] DON'T ZAP S.PVS IF WE DIDN'T USE IT
|
||
PUSHJ P,SY.ZST ;AND ZAP 2NDARY 3RPLET
|
||
MOVE W1,0(P1) ;GET FLAGS FOR SY.FXP
|
||
PUSHJ P,SY.FXP ;GO DO ALL DEFINITIONS
|
||
JRST SYSTFL ;AND CORRECT LS AREA TRIPLET
|
||
|
||
;HERE IF WE FOUND A MULTIPLE DEFINITION, WITH T1 POINTING TO PRIMARY,
|
||
;AND T2 POINTING TO S.PVS TRIPLET. WARN USER AND DISCARD NEW VALUE.
|
||
|
||
SYSTFM: MOVE P1,T2 ;STORE P.T. ADDR IN P1 FOR SY.MDF
|
||
MOVE T4,0(T2) ;GET STILL UNDEF BITS IF ANY
|
||
MOVE T2,2(T1) ;NEW SYMBOL VALUE
|
||
TXNE T3,PS.UDR ;NOT DEFINING RH?
|
||
TXNE T4,PS.UDR ;RH STILL UNKNOWN?
|
||
HRR T2,2(P1) ;YES, CAN'T BE MULTIPLE DEFINITION
|
||
TXNE T3,PS.UDL ;SAME CASE FOR LH
|
||
TXNE T4,PS.UDL ;ONLY GIVE MDS IF CONFLICT
|
||
HLL T2,2(P1) ;NOW HAVE ADJUSTED NEW VAL IN T2
|
||
CAMN T2,2(P1) ;MULTIPLE DEFINITION?
|
||
JRST SYSTFL ;NO (WHAT LUCK!) GO FIX LS AREA
|
||
DMOVE W1,0(P1) ;YES, SET NEW TRIPLET FROM OLD
|
||
MOVE W3,2(T1) ;BUT WITH DIFFERENT VALUE
|
||
PUSHJ P,SY.MDF ;WARN USER OF BUG
|
||
SKIPA T4,[PS.MDF] ;FLAG TO SET IN LOCAL TABLE
|
||
|
||
;SKIP THROUGH TO FIXUP LOCAL TABLE
|
||
;HERE TO FIX THINGS UP IN THE LOCAL SYMBOL TABLE
|
||
|
||
SYSTFL: MOVEI T4,0 ;NORMAL ENTRY, NOT MDS
|
||
PUSH P,T4 ;REMEMBER FOR AFTER SYSTF4 RETURNS
|
||
MOVE P1,-1(P) ;RESTORE EVERYTHING
|
||
MOVE W1,-2(P) ;. .
|
||
MOVE W2,-3(P) ;. .
|
||
MOVE W3,-4(P) ;. .
|
||
PUSHJ P,SYSTF4 ;GO FIXUP LOCAL TABLE
|
||
SPOP <T4,P1,W1,W2,W3> ;RESTORE THINGS FOR POSTERITY
|
||
MOVE T2,W3 ;[2255] GET RELATIVE LS ADDRESS
|
||
JUMPE T2,CPOPJ ;[572] GIVE UP IF NONE
|
||
CAML T2,LW.LS ;[572] IS IT STILL IN CORE?
|
||
IORM T4,0(T1) ;YES, SET MULTIPLY DEFINED
|
||
POPJ P, ;DONE
|
||
|
||
SYSTF4: MOVE T2,W3 ;[2255] GET ADDRESS IN LOCAL TABLE
|
||
JUMPE T2,CPOPJ ;FORGET IT IF NOT IN LOCAL TABLE
|
||
CAMGE T2,LW.LS ;STILL IN CORE?
|
||
JRST SY.STP ;NO, GO GENERATE FIXUP
|
||
ADD T2,LS.LB ;YES, MAKE ABSOLUTE ADDRESS
|
||
SUB T2,LW.LS ;IN CASE PAGING
|
||
MOVX T3,PS.UDR ;ASSUME RH FIXUP
|
||
TXNE W1,FS.FXL ;LEFT HALF?
|
||
TXC T3,PS.UDF ;YES, MAKE DEFINITION LH TOO
|
||
TXNN W1,FS.FXF ;[2214] UNLESS FULL WORD
|
||
TXNE W1,FS.FXE ;[2214] OR THIRTY BIT
|
||
TXO T3,PS.UDF ;IN WHICH CASE WE'RE DEFINING ALL
|
||
PUSHJ P,SYSTFF ;SET FLAGS AT 0(T2) CORRECTLY
|
||
MOVE T1,T2 ;T1 POINTS TO LS TRIPLET
|
||
MOVE T2,W1 ;T2 CONTAINS FIXUP FLAGS
|
||
MOVE W3,2(P1) ;[572] W3 IS ADDITIVE DEFINITION
|
||
PJRST SY.AST ;GO FIXUP LS TRIPLET
|
||
|
||
;HERE TO SET THE FLAGS AT 0(T2) FROM T3 & W1
|
||
SYSTFF: ANDCAB T3,0(T2) ;ZAP BITS NOW DEFINED
|
||
MOVX T4,PS.REQ ;HOPE WE CAN CLEAR THIS NOW
|
||
TXNN T3,PS.UDF ;ONLY IF COMPLETELY DEFINED
|
||
ANDCAM T4,0(T2) ;GOT IT!
|
||
MOVX T4,PS.REL ;MUST ALSO SET RELOC IF OTHER WAS
|
||
TXNE W1,FS.REL ;WAS IT?
|
||
IORM T4,0(T2) ;YES, SO NEW SYMBOL IS TOO
|
||
POPJ P, ;RETURN WITH T3 SET UP
|
||
;HERE FOR POLISH FIXUPS CAUSED BY A BLOCK TYPE 11
|
||
;CONTAINING ONE OR MORE UNDEFINED GLOBAL SYMBOLS
|
||
;REPLACE THE NOW DEFINED SYMBOL BY ITS VALUE
|
||
;IF MORE UNDEFS EXIST GIVE UP
|
||
;IF ALL SYMBOLS ARE DEFINED DO FIXUP
|
||
|
||
SY.PF0: MOVE T4,2(P1) ;GET REL ADDRESS OF POLISH BLOCK
|
||
ADD T4,FX.LB ;ADD BASE
|
||
MOVE T1,(T4) ;[2212] GET THE HEADER WORD
|
||
TXNE T1,FF.NEW ;[2212] NEW STYLE POLISH BLOCK?
|
||
JRST SY.NPF ;[2212] YES
|
||
HRLI T4,(POINT 18) ;FORM BYTE POINTER
|
||
ADDI T4,2 ;BYPASS HEADER AND GLOBAL COUNT
|
||
SKIPA T3,T4 ;USE T3 AS CURRENT, T4 AS INITAL
|
||
SYPF1: IBP T3 ;BYPASS NEXT HALF WORD
|
||
SYPF2: ILDB T1,T3 ;READ HALF WORD
|
||
CAIL T1,MXPLOP## ;[712] CHECK FOR VALID OPS
|
||
JRST [CAIGE T1,600000 ;[2203] PSECT INDEX?
|
||
JRST SYPF2 ;[2203] YES, SKIP IT
|
||
CAIGE T1,610000 ;[2203] NEW STYLE HALFWORD FETCH?
|
||
JRST SYPF1 ;[2203] YES, IGNORE NEXT HALFWORD TOO
|
||
POPJ P,] ;[712] STORE OPERATOR, IGNORE, NOT ALL DEFINED
|
||
CAIL T1,3 ;IF OPERATOR
|
||
JRST SYPF2 ;IGNORE IT
|
||
CAIN T1,1 ;36 BIT VALUE?
|
||
AOJA T3,SYPF2 ;YES, GET NEXT HALF WORD AFTER IT
|
||
;HERE IF T1=2, GLOBAL SYMBOL REQUEST
|
||
ILDB T1,T3 ;GET FIRST PART OF SYMBOL
|
||
HRLZ T2,T1 ;STORE LEFT HALF PART OF SYMBOL
|
||
ILDB T1,T3 ;GET RIGHT HALF PART
|
||
HRR T2,T1 ;FULL SYMBOL IN W2
|
||
CAME T2,W2 ;IS THIS THE SYMBOL NOW DEFINED?
|
||
JRST SYPF2 ;NO
|
||
SUBI T3,2 ;BACKUP BYTE POINTER
|
||
IBP T3 ;TO POINT TO 2
|
||
MOVEI T1,1 ;CHANGE GLOBAL MARKER INTO 36 BIT VALUE MARKER
|
||
IDPB T1,T3
|
||
MOVS T1,W3 ;GET VALUE
|
||
IDPB T1,T3 ;STORE IT
|
||
MOVSS T1
|
||
IDPB T1,T3 ;T3 BACK AS IT WAS
|
||
SOSE -1(T4) ;ALL UNDEFS NOT DEFINED?
|
||
POPJ P, ;[2212] NO, CAN'T EVALUATE THIS TIME
|
||
;NOW TO EVALUATE POLISH FIXUP
|
||
;USE T.11EV (IN LNKOLD)
|
||
;THIS USES W1, W2, W3 FOR NON-SYMBOL USE
|
||
SPUSH <W1,W2,W3> ;SAVE SYMBOL ACCS
|
||
SUB T4,FX.LB ;UNRELOCATE
|
||
MOVEM T4,T11BP ;SETUP BYTE POINTER
|
||
MOVE T1,2(P1) ;ADDRESS OF POLISH BLOCK
|
||
ADD T1,FX.LB ;MAKE ABSOLUTE
|
||
HRLZ T1,0(T1) ;BLOCK LENGTH
|
||
HRRI T1,-2(T4) ;START ADDRESS OF BLOCK
|
||
MOVEM T1,T11FA
|
||
PUSHJ P,T.11EV## ;EVALUATE
|
||
SPOP <W3,W2,W1> ;RESTORE ACCS
|
||
POPJ P,
|
||
|
||
|
||
;[2212] Here to handle new style (1072) polish fixup blocks
|
||
SY.NPF: PUSH P,P1 ;[2212] Save some AC's which are used as
|
||
PUSH P,P2 ;[2212] temporaries in the EXTEND instructions
|
||
PUSH P,P3 ;[2212] Save a place for the pointer
|
||
PUSH P,P4 ;[2212] And another place for T1072E
|
||
MOVEI P3,2(T4) ;[2212] Get the start of the polish
|
||
HRLI P3,(POINT 18) ;[2212] Make it a byte pointer
|
||
SKIPA P4,P3 ;[2212] Keep the pointer to the beginning
|
||
SYNP0: IBP P3 ;[2212] Eat a halfword
|
||
SYNP1: ILDB T1,P3 ;[2212] Get the next halfword
|
||
CAIL T1,PL.NSO ;[2212] Store operator (new style)
|
||
JRST SYNPR ;[2212] Yes, Go pop and return
|
||
CAIL T1,PL.NEW ;[2212] Halfword data operator?
|
||
JRST SYNP0 ;[2212] Yes, eat the next halfword
|
||
CAIL T1,PL.IL ;[2212] Psect index?
|
||
JRST SYNP1 ;[2212] Yes, ignore it
|
||
JUMPE T1,SYNP0 ;[2212] If absolute halfword eat 1 halfword
|
||
CAIE T1,PL.ABF ;[2212] Fullword absolute?
|
||
CAIN T1,PL.RLF ;[2212] Or fullword relocatable?
|
||
AOJA P3,SYNP1 ;[2212] Yes, ignore the next 2 halfwords
|
||
CAIL T1,PL.OL ;[2212] Too low for operator?
|
||
CAILE T1,PL.OH ;[2212] Or too high?
|
||
CAIA ;[2212] Not an operator
|
||
JRST SYNP1 ;[2212] An operator, ignore it
|
||
|
||
;[2212] Here if a symbol. Figure out whether a long symbol test is
|
||
;[2212] needed.
|
||
|
||
LSH T1,-^D9 ;[2212] Get the count
|
||
TLNN W2,770000 ;[2212] Short symbol
|
||
JRST SYNPL ;[2212] Long symbol, must compare strings
|
||
|
||
;[2212] Check special case of long symbol in polish block. Must be
|
||
;[2212] compared anyways because symbol in polish block could be short
|
||
;[2212] symbol padded with null halfwords.
|
||
|
||
CAILE T1,1 ;[2212] Short symbol (or converted radix-50)?
|
||
JRST SYNPS ;[2212] No, it's special
|
||
|
||
;[2212] Here for a short symbol compare. Build the symbol in an AC
|
||
;[2212] and do a simple compare.
|
||
ILDB T2,P3 ;[2212] Get a symbol halfword
|
||
ILDB T1,P3 ;[2212] And another
|
||
HRL T1,T2 ;[2212] Build entire symbol
|
||
CAME T1,W2 ;[2212] This the symbol?
|
||
JRST SYNP1 ;[2212] No, try some more
|
||
SUBI P3,2 ;[2212] Back up the byte pointer
|
||
IBP P3 ;[2212] By three bytes
|
||
MOVEI T2,PL.ABF ;[2212] Get absolute fullword code
|
||
IDPB T2,P3 ;[2212] Store it
|
||
HLR T2,W3 ;[2212] Get the high order value
|
||
IDPB T2,P3 ;[2212] Store it
|
||
IDPB W3,P3 ;[2212] Store the low order value
|
||
JRST SYNPE ;[2212] See if ready to evaluate
|
||
|
||
;[2212] Here to compare a short symbol and a long one. Build a pointer
|
||
;[2212] to the short symbol and use the long symbol code.
|
||
SYNPS: MOVEI T4,2 ;[2212] Count two halfwords for symbol
|
||
MOVE P1,[POINT 18,W2] ;[2212] Symbol is in W2
|
||
JRST SYNPX ;[2212] Join the long symbol code
|
||
|
||
;[2212] Here for long symbols. Set up and do a string compare.
|
||
;[2212] T1 and T2 contain the count and pointer for the polish block.
|
||
;[2212] T4 and P1 contain the count and pointer for the symbol.
|
||
;[2212] Also adjust the byte pointer to the end of the symbol.
|
||
SYNPL: HRR P1,W2 ;[2212] Get the address of the symbol
|
||
ADD P1,GS.LB ;[2212] Make it absolute
|
||
HRLI P1,(POINT 18,) ;[2212] Get the pointer
|
||
HLR T4,W2 ;[2212] Get the count (in words)
|
||
ADD T4,T4 ;[2212] Make count into halfwords
|
||
SYNPX: ADDI T1,1 ;[2212] Get a correct count
|
||
PUSH P,P3 ;[2212] Save the pointer in case of match
|
||
PUSH P,T1 ;[2212] And the length
|
||
MOVE T2,P3 ;[2212] Get the pointer to the string
|
||
MOVE T3,P3 ;[2212] Get the pointer
|
||
MOVE P3,T1 ;[2212] Get the count
|
||
ADJBP P3,T3 ;[2212] Point at the end of the string
|
||
EXTEND T1,[CMPSE ;[2212] Do the string compare
|
||
0 ;[2212] Pad with zeros if either string
|
||
0] ;[2212] runs out.
|
||
JRST [POP P,(P) ;[2212] Not the same, toss the count
|
||
POP P,(P) ;[2212] And the old pointer
|
||
JRST SYNP1] ;[2212] Keep looking
|
||
POP P,T1 ;[2212] Get the count
|
||
POP P,T2 ;[2212] And the pointer
|
||
MOVEI T3,PL.ABF ;[2212] Get the code for absolute fullword
|
||
DPB T3,T2 ;[2212] Store it
|
||
HLR T3,W3 ;[2212] Get the value (left half)
|
||
IDPB T3,T2 ;[2212] Store it
|
||
IDPB W3,T2 ;[2212] Store the right half of the value
|
||
|
||
MOVEI T3,PL.IL ;[2212] Get a psect index (no-op)
|
||
SUBI T1,2 ;[2212] Account for the two stored halfwords
|
||
SYNPZ: IDPB T3,T2 ;[2212] Overwrite a symbol halfword
|
||
SOJG T1,SYNPZ ;[2212] Clear all extra symbol halfwords
|
||
; JRST SYNPE ;[2212] See if ready to evaluate
|
||
|
||
;[2212] Here to decide whether to evaluate. Evaluate if the last
|
||
;[2212] Global in the block has just been defined.
|
||
|
||
SYNPE: SOSE -1(P4) ;[2212] Count one more defined, last one?
|
||
JRST SYNPR ;[2212] No, can't evaluate this time
|
||
|
||
;[2212] Here to evaluate a new-style polish fixup. The evaluation
|
||
;[2212] is done in T1072E in LNKNEW.
|
||
SPUSH <W1,W2,W3> ;[2212] Save the symbol ACs
|
||
HRRZI T1,-2(P4) ;[2212] Get address of beginning of block
|
||
SUB P4,FX.LB ;[2212] Relocate
|
||
MOVEM P4,T11BP ;[2212] Save the byte pointer
|
||
HRL T1,0(T1) ;[2212] Get the count
|
||
SUB T1,FX.LB ;[2212] Relocate, make count,,address in FX
|
||
MOVEM T1,T11FA ;[2212] Save it
|
||
PUSHJ P,T1072E## ;[2212] Evaluate the polish block
|
||
SPOP <W3,W2,W1> ;[2212] Restore the symbol ACs
|
||
SYNPR: POP P,P4 ;[2212] Restore the ACs
|
||
POP P,P3 ;[2212]
|
||
POP P,P2 ;[2212]
|
||
POP P,P1 ;[2212]
|
||
POPJ P, ;[2212] And return
|
||
|
||
|
||
;HERE TO GENERATE LOCAL SYMBOL FIXUP IN A LINKED LIST
|
||
;FORMAT OF FIXUP IS THE SAME AS ALL OTHER PAGED FIXUPS
|
||
;WORD 1 BACK PTR,,FORWARD PTR
|
||
;WORD 2 INDEX,,SYMPTR
|
||
;WORD 3 VALUE
|
||
;
|
||
;CALLED BY
|
||
; MOVE W1,DEFINING SYMBOL FLAGS
|
||
; MOVE W3,SYMBOL PTR
|
||
; MOVE P1,PTR TO DEFINING SYMBOL
|
||
; PUSHJ P,SY.STP
|
||
;DESTROYS R
|
||
|
||
SY.STP: PUSH P,W3 ;SAVE LOCAL SYMBOL PTR
|
||
MOVE T2,W3 ;[2255] AND REL ADDRESS IN SYMBOL TABLE
|
||
MOVE W3,2(P1) ;FIXUP VALUE FROM ORIGINAL SYMBOL DEF
|
||
TXNE W1,FS.FXR ;RIGHT HALF FIXUP?
|
||
TXO T2,SPF.AR ;[2200] YES
|
||
TXNE W1,FS.FXL ;LEFT HALF FIXUP?
|
||
TXO T2,SPF.AL ;[2200] YES
|
||
TXNE W1,FS.FXF ;FULL WORD FIXUP?
|
||
TXO T2,SPF.AF ;[2200] YES
|
||
TXNE W1,FS.FXE ;[2214] THIRTY BIT FIXUP?
|
||
TXO T2,SPF.AE ;[2214] YES
|
||
TXNN W1,FS.REL ;DEFINING SYMBOL RELOCATABLE?
|
||
JRST SYSTP1 ;NO, FIXUP TYPE IS OK
|
||
ADD T2,[SPF.RR-SPF.AR] ;[2200] MAKE CORRESPONDING
|
||
SYSTP1: MOVEI R,FS.SS-FX.S0 ;LOAD INDEX
|
||
SUB P1,FX.LB ;REMOVE OFFSET INCASE CORE MOVES
|
||
PUSHJ P,SY.CHP ;LINK INTO LIST
|
||
ADD P1,FX.LB ;...
|
||
POP P,W3 ;RESTORE W3
|
||
POPJ P,
|
||
SUBTTL ADDRESS CHAINS (RH, LH, FULL WORD)
|
||
|
||
|
||
;FIXUP CHAINING OF SYMBOLS
|
||
;ENTER WITH
|
||
;W3 = VALUE
|
||
;T2 = ADDRESS OF CHAIN (REL TO PROG ORIGIN)
|
||
|
||
;RIGHT HALF
|
||
SY.CHR::
|
||
SKIPE T2 ;[1733] NO CHAIN?
|
||
SKIPE BADCORE## ;[1300] POSSIBLE FIXUP TO OVERLAID PSECT?
|
||
POPJ P, ;[1300] YES, DON'T DO FIXUP
|
||
IFN TOPS20,< ;[2202]
|
||
TLNN W2,770000 ;[1733] SIXBIT symbol ?
|
||
JRST SYCHR0 ;[1733] No, just store the value
|
||
MOVE T1,W3 ;[1734] Don't hack with real value
|
||
TLCE T1,-1 ;[1734] Is the left half all zeros ?
|
||
TLCN T1,-1 ;[1734] Or all ones?
|
||
JRST SYCHR0 ;[1733] Yes, store RH of value
|
||
PUSH P,T2 ;[1420] Save the address
|
||
XOR T2,W3 ;[1733] Clear bits that match
|
||
TLNE T2,-1 ;[1733] Same left half value ?
|
||
PUSHJ P,E$$FTH ;[1412] No, warn user of value truncation
|
||
POP P,T2 ;[1420] Get back store address
|
||
> ;[2202] IFN TOPS20
|
||
SYCHR0: HLL T1,T2 ;[2200] Get the section number for the chain
|
||
SYCHR1: ;[1733]
|
||
IFN FTOVERLAY,<
|
||
SKIPE RT.LB ;RELOCATABLE OVERLAY?
|
||
PUSHJ P,RT.T2R## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
JRST [TXO T2,CPF.CR ;[2200] PAGE NOT IN CORE
|
||
JRST SY.CHP] ;CHAIN REQUESTS TOGETHER
|
||
HRR T1,(T2) ;[2200] GET NEXT LINK, PRESERVING SECTION
|
||
;[2200] Here is where section defaulting is done for right halfword
|
||
;[2200] fixups. The current rule is to wrap within a section.
|
||
HRRM W3,(T2) ;FILL IN VALUE
|
||
MOVE T2,T1 ;SETUP FOR NEXT
|
||
TRNE T2,-1 ;[2200] Any more?
|
||
JRST SYCHR1 ;[2200] Yes, loop back
|
||
POPJ P, ;[1733] End of chain, return
|
||
|
||
;LEFT HALF
|
||
SY.CHL::SKIPE T2 ;[1733] No chain to worry about?
|
||
SKIPE BADCORE## ;[1733] or possible fixup to overlaid psect?
|
||
POPJ P, ;[1300] Yes, don't do fixup
|
||
IFN TOPS20,< ;[2202]
|
||
TLNN W2,770000 ;[1733] SIXBIT symbol ?
|
||
JRST SYCHL0 ;[1420] No, just store the value
|
||
MOVE T1,W3 ;[1734] Don't hack with real value
|
||
TLCE T1,-1 ;[1734] Is the left half all zeros ?
|
||
TLCN T1,-1 ;[1734] Or all ones?
|
||
JRST SYCHL0 ;[1733] Yes, store RH of value
|
||
PUSH P,T2 ;[1420] SAVE THE ADDRESS
|
||
XOR T2,W3 ;[1733] Clear bits that match
|
||
TLNE T2,-1 ;[1733] Same left half value ?
|
||
PUSHJ P,E$$FTH ;[1412] No, warn user of value truncation
|
||
POP P,T2 ;[1420] Get back store address
|
||
> ;[2202] IFN TOPS20
|
||
SYCHL0: HLL T1,T2 ;[2200] Get the section number for the chain
|
||
SYCHL1: ;[1733]
|
||
IFN FTOVERLAY,<
|
||
SKIPE RT.LB ;RELOCATABLE OVERLAY?
|
||
PUSHJ P,RT.T2L## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
JRST [ TXO T2,CPF.CL ;[2200] PAGE NOT IN CORE
|
||
JRST SY.CHP] ;CHAIN REQUESTS TOGETHER
|
||
HLR T1,(T2) ;[2200] GET NEXT LINK, PRESERVING SECTION
|
||
;[2200] Here is where section defaulting is done for left halfword
|
||
;[2200] fixups. The current rule is to wrap within a section.
|
||
HRLM W3,(T2) ;FILL IN VALUE
|
||
MOVE T2,T1 ;SETUP FOR NEXT
|
||
TRNE T2,-1 ;[2200] Any more?
|
||
JRST SYCHL1 ;[2200] Yes, loop back
|
||
POPJ P, ;[1733] END OF CHAIN, RETURN
|
||
E$$FTH::
|
||
.ERR. (MS,.EC,V%L,L%W,S%W,FTH,<Fullword value >) ;[2007]
|
||
.ETC. (SBX,.EC!.EP,,,,W2) ;[1412]
|
||
.ETC. (STR,,,,,,< being truncated to halfword>) ;[1412]
|
||
POPJ P, ;[1420]
|
||
;FULL WORD
|
||
SY.CHF::SKIPE BADCORE## ;[1300] POSSIBLE FIXUP TO OVERLAID PSECT?
|
||
POPJ P, ;[1300] YES, DON'T DO FIXUP
|
||
SY.CF1: ;[2200]
|
||
IFN FTOVERLAY,<
|
||
SKIPE RT.LB ;RELOCATABLE OVERLAY?
|
||
PUSHJ P,RT.T2F## ;YES, SET RELOC BIT CORRECTLY
|
||
>
|
||
PUSHJ P,SEGCHK ;SETUP INCORE ADDRESS
|
||
JRST [TXO T2,CPF.CF ;[2200] PAGE NOT IN CORE
|
||
JRST SY.CHP] ;CHAIN REQUESTS TOGETHER
|
||
;[2214] Here is where section defaulting is done for fullword chained
|
||
;[2214] fixups. The current rule is use the 30 bit address and cross
|
||
;[2214] sections as necessary.
|
||
LDB T1,[ADDRESS(T2)] ;[2214] GET NEXT LINK
|
||
MOVEM W3,(T2) ;FILL IN VALUE
|
||
MOVE T2,T1 ;SETUP FOR NEXT
|
||
JUMPN T2,SY.CF1 ;[2214] IF MORE TO FIXUP, DO IT
|
||
POPJ P, ;[2200] DONE IF END OF CHAIN
|
||
|
||
;Thirty Bit
|
||
SY.CHE::SKIPE BADCORE## ;[2214] Possible fixup to overlaid psect?
|
||
POPJ P, ;[2214] Yes, don't do fixup
|
||
SY.CE1: ;[2214]
|
||
IFN FTOVERLAY,< ;[2214]
|
||
SKIPE RT.LB ;[2214] Relocatable overlay?
|
||
PUSHJ P,RT.T2F## ;[2214] Yes, set reloc bit correctly
|
||
> ;[2214]
|
||
PUSHJ P,SEGCHK ;[2214] Setup incore address
|
||
JRST [TXO T2,CPF.CE ;[2214] Page not in CORE
|
||
JRST SY.CHP] ;[2214] Chain requests together
|
||
;[2214] Here is where section defaulting is done for fullword chained
|
||
;[2214] fixups. The current rule is use the 30 bit address and cross
|
||
;[2214] sections as necessary.
|
||
LDB T1,[ADDRESS(T2)] ;[2214] Get next link
|
||
DPB W3,[ADDRESS(T2)] ;[2214] Fill in value
|
||
MOVE T2,T1 ;[2214] Setup for next
|
||
JUMPN T2,SY.CE1 ;[2214] If more, do it
|
||
POPJ P, ;[2214] Done if end of chain
|
||
|
||
SUBTTL DEFER FIXUPS
|
||
;HERE IF REQUIRED ADDRESS NOT INCORE
|
||
;DO NOT READ PAGE BACK IN, JUST STORE REQUEST IN FX TABLE
|
||
;FILL IN LATER WHEN ENOUGH TO JUSTIFY READING PAGE BACK
|
||
;FIXUPS ARE STORED IN DOUBLLY LINKED LIST IN ASCENDING ORDER
|
||
;POINTER IS PTR TO HIGHEST ADD,,PTR TO LOWEST ADD
|
||
;THE NULL LINK IS 0
|
||
;DATA BLOCK IS
|
||
; BACKWARD PTR,,FORWARD PTR
|
||
; FIXUP ADDRESS IN USER CORE
|
||
; FIXUP VALUE
|
||
|
||
;CALLED BY
|
||
; MOVEI R,TABLE OFFSET (REL TO FX.S0)
|
||
; MOVE T2,REL ADDRESS OF FIXUP
|
||
; MOVE W3,VALUE OF FIXUP
|
||
; PUSHJ P,SY.CHP
|
||
|
||
SY.CHP::HRRZ T1,R ;CLEAR RELOCATION BITS
|
||
CAILE T1,FS.SS-FX.S0 ;VALIDATE INDEX
|
||
PUSHJ P,INVIDX ;INVALID INDEX
|
||
PUSH P,T2 ;SAVE ADDRESS
|
||
MOVEI T2,3 ;NEED 3 WORD BLOCK
|
||
PUSHJ P,FX.GET## ;IN FIXUP AREA
|
||
POP P,T2 ;REL ADDRESS (TO SEGMENT) OF REQUEST
|
||
MOVEM T2,1(T1) ;STORE IN BLOCK
|
||
MOVEM W3,2(T1) ;AND VALUE
|
||
SUB T1,FX.LB ;REMOVE SET
|
||
.JDDT LNKLOD,SY.CHP,<<CAMN T1,$FIXUP##>> ;[632]
|
||
TLZ T2,770000 ;[2200] Addresses are only 30 bits
|
||
PUSH P,P1 ;[2200] Save an accumulator
|
||
HLRZ T3,T2 ;[2200] Get the section number
|
||
MOVEI P1,FX.S0(R) ;[2200] Point to the correct segment
|
||
HRRZ T4,R ;[2200] Get the section number
|
||
CAIN T4,1 ;[2200] Pointing to low segment?
|
||
MOVEI P1,FXSPTR(T3) ;[2200] Yes, use section specific pointer
|
||
AOS FXC.S0(R) ;[2200] Increment count of fixups per segment
|
||
PUSHJ P,SY.FP0 ;[2200] Store the fixup
|
||
POP P,P1 ;[2200] Restore P1
|
||
POPJ P, ;[2200] Return
|
||
|
||
SUBTTL FIXUP CHAIN CONSTRUCTION
|
||
;NOW TO LINK IN CHAIN, HERE WITH
|
||
;P1 = POINTER TO FIXUP CHAIN
|
||
;T1 = ADDRESS (REL TO FX.LB) OF THIS BLOCK
|
||
;T2 = VALUE (ADDRESS REL TO SEG OF FIXUP)
|
||
;USES T3, T4 AS POINTERS
|
||
|
||
|
||
SY.FP0: SKIPE (P1) ;[2200] VIRGIN CHAIN?
|
||
JRST SY.FP1 ;NO
|
||
HRL T1,T1 ;BOTH ENDS POINT TO SAME LOC
|
||
MOVEM T1,(P1) ;[2200] STORE LINK
|
||
POPJ P, ;RETURN
|
||
|
||
|
||
INVIDX: POP P,T1 ;GET LOCATION
|
||
HRRZS T1 ;CLEAR FLAGS
|
||
E$$IVC::.ERR. (MS,.EC,V%L,L%F,S%F,IVC,<Index validation check failed at address >) ;[1212]
|
||
.ETC. (OCT,.EP,,,,T1)
|
||
;HERE IF CHAIN ALREADY SETUP
|
||
SY.FP1: HLRZ T3,(P1) ;[2200] GET PTR TO TOP OF CHAIN
|
||
ADD T3,FX.LB ;ADD IN OFFSET
|
||
SETZ T4, ;PREV PTR WAS START OF CHAIN
|
||
PUSH P,T1 ;[2200] SAVE THE POINTER
|
||
TLZ T2,770000 ;[2200] GET THE 30 BIT ADDRESS PART ONLY
|
||
JRST SY.FP4 ;FIRST TIME THROUGH LOOP
|
||
|
||
SY.FP2: HRLZ T4,T4 ;SAVE LAST IN LEFT HALF
|
||
HRR T4,T3 ;SAVE THIS IN RIGHT
|
||
HLRZ T3,(T4) ;GET NEXT LOWER
|
||
JUMPE T3,SY.FX6 ;END IF ZERO
|
||
ADD T3,FX.LB ;ADD IN OFFSET
|
||
SY.FP4: LDB T1,[ADDRESS 1(T3)] ;[2200] GET THE 30 BIT ADDRESS
|
||
CAML T2,T1 ;[2200] FIND ADDRESS SMALLER THAN WHAT WE HAVE
|
||
JRST SY.FP3 ;YES, LINK INTO LIST
|
||
JRST SY.FP2 ;NO, TRY AGAIN
|
||
|
||
SY.FX6: POP P,T1 ;[2200] AND THE POINTER
|
||
HRLM T1,(T4) ;[2200] ADD TO END
|
||
HRRM T1,(P1) ;[2200] AND TO INITIAL PTR
|
||
SUB T4,FX.LB ;-OFFSET
|
||
ADD T1,FX.LB ;+OFFSET
|
||
HRRZM T4,(T1) ;FORWARD LINK
|
||
POPJ P,
|
||
|
||
SY.FP3: POP P,T1 ;[2200] AND THE POINTER
|
||
TRNN T4,-1 ;[2200] START OF CHAIN IF 0 ADDRESS
|
||
JRST SY.FP5 ;YES, USE PREV POINTERS
|
||
HRRM T1,(T3) ;FWD PTR IN NEXT LOWER
|
||
HRLM T1,(T4) ;BKW PTR IN NEXT HIGHER
|
||
ADD T1,FX.LB ;ADD OFFSET
|
||
SUB T4,FX.LB ;REMOVE OFFSET
|
||
SUB T3,FX.LB ;FROM ADJACENT BLOCKS
|
||
HRRM T4,(T1) ;STORE IN LINK ADDRESS
|
||
HRLM T3,(T1)
|
||
POPJ P,
|
||
|
||
;HERE IF NEW ADDRESS IS BIGGEST YET
|
||
SY.FP5: HRRM T1,(T3) ;LINK BACK IN CHAIN
|
||
HRLM T1,(P1) ;[2200] AND INITIAL PTR
|
||
ADD T1,FX.LB ;FIX
|
||
SUB T3,FX.LB ;REMOVE OFFSET
|
||
HRLZM T3,(T1) ;BACKWARDS PTR
|
||
POPJ P,
|
||
SUBTTL MULTIPLY DEFINED GLOBAL
|
||
|
||
|
||
;HERE IF MULTIPLY DEFINED GLOBAL SYMBOL
|
||
;ENTER WITH W1, W2, W3 CONTAIN NEW SYMBOL
|
||
;P1 IS POINTER TO OLD SYMBOL
|
||
;USES T1
|
||
|
||
SY.MDS::PUSHJ P,SY.MDF ;WARN USER AND SET GLOBAL FLAG
|
||
TXO W1,PS.MDF ;FLAG MULTIPLE FOR LOCALS
|
||
PJRST LS.ADD ;AND GO STICK IN LOCAL TABLE
|
||
|
||
|
||
SY.MDF: MOVE T1,0(P1) ;GET CURRENT FLAGS
|
||
TXON T1,PS.MDF ;FLAG IT MULTIPLY DEFINED
|
||
AOS MSYM ;AND COUNT ONE MORE IF NEW
|
||
MOVEM T1,0(P1)
|
||
MOVE T1,2(P1) ;CURRENT VALUE
|
||
E$$MDS::.ERR. (MS,.EC,V%L,L%W,S%W,MDS,<Multiply-defined global symbol >) ;[1174]
|
||
.ETC. (SBX,.EC!.EP,,,,W2) ;SYMBOL IN W2
|
||
.ETC. (JMP,.EC,,,,.ETIMF##) ;[1174] PRINT OFFENDING MODULE
|
||
.ETC. (NLN,.EC) ;[1174]
|
||
.ETC. (STR,.EC,,,,,<Defined value = >) ;[1174]
|
||
.ETC. (OCT,.EC!.EP,,,,T1) ;CURRENT VALUE
|
||
.ETC. (STR,.EC,,,,,<, this value = >)
|
||
.ETC. (OCT,.EP,,,,W3) ;[1174]
|
||
SETZM LSTGBL ;[2255] SO WE DON'T DO FIXUPS?
|
||
SETZM LSTLCL ;[2255] TO LOCAL OR GLOBAL SYMBOL
|
||
POPJ P,
|
||
;HERE TO FILL IN PARTIAL VALUE SYMBOL (SYM1=SYM2)
|
||
;PRIMARY VALUE IS USUAL CHAINED REFERENCES
|
||
;SECONDARY VALUE IS ADDITIVE VALUE OF PARTIAL DEFINITION
|
||
;THERE MAY ALSO BE ADDITIVE GLOBAL FIXUPS REQUIRED
|
||
|
||
;CALLED BY
|
||
; MOVE T1,ADDRESS OF GLOBAL TO FIXUP
|
||
; MOVE T2,FLAGS FOR FIXUP TYPE
|
||
; MOVE W1,SYMBOL FLAGS
|
||
; MOVE W3,FIXUP VALUE
|
||
; PUSHJ P,SY.AS0
|
||
|
||
SY.AS1: TXNE T3,S.LST ;IF LAST TRIPLET
|
||
JRST SY.AS4 ;GIVE UP
|
||
|
||
SY.AS0::ADDI T1,.L ;GET NEXT TRIPLET
|
||
MOVE T3,(T1) ;GET FLAGS
|
||
JUMPL T3,SY.AS4 ;JUST INCASE
|
||
TXNN T3,S.PVS ;IS THIS THE ONE WE WANT
|
||
JRST SY.AS1 ;NO, TRY AGAIN
|
||
PUSHJ P,SY.AST ;FIXUP VALUE
|
||
TXNE W1,PS.UDF ;IF STILL UNDEFINED
|
||
JRST SY.AS4 ;GIVE UP
|
||
SOSGE USYM ;ONE LESS UNDEFINED THEN
|
||
PUSHJ P,E$$DUZ ;[1174] BUT NOT TOO FAR
|
||
MOVX T3,PS.REQ ;IF NOW FULLY DEFINED
|
||
ANDCAM T3,0(P1) ;CLEAR GLOBAL REQUEST FLAG IF SET
|
||
MOVE W3,2(T1) ;GET FIXUP VALUE (TEMP STORAGE ONLY)
|
||
PUSHJ P,SY.ZST ;ZAP PVS TRIPLET (T1 POINTS TO IT)
|
||
SY.FXP: EXCH W3,2(P1) ;GET VALUES RIGHT WAY ROUND
|
||
;AND FIXUP ALL REQUESTS
|
||
MOVE T2,W3 ;GET START OF CHAIN
|
||
DMOVE W2,1(P1) ;GET NAME AND VALUE OF SYMBOL
|
||
PUSHJ P,SY.CHR ;RIGHT-HALF CHAINED FIXUP
|
||
TXNN W1,PS.FXP ;ANY FIXUPS TO BE DONE?
|
||
SY.AS4: POPJ P, ;NO
|
||
PJRST SY.RF2 ;YES, DO ALL ADDITIVE FIXUPS
|
||
;HERE TO GET RID OF A SECONDARY TRIPLET IN THE GS AREA POINTED TO BY T1
|
||
|
||
SY.ZST: MOVE T3,0(T1) ;GET TRIPLET FLAGS
|
||
TXNN T3,S.LST ;LAST BLOCK?
|
||
PUSHJ P,SY.ZS1 ;NO, GIVE BACK THE MIDDLE FIRST
|
||
MOVEI T2,.L ;GIVE IT BACK
|
||
PUSH P,T1 ;SAVE ADDRESS
|
||
PUSHJ P,GS.RET##
|
||
POP P,T1 ;GET BACK POINTER
|
||
MOVE T3,-.L(T1) ;GET FLAGS
|
||
JUMPL T3,SY.ZS2 ;REACHED PRIMARY
|
||
MOVX T3,S.LST ;SET THIS IS LAST TRIPLET NOW
|
||
IORM T3,-.L(T1)
|
||
POPJ P, ;DONE
|
||
|
||
SY.ZS2: MOVX T3,PT.EXT!PS.FXP ;REMOVE EXTENDED FLAG
|
||
ANDCAM T3,-.L(T1) ;SINCE WE DON'T HAVE IT NOW
|
||
POPJ P, ;DONE
|
||
|
||
;HERE TO MOVE UP THE SECONDARY TRIPLETS
|
||
SY.ZS1: HRLZI T2,.L(T1) ;NEXT TRIPLET
|
||
HRRI T2,0(T1) ;THIS TRIPLET
|
||
ADDI T1,.L ;POINT TO NEXT
|
||
BLT T2,-1(T1) ;MOVE IT UP
|
||
SKIPG T2,0(T1) ;GET FLAGS
|
||
PUSHJ P,E$$ISP ;[1174]
|
||
TXNN T2,S.LST ;GOT THERE YET
|
||
JRST SY.ZS1 ;NO, TRY AGAIN
|
||
POPJ P,
|
||
;HERE TO FIXUP PARTIAL VALUE EITHER RH OR LH
|
||
;ENTER WITH
|
||
; T1 = PTR TO CURRENT EXTENDED TRIPLET
|
||
; T2 = FLAGS (WHICH HALF TO FIXUP)
|
||
; W3 = ADDITIVE VALUE
|
||
|
||
SY.AST::TXNE T2,FS.FXR ;RIGHT HALF?
|
||
JRST SY.ASR ;YES
|
||
TXNE T2,FS.FXL ;LEFT HALF?
|
||
JRST SY.ASL ;YES
|
||
TXNE T2,FS.FXE ;[2214] THIRTY BIT?
|
||
JRST SY.ASE ;[2214] YES
|
||
SY.ASF: MOVE T3,2(T1) ;GET CURRENT VALUE
|
||
ADD T3,W3 ;ADD, IGNORE CARRY
|
||
MOVEM T3,2(T1) ;STORE VALUE BACK
|
||
POPJ P,
|
||
|
||
SY.ASR: HRRZ T3,2(T1) ;GET CURRENT VALUE
|
||
ADDI T3,(W3) ;IGNORE CARRY
|
||
HRRM T3,2(T1) ;STORE VALUE IN RIGHT
|
||
POPJ P,
|
||
|
||
SY.ASL: HLRZ T3,2(T1) ;GET CURRENT VALUE
|
||
ADDI T3,(W3) ;IGNORE CARRY
|
||
HRLM T3,2(T1) ;STORE BACK
|
||
POPJ P,
|
||
|
||
SY.ASE: LDB T3,[ADDRESS 2(T1)] ;[2214] Get current value
|
||
ADD T3,W3 ;[2214] Add, ignore carry
|
||
DPB T3,[ADDRESS 2(T1)] ;[2214] Store back
|
||
POPJ P, ;[2214] Return
|
||
|
||
SUBTTL SYMBOL ROUTINES
|
||
|
||
|
||
;HERE TO MOVE A SYMBOL TO ANOTHER (LARGER) AREA
|
||
;GENERALLY TO ADD EXTENDED TRIPLETS
|
||
|
||
;CALLED BY
|
||
; MOVE T1,EXTRA REQUIRED
|
||
; MOVE P1,ABS LOC OF PRIMARY
|
||
; MOVE P2,REL OFFSET OF PRIMARY
|
||
; PUSHJ P,SY.MOV
|
||
;RETURNS
|
||
;P1 = NEW ABS ADDRESS
|
||
;T1 = LAST SYMBOL TRIPLET IN USE
|
||
|
||
SY.MOV::PUSH P,T1 ;SAVE EXTRA
|
||
PUSHJ P,SY.CHK ;SEE HOW MUCH WE ALREADY HAVE
|
||
EXCH T2,0(P) ;SWAP SO WE SAVE LENGTH
|
||
ADD T2,0(P) ;THIS IS HOW MUCH WE WANT
|
||
PUSHJ P,GS.GET## ;GET IT
|
||
HRRZ P1,@HT.PTR ;RESET P1(INCASE CORE MOVED)
|
||
ADD P1,NAMLOC ;FIX IN CORE
|
||
HRLZ T2,P1 ;MOVE FROM
|
||
HRR T2,T1 ; TO
|
||
MOVE T3,T1 ;UPTO
|
||
ADD T3,0(P) ;END
|
||
BLT T2,-1(T3)
|
||
EXCH P1,T1 ;SWAP
|
||
MOVE T2,0(P) ;FINISHED WITH OLD AREA
|
||
;UNLESS THERE ARE PARTIAL VALUE FIXUPS
|
||
MOVE T3,0(T1) ;GET FLAGS
|
||
TXNN T3,PT.EXT ;EXTENDED?
|
||
JRST SYMOV2 ;NO DON'T WASTE TIME
|
||
MOVE T3,T1 ;YES, MIGHT BE PARTIAL VALUES
|
||
SYMOV1: ADDI T3,.L ;ADVANCE TO NEXT SECONDARY
|
||
SKIPGE T4,0(T3) ;GET SECONDARY FLAGS
|
||
JRST SYMOV2 ;DONE
|
||
TXNE T4,S.PVS ;ONLY WANT PARTIAL VALUE
|
||
JRST SYMOV3 ;YES, MUST SAVE A POINTER TO NEW BLOCK
|
||
TXNN T4,S.LST ;IF LAST TRIPLET WE ARE FINISHED
|
||
JRST SYMOV1 ;NO TRY AGAIN
|
||
JRST SYMOV2 ;NOTHING WORTH SAVING HERE
|
||
;HERE WHEN PVS TRIPLET FOUND
|
||
|
||
SYMOV3: MOVX T4,PT.SGN!PT.OTH!PO.IND ;SET FLAGS
|
||
MOVEM T4,0(T1) ;IN MEMORY
|
||
MOVE T4,P1 ;GET NEW POINTER
|
||
SUB T4,NAMLOC ;MINUS OFFSET
|
||
MOVEM T4,2(T1) ;AS VALUE
|
||
ADDI T1,.L ;ADDVANCE
|
||
SUBI T2,.L
|
||
SYMOV2: PUSHJ P,GS.RET## ;SO GIVE IT BACK
|
||
MOVX T1,PT.EXT ;[612] TRIPLET IS NOW EXTENDED
|
||
IORM T1,0(P1) ;[612] SO MARK IT SO
|
||
MOVE T1,P1 ;ABS ADDRESS
|
||
SUB T1,NAMLOC ;MAKE REL
|
||
HRRM T1,@HT.PTR ;RESET POINTER
|
||
POP P,T2 ;GET LENGTH BACK
|
||
MOVE T1,P1
|
||
ADD T1,T2 ;POINT TO END
|
||
MOVX T3,S.LST ;IS NOT LAST NOW, SO REMOVE FLAG
|
||
SKIPL -.L(T1) ;BUT NOT IF PRIMARY
|
||
ANDCAM T3,-.L(T1)
|
||
POPJ P,
|
||
|
||
;HERE TO COUNT THE NUNBER OF TRIPLETS IN A SYMBOL
|
||
;ENTER WITH P1 = ADDRESS (ABS)
|
||
;RETURN T2 = LENGTH
|
||
;USES T1
|
||
;STOPS ON EITHER LAST TRIPLET (S.LST) OR NEXT PRIMARY (PT.SGN)
|
||
|
||
SY.CHK::SKIPGE T1,0(P1) ;SEE IF PRIMARY
|
||
TXNE T1,PT.EXT ;YES, BUT IS SYMBOL EXTENDED?
|
||
JRST SYCHK1 ;MUST COUNT EXTENDED
|
||
MOVEI T2,.L ;THE EASY WAY TO GET LENGTH
|
||
POPJ P, ;JUST RETURN
|
||
|
||
SYCHK1: HRRZ T2,P1 ;COPY STARTING ADDRESS
|
||
JUMPGE T1,SYCHK2 ;JUMP IF SECONDARY ON ENTRY
|
||
ADDI T2,.L ;GET FIRST SECONDARY
|
||
SYCHK2: SKIPGE T1,0(T2) ;MAKE SURE NOT PRIMARY
|
||
PUSHJ P,E$$ISP ;[1174] SHOULD NEVER HAPPEN
|
||
ADDI T2,.L ;ADVANCE PAST
|
||
TXNN T1,S.LST ;LAST TRIPLET?
|
||
JRST SYCHK2 ;NOT YET
|
||
SUBI T2,(P1) ;YES, GET LENGTH
|
||
POPJ P,
|
||
|
||
;HERE TO RETURN OLD SYMBOL AREA BACK TO POOL
|
||
;MAY BE ANY LENGTH (MULTIPLE OF .L)
|
||
;ENTER WITH P1 = ADDRESS OF SYMBOL IN CORE
|
||
;USES T1, T2
|
||
|
||
SY.RET::PUSHJ P,SY.CHK ;SEE HOW LONG IT IS
|
||
HRRZ T1,P1 ;GET START ADDRESS
|
||
SETZM @HT.PTR ;DELETE IN SYMBOL TABLE
|
||
PJRST GS.RET## ;RETURN IT
|
||
;HERE TO SETUP T2 TO POINT TO INCORE ADDRESS
|
||
;ENTER WITH T2 = RELATIVE ADDRESS
|
||
;SETS UP RHS OF R, LEAVES RELOC BITS IN LHS
|
||
;RETURNS
|
||
;+1 ADDRESS NOT IN CORE (PAGING ONLY)
|
||
; T2 UNAFFECTED, R CHANGED
|
||
;+2 ADDRESS IN CORE AND T2 POINTS TO IT
|
||
|
||
SEGCHK::
|
||
PUSH P,T2 ;[1132] SAVE USER VIRTUAL ADDRESS
|
||
HRRI R,2 ;ASSUME IN HIGH SEG
|
||
SKIPE LL.S2 ;[1132] MUST BE LOW IF ONLY ONE SEGMENT
|
||
CAMGE T2,LL.S2 ;[1132] BELOW BOTTOM OF HIGH SEGMENT?
|
||
SOJA R,SEGCK2 ;[1132] IN LOW SEGMENT
|
||
SUB T2,LL.S2 ;[1132] FORM OFFSET INTO HIGH SEGMENT
|
||
CAMGE T2,HL.S2 ;[1132] BEFORE END OF HIGH SEGMENT?
|
||
JRST SEGCK4 ;[1132] YES, IN HIGH SEGMENT
|
||
MOVE T2,0(P) ;[1132] RESTORE ADDRESS (OFFSET INTO LOW SEG)
|
||
HRRI R,1 ;[1132] SET R TO LOW SEGMENT
|
||
SEGCK2: ;[1132] HERE IF T2 AND R POINT TO LOW SEG
|
||
IFN FTOVERLAY,<
|
||
SUB T2,PH+PH.ADD ;[1400] OFFSET INTO LC IF NOT ROOT LINK
|
||
> ;END IFN FTOVERLAY
|
||
|
||
SEGCK4: SKIPN PAG.S0(R) ;[1132] IS THIS AREA PAGING?
|
||
JRST SEGCK6 ;[1132] NO, ADDR CAN'T BE ON DISK
|
||
CAML T2,LW.S0(R) ;[632] IS ADDRESS IN CORE?
|
||
CAMLE T2,UW.S0(R) ;[632] MAYBE, IS IT?
|
||
JRST [POP P,T2 ;[1132] NOT IN CORE, RESTORE CALLER'S T2
|
||
POPJ P,] ;[1132] RETURN TO CALLER
|
||
|
||
;HERE IF ADDRESS IS DEFINITELY IN CORE.
|
||
SEGCK6: EXCH T2,0(P) ;[1132] GET PHYSICAL ADDRESS FOR .JDDT
|
||
.JDDT LNKLOD,SEGCK6,<<CAMN T2,$LOCATION>> ;[1132]
|
||
POP P,T2 ;[1132] RESTORE OFFSET INTO SEGMENT
|
||
SUB T2,LW.S0(R) ;[632] RELATIVE TO IN-CORE PART OF AREA
|
||
HRR R,@SG.TB ;[632] FIND APPROPRIATE RC BLOCK
|
||
ADD T2,@RC.LB(R) ;[632] MAKE PHYSICAL LOAD-TIME ADDRESS
|
||
JRST CPOPJ1 ;[632] SUCCESS RETURN TO USER
|
||
;HERE TO PUT REQUEST IN GLOBAL SYMBOL TABLE
|
||
;ENTER WITH
|
||
;W1 = SECONDARY TRIPLET FLAGS
|
||
;W2 = SYMBOL NAME
|
||
;W3 = FIXUP VALUE (NOT USED)
|
||
;+0(P) = RETURN ADDRESS
|
||
;-1(P) = VALUE OF PRIMARY TRIPLET
|
||
;-2(P) = FLAGS FOR PRIMARY TRIPLET
|
||
;
|
||
;NOTE, REMOVES 3 ITEMS FROM STACK
|
||
|
||
GS.FX0::MOVEI T2,2*.L ;NEED EXTENDED SYMBOL
|
||
PUSHJ P,GS.GET## ;GET SPACE FOR SYMBOL
|
||
TXO W1,S.LST ;SIGNAL AS LAST TRIPLET
|
||
TMOVEM W1,.L(T1) ;STORE SECONDARY TRIPLET FLAGS, NAME, VALUE
|
||
MOVE W1,-2(P) ;GET PRIMARY FLAGS
|
||
TXO W1,PS.FXP!PT.EXT ;MARK ADDITIVE REQUESTS IN FIXUP TABLE
|
||
MOVE W3,-1(P) ;GET VALUE FROM STACK
|
||
TMOVEM W1,0(T1) ;STORE FLAGS, NAME, VALUE
|
||
MOVE W3,T1 ;POINT TO INCORE BLOCK
|
||
SUB W3,NAMLOC ;INCASE IT MOVES
|
||
PUSH P,W3 ;SAVE VALUE INCASE CORE MOVES
|
||
PUSHJ P,INSRT ;PUT IN GLOBAL TABLE
|
||
POP P,W3 ;GET ADDRESS BACK (RELATIVE TO GX.LB)
|
||
POP P,T2 ;GET RETURN ADDRESS
|
||
SUB P,[2,,2] ;REMOVE JUNK FROM STACK
|
||
JRSTF @T2 ;AND RETURN
|
||
|
||
|
||
;HERE TO LINK FIXUP TRIPLET TO CURRENT GLOBAL TRIPLET
|
||
;ENTER WITH FIXUP ADDRESS (RELATIVE TO FX.LB)
|
||
;IN W3 (SET BY SY.FX0)
|
||
;AND GLOBAL ADDRESS (RELATIVE TO GX.LB)
|
||
;IN P2
|
||
;NOTE BOTH TABLES MAY MOVE
|
||
|
||
SY.GX0::HRRZ T1,@HT.PTR ;FIND OUT WHERE GLOBAL TRIPLET
|
||
ADD T1,NAMLOC ;IS IN CORE
|
||
HRRZM W3,.L+2(T1) ;FIXUP POINTER TO FIXUP LIST
|
||
POPJ P,
|
||
;HERE TO PUT SYMBOL INTO FIXUP TABLE
|
||
;ENTER WITH
|
||
;W1 = FLAGS
|
||
;W2 = SYMBOL
|
||
;W3 = VALUE
|
||
;RETURN WITH
|
||
;W3 = POINTER TO LOCATION RELATIVE TO FX.LB
|
||
|
||
SY.FX0::MOVEI T2,.L ;SPACE IN 3 WORD CHUNKS
|
||
PUSHJ P,FX.GET## ;SPECIAL SPACE GETTER
|
||
TMOVEM W1,0(T1) ;STORE FIXUP REQUEST
|
||
MOVE W3,T1 ;PUT ADDRESS IN W3
|
||
SUB W3,FX.LB ;MAKE IT RELATIVE TO ORIGIN
|
||
.JDDT LNKLOD,SY.FX0,<<CAMN W3,$FIXUP##>> ;[632]
|
||
POPJ P, ;RETURN
|
||
;HERE TO SEE IF SYMBOL REQUESTED FOR SYMBOL TABLE FIXUP WAS LAST
|
||
;SYMBOL DEFINED (NOT FULLY DEFINED OF COURSE)
|
||
;CALLED BY
|
||
; MOVE W3,SYMBOL
|
||
; PUSHJ P,SY.RLS
|
||
;RETURNS
|
||
;+1 NOT LAST SYMBOL DEFINED
|
||
;+2 LAST SYMBOL DEFINED
|
||
;T1= ADDRESS OF SYMBOL IN LOCAL TABLE
|
||
;T2= ADDRESS OF SYMBOL IN GLOBAL TABLE
|
||
|
||
SY.RLS::MOVE T1,LSTLCL ;[2255] GET LOCAL ADDRESS
|
||
JUMPE T1,.+3 ;LEAVE ZERO ALONE
|
||
ADD T1,LS.LB ;RELOCATE
|
||
SUB T1,LW.LS ;BUT REMOVE WINDOW BASE
|
||
MOVE T2,LSTGBL ;[2255] AND GLOBAL
|
||
SKIPE T2
|
||
ADD T2,NAMLOC ;RELOCATE
|
||
TLNN W3,770000 ;[2216] LONG SYMBOL?
|
||
JRST SY.RLL ;[2216] YES
|
||
JUMPE T1,[JUMPE T2,SYRLSZ ;[1165] NO LOCALS, TRY GLOBAL
|
||
CAME W3,1(T2) ;IF IN GLOBAL TABLE
|
||
JRST SYRLSZ ;[1165] NO MATCH
|
||
JRST CPOPJ1] ;[2255] GOT IT HERE
|
||
CAME W3,1(T1) ;SAME?
|
||
JRST SYRLSZ ;[1165] NO
|
||
CPOPJ1: AOS (P)
|
||
CPOPJ: POPJ P,
|
||
|
||
;[2216] Here to handle long symbols
|
||
SY.RLL: JUMPE T2,SYRLL3 ;[2216] Check for local
|
||
SPUSH <T1,T2,P1,P2> ;[2216] Global, save accs for compare
|
||
HLRZ T4,W3 ;[2216] Get the count
|
||
HRRZ P1,W3 ;[2216] And the address
|
||
HRLI P1,(POINT 36) ;[2216] Build a byte pointer
|
||
MOVE T2,1(T2) ;[2216] Get the count,,pointer for the global
|
||
TLNE T2,770000 ;[2216] A short symbol?
|
||
JRST [MOVEI T2,W3 ;[2216] Yes, point at symbol
|
||
MOVEI T1,1 ;[2216] Only one word long
|
||
JRST SYRLL0] ;[2216] Go compare it
|
||
HLRZ T1,T2 ;[2216] Get the count
|
||
ADD T2,GS.LB ;[2216] Relocate it
|
||
SYRLL0: HRLI T2,(POINT 36) ;[2216] Make a byte pointer
|
||
EXTEND T1,[CMPSE ;[2216] Compare the strings
|
||
0
|
||
0]
|
||
JRST SYRLL2 ;[2216] Not the same
|
||
SYRLL1: SPOP <P2,P1,T2,T1> ;[2216] A match, restore accs
|
||
JRST CPOPJ1 ;[2255] and return success
|
||
|
||
SYRLL2: SPOP <P2,P1,T2,T1> ;[2216] Not the same, restore accs
|
||
SYRLSZ: SETZM LSTGBL ;[2255] DON'T CONFUSE SYMBOLS DOWN THE PIKE
|
||
SETZM LSTLCL ;[2255] EITHER LOCAL OR GLOBAL
|
||
POPJ P, ;[1165]
|
||
|
||
;[2216] Here to handle long local symbols
|
||
SYRLL3: SPUSH <T1,T2,P1,P2> ;[2216] Save some accs
|
||
HLRZ P1,W3 ;[2216] Get the count
|
||
HRRZ P2,W3 ;[2216] And the address of the symbol
|
||
MOVE T2,(P2) ;[2216] Get the first six characters
|
||
CAME T2,1(T1) ;[2216] Same?
|
||
JRST SYRLL2 ;[2216] No, not a match
|
||
SOJLE P1,[MOVE T2,(T1) ;[2216] One word symbol? Get the flags
|
||
TXNN T2,PS.EXO ;[2216] Extended?
|
||
JRST SYRLL1 ;[2216] No, it's a match
|
||
JRST SYRLL2] ;[2216] Different size, not a match
|
||
|
||
;[2216] Here for each secondary triplet
|
||
SYRLL4: ADDI T1,.L ;[2216] Point to next triplet
|
||
ADDI P2,2 ;[2216] Point to next two symbol words
|
||
MOVE T2,-1(P2) ;[2216] Get the next symbol word
|
||
CAME T2,1(T1) ;[2216] Same?
|
||
JRST SYRLL2 ;[2216] No, not a match
|
||
SOJE P1,[SKIPN 2(T1) ;[2216] If end of symbol, check extra word
|
||
JRST SYRLL1 ;[2216] Null word, it's a match
|
||
JRST SYRLL2] ;[2216] Different size, not a match
|
||
MOVE T2,(P2) ;[2216] Get the next symbol word
|
||
CAME T2,2(T1) ;[2216] Same?
|
||
JRST SYRLL2 ;[2216] No, not a match
|
||
SOJG P1,SYRLL4 ;[2216] Still OK, last one?
|
||
MOVE T2,(T1) ;[2216] Get the bits
|
||
TXNN T2,S.LST ;[2216] Last secondary?
|
||
JRST SYRLL1 ;[2216] Yes, it's a match
|
||
JRST SYRLL2 ;[2216] Different size, not a match
|
||
|
||
SUBTTL ADD SECONDARY TYPECHECKING BLOCK
|
||
|
||
SY.TYP::
|
||
IFN FTOVERLAY,< ;[2053]
|
||
SKIPN OVERLW ;[2053] Overlayed program?
|
||
JRST SYTYP ;[2053] No, don't worry about BG area
|
||
MOVE T3,ABCNT(W3) ;[2053] Compute ptr to flag word
|
||
IDIVI T3,5 ;[2053] Byte count to word count
|
||
SKIPE T4 ;[2053] If not exact fit
|
||
AOS T3 ;[2053] Count extra in next word
|
||
ADDI T3,ABNAM(W3) ;[2053] T3 Points to flag word
|
||
MOVE T3,(T3) ;[2053] Flags
|
||
TXNN T3,TPWHO ;[2053] Caller?
|
||
PUSHJ P,TYP.BG## ;[2053] Callee, typecheck the bound globals
|
||
; JRST SYTYP ;[2053] Check the current overlay
|
||
>;[2053] IFN FTOVERLAY
|
||
|
||
SYTYP:: MOVX W1,PT.SGN ;[2053] SET UP TYPECHECK BLOCKS IN GS
|
||
SKIPN R2,PAG.TP ;[2342] REMEMBER IF TP AREA PAGING
|
||
SUB W3,TP.LB ;[2270] NOT PAGING, RELOCATE POINTER
|
||
PUSHJ P,TRYSYM## ;[1405] SEE IF IN TABLE
|
||
JRST SY.TY0 ;[1405] NO, PUT IN
|
||
JRST SY.TY1 ;[1405] ALREADY IN UNDEF TABLE
|
||
JRST SY.TY1 ;[1405] STORE NEW BLOCK EVEN IF
|
||
;[1405] CALLEE IS KNOWN
|
||
|
||
SY.TY0: SKIPN PAG.TP ;[2270] PAGING?
|
||
ADD W3,TP.LB ;[2270] NO, UNRELOCATE
|
||
SKIPE PAG.TP ;[2270] PAGING?
|
||
SKIPE R2 ;[2342] AND JUST STARTED PAGING?
|
||
CAIA ;[2270] NO, IT'S OK
|
||
PUSHJ P,TPTODY ;[2270] JUST STARTED PAGING - PUT BLOCK IN DY
|
||
IFN FTOVERLAY,< ;[2053]
|
||
SKIPE ARGOVL ;[2053] Argchecking the BG area?
|
||
POPJ P, ;[2053] Yes, don't put it in
|
||
>;[2053] IFN FTOVERLAY
|
||
;[1405] HERE TO PUT UNKNOWN SYMBOL'S ARGBLK DATA PTR IN GLOBAL TABLE
|
||
;[1405] USE EXTENDED BLOCK TO HOLD POINTER
|
||
AOS USYM ;[1405] COUNT FUNCT NAME AS UNDEFINED
|
||
MOVEI T2,.L*2 ;[1405] NEED TWO BLOCKS TO HOLD
|
||
SKIPN PAG.TP ;[2405] TP PAGING?
|
||
SUB W3,TP.LB ;[2405] NO MAKE ADDRESS RELATIVE
|
||
PUSHJ P,GS.GET## ;[1405] PARTIAL DEFINITION AND ARGBLK DATA
|
||
SKIPN PAG.TP ;[2405] TP PAGING?
|
||
ADD W3,TP.LB ;[2405] ADD LOWER BOUND - MAKE ABSOLUTE
|
||
SKIPE PAG.TP ;[2405] PAGING?
|
||
SKIPE R2 ;[2405] AND JUST STARTED PAGING?
|
||
CAIA ;[2405] NO, IT'S OK
|
||
PUSHJ P,TPTODY ;[2405] JUST STARTED PAGING - PUT BLOCK IN DY
|
||
|
||
TXO W1,PT.EXT!PS.REQ!PT.SYM
|
||
;[1476] MARK AS USING EXTENDED TRIPLET
|
||
DMOVEM W1,0(T1) ;[1405] PRIMARY FLAGS & SYMBOL
|
||
SETZM 2(T1) ;[1405] NO REQUESTS YET
|
||
PUSH P,W2 ;[2270] SAVE THE NAME
|
||
PUSHJ P,SYTY0A ;[2020] BUILD THE SECONDARY TRIPLET
|
||
POP P,W2 ;[2270] RESTORE THE NAME (INSRT WANTS IT)
|
||
MOVE W3,T1 ;[2020] FOR EXTENDED SYMBOLS
|
||
SUB W3,NAMLOC ;[2020] W3 CONTAINS POINTER TO EXTENDED TRIPLET
|
||
PUSHJ P,INSRT ;[2020] PUT IN GLOBAL TABLE
|
||
POPJ P, ;[2020] DONE
|
||
|
||
SYTY0A: MOVX T2,S.LST!S.OTH ;[2020] TYPECHECK MARKER
|
||
MOVE T3,ABCNT(W3) ;[1474] COMPUTE PTR TO FLAG WORD
|
||
IDIVI T3,5 ;[1474] BYTE COUNT TO WORD COUNT
|
||
SKIPE T4 ;[1474] IF NOT EXACT FIT
|
||
AOS T3 ;[1474] COUNT EXTRA IN NEXT WORD
|
||
ADDI T3,ABNAM(W3) ;[1474] T3 POINTS TO FLAG WORD
|
||
MOVE T3,(T3) ;[1474] FLAGS,,COUNT
|
||
PUSHJ P,TP.REL ;[2270] RELOCATE (AND PUT IN TP AREA IF IN DY)
|
||
SETZ W2, ;[2270] CLEAR END OF CHAIN POINTER
|
||
TXNE T3,TPWHO ;[1474] CALLER?
|
||
MOVE W2,W3 ;[2270] YES, POINT TO END OF CHAIN
|
||
MOVEM T2,.L+0(T1) ;[1405] SECONDARY FLAGS
|
||
DMOVEM W2,.L+1(T1) ;[1405] SYMBOL AGAIN (MAY AS WELL) & PTR
|
||
POPJ P, ;[1702] AND RETURN
|
||
|
||
;[1405] Here if "partially defined" symbol is already present.
|
||
;[2020] Look for secondary triplet for typechecking.
|
||
|
||
SY.TY1:
|
||
SKIPN PAG.TP ;[2270] PAGING?
|
||
ADD W3,TP.LB ;[2270] NO, UNRELOCATE
|
||
SKIPE PAG.TP ;[2270] PAGING?
|
||
SKIPE R2 ;[2342] AND JUST STARTED PAGING?
|
||
CAIA ;[2270] NO, IT'S OK
|
||
PUSHJ P,TPTODY ;[2270] JUST STARTED PAGING - PUT BLOCK IN DY
|
||
MOVE T1,(P1) ;[2020] GET PRIMARY FLAGS
|
||
TXNN T1,PT.EXT ;[2020] EXTENDED?
|
||
JRST SYTY1N ;[2020] NO, NO TYPECHECKING SECONDARY
|
||
MOVEI T2,(P1) ;[2020] POINT TO THE FIRST TRIPLET
|
||
SYTY1A: ADDI T2,.L ;[2020] ADVANCE TO NEXT TRIPLET
|
||
MOVE T1,(T2) ;[2020] GET THE FLAGS
|
||
TXNE T1,S.OTH ;[2020] TYPECHECKING?
|
||
JRST SYTY1B ;[2020] YES, FOUND IT
|
||
TXNN T1,S.LST ;[2045] LAST ONE?
|
||
JRST SYTY1A ;[2020] NO, TRY ANOTHER
|
||
SYTY1N: ;[2053]
|
||
IFN FTOVERLAY,< ;[2053]
|
||
SKIPE ARGOVL ;[2053] Typechecking the BG area?
|
||
POPJ P, ;[2053] Yes, don't put it in
|
||
>;[2053] IFN FTOVERLAY
|
||
MOVEI T1,.L ;[2053] NO TYPCHECKING YET, NEED EXTRA TRIPLET
|
||
SKIPN PAG.TP ;[2405] TP PAGING?
|
||
SUB W3,TP.LB ;[2405] NO MAKE ADDRESS RELATIVE
|
||
PUSHJ P,SY.MOV ;[1405] MOVE WHAT WE HAVE
|
||
PUSH P,T1 ;[2405] SAVE T1
|
||
SKIPN PAG.TP ;[2405] TP PAGING?
|
||
ADD W3,TP.LB ;[2405] ADD LOWER BOUND - MAKE ABSOLUTE
|
||
SKIPE PAG.TP ;[2405] PAGING?
|
||
SKIPE R2 ;[2405] AND JUST STARTED PAGING?
|
||
CAIA ;[2405] NO, IT'S OK
|
||
PUSHJ P,TPTODY ;[2405] JUST STARTED PAGING - PUT BLOCK IN DY
|
||
POP P,T1 ;[2405] RESTORE T1
|
||
|
||
SUBI T1,.L ;[2045] GET POINTER TO PREVIOUS TRIPLET
|
||
JRST SYTY0A ;[2020] FILL IN NEW SECONDARY
|
||
|
||
SYTY1B: MOVEI W1,(T2) ;[2270] SAVE TYPECHECKING POINTER
|
||
MOVE T3,ABCNT(W3) ;[2020] COMPUTE PTR TO FLAG WORD
|
||
IDIVI T3,5 ;[1474] BYTE COUNT TO WORD COUNT
|
||
SKIPE T4 ;[1474] IF NOT EXACT FIT
|
||
AOS T3 ;[1474] COUNT EXTRA IN NEXT WORD
|
||
MOVE R,T3 ;[1474] REMEMBER THIS OFFSET
|
||
ADDI T3,ABNAM(W3) ;[1474] T3 POINTS TO FLAG WORD
|
||
MOVE T2,1(W1) ;[2020] GET POINTER TO END OF LIST
|
||
MOVE T3,(T3) ;[1474] FLAGS,,COUNT
|
||
|
||
; W1 Points To the header word in the argument checking secondary [2270]
|
||
; triplet. The second word of the triplet contains either 0 if [2270]
|
||
; the callee has been seen, or the address of the last caller if no [2270]
|
||
; callee has been seen. The third word of the triplet contains the [2270]
|
||
; address of the first caller or the address of the callee. [2270]
|
||
; W3 Points to the new block. [2020]
|
||
; T3 contains the flags for the new block. [2020]
|
||
; R contains the number of words in the name. [2005]
|
||
; must not be touched, TMATCH looks at it. [2005]
|
||
|
||
TXNN T3,TPWHO ;[1474] CALLER?
|
||
JRST SYTY1D ;[2020] NO, THIS IS CALLEE
|
||
JUMPE T2,SYTY1P ;[2020] CHECK FOR CALLER AND CALLEE
|
||
|
||
;Here if have caller and callee has not been seen. Link it at end of list.
|
||
ADD T2,TP.LB ;[2270] UNRELOCATE
|
||
SKIPE PAG.TP ;[2270] PAGING?
|
||
JRST SYTY1W ;[2270] YES, LINK IN FRONT OF LIST
|
||
SUB W3,TP.LB ;[2270] RELOCATE
|
||
MOVEM W3,ABLNK(T2) ;[2020] ADD TO END OF LIST
|
||
MOVEM W3,1(W1) ;[2270] REMEMBER NEW LIST END
|
||
POPJ P, ;[2020] DONE
|
||
|
||
;[2270] Here if paging the TP area. Move the block into the TP
|
||
;[2270] area and link it to the front of the list. Linking it
|
||
;[2270] to the end of the list is preferred, but would involve
|
||
;[2270] doing a fixup to the linked list.
|
||
|
||
SYTY1W: PUSHJ P,TP.REL ;[2270] MOVE IT INTO THE DY AREA
|
||
MOVE T1,2(W1) ;[2270] GET POINTER TO BEGINNING OF LIST
|
||
MOVEM W3,2(W1) ;[2270] PUT THE POINTER IN THE FRONT
|
||
SUB W3,LW.TP ;[2270] SUBTRACT THE WINDOW BOUND
|
||
ADD W3,TP.LB ;[2270] UNRELOCATE IT
|
||
MOVEM T1,ABLNK(W3) ;[2270] STORE THE OLD FIRST IN THE LINK WORD
|
||
POPJ P, ;[2270] DONE
|
||
|
||
;Here if have caller and callee has been seen. Typecheck it and toss it.
|
||
SYTY1P: PUSH P,W3 ;[2020] SAVE POINTER TO CALLER
|
||
MOVE P1,W3 ;[2020] GET THE CALLER ARG BLOCK
|
||
MOVE P2,2(W1) ;[2270] GET THE CALLEE ARG BLOCK
|
||
SKIPN PAG.TP ;[2270] PAGING?
|
||
JRST SYTY1R ;[2270] NO, IT'S IN MEMORY
|
||
MOVE T1,P2 ;[2270] GET THE ADDRESS
|
||
MOVE T2,ABSIZ(P1) ;[2270] AND THE SIZE (FROM THE CALLER)
|
||
PUSHJ P,PG.TP ;[2270] MAKE SURE IT'S IN MEMORY
|
||
MOVE T2,ABSIZ(T1) ;[2270] GET THE ACTUAL SIZE
|
||
CAMG T2,ABSIZ(P1) ;[2270] BIGGER THAN EXPECTED?
|
||
JRST SYTY1Q ;[2270] NO, IT'S IN MEMORY
|
||
MOVE T1,P2 ;[2270] GET THE ADDRESS AGAIN
|
||
PUSHJ P,PG.TP ;[2270] AND ASK FOR THE BIGGER BLOCK
|
||
SYTY1Q: SKIPA P2,T1 ;[2270] GET THE UNRELOCATED POINTER
|
||
SYTY1R: ADD P2,TP.LB ;[2270] UNRELOCATE
|
||
PUSHJ P,TMATCH ;[2020] ARG CHECK IT
|
||
POP P,T1 ;[2020] GET POINTER TO BLOCK
|
||
MOVE T2,ABSIZ(T1) ;[2270] AND IT'S SIZE
|
||
JRST SYTY1C ;[2046] RETURN BLOCK
|
||
|
||
;Here if have callee and callee has not been seen. Typecheck all callers.
|
||
SYTY1D: JUMPE T2,SYTY1I ;[2020] CHECK FOR ANOTHER CALLER
|
||
MOVE P2,W3 ;[2270] GET POINTER TO CALLEE
|
||
MOVE P1,2(W1) ;[2270] GET POINTER TO FIRST CALLER
|
||
SUB W1,GS.LB ;[2342] RELOCATE IN CASE GS AREA MOVES
|
||
PUSH P,W1 ;[2342] SAVE SYMBOL POINTER
|
||
SYTY1L: SKIPN PAG.TP ;[2270] PAGING?
|
||
JRST SYTY1E ;[2270] NO, IT'S IN MEMORY
|
||
MOVE T1,P1 ;[2270] GET THE ADDRESS
|
||
MOVE T2,ABSIZ(P2) ;[2270] AND THE SIZE (FROM THE CALLEE)
|
||
PUSHJ P,PG.TP ;[2270] MAKE SURE IT'S IN MEMORY
|
||
MOVE T2,ABSIZ(T1) ;[2270] GET THE ACTUAL SIZE
|
||
CAMG T2,ABSIZ(P2) ;[2270] BIGGER THAN EXPECTED?
|
||
JRST SYTY1F ;[2270] NO, IT'S IN MEMORY
|
||
MOVE T1,P1 ;[2270] GET THE ADDRESS AGAIN
|
||
PUSHJ P,PG.TP ;[2270] AND ASK FOR THE BIGGER BLOCK
|
||
SYTY1F: SKIPA P1,T1 ;[2270] GET THE UNRELOCATED POINTER
|
||
SYTY1E: ADD P1,TP.LB ;[2270] UNRELOCATE
|
||
SPUSH <R,P1,P2> ;[2270] SAVE THE ACS FOR TYPECHECKING
|
||
PUSHJ P,TMATCH ;[2020] ARGCHECK THIS ONE
|
||
SPOP <P2,P1,R> ;[2020] RESTORE THE REGISTERS
|
||
HRRZ T1,P1 ;[2020] GET ADDRESS OF CALLER BLOCK
|
||
MOVE T2,ABSIZ(P1) ;[2270] GET THE SIZE OF THE BLOCK
|
||
MOVE P1,ABLNK(P1) ;[2270] GET POINTER TO NEXT BLOCK
|
||
AOS TPGCNT ;[2270] COUNT FOR GARBAGE COLLECTION
|
||
SKIPN PAG.TP ;[2270] PAGING?
|
||
PUSHJ P,TP.RET## ;[2270] NO, TOSS THE BLOCK
|
||
JUMPN P1,SYTY1L ;[2020] ARGUMENT CHECK ALL OF THEM
|
||
MOVE W3,P2 ;[2270] GET BACK THE CALLEE BLOCK IN W3
|
||
;**; insert at SYTY1E + 12 edit 2374
|
||
PUSH P,P2 ;[2374] SAVE P2
|
||
PUSHJ P,TP.REL ;[2270] RELOCATE THE POINTER, PUT IN TP
|
||
POP P,P2 ;[2374] RESTORE P2
|
||
POP P,W1 ;[2270] GET BACK GLOBAL SYMBOL POINTER
|
||
ADD W1,GS.LB ;[2342] ADD AREA BASE
|
||
MOVEM W3,2(W1) ;[2270] FROM NOW ON, THE CALLER IS KNOWN
|
||
SETZM 1(W1) ;[2270] REMEMBER IT
|
||
;**; insert at SYTY1E + 18 edit 3274
|
||
MOVE W3,P2 ;[2374] CALLEE BLOCK TO W3
|
||
JRST SYTY1G ;[2046] DONE, CHECK FOR GARBAGE COLLECT
|
||
|
||
;Here if have callee and callee has been seen. Toss the new block.
|
||
SYTY1I: MOVE T1,W3 ;[2020] GET POINTER TO SECOND CALLEE BLOCK
|
||
MOVE T2,ABSIZ(T1) ;[2270] GET SIZE OF NEW BLOCK
|
||
|
||
;[2046] Here to return a block, and to garbage collect if not done recently.
|
||
SYTY1C: AOS TPGCNT ;[2270] COUNT THE BLOCK
|
||
SKIPN PAG.TP ;[2270] PAGING?
|
||
PUSHJ P,TP.RET## ;[2270] NO, REMOVE IT FROM TP AREA
|
||
SKIPE PAG.TP ;[2270] PAGING?
|
||
PUSHJ P,DY.RET## ;[2270] YES, REMOVE IT FROM DY AREA
|
||
SYTY1G: MOVE T1,TPGCNT ;[2270] GET THE COUNT OF RETURNED BLOCKS
|
||
CAIGE T1,TP.MRB ;[2270] CHECK FOR LOTS OF THEM
|
||
POPJ P, ;[2046] NOT TOO MANY
|
||
SETZM TPGCNT ;[2270] LOTS, RESET COUNTER
|
||
SKIPN PAG.TP ;[2270] PAGING?
|
||
PJRST TP.GBC## ;[2270] NO, GARBAGE COLLECT TP AREA
|
||
PJRST DY.GBC## ;[2270] YES, GARBAGE COLLECT DY AREA
|
||
|
||
;[2270] Here to relocate the address in W3. If the block is in the
|
||
;[2270] DY area, put it in the TP area.
|
||
;[2270] W3 contains the pointer.
|
||
|
||
TP.REL: SKIPE PAG.TP ;[2270] Paging?
|
||
JRST TPREL1 ;[2270] Yes, must move to TP area
|
||
SUB W3,TP.LB ;[2270] No, relocate
|
||
POPJ P, ;[2270] Done
|
||
|
||
TPREL1: SPUSH <T1,T2,T3> ;[2270] Get some acs
|
||
PUSHJ P,DYTOTP ;[2270] Copy the block
|
||
;**; Insert AT TPREL1 + 2 edit 2374
|
||
SKIPN ARGOVL ;[2374] Typchecking the BG area ?
|
||
PUSHJ P,DY.RET## ;[2270] Give back the DY block
|
||
SPOP <T3,T2,T1> ;[2270] Restore the acs
|
||
POPJ P, ;[2270] Done
|
||
|
||
;[2270] Here to move the block from the DY area to the TP area.
|
||
;[2342] W3 contains the address in the TP area.
|
||
;[2270] Returns W3 as address of the block in the TP area.
|
||
;[2270] T1 as address of the block in the DY area.
|
||
;[2270] T2 as the length of the block.
|
||
|
||
DYTOTP: MOVE T1,TPPTR ;[2374] Get the "first free" in the TP area
|
||
PUSH P,TPPTR ;[2374] Remember where the block starts
|
||
MOVE T2,ABSIZ(W3) ;[2270] Get the size in T2
|
||
PUSHJ P,PG.TP ;[2270] Get the block in the window
|
||
MOVE T2,ABSIZ(W3) ;[2270] Restore the size in T2
|
||
ADDM T2,TPPTR ;[2374] Bump the "first free" pointer
|
||
ADDI T2,-1(T1) ;[2270] Last address to copy to
|
||
HRL T1,W3 ;[2270] Get the DY address
|
||
BLT T1,(T2) ;[2270] Copy the block inot the TP area
|
||
MOVE T1,W3 ;[2270] Get the address
|
||
MOVE T2,ABSIZ(W3) ;[2270] And the size
|
||
POP P,W3 ;[2270] Get the TP address of the block
|
||
POPJ P, ;[2270] Done
|
||
|
||
;[2270] Here to move the block from the TP area to the DY area.
|
||
;[2270] W3 contains the address in the DY area.
|
||
;[2270] Returns W3 as address of the block in the DY area.
|
||
|
||
TPTODY: MOVE T1,W3 ;[2270] Get the TP address
|
||
MOVEI T2,ABOVH ;[2270] Need the overhead words
|
||
PUSHJ P,PG.TP ;[2270] Get the block in the window
|
||
MOVE T2,ABSIZ(T1) ;[2270] Get the actual size
|
||
PUSHJ P,DY.GET## ;[2270] Get a block of DY memory
|
||
EXCH T1,W3 ;[2270] TP Address in T1, DY in W3
|
||
PUSHJ P,PG.TP ;[2270] Get whole block in window
|
||
MOVE T2,ABSIZ(T1) ;[2270] Get back the size
|
||
HRL T1,W3 ;[2270] Get DY,,TP address
|
||
MOVSS T1 ;[2270] Make it source,,dest
|
||
ADDI T2,-1(W3) ;[2270] Last address to copy to
|
||
BLT T1,(T2) ;[2270] Copy the data
|
||
POPJ P, ;[2270] Done
|
||
|
||
;[2270] Here to get an argument typechecking block in memory.
|
||
;[2270] This routine will not expand the TP area beyond TP.UB
|
||
;[2270] Unless absolutely necessary.
|
||
;[2270] T1 contains the address.
|
||
;[2270] T2 contains the block size.
|
||
;[2270] Return T1 as in-memory address of block.
|
||
;[2270] Uses T1,T2,T3
|
||
|
||
PG.TP: ADD T2,T1 ;[2270] Add the origin and the size
|
||
SUBI T2,1 ;[2270] Minus one is end of block
|
||
CAMGE T1,LW.TP ;[2270] Bottom within window?
|
||
JRST PG.TPM ;[2270] No, must rewindow
|
||
CAMG T2,UW.TP ;[2270] Top within window?
|
||
JRST PG.TPZ ;[2270] Yes, unrelocate and exit
|
||
|
||
;[2270] Here to see if expanding the window with LNKCOR will keep it
|
||
;[2270] within TP.UB. If not, don't bother expanding, just move it.
|
||
|
||
MOVE T3,T2 ;[2270] Get the upper bound
|
||
SUB T3,LW.TP ;[2270] Minus the window
|
||
ADD T3,TP.LB ;[2270] Where it would be in memory
|
||
CAMG T3,TP.UB ;[2270] Can it expand easily?
|
||
JRST PG.TPU ;[2270] Yes, expand the window
|
||
|
||
|
||
;[2270] Must move the window. Unmap it and remap within what's
|
||
;[2270] available. If the window is too small, call LNKCOR to
|
||
;[2270] expand it.
|
||
|
||
PG.TPM: PUSH P,T2 ;[2270] Save the upper address
|
||
PUSH P,T1 ;[2270] And the lower address
|
||
MOVE T1,LW.TP ;[2270] Get the window bottom
|
||
MOVE T2,UW.TP ;[2270] And the top
|
||
PUSHJ P,TP.OUT## ;[2270] Write it
|
||
MOVE T1,(P) ;[2270] Recover the lower bound
|
||
TRZ T1,.IPM ;[2270] Put it on a page bound
|
||
MOVE T2,TP.AB ;[2270] Get the upper bound
|
||
SUB T2,TP.LB ;[2270] Minus the lower is size
|
||
ADD T2,T1 ;[2270] Lower plus size is upper bound
|
||
MOVEM T1,LW.TP ;[2270] Store new lower window
|
||
MOVEM T2,UW.TP ;[2270] And upper window
|
||
PUSHJ P,TP.IN## ;[2270] Bring it into memory
|
||
POP P,T1 ;[2270] Get the pointer
|
||
POP P,T2 ;[2270] And the top
|
||
MOVE T3,T2 ;[2270] Get the upper bound
|
||
SUB T3,LW.TP ;[2270] Minus the window
|
||
ADD T3,TP.LB ;[2270] Where it would be in memory
|
||
CAMG T3,TP.AB ;[2270] Does it fit?
|
||
JRST PG.TPZ ;[2270] Yes, unrelocate and exit
|
||
|
||
PG.TPU: SUB T3,TP.AB ;[2270] How much is necessary
|
||
SPUSH <T1,P1,P2> ;[2270] Save the pointer and some ACs
|
||
MOVEI P1,TP.IX ;[2270] Want memory in the TP area
|
||
MOVE P2,T3 ;[2270] Get the size
|
||
PUSHJ P,LNKCOR## ;[2270] Get the memory
|
||
PUSHJ P,E$$MEF## ;[2270] No memory available
|
||
SPOP <P2,P1,T1> ;[2270] Restore the acs and pointer
|
||
|
||
PG.TPZ: SUB T1,LW.TP ;[2270] Remove the window base
|
||
ADD T1,TP.LB ;[2270] Add the area base
|
||
POPJ P, ;[2270] Done
|
||
|
||
; COMPLAIN ABOUT ARG COUNT MISMATCHES.
|
||
; THEN FEED THE INDIVIDUAL ENTRIES TO ARGSCN.
|
||
; IF THERE ARE 2NDARY DESCRIPTORS FOR AN INDIVIDUAL ENTRY NOTE ANY
|
||
; DISAGREEMENTS THERE.
|
||
|
||
TMATCH:
|
||
MOVE P3,P1 ;[1476] REMEMBER THE CALLER'S ENTIRE ARGBLK
|
||
MOVE R2,ABMOD(P1) ;[2005] GET CALLERS NAME FOR ERRORS
|
||
ADDI P1,ABNAM(R) ;[1476] GO STRAIGHT TO THE ARG DESCRIPTORS
|
||
ADDI P2,ABNAM(R) ;[1476]
|
||
MOVE T1,(P1) ;[2005] FLAGS,,CALLER COUNT
|
||
MOVNI T2,(T1) ;[2005] MINUS CALLER COUNT
|
||
TXNN T1,TPVAL ;[2005] IS IT A FUNCTION
|
||
SUBI T2,1 ;[2005] NO, COUNT LAST ARGUMENT
|
||
HRRZ W1,P1 ;[2005] TEMP PTR FOR CALLER LIST
|
||
HRL W1,T2 ;[2005] AS AN AOBJN POINTER
|
||
MOVE T1,(P2) ;[2005] FLAGS,,CALLEE COUNT
|
||
MOVNI T2,(T1) ;[2005] MINUS CALLEE COUNT
|
||
TXNN T1,TPVAL ;[2005] IS IT A FUNCTION
|
||
SUBI T2,1 ;[2005] NO, COUNT LAST ARGUMENT
|
||
HRRZ W3,P2 ;[2005] TEMP PTR FOR CALLEE LIST
|
||
HRL W3,T2 ;[2005] AS AN AOBJN POINTER
|
||
SETZM P4 ;[1476]
|
||
TMTCH1: AOBJP W1,TMTCH2 ;[2005] BUMP POINTER, SEE IF DONE
|
||
MOVE T1,(W1) ;[1476] PICK UP ARG DESC
|
||
TXNE T1,TPIAD ;[2005] IS IT INTRINSIC?
|
||
JRST [LDB T1,[TPSND(W1)] ;[2005] GET NUMBER OF SECONDARYS
|
||
ADD W1,T1 ;[2005] ACCOUNT FOR THEM
|
||
JRST TMTCH1] ;[2005] TRY FOR ANOTHER PRIMARY
|
||
TMTCH2: AOBJP W3,TMTCH3 ;[2005] BUMP POINTER, SEE IF DONE
|
||
MOVE T2,(W3) ;[2005] PICK UP ARG DESC
|
||
TXNE T2,TPIAD ;[2005] IS IT INTRINSIC?
|
||
JRST [LDB T2,[TPSND(W3)] ;[2005] GET NUMBER OF SECONDARYS
|
||
ADD W3,T2 ;[2005] ACCOUNT FOR THEM
|
||
JRST TMTCH2] ;[2005] TRY FOR ANOTHER PRIMARY
|
||
JUMPGE W1,TMTCH3 ;[2005] CHECK FOR DONE
|
||
ADDI P4,1 ;[2005] COUNT ANOTHER ARGUMENT
|
||
PUSHJ P,ARGSCN ;[1476]
|
||
JRST TMTCH1 ;[1476] AND DO IT AGAIN
|
||
TMTCH3: HLRZ T1,W1 ;[2005] GET THE CALLER ARG COUNT
|
||
HLRZ T2,W3 ;[2005] AND THE FUNCTION ARG COUNT
|
||
MOVE P4,(P1) ;[2005] GET THE FLAGS
|
||
TXNE P4,TPCNT ;[2005] COMPLAIN ABOUT DIFFERENT COUNTS?
|
||
CAMN T1,T2 ;[2005] YES, ARE THEY DIFFERENT?
|
||
SKIPA ;[2005] NO
|
||
PUSHJ P,ARGCNE ;[2005] YES, ERROR
|
||
TMTC3A: MOVE T1,(P1) ;[2005] GET THE FLAG WORDS
|
||
MOVE T2,(P2) ;[2005] FOR BOTH LISTS
|
||
TXNE T1,TPVAL ;[2005] IS CALLER A FUNCTION?
|
||
TXNN T2,TPVAL ;[2005] AND CALLEE TOO?
|
||
JRST TMTCH8 ;[2005] NO
|
||
JUMPGE W1,TMTCH5 ;[2005] CHECK FOR AT END OF LIST
|
||
TMTCH4: LDB T1,[TPSND(W1)] ;[2005] GET NUMBER OF SECONDARIES
|
||
ADD W1,T1 ;[2005] ACCOUNT FOR THEM
|
||
AOBJN W1,TMTCH4 ;[2005] GET ANOTHER
|
||
TMTCH5: JUMPGE W3,TMTCH7 ;[2005] CHECK FOR AT END OF LIST
|
||
TMTCH6: LDB T1,[TPSND(W1)] ;[2005] GET NUMBER OF SECONDARIES
|
||
ADD W3,T1 ;[2005] ACCOUNT FOR THEM
|
||
AOBJN W3,TMTCH6 ;[2005] GET ANOTHER
|
||
TMTCH7: MOVE T1,(W1) ;[2005] GET PRIMARY DESCRIPTOR
|
||
MOVE T2,(W3) ;[2005] FOR BOTH
|
||
SETZ P4, ;[2005] ARGUMENT ZERO IS FUNCTION RETURN
|
||
PUSHJ P,ARGSCN ;[2005] COMPARE THE RETURN VALUES
|
||
TMTCH8: MOVE T1,(P1) ;[2005] GET CALLER ARGUMENT
|
||
TXNN T1,TPSOF ;[2005] COMPLAIN IF SUBROUTINE/FUNCTION?
|
||
POPJ P, ;[2005] NO, DONE
|
||
XOR T1,(P2) ;[2005] COMPARE THE BITS
|
||
TXNN T1,TPVAL ;[2005] ARE THEY DIFFERENT?
|
||
POPJ P, ;[2005] NO
|
||
MOVE T1,(P1) ;[2005] GET BACK CALLER ARG
|
||
TXNN T1,TPVAL ;[2005] WAS CALLER THE FUNCTION?
|
||
SKIPA T1,[1,,0] ;[2012] YES, SET FOR COERSION
|
||
MOVX T1,<0,,1> ;[2012] NO, SET FOR COERSION
|
||
MOVX T3,FCRTV ;[2005] COERSION BLOCK TYPE
|
||
PJRST ARGERR ;[2005] CALL THE COERSION ROUTINE
|
||
|
||
;[1474] Routine ARGSCN.
|
||
; Checks for mismatch
|
||
; T1: Caller's arg (actual)
|
||
; T2: Function arg (formal)
|
||
; P1: Pointer to Caller's arglist
|
||
; P2: Pointer to Function's arglist
|
||
; P3: Pointer to Caller's argblock
|
||
; P4: Arg number
|
||
; W1: Pointer to current arg descr of Caller
|
||
; W2: Sixbit Function name
|
||
; W3: Pointer to current arg descr of Function
|
||
; Uses T3,T4.
|
||
|
||
|
||
;POINTERS TO FUNCTION ARGUMENT DESCRIPTOR FIELDS
|
||
|
||
FUNFLD: POINTR(T2,TPNUP)
|
||
POINTR(T2,TPPASM)
|
||
POINTR(T2,TPTYPM)
|
||
POINTR(T2,TPCTC)
|
||
|
||
;POINTERS TO CALLER'S ARGUMENT DESCRIPTOR FIELDS
|
||
|
||
CALFLD: POINTR(<(P)>,TPNUP)
|
||
POINTR(<(P)>,TPPASM)
|
||
POINTR(<(P)>,TPTYPM)
|
||
POINTR(<(P)>,TPCTC)
|
||
|
||
;MASKS FOR EACH ARGUMENT DESCRIPTOR FIELD
|
||
|
||
MSKFLD: TPNUP
|
||
TPPASM
|
||
TPTYPM
|
||
TPCTC
|
||
|
||
ARGSCN: PUSH P,W3 ;[1477] NEED A SPARE REGISTER
|
||
PUSH P,T1 ;[1477] AND SAVE THE CALLER'S ARG
|
||
SETZM W3 ;[1477] USE REGISTER AS COUNTER
|
||
MOVE T4,T1 ;[1477]
|
||
XOR T4,T2 ;[1477] NOTE MISMATCHES
|
||
ARGSCL: CAILE W3,FCCTC ;[1477] ALL FIELDS EXAMINED?
|
||
JRST ARGSCX ;[1477] YES
|
||
TDNN T4,MSKFLD(W3) ;[1477] MISMATCH IN THIS FIELD?
|
||
AOJA W3,ARGSCL ;[1477] NO, CHECK THE NEXT ONE
|
||
LDB T1,CALFLD(W3) ;[1477] WHAT DID CALLER GIVE?
|
||
LDB T3,FUNFLD(W3) ;[1477] WHAT DID FUNC EXPECT?
|
||
HRL T1,T3 ;[1477] FORMAL,,ACTUAL
|
||
MOVE T3,W3 ;[1477] T3 HAS TYPE BEING SENT
|
||
PUSHJ P,ARGERR ;[1477] TAKE APPROPRIATE ACTION
|
||
AOJA W3,ARGSCL ;[1477] AND TRY AGAIN
|
||
|
||
ARGSCX:
|
||
|
||
;[2103] Check for structure mismatch too.
|
||
|
||
TDNN T4,[TPSTRM] ;[2103]
|
||
JRST ARGSX0 ;[2103] No mismatch seen
|
||
LDB T1,[POINTR(<(P)>,TPSTRM)]
|
||
;[2103] What did caller expect?
|
||
LDB T3,[POINTR(T2,TPSTRM)] ;[2103] What did func expect?
|
||
HRL T1,T3 ;[2103] Formal,,actual
|
||
MOVEI T3,FCSTR ;[2103] This is a structure mismatch
|
||
PUSHJ P,ARGERR ;[2103] Handle it
|
||
|
||
ARGSX0: ;[2103]
|
||
;[1477] There may be 2ndary descriptors. Check for them.
|
||
POP P,T1 ;[1477] GET CALLER DESCR BACK
|
||
POP P,W3 ;[1477] RESTORE REGISTER W3 TOO
|
||
ANDI T1,TPSNDM ;[2005] ISOLATE NUMBER OF SECONDARIES
|
||
ANDI T2,TPSNDM ;[2005] IN CALLER AND CALLEE
|
||
ARGSX1: JUMPE T1,ARGSX9 ;[2005] CHECK FOR NO SECONDARIES
|
||
JUMPE T2,ARGSX9 ;[2005] IN EITHER DESCRIPTOR
|
||
ADDI W1,1 ;[2005] INCREMENT THE POINTERS
|
||
ADDI W3,1 ;[2005]
|
||
SUBI T1,1 ;[2005] DECREMENT THE COUNTS
|
||
SUBI T2,1 ;[2005]
|
||
PUSH P,T2 ;[2005] SAVE AN AC
|
||
PUSH P,T1 ;[2005] AND ANOTHER
|
||
LDB T2,[TPSIZ(W1)] ;[2005] GET THE COUNTS
|
||
LDB T1,[TPSIZ(W3)] ;[2005] FOR BOTH ARGS
|
||
SUB T2,T1 ;[2005] ACTUAL MINUS FORMAL
|
||
LDB T4,[TPMCH(W3)] ;[2005] GET THE TYPE TO CHECK FOR
|
||
MOVEI T3,FCLEN ;[2005] LENGTH CODE
|
||
SETZ T1, ;[2005] SET FOR ZERO BLOCK
|
||
XCT ARGSXT(T4) ;[2005] DO THE COMPARISON
|
||
PUSHJ P,ARGERR ;[2005] FAILED - GIVE MESSAGE
|
||
POP P,T1 ;[2005] RESTORE THE AC
|
||
POP P,T2 ;[2005] AND THE OTHER
|
||
JRST ARGSX1 ;[2005] TRY FOR MORE
|
||
ARGSX9: ADD W1,T1 ;[2005] ACCOUNT FOR THEM
|
||
ADD W3,T2 ;[2005] IN CASE THEY ARE DIFFERENT
|
||
POPJ P, ;[1477] AND LEAVE
|
||
|
||
;TABLE OF POSSIBLE ACTIONS - WILL SKIP IF T2 IS PERMISSABLE
|
||
ARGSXT: SKIPA T2 ;[2005] 000 ALWAYS ALLOWED
|
||
SKIPE T2 ;[2005] 001 MUST BE EQUAL
|
||
SKIPL T2 ;[2005] 010 ACTUAL .LT. FORMAL
|
||
SKIPLE T2 ;[2005] 011 ACTUAL .LE. FORMAL
|
||
SKIPG T2 ;[2005] 100 ACTUAL .GT. FORMAL
|
||
SKIPGE T2 ;[2005] 101 ACTUAL .GE. FORMAL
|
||
JFCL ;[2005] 110 NEVER LEGAL (RESERVED)
|
||
JFCL ;[2005] 111 NEVER LEGAL (RESERVED)
|
||
|
||
|
||
ARGCNE: MOVX T3,FCWNA ;[2005] LOOKING FOR NUMBER OF ARGS
|
||
SETZ T1, ;[2005] MUST BE ZERO IN BLOCK
|
||
; PJRST ARGERR ;[2005] LOOK FOR COERSION BLOCK
|
||
|
||
ARGERR: PUSH P,T2 ;[1476]
|
||
MOVE T2,ABCAL(P3) ;[1476] PREPARE TO COMPLAIN
|
||
; If there's a coerblock find out if a mismatch of this kind has some
|
||
; particular action specified.
|
||
PUSHJ P,COETST ;[1476]
|
||
POP P,T2 ;[1476]
|
||
POPJ P, ;[1470]
|
||
|
||
;[1474] Routine COETST
|
||
;[1474] Scans the coercion block
|
||
;[2005] Return -- Error typed if appropriate
|
||
|
||
COETST: PUSH P,T1 ;[1474] SAVE IT FOR NOW
|
||
MOVE R,COERPT ;[2005] STARTING AT THE FIRST
|
||
JUMPE R,COEDSP ;[2005] IF NO BLOCK, DO INFORMATIONAL
|
||
SKIPA ;[2005] START WITH FIRST PAIR
|
||
COETS1: ADD R,[1,,1] ;[1474] SKIP THE PAIR
|
||
HLRZ T1,(R) ;[1474] PICK UP FIELD CODE
|
||
CAMN T1,T3 ;[1474] RIGHT ONE FOUND?
|
||
JRST COETS3 ;[1474] YES
|
||
COETS2: AOBJN R,COETS1 ;[1474] NO, TRY AGAIN
|
||
SETZ R, ;[2005] DEFAULT INFORMATIONAL
|
||
JRST COEDSP ;[2005] GIVE INFORMATION MESSAGE
|
||
COETS3: MOVE T1,1(R) ;[1474] CHECK OUT THE PAIR
|
||
CAME T1,(P) ;[1474] IS THIS THE MISMATCH SOUGHT?
|
||
JRST COETS2 ;[1474] NO, KEEP LOOKING
|
||
HRRZ T1,(R) ;[1474] PICK UP ACTION CODE
|
||
MOVEI R,3 ;[1474]
|
||
CAIN T1,-1 ;[1474] 777777 -- FATAL
|
||
JRST COEDSP ;[1474] GO DO IT
|
||
CAIN T1,3 ;[1743] SOMETHING SPECIAL
|
||
JRST COESPC ;[1474] GO DO IT
|
||
MOVE R,T1 ;[2005]
|
||
COEDSP: POP P,T1 ;[2005] RESTORE FORMAL,,ACTUAL
|
||
CAIN R,4 ;[2005] IS IT "DO NOTHING"?
|
||
POPJ P, ;[2005] YES
|
||
PUSH P,TERLVL(R) ;[1474] PUSH THE SEVERITY
|
||
JRST @TERDSP(T3) ;[2005] TYPE THE ERROR
|
||
|
||
S%F ;[2012] -1 FATAL
|
||
TERLVL: S%I4 ;[2005] 0 INFORMATIONAL
|
||
S%W ;[2005] 1 WARNING
|
||
S%C ;[2005] 2 ERROR
|
||
S%F ;[2005] 3 FATAL (RESERVED)
|
||
;[2005] 4 NO ACTION
|
||
|
||
TERDSP: COEUPD ;[2005] 0 UPDATE
|
||
E$$AMM ;[2005] 1 PASSING MECHANISM
|
||
E$$TMM ;[2005] 2 ARGUMENT TYPE CODE
|
||
E$$AMM ;[2005] 3 COMPILE TIME CONSTANT
|
||
E$$WNA ;[2005] 4 WRONG NUMBER OF ARGUMENTS
|
||
COERTV ;[2005] 5 RETURN VALUE
|
||
E$$LMM ;[2005] 6 LENGTH MISMATCH
|
||
E$$AMM ;[2103] 7 STRUCTURE CODE
|
||
|
||
COERTV: TRNN T1,-1 ;[2005] DOES CALLER EXPECT A VALUE?
|
||
JRST E$$URV ;[2012] NO, OTHER MESSAGE
|
||
JRST E$$NVR ;[2012] YES, GIVE THIS ERROR
|
||
|
||
COEUPD: TRNN T1,-1 ;[2005] CALLER NO-UPDATE?
|
||
JRST E$$AMM ;[2005] NO, SHOULD BE HARMLESS
|
||
JRST E$$PMA ;[2005] YES, POSSIBLE MODIFICATION
|
||
|
||
COESPC: POP P,(P) ;[2005] TOSS STACK VALUE
|
||
CAIE T1,3 ;[1474] SPECIAL DESCR-TO-HOLL FIXUP?
|
||
POPJ P, ;[1474] NO
|
||
;[1474] Make quite sure we're supposed to do this.
|
||
;[1474] Only caller's compile-time constants can be picked up.
|
||
;[1474] Sneak a peek at descriptor in caller block.
|
||
MOVE T1,(W1) ;[2005] CURRENT CALLER'S DESCRIPTOR
|
||
TXNN T1,TPCTC ;[2005] COMPILE-TIME-CONST?
|
||
POPJ P, ;[1777] FORGET ABOUT IT AND LEAVE
|
||
|
||
;[1476] P3: Pointer to Caller's argblock
|
||
;[2005] W1: (left half) Minus number of descriptors left to process
|
||
;[2005] P1: Pointer to flags word (and descriptor count)
|
||
;[1476] Pick up the address of the argblk, and construct a pointer
|
||
;[1476] to the descriptor being passed to the function.
|
||
|
||
SPUSH <P1,P2,P3> ;[1777] SAVE SOME ACS
|
||
PUSH P,T2 ;[1474] WILL NEED IT
|
||
HLRE T2,W1 ;[2005] MINUS COUNT OF ARGS TO DO
|
||
ADD T2,ABABA(P3) ;[2005] ADD ADDR OF CALLERS ARG BLK
|
||
HRRZ P3,(P1) ;[2005] GET NUMBER OF DESCRIPTORS
|
||
ADDI T2,-1(P3) ;[2005] CALCULATE THE DESCRIPTOR
|
||
MOVE P3,(P1) ;[2005] GET THE FLAGS
|
||
TXNN P3,TPVAL ;[2005] IS IT A FUNCTION?
|
||
ADDI T2,1 ;[2005] NO
|
||
LDB P3,[POINT 30,T2,35] ;[1777] TAKE 30 BIT ADDRESS
|
||
IFN FTOVERLAY,< ;[2053]
|
||
SKIPE ARGOVL ;[2053] Argchecking the BG area?
|
||
JRST COEOVL## ;[2053] Yes, may have to defer this fixup
|
||
>;[2053] IFN FTOVERLAY
|
||
COESP0::PUSH P,P3 ;[2053] SAVE IT
|
||
PUSHJ P,SGCHK. ;[1777] FIND OUT WHERE IT IS
|
||
PUSH P,P3 ;[1777] SAVE PTR TO ARG DESCRIPTOR
|
||
HRRZ P3,(P3) ;[1777] PICK UP PTR TO STRING DESCR
|
||
MOVEI T1,17 ;[1474] CHANGE ARG BITS TO HOLLERITH
|
||
DPB T1,[POINT 4,@(P),12] ;[1474] ...
|
||
POP P,(P) ;[1474] THROW AWAY THE 'FIXED' POINTER
|
||
HLL P3,0(P) ;[2217] ADD IN SECTION NUNBER
|
||
PUSHJ P,SGCHK. ;[1777] GET WHERE STRING DESC REALLY IS
|
||
LDB T1,[POINT 6,(P3),5] ;[2217] GET THE HIGH ORDER SIX BITS
|
||
CAIE T1,44 ;[2217] IS IT A VALID BYTE POINTER
|
||
CAIN T1,61 ;[2217] IS IT A VALID OWGBP
|
||
JRST COESP2 ;[2217] YES
|
||
CAIN T1,67 ;[2217] IS IT A 9-BIT ASCII BP
|
||
JRST COESP2 ;[2217] YES - ITS O.K.
|
||
PUSHJ P,E$$CCE ;[2217] NO - POINTER NOT WORD ALIGNED
|
||
POP P,(P) ;[2217] CLEAN UP THE STACK
|
||
JRST COESP1 ;[2217] SKIP FIXUP AND RESTORE ACS
|
||
COESP2: HRRZ T1,(P3) ;[1777] ABSOLUTE ADDR OF STRING
|
||
EXCH T1,(P) ;[1777] ABSOLUTE ADDRESS OF STRING TO
|
||
;STACK REL ADDR OF DISCRIPTOR TO P3
|
||
MOVE P3,T1 ;[1777] SET UP P3 FOR CALL
|
||
PUSHJ P,SGCHK. ;[1777] FIND OUT WHERE IT IS
|
||
POP P,T1 ;ABSOLUTE ADDR OF STRING TO T1
|
||
HRLI T1,(<Z 17,>+1B0) ;[2217] HOLLERITH BITS + SECTION LOCAL
|
||
MOVEM T1,(P3) ;[2217] PUT IT WHERE IT BELONGS
|
||
COESP1::POP P,T2 ;[2053] RESTORE OLD T2 VALUE
|
||
SPOP <P3,P2,P1> ;[1777] RESTORE ACS
|
||
POPJ P, ;[2005] DONE.
|
||
|
||
|
||
|
||
;LNKCCE Character constant not word aligned in call to routine FOO
|
||
; called form module BAR at location 123456
|
||
|
||
E$$CCE:: ;[2217]
|
||
.ERR. (MS,.EC,V%L,L%F,S%F,CCE,<Character constant not word aligned >)
|
||
.ETC. (JMP,,,,,.ETMW2) ;[2322]
|
||
|
||
;LNKWNA Wrong number of arguments in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$WNA:: ;[2005]
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,WNA,<Wrong number of arguments>) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW2) ;[1474]
|
||
|
||
;LNKNVR No value returned by routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$NVR:: ;[2005]
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,NVR,<No value returned by routine >) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW4) ;[2005]
|
||
|
||
;LNKURV Unexpected return value in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$URV:: ;[2005]
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,URV,<Unexpected return value>) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW2) ;[2005]
|
||
|
||
;LNKLMM Length mismatch for argument N in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$LMM:: ;[2005]
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,LMM,<Length mismatch for >) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW1) ;[2005]
|
||
|
||
|
||
;LNKTMM Type mismatch seen for argument N in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
|
||
E$$TMM:: ;[2005]
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,TMM,<Type mismatch for >) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW1) ;[1474]
|
||
|
||
;LNKPMA Possible modification of argument N in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$PMA::
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,PMA,<Possible modification of >) ;[2264]
|
||
.ETC. (JMP,,,,,.ETMW1) ;[2005]
|
||
|
||
;LNKAMM Argument mismatch in argument N in call to routine FOO
|
||
; called from module BAR at location 123456
|
||
|
||
E$$AMM::
|
||
.ERR. (MS,.EC,V%L,L%D,S%D,AMM,<Argument mismatch in >) ;[2005]
|
||
; .ETC. (JMP,,,,,.ETMW1) ;[2005]
|
||
|
||
.ETMW1: .ETC. (XCT,.EC,,,,<[SKIPN P4]>) ;[2005] FUNCTION ARGUMENT?
|
||
.ETC. (JMP,,,,,.ETMW3) ;[2005] ;[2005] NO
|
||
.ETC. (STR,.EC,,,,,<argument >) ;[2005] YES
|
||
.ETC. (DEC,.EP!.EC,,,,P4) ;[1751]
|
||
.ETMW2: .ETC. (STR,.EC,,,,,< in call to routine >)
|
||
.ETMW4: .ETC. (SBX,.EC!.EP,,,,W2)
|
||
.ETC. (NLN,.EC) ;[2005]
|
||
.ETC. (STR,.EC,,,,,<called from module >) ;[2005]
|
||
.ETC. (SBX,.EC!.EP,,,,R2) ;[2005]
|
||
.ETC. (STR,.EC,,,,,< at location >)
|
||
.ETC. (OCT,.EP,,,,T2)
|
||
POPJ P,
|
||
.ETMW3: .ETC. (STR,.EC,,,,,<returned value>) ;[2005]
|
||
.ETC. (JMP,,,,,.ETMW2) ;[2005]
|
||
|
||
SUBTTL COMPILER SPECIFIC ROUTINES
|
||
|
||
|
||
DEFINE X(A,B,C,D)< ;;[1225] ACCOUNT FOR EXTRA ARG
|
||
IF1,<BLOCK 1>
|
||
IF2,<
|
||
IFDEF B'NAM,< ;;[1120] CALL PROCESSOR ROUTINE
|
||
PUSHJ P,B'NAM
|
||
>
|
||
IFNDEF B'NAM,<
|
||
JFCL ;;[1120] NOTHING TO DO
|
||
>
|
||
>
|
||
>
|
||
|
||
XALL
|
||
CT.NAM::PROCESSORS
|
||
|
||
DEFINE X(A,B,C,D)< ;;[1225] ACCOUNT FOR EXTRA ARG
|
||
B'BIT
|
||
>
|
||
CT.BIT::PROCESSORS
|
||
SALL
|
||
;CALLED BY PUSHJ P,xxxNAM
|
||
;
|
||
;ENTER WITH
|
||
; T1/ INDEX TO CT.TAB
|
||
; T2/ PROCSN (CT.BIT)
|
||
; W2/ PROGRAM NAME
|
||
; -1(P)/ BLANK COMMON
|
||
|
||
;HERE IF ALGOL MAIN PROGRAM - SETS THIS AS PROGRAM NAME
|
||
ALGNAM: SKIPN -1(P) ;SEE IF BLANK COMMON SET
|
||
POPJ P, ;[1120] USES COMMON SIZE AS MAIN PROG MARKER.
|
||
SETZM -1(P) ;CLEAR COMMON SIZE
|
||
MOVEM W2,LODNAM ;SAVE NAME
|
||
HRLZM T1,MNTYPE ;AND SAVE ALGOL AS MAIN PROG TYPE
|
||
POPJ P, ;[1120] DONE
|
||
|
||
;[1433] COBOL
|
||
|
||
C68NAM: JUMPE T2,CPOPJ ;[1120] OK FIRST TIME
|
||
TXNE T2,C74BIT ;[1433] TEST FOR COBOL-74
|
||
JRST E$$CMC ;[1174] NOT ALLOWED
|
||
TXNE T2,CBLBIT ;[1433] TEST FOR COBOL
|
||
JRST E$$CM6 ;[1433] NOT ALLOWED
|
||
TXNE T2,C68BIT ;[1433] OR IF COBOL-68 ALREADY SEEN
|
||
POPJ P, ;[1120] DONE
|
||
E$$CMF::.ERR. (MS,.EC,V%L,L%F,S%F,CMF,<COBOL module must be loaded first>) ;[1545]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1174]
|
||
|
||
C74NAM: JUMPE T2,CPOPJ ;[1120] OK FIRST TIME
|
||
TXNE T2,C68BIT ;[1433] TEST FOR COBOL-68
|
||
JRST E$$CMC ;[1174] NOT ALLOWED
|
||
TXNE T2,CBLBIT ;[1433] TEST FOR COBOL
|
||
JRST E$$CM7 ;[1433] NOT ALLOWED
|
||
TXNN T2,C74BIT ;[1433] OR IF COBOL-74 ALREADY SEEN
|
||
JRST E$$CMF ;[1174]
|
||
POPJ P, ;[1227] DONE
|
||
|
||
CBLNAM: JUMPE T2,CPOPJ ;[1433] OK FIRST TIME
|
||
TXNE T2,C68BIT ;[1433] TEST FOR COBOL-68
|
||
JRST E$$CM6 ;[1433] NOT ALLOWED
|
||
TXNE T2,C74BIT ;[1433] TEST FOR COBOL-74
|
||
JRST E$$CM7 ;[1433] NOT ALLOWED
|
||
TXNN T2,CBLBIT ;[1433] OR IF COBOL ALREADY SEEN
|
||
JRST E$$CMF ;[1433]
|
||
POPJ P, ;[1433] DONE
|
||
|
||
E$$CMC::.ERR. (MS,.EC,V%L,L%F,S%F,CMC,<Cannot mix COBOL-68 and COBOL-74 compiled code>) ;[1174]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1174]
|
||
E$$CM6::.ERR. (MS,.EC,V%L,L%F,S%F,CM6,<Cannot mix COBOL-68 and COBOL compiled code>) ;[1433]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1433]
|
||
|
||
E$$CM7::.ERR. (MS,.EC,V%L,L%F,S%F,CM7,<Cannot mix COBOL-74 and COBOL compiled code>) ;[1433]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1433]
|
||
|
||
;FORTRAN
|
||
|
||
XFRNAM: TXNE T2,FORBIT ;[1203] SEEN OTHER FORTRAN?
|
||
JRST E$$CMX ;[1203] YES, ERROR
|
||
JRST FOROK ;[1203] NO, PROCEED
|
||
FORNAM: TXNE T2,XFRBIT ;[1203] OTHER FORTRAN?
|
||
JRST E$$CMX ;[1203] YES, COMPLAIN
|
||
|
||
PASNAM: ;[1435] SAME TEST FOR PASCAL
|
||
FOROK: MOVE T1,OTSEG ;[2300] DID USER SPECIFY NON-REENT OTS?
|
||
SOJE T1,CPOPJ ;YES, SO LOAD TWO SEG CODE IN TWO SEGMENTS
|
||
SKIPN HC.LB ; IF ANY HIGH LOADED
|
||
TRNE FL,R.FNS!R.FLS!R.FHS!R.LSO!R.HSO ;ANY REASON TO KEEP SEGMENTS DISTINCT?
|
||
POPJ P, ;EITHER USER HAS SPECIFIED WHICH, OR ALREADY LOADED HIGH
|
||
;IN EITHER CASE RIGHT THING HAPPENS
|
||
TRO FL,R.FLS ;NO, SO FORCE LOW SEGMENT
|
||
POPJ P, ;SO FOROTS WILL BE SHAREABLE
|
||
|
||
E$$CMX::SKIPE NOCMX ;[1262] HAS THIS ERROR BEEN PRINTED BEFORE?
|
||
JRST FOROK ;[1262] YES, DON'T PRINT IT AGAIN
|
||
SETOM NOCMX ;[1262] FLAG THIS AS SEEN
|
||
.ERR. (MS,.EC,V%L,L%W,S%W,CMX,<Cannot mix GFloating FORTRAN compiled code with FORTRAN compiled code>) ;[1753]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1203]
|
||
AOS .JBERR ;[1207] STOP EXECUTION
|
||
JRST FOROK ;[1207] BUT KEEP LOADING
|
||
;SITGO
|
||
|
||
STGNAM:
|
||
E$$SNS::.ERR. (MS,.EC,V%L,L%F,S%F,SNS,<SITGO not supported>)
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1203]
|
||
SUBTTL STORE CODE IN FX AREA
|
||
|
||
|
||
T3HOLD::MOVEI T2,.IPS ;STORE CODE IN INTERNAL PAGES
|
||
PUSHJ P,DY.GET## ;FIRST BLOCK IN DY, REST IN FX
|
||
MOVE T2,[3,,1] ;BLOCK HEADER
|
||
MOVEM T2,1(T1) ;FOR RE-READ
|
||
MOVEM W1,3(T1) ;STORE HIGH SEG ORIGIN
|
||
MOVEI W2,3(T1) ;POINT TO NEXT FREE LOC
|
||
HRLI W2,-.IPS+3 ;AOBJN WORD FOR THIS BLOCK
|
||
PUSH P,T1 ;SAVE ORIGIN
|
||
T3HEDR: PUSHJ P,D.IN1 ;GET NEXT HEADER
|
||
HLRZ T2,W1 ;[1320] GET TYPE
|
||
CAIN T2,5 ;[1320] NEED END BLOCK
|
||
JRST T5FND ;FOUND IT
|
||
PUSHJ P,FXHOLD ;HOLD CODE IN FX AREA
|
||
JRST T3HEDR ;AND CONTINUE
|
||
|
||
;HERE TO STORE BLOCK IN CORE (FX)
|
||
;ENTER WITH W1 = FIRST DATA WORD
|
||
|
||
FXHOLD: HRRZ T1,W1 ;GET WORD COUNT
|
||
JUMPE T1,FXHLD0 ;[1320] STORE ZERO IN CASE ASCII TEXT
|
||
CAILE T2,3777 ;[1320] ASCII TEXT BLOCK?
|
||
SKIPA T1,[0] ;[1320] YES, STORE ONLY ONE WORD
|
||
CAILE T2,377 ;[1320] OLD STYLE REL BLOCK?
|
||
JRST FXHLD0 ;[1320] NO, LONG COUNT IS OK
|
||
CAIG T1,^D18 ;ONLY 1 SUB BLOCK
|
||
AOJA T1,FXHLD0 ;YES
|
||
IDIVI T1,^D18 ;NO, COUNT NO.
|
||
IMULI T1,^D19 ;ADD RELOCATION WORD
|
||
JUMPE T2,FXHLD0 ;NO REMAINDER
|
||
ADDI T1,1(T2) ;ADD REMAINDER + BYTE WORD
|
||
FXHLD0: SKIPA W3,T1 ;NO OF WORDS IN THIS BLOCK
|
||
FXHLD1: PUSHJ P,D.IN1 ;GET NEXT WORD
|
||
AOBJP W2,FXHLD3 ;RAN OUT OF SPACE
|
||
FXHLD2: MOVEM W1,(W2) ;STORE IT
|
||
SOJGE W3,FXHLD1 ;LOOP FOR ALL OF BLOCK
|
||
POPJ P, ;GET NEXT BLOCK
|
||
|
||
FXHLD3: SUBI W2,.IPS ;BACKUP POINTER TO START OF BLOCK
|
||
SKIPE FX.LB ;LIST IN DY IF NOT SETUP
|
||
CAMGE W2,FX.LB ;IS LIST IN FX OR DY
|
||
TLOA W2,-1 ;IN DY
|
||
SUB W2,FX.LB ;IN FX, REMOVE OFFSET
|
||
MOVEI T2,.IPS ;GET NEXT BLOCK
|
||
PUSHJ P,FX.GET## ;IN FIXUP AREA
|
||
TLZN W2,-1 ;WAS IT IN DY
|
||
ADD W2,FX.LB ;NO, PUT BACK OFFSET
|
||
EXCH T1,W2 ;NEW POINTER IN W2, OLD IN T1
|
||
MOVE T2,W2 ;COPY IT
|
||
SUB T2,FX.LB ;REMOVE OFFSET
|
||
.JDDT LNKLOD,FXHLD3,<<CAMN T2,$FIXUP##>> ;[632]
|
||
SUB T2,LW.FX ;INCASE PAGING
|
||
MOVEM T2,(T1) ;FIXUP POINTER
|
||
HRLI W2,-.IPS ;FORM AOBJN POINTER
|
||
AOBJN W2,FXHLD2 ;STORE CURRENT WORD IN NEW BLOCK
|
||
;HERE WHEN END BLOCK FOUND
|
||
|
||
T5FND: MOVEI T1,2 ;ONLY STORE FIRST 3 WORDS
|
||
PUSHJ P,FXHLD0
|
||
PUSH P,W1 ;SAVE HIGH SEG BREAK
|
||
PUSHJ P,FXHLD1 ;FINISH OFF BLOCK
|
||
POP P,W1 ;DATA WORD BACK
|
||
;NOW GET FIRST BLOCK BACK
|
||
POP P,W2
|
||
HRLM W1,3(W2) ;NOW WE HAVE A VALID BREAK
|
||
T5FND1: PUSH P,DCBUF ;STACK REAL BUFFER HEADER
|
||
PUSH P,DCBUF+1
|
||
PUSH P,DCBUF+2
|
||
MOVEI T1,.IPS-1 ;MAX NO. OF WORDS IN BUFFER
|
||
MOVEM T1,DCBUF+2
|
||
HRRM W2,DCBUF+1 ;NEW BUFFER HEADER
|
||
SETZM DCBUF ;SIGNAL INCORE
|
||
JRST LOAD ;AND TRY AGAIN
|
||
;HERE TO GET NEXT BUFFER
|
||
;MOVE IT FROM FX AREA TO DY AREA (FIXED ADDRESS)
|
||
|
||
FXRED1: PUSHJ P,FXREAD ;CALLED FROM D.INP
|
||
JRST D.IN1 ;SO RETURN THERE
|
||
|
||
FXRED2: PUSHJ P,FXREAD ;CALLED FROM D.READ
|
||
JRST D.RED1 ;SO RETURN TO THE CALLER
|
||
|
||
FXREAD::PUSHJ P,.PSH4T## ;[2262] NEED SOME TEMP ACCS
|
||
HRRZ T1,DCBUF+1 ;GET FINAL BYTE POINTER
|
||
SUBI T1,.IPS-1 ;BACKUP
|
||
HRRM T1,DCBUF+1
|
||
MOVEI T2,.IPS-1 ;NO OF WORDS IN BUFFER
|
||
MOVEM T2,DCBUF+2
|
||
SKIPN T1,(T1) ;GET FIRST WORD (POINTER)
|
||
HALT
|
||
SKIPE PAG.FX ;PAGING?
|
||
HALT
|
||
.JDDT LNKLOD,FXREAD,<<CAMN T1,$FIXUP##>> ;[632]
|
||
ADD T1,FX.LB ;ADD IN BASE
|
||
HRRZ T2,DCBUF+1 ;ADDRESS OF FIXED DY AREA ARRAY
|
||
HRLZ T3,T1 ;FROM
|
||
HRR T3,T2 ;TO
|
||
BLT T3,.IPS-1(T2) ;UNTIL
|
||
MOVEI T2,.IPS ;NOW GIVE BACK
|
||
PUSHJ P,FX.RET##
|
||
PUSHJ P,.POP4T## ;RESTORE T1-T4
|
||
POPJ P, ;AND RETURN
|
||
|
||
;HERE WHEN ALL DONE
|
||
T5FIN:: PUSHJ P,FX.GBC## ;GARBAGE COLLECT FX AREA
|
||
HRRZ T1,DCBUF+1 ;WHERE WE ARE NOW
|
||
ADD T1,DCBUF+2 ;+ WHATS LEFT
|
||
SUBI T1,.IPS-1 ;BACKUP
|
||
SKIPE (T1) ;BETTER HAVE FINISHED
|
||
HALT
|
||
MOVEI T2,.IPS ;GIVE BLOCK BACK
|
||
PUSHJ P,DY.RET##
|
||
POP P,DCBUF+2
|
||
POP P,DCBUF+1
|
||
POP P,DCBUF
|
||
JRST T.LOAD ;GET NEXT BLOCK
|
||
SUBTTL HERE TO TERMINATE LOAD
|
||
|
||
|
||
GO:: PUSHJ P,LIBRARY ;LOAD DEFAULT LIBS
|
||
MOVE T1,SYMSEG ;GET /SYMSEG
|
||
SKIPN NOSYMS ;NO SYMBOLS AVAILABLE?
|
||
CAIN T1,$SSGNONE ;[1201] USER GIVE /SYMSEG:NONE?
|
||
JRST [SETZM SYMSEG ;YES, TELL LNKXIT
|
||
JRST GOSTRT] ;DEFINE START ADDRESS
|
||
CAIE T1,$SSGHIGH ;[1246] WANT SYMBOLS IN HIGH SEGMENT?
|
||
JRST GOSYM ;[1246] NO - CHECK DEFAULT
|
||
SKIPE HC.LB ;[1246] HIGH SEG EXIST YET?
|
||
JRST GOSTRT ;[1246] YES - NO NEED TO CREATE ONE
|
||
SETZ W1, ;[1246] USE DEFAULT ORIGIN
|
||
PUSHJ P,SETRC## ;[1246] AND SET UP THE HIGH SEGMENT
|
||
MOVEI T1,$SSGHIGH ;[1246] RESTORE T1 TO /SYMSEG:HIGH
|
||
GOSYM: JUMPN T1,GOSTRT ;OK IF USER SPECIFIED
|
||
IFN TOPS20,<
|
||
MOVEI T1,$SSGLOW ;[1201] OTHERWISE, DEFAULT TO LOW
|
||
MOVEM T1,SYMSEG ;STORE FOR LNKXIT
|
||
> ;END IFN TOPS20
|
||
GOSTRT: SKIPN W2,STADDR+1 ;IS START ADDRESS STILL SYMBOLIC?
|
||
JRST GOUPTO ;[1175] NO
|
||
MOVX W1,PT.SGN!PT.SYM
|
||
PUSHJ P,TRYSYM## ;SEE IF DEFINED BY NOW
|
||
JRST NOSTRT ;[1232] UNDEFINED
|
||
JRST NOSTRT ;[1232] UNDEFINED
|
||
MOVE T1,2(P1) ;GET VALUE
|
||
ADDM T1,STADDR ;CALCULATE VALUE
|
||
SETZM STADDR+1 ;NOW KNOWN
|
||
JRST GOUPTO ;[1175] GO CHECK /UPTO
|
||
|
||
;HERE WHEN THE START ADDRESS IS UNDEFINED.
|
||
|
||
NOSTRT: PUSHJ P,E$$USA ;[1232] NOTIFY THE USER
|
||
JRST GOUPTO ;[1232] GO CHECK /UPTO:
|
||
|
||
E$$USA::.ERR. (MS,.EC,V%L,L%W,S%W,USA,<Undefined start address >) ;[1174]
|
||
.ETC. (SBX,.EP,,,,W2) ;[1174]
|
||
SETZM STADDR ;[1175] CLEAR ADDRESS
|
||
SETZM STADDR+1 ;[1175] ...
|
||
POPJ P, ;[1232] DONE
|
||
;NOW TO CHECK THE /UPTO SYMBOL, IF ANY
|
||
|
||
GOUPTO: MOVE W2,SYMLIM ;[1175] GET /UPTO VALUE
|
||
SKIPN SYMLMS ;[2220] SYMBOLIC?
|
||
JRST GOUSYM ;[1175] NO
|
||
MOVX W1,PT.SGN!PT.SYM ;[1175] FLAGS
|
||
PUSHJ P,TRYSYM## ;[1175] SEE IF DEFINED
|
||
JRST E$$UUA ;[1175] NO
|
||
JRST E$$UUA ;[1175] NO
|
||
MOVE T1,2(P1) ;[1175] YES, FETCH VALUE
|
||
MOVEM T1,SYMLIM ;[1175] STORE FOR LNKXIT
|
||
SETZM SYMLMS ;[2220] NO LONGER SYMBOLIC
|
||
JRST GOUSYM ;[1175] GO CHECK UNDEFINED SYMBOLS
|
||
|
||
|
||
;HERE IF THE /UPTO ADDRESS IS UNDEFINED.
|
||
|
||
E$$UUA::.ERR. (MS,.EC,V%L,L%W,S%W,UUA,<Undefined /UPTO: address >)
|
||
.ETC. (SBX,.EP,,,,W2) ;[1175]
|
||
SETZM SYMLIM ;[1175] NO LIMIT
|
||
SETZM SYMLMS ;[2220] AND NOT SYMBOLIC
|
||
; ..
|
||
; ..
|
||
|
||
;HERE TO MAKE A LAST-DITCH TRY AT DEFINING THE LAST UNDEFINED SYMBOL.
|
||
|
||
GOUSYM: SKIPN USYM ;STILL SOME UNDEFS?
|
||
JRST LODXIT ;NO, GIVE UP
|
||
MOVX W1,PT.SGN!PT.SYM ;MIGHT BE ALGOL REFERENCE
|
||
MOVE W2,['%OWN ']
|
||
SETZ W3,
|
||
PUSHJ P,TRYSYM## ;SEE IF PENDING REQUEST
|
||
CAIA ;NOT IN TABLE
|
||
JRST DEFOWN ;YES, NEEDS DEFINING
|
||
|
||
|
||
;HERE TO EXIT
|
||
;GO EITHER TO LNKMAP OR LNKXIT
|
||
|
||
LODXIT: MOVEI T1,TP.IX ;[2270] NOW DELETE TYPECHECKING AREA
|
||
PUSHJ P,XX.ZAP## ;[2270] GET RID OF IT
|
||
PUSHJ P,RETPSC ;[2270] RETURN PSECT/COMMON BLOCKS
|
||
MOVEI R,1 ;[1305] SET UP FOR LOW SEG
|
||
MOVE R,@SG.TB ;[1305]
|
||
MOVE T1,HP.S1 ;[1305] GET .LOW. PSECT BREAK
|
||
CAMLE T1,RC.HL(R) ;[1305] IS IT HIGHER?
|
||
MOVEM T1,RC.HL(R) ;[1305] PUT IT IN THE PSECT BLOCK
|
||
SKIPN LL.S2 ;[1305] IS THERE A HIGH SEG?
|
||
JRST LODXI1 ;[1305] NO - IGNORE HP.S2
|
||
MOVEI R,2 ;[1305] SET UP FOR HIGH SEG
|
||
MOVE R,@SG.TB ;[1305]
|
||
MOVE T1,HP.S2 ;[1305] GET .HIGH. PSECT BREAK
|
||
CAMLE T1,RC.HL(R) ;[1305] IS IT HIGHER?
|
||
MOVEM T1,RC.HL(R) ;[1305] PUT IT IN THE PSECT BLOCK
|
||
LODXI1: SKIPE USYM ;ANY UNDEFINED SYMBOLS?
|
||
PUSHJ P,LODUGS ;[1174] PRINT UNDEFINED GLOBALS MESSAGE
|
||
HLRZ P1,INCPTR ;GET GLOBAL INCLUDE POINTER
|
||
JUMPN P1,[TLO P1,100 ;SET LH POSITIVE AS ERROR
|
||
MOVEI T1,[ASCIZ \?LNKIMM \]
|
||
PUSHJ P,MISNG1##
|
||
JRST .+1] ;AND REENTER MAIN STREAM
|
||
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 ;FORGET ABOUT IT
|
||
PUSHJ P,LODFIX ;DO ALL FIXUPS WE NEED
|
||
PUSHJ P,ALGCHK ;SEE IF ALGOL SYMBOL FILE NEEDED
|
||
MOVEI T3,1 ;[704] USED FOR LOOP CONTROL IN SRT.RC
|
||
PUSHJ P,SRT.RC ;[704] YES, GO SORT THE RELOC TABLES
|
||
IFN TOPS20,< ;[2242]
|
||
PUSHJ P,CHK.RC ;[2242] MAKE SURE ALL PAGES EXIST
|
||
> ;[2242] IFN TOPS20
|
||
MOVE T1,MAPSW ;SEE IF WE NEED A MAP
|
||
CAME T1,[$MAPEND] ;AT THE END
|
||
JRST LNKXIT ;NO
|
||
JRST LNKMAP ;YES
|
||
|
||
LODUGS: MOVE T1,[PUSHJ P,UNDNXT##] ;[1174] SET UP NEXT SYMBOL ROUTINE
|
||
MOVEM T1,NXTGLB ;[1174] ..
|
||
MOVE W3,HT.PRM ;[1174] SET UP INDEX TO HASH TABLE
|
||
ADDI W3,1 ;[1174] START 1 UP FOR SOSGE IN UGSNXT
|
||
E01UGS::.ERR. (MS,.EC,V%L,L%F,S%C,UGS) ;[1174]
|
||
.ETC. (JMP,,,,,.ETUGS##) ;[1174] PRINT UNDEF'ED GLOBALS AND RETURN
|
||
|
||
;[2227] Here to return the common/psect blocks
|
||
RETPSC: SKIPN R,CPSECT ;[2227] Get the base of the list
|
||
POPJ P, ;[2227] Nothing to do
|
||
RETPS0: HLRZ T2,PC.PSC(R) ;[2227] Get the psect name
|
||
TRNE T2,770000 ;[2227] Short symbol?
|
||
JRST RETPS1 ;[2227] Yes, don't return much
|
||
HRRZ T1,PC.PSC(R) ;[2227] Get it's address
|
||
PUSHJ P,DY.RET## ;[2227] Give it back
|
||
RETPS1: HLRZ T2,PC.CMN(R) ;[2227] Get the common name
|
||
TRNE T2,770000 ;[2227] Short symbol?
|
||
JRST RETPS2 ;[2227] Yes, don't return much
|
||
HRRZ T1,PC.CMN(R) ;[2227] Get it's address
|
||
PUSHJ P,DY.RET## ;[2227] Give it back
|
||
RETPS2: MOVE T1,R ;[2227] Get the block address
|
||
MOVEI T2,PC.SIZ ;[2227] And the length
|
||
MOVE R,PC.LNK(R) ;[2227] Point to the next one
|
||
PUSHJ P,DY.RET## ;[2227] Give this one back
|
||
JUMPN R,RETPS0 ;[2227] Return them all
|
||
POPJ P, ;[2227] Done
|
||
|
||
;[704] HERE TO SORT THE PSECT RELOCATION TABLES BY ORDER OF
|
||
;[704] THEIR ORIGINS BEFORE DOING THE MAP OR EXIT.
|
||
;[704] USES T1,T2,T3,W1 AND R
|
||
;[747] ONCE THE SORT IS DONE, UPDATE LOWLOC and then
|
||
;[746] jump to check PSECT boundaries for any overlap.
|
||
|
||
SRT.RC: CAML T3,RC.NO ;[704] FINISHED?
|
||
JRST CHKLLC ;[747] YES, UPDATE LOWLOC
|
||
MOVE R,RC.NO ;[704] NO, START FROM THE END
|
||
SRT.R2: MOVE T1,@RC.TB ;[704] GET TABLE ADDRESS
|
||
SUBI R,1 ;[704] NEXT TABLE DOWN
|
||
MOVE T2,@RC.TB ;[704] ITS ADDRESS
|
||
MOVE W2,T2 ;[704] SAVE IT ALSO IN W2, INCASE OF EXCHANGE
|
||
MOVE W1,RC.IV(T1) ;[704] GET ORIGIN OF FIRST ONE
|
||
CAMGE W1,RC.IV(T2) ;[704] COMPARE WITH THE ORIGIN OF THE SECOND
|
||
JRST [ADDI R,1 ;[704] FIRST ON IS LESS, SO SWAP
|
||
EXCH W2,@RC.TB ;[704] THE TABLE ADDRESSES
|
||
SUBI R,1 ;[704]
|
||
MOVEM W2,@RC.TB ;[704]
|
||
JRST .+1] ;[704]
|
||
JUMPG R,SRT.R2 ;[704] LOOP BACK IF MORE TABLES
|
||
AOJA T3,SRT.RC ;[704] LOOP FOR ANOTHER SORT PASS
|
||
|
||
;[747] HERE TO UPDATE LOWLOC.
|
||
|
||
CHKLLC:
|
||
IFE TOPS20,< ;[2247]
|
||
SKIPN LOWLOC ;[747] IF LOWLOC IS ZERO ALREADY
|
||
JRST CHKLL1 ;[760][747] DON'T NEED TO CHECK
|
||
SETZ R, ;[747] GET .ABS.
|
||
MOVE T1,@RC.TB ;[747]
|
||
MOVE W1,RC.HL(T1) ;[1215] USE HIGHEST LOC EVER SEEN
|
||
MOVEI R,1 ;[747] GET .LOW.
|
||
MOVE T2,@RC.TB ;[747]
|
||
MOVE W2,RC.HL(T2) ;[1215] USE HIGHEST LOCATION EVER SEEN
|
||
SKIPN W1 ;[2065] ANYTHING IN .ABS.?
|
||
CAILE W2,140 ;[2065] OR IN .LOW.?
|
||
JRST [SETZM LOWLOC ;[747] YES,
|
||
JRST CHKLL1] ;[760][747] NOW, GO CHECK PSECT OVERLAP
|
||
AOS R ;[747] NOTHING IN .LOW.
|
||
CAMLE R,RC.NO ;[1132] NEXT PSECT ORG MUST BE LOWEST
|
||
JRST [SETZM LOWLOC ;[1132] NO NEXT, LOWLOC IS ZERO
|
||
JRST CHKLL1] ;[1132] DONE
|
||
MOVE T1,@RC.TB ;[1132] GET POINTER TO RC BLOCK
|
||
MOVE W1,RC.IV(T1) ;[747]
|
||
CAMGE W1,LOWLOC ;[747]
|
||
MOVEM W1,LOWLOC ;[747] IN THAT CASE, UPDATE
|
||
CHKLL1: ;[2247]
|
||
>;[2247] IFE TOPS20
|
||
;FALL THROUGH TO NEXT PAGE
|
||
;HERE TO UPDATE HL.S1 FROM PSECT INFO, IF NEEDED
|
||
|
||
MOVE R,RC.NO ;[2247] POINT TO HIGHEST PSECT
|
||
CHKLL2: MOVE T1,@RC.TB ;[1106] GET POINTER TO THIS RC BLOCK
|
||
MOVE T2,RC.SG(T1) ;[1106] GET SEGMENT NUMBER
|
||
CAIN T2,1 ;[1106] LOW SEG?
|
||
JRST CHKLL3 ;[1106] GOT HIGHEST PSECT, GO FIX HL.S1
|
||
SOJGE R,CHKLL2 ;[1106] NO, LOOP OVER OTHER RELOC. COUNTERS
|
||
JRST CHKLL4 ;[1106] NONE FOUND, DONE
|
||
|
||
;HERE WHEN WE HAVE FOUND THE HIGHEST RC IN THE LOW SEG (A PSECT)
|
||
CHKLL3: SKIPN T2,RC.HL(T1) ;[1106] GET HL IF AVAILABLE
|
||
MOVE T2,RC.CV(T1) ;[1106] OR CV IF ITS NOT
|
||
CAMLE T2,HL.S1 ;[1106] POINT BEYOND CURRENT HL.S1?
|
||
MOVEM T2,HL.S1 ;[1106] YES, UPDATE WITH NEW VALUE
|
||
CHKLL4: MOVE R2,RC.NO ;[1106] USED IN CHKBND FOR LOOP CONTROL
|
||
; JRST CHKBND ;[760]
|
||
;[746] HERE TO CHECK FOR PSECT OVERLAP. IF OVERLAP IS FOUND
|
||
;A WARNING IS OUTPUT AND RETURN.
|
||
|
||
CHKBND: MOVE R,R2 ;[760][746] START FROM THE END
|
||
MOVE T1,@RC.TB ;[760][746] GET RELOC TABLE POINTER
|
||
MOVE T2,RC.HL(T1) ;[1204] HIGHEST EVER LOADED
|
||
MOVE T3,RC.CV(T1) ;[1204] WHERE NEXT WORD GOES
|
||
MOVE W1,RC.IV(T1) ;[746] GET THE ORIGIN
|
||
CHKBN1: SOJLE R,CHKBN2+1 ;[760] CHECK WITH ALL LOWER PSECTS
|
||
MOVE T2,@RC.TB ;[746] GET TABLE PTR TO PSECT BEFORE
|
||
MOVE W2,RC.CV(T2) ;[760][746] AND ITS CURRENT VALUE
|
||
CAML W1,W2 ;[746] ANY OVERLAP?
|
||
JRST CHKBN2 ;[760][746] NO, LOOP
|
||
CAMLE W2,RC.CV(T1) ;[760] MIN OF THE TWO RC.CV'S
|
||
MOVE W2,RC.CV(T1) ;[760]
|
||
CAMGE W1,RC.IV(T2) ;[760] MAX OF THE TWO RC.IV'S
|
||
MOVE W1,RC.IV(T2) ;[760]
|
||
SKIPGE RC.AT(T2) ;[2247] HAS THE PSECT BEEN USED?
|
||
JRST CHKBN2 ;[2247] NO (MUST BE UNUSED .LOW.)
|
||
PUSH P,T1 ;[1234] SAVE PTR TO PSEG
|
||
MOVE T1,RC.NM(T1) ;[746] SET UP TO OUTPUT WARNING
|
||
MOVE T2,RC.NM(T2) ;[746] GET THE TWO PSECT NAMES
|
||
E$$POV::.ERR. (MS,.EC,V%L,L%W,S%W,POV,<Psects >) ;[1174]
|
||
.ETC. (SBX,.EC!.EP,,,,T1) ;[1174]
|
||
.ETC. (STR,.EC,,,,,< and >)
|
||
.ETC. (SBX,.EC!.EP,,,,T2) ;[1174]
|
||
.ETC. (STR,.EC,,,,,< overlap from address >) ;[1212]
|
||
.ETC. (OCT,.EC!.EP,,,,W1) ;[1174]
|
||
.ETC. (STR,.EC,,,,,< to >)
|
||
.ETC. (OCT,.EP,,,,W2) ;[1174]
|
||
POP P,T1 ;[1234] RESTORE PTR TO PSEG
|
||
CHKBN2: JUMPG R,CHKBN1 ;[760] LOOP DOWN IF MORE IN THIS SWEEP
|
||
SOJG R2,CHKBND ;[760] NEXT PSECT
|
||
POPJ P, ;[760] ALL DONE
|
||
LODFIX::SKIPN W1,LINKTB ;ANY BLOCK TYPE 12 LINKS?
|
||
JRST B12NOT ;NO
|
||
HRLI W1,-LN.12 ;FORM AOBJN WORD
|
||
B12LUP: MOVE T2,LN.12(W1) ;[2273] GET END ADDRESS
|
||
JUMPE T2,B12END ;NONE
|
||
MOVE W3,(W1) ;[2273] LAST ADDRESS
|
||
PUSHJ P,SEGCHK ;GET IN CORE ADDRESS
|
||
JRST [TXO T2,CPF.RR ;[2200] NOT IN CORE
|
||
PUSHJ P,SY.CHP ;SO PUT IN FIXUP LIST
|
||
JRST B12END] ;AND RETURN FOR NEXT
|
||
HRRM W3,(T2) ;STORE IN CORE
|
||
B12END: AOBJN W1,B12LUP ;LOOP FOR ALL ITEMS
|
||
HRRZ T1,LINKTB ;ADDRESS OF TABLE
|
||
MOVEI T2,2*LN.12 ;[2273] LENGTH
|
||
PUSHJ P,DY.RET## ;GIVE IT BACK
|
||
SETZM LINKTB ;[737] CLEAR POINTER
|
||
B12NOT: SKIPN P1,PRGPTR ;ANY BLOCK TYPE 16 TO RETURN?
|
||
JRST B16NOT ;NO
|
||
B16RET: MOVEI T1,(P1) ;ADDRESS
|
||
MOVEI T2,4 ;SIZE
|
||
HRRZ P1,(P1) ;NEXT
|
||
PUSHJ P,DY.RET## ;RETURN SPACE
|
||
JUMPN P1,B16RET ;LOOP
|
||
SETZM PRGPTR ;[1103] REMEMBER THAT WE'RE DONE
|
||
B16NOT: PJRST COR.FX ;FIXUP ALL CODE CHAINS
|
||
|
||
IFN TOPS20,< ;[2242]
|
||
;[2242] Here to make sure all sections exist
|
||
;[2243] Also insure that that RC.HL is not below RC.CV
|
||
;[2242] Uses R, W1, W2, P1, and T1-T4 (in RC.CHK)
|
||
|
||
CHK.RC: MOVE R,RC.NO ;[2242] Start at the last psect
|
||
RCCHK0: MOVE W1,@RC.TB ;[2242] Get pointer to RC block
|
||
MOVE W2,RC.CV(W1) ;[2243] Get current value
|
||
CAMLE W2,RC.HL(W1) ;[2243] Higher than "highest loaded"?
|
||
MOVEM W2,RC.HL(W1) ;[2243] Yes, probably /REDIRECT - fix it
|
||
MOVE W2,RC.IV(W1) ;[2242] Get the base of the psect
|
||
CAML W2,RC.HL(W1) ;[2262] Empty psect?
|
||
JRST RCCHK2 ;[2242] Yes, don't create section
|
||
HLLZS W2 ;[2242] Make it section,,0
|
||
RCCHK1: MOVE P1,W2 ;[2242] Put it in in correct AC
|
||
MOVE T4,RC.SG(W1) ;[2242] Get the index
|
||
SKIPE P1 ;[2242] Don't bother for section zero
|
||
PUSHJ P,NEWSCT## ;[2242] Make sure it exists
|
||
ADD W2,[1,,0] ;[2242] Next section
|
||
CAMGE W2,RC.HL(W1) ;[2243] This section in psect?
|
||
JRST RCCHK1 ;[2242] Yes, create it too
|
||
RCCHK2: SOJG R,RCCHK0 ;[2242] Done with this one, do others
|
||
POPJ P, ;[2242] No more
|
||
>;[2242] IFN TOPS20
|
||
|
||
;HERE TO SETUP FILE/SYMBOL:ALGOL IF NEEDED, AND STORE THE
|
||
;FILESPEC IN THE FIRST ALGOL OWN BLOCK SEEN THIS LOAD
|
||
|
||
|
||
ALGCHK::SKIPN NOSYMS ;[1265] /NOSYMS? (AFTER 1044 SEEN)
|
||
JRST ALGCH2 ;NO
|
||
ALGCH1: MOVEI T1,AC ;POINT TO ALGOL CHANNEL
|
||
SKIPE PAG.AS ;AS AREA PAGING?
|
||
PUSHJ P,DVDEL.## ;YES, DELETE OVERFLOW FILE
|
||
SETZM LW.AS ;ZAP PAGING POINTERS
|
||
SETZM UW.AS ;..
|
||
MOVEI T1,AS.IX ;NOW DELETE AREA
|
||
PJRST XX.ZAP## ;SO LNKXIT WILL HAVE MORE ROOM
|
||
|
||
;HERE IF NOT /NOSYMBOLS
|
||
ALGCH2: SKIPE T1,SYMFRM ;USER SAY /SYMBOL?
|
||
CAIN T1,2 ;YES, /SYMBOL:ALGOL?
|
||
CAIA ;YES, GIVE IT TO HIM
|
||
JRST ALGCH1 ;NO, FORGET WE EVER SAW 1044
|
||
JUMPN T1,ALGCH3 ;DON'T DEFAULT IF USER SPECIFIED
|
||
MOVX T1,ALGBIT ;GET BIT FOR ALGOL
|
||
TDNE T1,MNSEEN ;SEEN AN ALGOL MAIN PROGRAM?
|
||
SKIPN AS.LB ;AND SOME ALGOL SYMBOLS?
|
||
JRST ALGCH1 ;NO
|
||
MOVEI T1,2 ;DEFAULT TO /SYMBOL:ALGOL
|
||
MOVEM T1,SYMFRM ;SINCE USER DIDN'T SAY
|
||
MOVEI T2,F.LEN ;NEED A TEMP IO DATA BLOCK
|
||
PUSHJ P,DY.GET## ;FROM THE DY AREA
|
||
MOVE P1,T1 ;SAVE ADDR FOR DV.OUT
|
||
MOVE T1,LODNAM ;USE MAIN PROG NAME AS FILE NAME
|
||
MOVEM T1,F.NAME(P1) ;SAVE IN BLOCK
|
||
MOVSI T1,'SYM' ;EXTENSION '.SYM'
|
||
MOVEM T1,F.EXT(P1) ;SAVE FOR LNKFIO
|
||
PUSHJ P,DVOUT.## ;MAKE SCAN BLOCK INTO IO BLOCK
|
||
%SC,,.IODPR ;SYMBOL CHANNEL, DUMP RECORDS MODE
|
||
MOVE T1,P1 ;DONE WITH SCAN BLOCK
|
||
MOVEI T2,F.LEN ;SO RETURN IT TO DY AREA
|
||
PUSHJ P,DY.RET## ;..
|
||
MOVE T1,IO.PTR+%SC ;[1230] FORCE ALGOL SYM FILE TO
|
||
MOVX T2,<Z AC,> ;[1230] USE CHANNEL AC
|
||
MOVEM T2,I.CHN(T1) ;[1230] ..
|
||
ALGCH3: SKIPN SYMSEG ;USER SPECIFY WHERE SYMBOLS GO?
|
||
AOS SYMSEG ;NO, PUT THEM IN LOW SEG (ALGOL 7)
|
||
SKIPN P3,ASFILE ;LOW ADDRESS OF DESCRIPTOR
|
||
POPJ P, ;NO TYPE 15 SEEN, DON'T FILL IN
|
||
MOVEI P2,LN.ABL(P3) ;TOP ADDRESS OF DESCRIPTOR
|
||
SKIPE PAG.S1 ;PAGING LOWSEG?
|
||
PUSHJ P,PG.LSG ;YES, MAKE SURE BLOCK ADDRESSABLE
|
||
ADD P3,LC.LB ;MAKE ABSOLUTE PHYSICAL ADDRESS
|
||
HRRZ T1,IO.PTR+%SC ;ADDRESS OF FILE INFO
|
||
MOVE T2,I.DEV(T1) ;GET DEVICE OUT OF IO BLOCK
|
||
MOVEM T2,0(P3) ;MAKE 1ST WORD OF OTS DESCRIPTOR
|
||
MOVE T2,I.NAM(T1) ;SAME FOR FILE NAME
|
||
MOVEM T2,1(P3) ;IT BECOMES 2ND WORD
|
||
HLLZ T2,I.EXT(T1) ;EXTENSION...
|
||
MOVEM T2,2(P3) ;...INTO 3RD WORD
|
||
SKIPN T2,I.PPN(T1) ;GET PPN IF SPECIFIED
|
||
JRST ALGCH5 ;NOT, USE DEFAULT PATH
|
||
TLNE T2,-1 ;POINTER TO PATH?
|
||
JRST ALGCH4 ;NO
|
||
SKIPN T3,2(T2) ;YES, GET PPN
|
||
MOVE T3,PTHDIR ;OR DEFAULT PATH IF NOT SPECIFIED
|
||
MOVEM T3,3(P3) ;STORE AS WORD 4 FOR ALGOL
|
||
MOVSI T3,3(T2) ;MAKE BLT POINTER FOR SFD'S
|
||
HRRI T3,4(P3) ;INTO WORDS 5-9 OF BLOCK
|
||
BLT T3,11(P3) ;COPY SFD'S & TRAILING ZERO
|
||
POPJ P, ;FINISHED
|
||
|
||
ALGCH4: MOVEM T2,3(P3) ;STORE PPN IN CORE
|
||
SETZM 4(P3) ;INDICATE NO SFD'S
|
||
POPJ P, ;DONE
|
||
|
||
ALGCH5: MOVSI T2,PTHDIR ;WANTS DEFAULT - BLT OUR DEFAULT
|
||
HRRI T2,3(P3) ; PATH INTO THE ALGOL OWN BLOCK
|
||
BLT T2,11(P3) ;BLLLLLLLLLLIIIIIIIITTTTTTTT
|
||
POPJ P, ;DONE AT LAST
|
||
LIBRARY::
|
||
POP P,T1 ;RESTACK TOP 2 ITEMS
|
||
EXCH T1,(P) ;SO WE RETURN TO MAIN CALLER
|
||
PUSH P,T1 ;UNTIL ALL LOADED
|
||
IFN FTOVERLAY,<
|
||
SKIPE OVERLW ;SEEN /OVERLAY?
|
||
SKIPL LNKMAX ;AND STILL IN ROOT?
|
||
JRST PRGTST ;NO
|
||
TDO FL,[L.LIB,,R.LIB] ;FORCE LIBRARY SEARCH MODE
|
||
HLRZ P4,MNTYPE ;[1256] GET MAIN PROCESSOR TYPE
|
||
JUMPN P4,LIBOVL ;[1256] IS THERE ONE?
|
||
MOVE T1,LIBPRC ;[1256] NO - GET THE LIST OF ONES USED
|
||
ANDCM T1,NOLIBS ;[1256] BUT NOT THE ONES ELIMINATED
|
||
JFFO T1,.+1 ;[1256] FIND THE NUMBER OF THE FIRST ONE
|
||
MOVE P4,T2 ;[1256] PUT IT AS ARG FOR QREENT
|
||
LIBOVL: ;[1256]
|
||
PUSHJ P,QREENT ;WANT REENTRANT VERSION?
|
||
CAIA ;NO, LOAD AS IS
|
||
TRO FL,R.FLS ;YES, FORCE LOW SEG
|
||
MOVEI T2,F.LEN ;GET SPACE
|
||
PUSHJ P,DY.GET## ;FOR FILE SPEC
|
||
MOVSI T3,'SYS' ;DEFAULT DEVICE
|
||
MOVE T4,['OVRLAY'] ;FILE NAME
|
||
DSTORE T3,F.DEV(T1),F.NAME(T1)
|
||
MOVSI T3,'REL'
|
||
SETOM F.NAMM(T1) ;SET MASK
|
||
HLLOM T3,F.EXT(T1)
|
||
PUSHJ P,LNKPRG ;PUT IN LIST
|
||
; JRST PRGTST
|
||
>
|
||
PRGTST: SKIPG PRGPTR ;ANYTHING TO DO HERE
|
||
JRST LIBTST ;NO, SEE IF ANY LIBRARIES
|
||
TDZ FL,[L.LIB,,R.LIB] ;INCASE WE WERE IN SEARCH MODE
|
||
PUSH P,P1 ;NEED AN ACC
|
||
MOVE P1,PRGPTR ;GET START
|
||
PRGTS1: SKIPGE (P1) ;WANT THIS ONE?
|
||
JRST PRGTS2 ;NO, ALREADY LOADED
|
||
MOVEI T2,F.LEN ;GET SPACE FOR DATA BLOCK
|
||
PUSHJ P,DY.GET##
|
||
MOVE T2,P1 ;GET POINTER TO TYPE 16 BLOCK
|
||
PUSHJ P,PRGLIB ;TRANSFORM AND LINK IN
|
||
HRROS (P1) ;MARK AS LOADED
|
||
PRGTS2: HRRZ P1,(P1) ;GET NEXT ADDRESS
|
||
JUMPN P1,PRGTS1 ;NOT DONE YET IF NON-ZERO
|
||
HRROS PRGPTR ;MARK WHOLE LIST DONE
|
||
POP P,P1
|
||
PUSHJ P,NXTLIB ;SETUP RETURN ADDRESS
|
||
JRST PRGTST ;SEE IF WE LOADED ANY MORE TYPE 16 BLOCKS
|
||
|
||
LIBTST: SKIPN LIBPTR ;ANY LIBRARIES
|
||
JRST USETST ;NO TRY USER DEFAULT LIBRARY(S)
|
||
SKIPN USYM ;YES, BUT ANY NEED FOR THEM
|
||
JRST REMLIB ;NO REMOVE THE SPACE THEY OCCUPY
|
||
TDO FL,[L.LIB,,R.LIB] ;GET INTO LIBRARY SEARCH MODE
|
||
MOVEI T2,F.LEN ;GET SPACE FOR DATA BLOCK
|
||
PUSHJ P,DY.GET##
|
||
MOVE T2,LIBPTR ;GET POINTER TO TYPE 17 BLOCK
|
||
PUSHJ P,PRGLIB ;TRANSFORM AND LINK IN
|
||
MOVE T1,LIBPTR ;GET POINTER BACK
|
||
MOVE T2,(T1) ;GET NEXT ADDRESS
|
||
MOVEM T2,LIBPTR ;AND STORE IT (ZERO IS END)
|
||
MOVEI T2,4 ;GIVE BACK BLOCK
|
||
PUSHJ P,DY.RET##
|
||
SKIPN LIBPTR ;NOT DONE YET IF NON-ZERO
|
||
PUSHJ P,NXTLIB
|
||
JRST PRGTST ;INCASE WE LOADED ANY MORE TYPE 16 OR 17
|
||
;HERE FOR USER DEFINED DEFAULT LIBRARIES
|
||
|
||
USETST: SKIPE USYM ;ANY UNDEFS LEFT?
|
||
SKIPG USEPTR ;ANY LIBRARIES
|
||
JRST DEFTST ;NO, TRY SYSTEM DEFAULTS
|
||
HRROS USEPTR ;ONLY ONCE THOUGH
|
||
PUSH P,P1 ;NEED A SAFE ACC
|
||
MOVE P1,USEPTR ;TO HOLD PTR TO LIST
|
||
USETS1: MOVE T1,1(P1) ;[1315] GET LANGUAGE TYPE BITS
|
||
TDNN T1,PROCSN ;HAVE WE LOADED THIS TYPE?
|
||
JRST USETS3 ;NO, GIVE IT A MISS
|
||
USETS2: MOVEI T2,F.LEN ;SPACE WE NEED
|
||
PUSHJ P,DY.GET## ;FOR LOOKUP BLOCK
|
||
ADDI T2,-1(T1) ;END OF BLT
|
||
MOVEI T3,2(T1) ;BYPASS FIRST 2 WORDS
|
||
HRLI T3,2(P1) ;BLT PTR
|
||
BLT T3,(T2) ;MOVE TO TEMP BLOCK
|
||
PUSHJ P,LNKPRG ;PUT IN LIST
|
||
USETS3: HRRZ P1,(P1) ;GET NEXT
|
||
JUMPN P1,USETS1 ;DO IT
|
||
POP P,P1
|
||
TDO FL,[L.LIB,,R.LIB] ;[613] MAKE SURE IN /SEARCH MODE
|
||
PUSHJ P,NXTLIB ;[613] LOAD THE USER LIBRARIES
|
||
; JRST DEFTST ;NOW FOR SYSTEM DEFAULT LIBS
|
||
DEFTST: SKIPN USYM ;ANYTHING TO DO?
|
||
JRST DEFXIT ;NO, RETURN TO LNKOV1 OR LNKLOD
|
||
TDO FL,[L.LIB,,R.LIB] ;MAKE SURE
|
||
PUSHJ P,DEFLOD ;YES, TRY DEFAULT LIBS
|
||
PUSHJ P,NXTLIB
|
||
SKIPG PRGPTR ;SEE IF WE LOADED ANYMORE 16
|
||
SKIPE LIBPTR ;OR 17 BLOCKS
|
||
JRST PRGTST ;YES, CYCLE AGAIN
|
||
SKIPE LIBPRC ;DID WE LOAD ANYTHING?
|
||
JRST DEFTST ;YES, TRY AGAIN
|
||
MOVX W1,PT.SGN!PT.SYM ;FLAGS
|
||
MOVE W2,['%OWN '] ;SYMBOL
|
||
SETZ W3, ;TRY AGAIN FOR %OWN
|
||
PUSHJ P,TRYSYM##
|
||
CAIA ;NOT IN TABLE
|
||
JRST DEFOWN ;UNDEFINED
|
||
DEFXIT: SETZM GOTO ;BACK TO NORMAL SCANNING
|
||
HRRZS USEPTR ;BACK AS IT WAS
|
||
TPOPJ: POP P,T1 ;REMOVE TOP RETURN
|
||
POPJ P, ;RETURN TO REAL CALLER
|
||
|
||
DEFOWN: MOVE W3,%OWN ;GET BASE
|
||
PUSHJ P,SY.GS## ;DEFINE
|
||
JRST DEFXIT
|
||
|
||
|
||
NXTLIB: POP P,GOTO ;STORE RETURN ADDRESS
|
||
JRST LNKWLD ;AND LOAD THIS
|
||
PRGLIB: DGET T3,<R.DEV(T2)>,<R.NAM(T2)> ;GET DEV & FILE NAME
|
||
DSTORE T3,F.DEV(T1),F.NAME(T1)
|
||
SETOM F.NAMM(T1) ;SET MASK
|
||
MOVE T3,R.EXT(T2) ;GET USER EXTENSION
|
||
HLLOM T3,F.EXT(T1) ;STORE WITH -1 MASK
|
||
MOVX T4,FX.DIR ;[672] BIT THAT SAYS DIR SPECIFIED
|
||
MOVEM T4,F.MODM(T1) ;[672] SAY TO LOOK AT IT
|
||
SKIPE T3,R.PPN(T2) ;[672] GET PPN, IF ANY
|
||
MOVEM T4,F.MOD(T1) ;[672] THERE WAS, REMEMBER IT
|
||
MOVEM T3,F.DIR(T1)
|
||
SETOM F.DIRM(T1) ;MUST MATCH EXACTLY
|
||
HRLI T2,-5 ;SET UP TO COPY ANY SFD'S
|
||
MOVE T4,T1
|
||
PRGSFD: SKIPN T3,R.SFD(T2) ;ANY MORE THERE?
|
||
JRST LNKPRG ;NO...WE'RE DONE
|
||
MOVEM T3,F.SFD(T4) ;STORE THE SFD
|
||
SETOM F.SFDM(T4) ;MUST MATCH EXACTLY
|
||
ADDI T4,2 ;SFD'S COME IN BIWORDS FOR SCAN
|
||
AOBJN T2,PRGSFD ;LOOP FOR ALL SFD'S
|
||
;NOW TO LINK INTO LIST
|
||
LNKPRG: SKIPN F.INZR ;FIRST TIME?
|
||
JRST FSTPRG ;YES
|
||
MOVE T2,F.NXZR ;GET CURRENT
|
||
MOVEM T1,(T2) ;STORE FORWARD POINTER
|
||
MOVEM T1,F.NXZR ;AND POINT TO IT
|
||
POPJ P,
|
||
|
||
|
||
FSTPRG: MOVEM T1,F.INZR ;SET FIRST POINTER
|
||
MOVEM T1,F.NXZR ;AND CURRENT
|
||
POPJ P,
|
||
DEFLOD: MOVE T1,NOLIBS ;GET MASK OF PROCESSORS NOT TO LOOK AT
|
||
ANDCAM T1,LIBPRC
|
||
SKIPE @GS.LB ;LOAD JOBDAT UNLESS LOADED ORIGINALLY BY DEFAULT
|
||
JRST DEFLD2 ; OR IF BEEN THROUGH LOOP ONCE ALREADY
|
||
MOVE P1,['JOBDAT']
|
||
PUSHJ P,LOAD1 ;LOAD JOBDAT
|
||
SETOM @GS.LB ; BUT ONLY ONCE
|
||
DEFLD2: HLRZ T1,MNTYPE ;GET COMPILER OF MAIN PROG
|
||
JUMPE T1,DEFLD1 ;NO MAIN (MAYBE 2ND TIME ROUND)
|
||
MOVE T2,CT.BIT(T1) ;GET CORRESPONDING BIT
|
||
ANDCAM T2,LIBPRC ;REMOVE FROM LIST TO LOOK AT
|
||
IORM T2,MNSEEN ;[614] A NEW MAIN PROG TYPE SEEN
|
||
MOVE P4,T1 ;[2013] PASS COMPILER TYPE TO MAIN PRG PROC
|
||
TDNN T2,NOLIBS ;[2013] NOT TO SEARCH THIS LIBRARY?
|
||
PUSHJ P,@MNTBL(T1) ;DO WHAT WE HAVE TO FOR IT
|
||
DEFLD1: SKIPN T1,LIBPRC ;GET LIST OF OTHER PROCS SEEN
|
||
POPJ P, ;ALL DONE
|
||
JFFO T1,.+1 ;GET LEADING BIT
|
||
MOVE T1,CT.BIT(T2) ;GET BIT
|
||
ANDCAM T1,LIBPRC ;CLEAR IT
|
||
MOVE P4,T2 ;[1225] PASS COMPILER TYPE TO SUBROUTINE PROC
|
||
PUSHJ P,@PRCTBL(T2) ;DO ACTION FOR THIS PROCESSOR
|
||
JRST DEFLD1 ;LOOP
|
||
;HERE TO SEE IF LIBRARY IS ALREADY REQUESTED
|
||
;IF NOT PUT IN LIST OF FILES TO LOAD (IN SEARCH MODE)
|
||
;ENTER WITH P1 = SIXBIT \FILE.NAME\
|
||
|
||
LOAD1: SKIPN T1,F.INZR ;GET BASE OF LIST
|
||
JRST LOAD2 ;NO LIST NO REQUESTS YET
|
||
CAMN P1,F.NAME(T1) ;ALREADY IN LIST
|
||
POPJ P, ;YES JUST RETURN
|
||
MOVE T1,F.NXT(T1) ;GET NEXT POINTER
|
||
JUMPN T1,.-3 ;TRY IT
|
||
LOAD2: MOVEI T2,F.LEN ;GET SPACE
|
||
PUSHJ P,DY.GET## ;FOR DATA BLOCK
|
||
MOVSI T2,'SYS' ;ALL DEFAULT LIBS LIVE ON SYS (FOR NOW)
|
||
MOVEM T2,F.DEV(T1)
|
||
MOVEM P1,F.NAME(T1) ;STORE NAME
|
||
SETOM F.NAMM(T1) ;SET MASK
|
||
MOVSI T2,'REL' ;DEFAULT EXT IS REL
|
||
HLLOM T2,F.EXT(T1)
|
||
PJRST LNKPRG ;PUT IN LIST AND RETURN
|
||
|
||
REMLIB: SKIPN T1,LIBPTR ;GET SPACE TO REMOVE
|
||
JRST DEFXIT ;ALL DONE
|
||
MOVE T2,(T1) ;GET NEXT BLOCK
|
||
HRRZM T2,LIBPTR ;RESET POINTER
|
||
MOVEI T2,4 ;SIZE OF BLOCK
|
||
PUSHJ P,DY.RET## ;GIVE IT BACK
|
||
JRST REMLIB ;LOOP
|
||
DEFINE X(A,B,C,D)< ;;[1225] ACCOUNT FOR EXTRA ARG
|
||
IF1,<
|
||
BLOCK 1
|
||
>
|
||
IF2,<
|
||
IFDEF B'.L0,<
|
||
EXP B'.L0
|
||
>
|
||
IFNDEF B'.L0,<
|
||
EXP CPOPJ
|
||
>>>
|
||
;HERE FOR TABLE FOR MAIN COMPILER
|
||
XALL
|
||
MNTBL: PROCESSORS
|
||
;HERE FOR ALL OTHER PROCESSORS SEEN
|
||
DEFINE X(A,B,C,D)< ;;[1225] ACCOUNT FOR EXTRA ARG
|
||
IF1,<
|
||
BLOCK 1
|
||
>
|
||
IF2,<
|
||
IFDEF B'.L1,<
|
||
EXP B'.L1
|
||
>
|
||
IFNDEF B'.L1,<
|
||
EXP CPOPJ
|
||
>>>
|
||
|
||
PRCTBL: PROCESSORS
|
||
;DEFINE A TABLE OF THE HIGH SEGMENT ORIGIN FOR EACH COMPILER'S OTS, WHEN THE OTS
|
||
;IS TO BE BROUGHT IN AT RUNTIME.
|
||
|
||
|
||
DEFINE X(A,B,C,D)< ;;[1225] EXPAND THE OTS ORIGINS
|
||
IFB <D>,< ;;[1225] IF NO ORIGIN, JUST SET TO 0
|
||
EXP 0 ;NO RUNTIME OTS FOR C
|
||
> ;;[1225] ..
|
||
IFNB <D>,< ;;[1225] ELSE EXPAND THE ORIGIN
|
||
EXP D ;START OF C OTS
|
||
> ;;[1225] ..
|
||
> ;[1225]
|
||
|
||
|
||
OTSTBL: PROCESSORS ;[1225] GENERATE THE TABLE
|
||
|
||
|
||
SALL
|
||
;HERE TO DO SPECIAL ACTION FOR SOME PROCESSORS
|
||
|
||
FOR.L0: ;[2300]
|
||
MOVX P4,CT.FOR ;WE'VE NOW SELECTED FORTRAN'S OTS
|
||
PUSHJ P,QREENT ;SEE IF WE WANT REENT OTS
|
||
JRST FORL03 ;[1271] NO
|
||
MOVX W1,PT.SGN!PT.SYM
|
||
MOVE W2,['FOROT%'] ;SPECIAL SYMBOL
|
||
MOVEI W3,400000+.JBHDA
|
||
;[2025] Set 5A FOROTS origin,
|
||
;[2025] this is the last using FOROT%
|
||
PUSHJ P,SY.GS## ;DEFINE IT
|
||
PUSHJ P,FORL03 ;[1271] PUT FORLIB IN LIST OF LIBRARIES
|
||
; ..
|
||
;SINCE WE'RE LOADING REENTRANT FOROTS, LOAD SYS:FORLIB/SEGMENT:LOW.
|
||
;THIS IS REQUIRED BY FOROTS VERSION 6 AND LATER.
|
||
|
||
FORL04: MOVE P2,F.NXZR ;[1271] LAST LIBRARY PUT ON LIST
|
||
CAMN P1,F.NAME(P2) ;[1200] WAS IT FORLIB?
|
||
SKIPE F.SWP(P2) ;[1200] WITH NO SWITCHES YET?
|
||
POPJ P, ;[1200] NO, RETURN FROM FOR.L0
|
||
MOVEI T2,3 ;[1200] YES, ALLOCATE A SWITCH BLOCK
|
||
PUSHJ P,DY.GET## ;[1200] IN DY AREA
|
||
MOVEM T1,F.SWP(P2) ;[1200] PUT SWITCH IN FILE BLOCK
|
||
HRLZM T2,0(T1) ;[1200] STORE BLOCK SIZE
|
||
DMOVE T2,[EXP %SEG%,$SSGLOW] ;[1201] SWITCH AND ARGUMENT
|
||
DMOVEM T2,1(T1) ;[1200] STORE IN SWITCH BLOCK
|
||
POPJ P, ;[1200] DONE
|
||
|
||
|
||
;DEFINE %SEG%. MUST CALL SWTCHS MACRO.
|
||
|
||
..SEG==0
|
||
|
||
DEFINE SWMAC(A,B,C,D,E,F,G,H,I)<
|
||
|
||
IFIDN <B>,<SEGMENT>,<%SEG%==..SEG>
|
||
..SEG==..SEG+1>
|
||
|
||
SWTCHS ;[1200] LOOK FOR /SEGMENT
|
||
|
||
|
||
;HERE WHEN FORTRAN CODE IS SEEN, BUT NO MAIN PROGRAM.
|
||
|
||
FOR.L1: PUSHJ P,FORL03 ;[1271] LOAD THE LIBRARY
|
||
SKIPE T1,OTSEG ;[1271] GET THE /OTS: SWITCH
|
||
CAIE T1,1 ;[1271] /OTS:NONSHAR?
|
||
SKIPE HL.S2 ;[1271] NO - HIGH SEG EXIST?
|
||
POPJ P, ;[1271] LEAVE IT TWOSEG
|
||
PJRST FORL04 ;[1271] MAKE IT /SEG:LOW
|
||
FORL03: MOVE P1,['FORLIB'] ;[2300] COMMON LIBRARY
|
||
PJRST LOAD1
|
||
|
||
|
||
;HERE WHEN EXTENDED FORTRAN IS SEEN. SAME AS FORTRAN.
|
||
|
||
XFR.L0==FOR.L0 ;[1203] MAIN PROGRAM ENTRY
|
||
XFR.L1==FOR.L1 ;[1203] ANY CODE SEEN ENTRY
|
||
C68.L0: ;[1433]
|
||
C68.L1: MOVE P1,['LIBOL '] ;[1433]
|
||
PJRST LOAD1
|
||
C74.L0:
|
||
C74.L1: MOVE P1,['C74LIB']
|
||
PJRST LOAD1
|
||
|
||
CBL.L0:
|
||
CBL.L1: MOVE P1,['COBLIB']
|
||
PJRST LOAD1
|
||
|
||
ALG.L0: PUSHJ P,QREENT ;SEE IF WE WANT REENT VERSION
|
||
JRST ALG.L2 ;NO
|
||
MOVX W1,PT.SGN!PT.SYM
|
||
MOVE W2,['%SHARE']
|
||
SETZ W3,
|
||
PUSHJ P,SY.RQ## ;PUT IN REQUEST
|
||
ALG.L1: SKIPE LODNAM ;SEE THE MAIN PROGRAM YET?
|
||
JRST ALG.L2 ;YES
|
||
E$$AMP::.ERR. (MS,,V%L,L%W,S%W,AMP,<ALGOL main program not loaded>) ;[1174]
|
||
ALG.L2: MOVE P1,['ALGLIB']
|
||
PJRST LOAD1
|
||
|
||
NLI.L0:
|
||
NLI.L1: MOVX W1,PT.SGN!PT.SYM
|
||
MOVE W2,['%NELGO'] ;DEFINE SYMBOL
|
||
SETZ W3, ;WITH ZERO VALUE
|
||
PUSHJ P,SY.RQ## ;PUT IN REQUEST FOR IT
|
||
MOVE P1,['LIBNEL'] ;AND SPECIAL LIBRARY
|
||
JRST LOAD1 ;NOW LOAD IT
|
||
|
||
BCL.L0:
|
||
BCP.L1: MOVE P1,['BCPLIB']
|
||
PJRST LOAD1
|
||
|
||
SIM.L1: SKIPE LODNAM ;MAIN PROGRAM SEEN YET?
|
||
JRST SIM.L0 ;YES
|
||
E$$SMP::.ERR. (MS,,V%L,L%W,S%W,SMP,<SIMULA main program not loaded>) ;[1174]
|
||
SIM.L0: MOVE P1,['SIMLIB']
|
||
PJRST LOAD1
|
||
|
||
PAS.L0: PUSHJ P,QREENT ;[1435] SEE IF WE WANT REENT OTS
|
||
SKIPA W2,['PASOT%'] ;[1435] NO, DEFINE SPECIAL SYMBOL
|
||
;[1451] JRST PASL01 ;[1435] YES
|
||
JRST [ TLO FL,L.FLS
|
||
TRO FL,R.FLS
|
||
JRST PASL01 ];[1451] FORCE LIBRARY LOAD TO LOWSEG
|
||
MOVX W1,PT.SGN!PT.SYM
|
||
SETO W3, ;[1435] GIVE IT A DEFINITE VALUE
|
||
PUSHJ P,SY.GS ;[1435] DEFINE IT
|
||
PASL01: MOVX W1,PT.SGN!PT.SYM ;[1435]
|
||
MOVE W2,['PASDT%'] ;[1435] LOOKUP SPECIAL SYMBOL
|
||
SETZ W3, ;[1435] PROBABLY NOT REQUIRED
|
||
PUSHJ P,TRYSYM ;[1435]
|
||
JRST PASLUK ;[1435] UNKNOWN
|
||
JRST PASLUD ;[1435] UNDEFINED
|
||
JRST PAS.L1 ;[1435] HERE WHEN PASDT% IS ALREADY DEFINED
|
||
;[1435] USER HAS LOADED PASDDT BY HAND, DO NOTHING
|
||
;PASDT% IS UNKNOWN, USER DID NOT COMPILE WITH DEBUGGER SWITCH, DO NOT LOAD PASDDT.
|
||
;[1435] GIVE ERROR IF /DEB:PAS SEEN
|
||
|
||
PASLUK: SKIPN PASDFL ;[1435] /DEB:PAS SEEN?
|
||
JRST PAS.L1 ;[1435] NO, DO NOTHING
|
||
.ERR. (MS,0,V%L,L%W,S%W,PCD,<PASCAL program not compiled with debug switch, PASDDT not loaded>)
|
||
JRST PAS.L1 ;[1435] AND CONTINUE
|
||
|
||
PASLUD:
|
||
|
||
PAS.L1: MOVE P1,['PASLIB'] ;[1435] LOAD PASCAL LIBRARY
|
||
JRST LOAD1 ;[1435]
|
||
|
||
QREENT:
|
||
IFN TOPS20,< ;[2366]
|
||
MOVE T1,FXSBIT ;[2224] GET THE SECTION BITS
|
||
TDNE T1,[^-1B0] ;[2224] ANY NON-ZERO SECTIONS?
|
||
JRST QREEN2 ;[2224] YES
|
||
>;[2366] IFN TOPS20
|
||
|
||
IFE TOPS20,< ;[2366]
|
||
MOVE T1,HL.S1 ;[2366] GET THE HIGHEST LOADED
|
||
TLNE T1,-1 ;[2366] OUTSIDE OF SECTION ZERO?
|
||
JRST QREEN2 ;[2366] YES
|
||
>;[2366] IFE TOPS20
|
||
|
||
MOVE T1,OTSTBL(P4) ;[1225] ARE WE TOO CLOSE TO ORIGIN OF
|
||
SUBX T1,LN.OTS ;[1225] OTS IF BROUGHT IN AT RUNTIME?
|
||
CAMLE T1,HL.S1 ;[1225] ..
|
||
JRST QREEN1 ;[1131] NO--GO TRY FOR SHARABLE RUNTIME OTS
|
||
SKIPN HL.S2 ;[574] NON-SHARABLE OTS. HIGH SEG EXIST?
|
||
TDO FL,[L.FLS,,R.FLS] ;[574] NO, DON'T START ONE
|
||
POPJ P, ;[574] NON-SKIP RETURN
|
||
|
||
;HERE IF LOW SEG .LT. 128K. CHECK /OTS AND HI SEG EXISTANCE
|
||
QREEN1: SKIPE T1,OTSEG ;[574] HAS USER SPECIFIED /OTS?
|
||
SOJE T1,CPOPJ ;[574] YES, /OTS:NONSHARABLE?
|
||
MOVE T1,SYMSEG ;[1312] GET /SYMSEG
|
||
SUBI T1,$SSGHIGH ;[1312] IN CASE /SYMSEG:HIGH
|
||
SKIPN NOSYMS ;[1312] DON'T CHECK IF NO SYMBOLS
|
||
JUMPE T1,CPOPJ ;[1312] NONSHARABLE IF /SYMSEG:HIGH
|
||
HLRZ T1,PRGPDV ;[2224] GET THE PDV KEYWORD
|
||
CAIE T1,$SSGHIGH ;[2224] /PVBLOCK:HIGH?
|
||
SKIPE HL.S2 ;[1225] NO, GREAT. HIGH SEG EXIST YET?
|
||
POPJ P, ;[1225] YES--MUST LOAD OTS
|
||
MOVE T1,OTSTBL(P4) ;[1225] NO--GET OTS AT RUNTIME--MAKE SURE SYMBOL
|
||
SUBI T1,1 ;[1225] DOESN'T GROW INTO RUNTIME OTS BY
|
||
SKIPN SYMLIM ;[1225] FORCING /UPTO: JUST UNDER IT (UNLESS
|
||
MOVEM T1,SYMLIM ;[1225] USER SPECIFIED DIFFERENT /UPTO:)
|
||
JRST CPOPJ1 ;[1225] ALLOW GETSEG AT RUNTIME
|
||
|
||
;[2224] Here if non-zero sections
|
||
QREEN2: SKIPE T1,OTSEG ;[2224] Has user specified /OTS?
|
||
SOJE T1,CPOPJ ;[2224] Yes, /OTS:NONSHARABLE?
|
||
JRST CPOPJ1 ;[2224] No, re-entrant ots
|
||
|
||
SUBTTL COMMON I/O ROUTINES
|
||
|
||
|
||
;THESE ROUTINES POP OFF THE RETURN AND GO TO LODNXT ON EOF.
|
||
|
||
D.IN2:: PUSHJ P,D.IN1 ;GET A WORD
|
||
MOVE W2,W1 ;IN W2
|
||
D.IN1:: SOSGE DCBUF+2 ;ANYTHING IN BUFFER?
|
||
JRST D.INP ;NO DO INPUT
|
||
ILDB W1,DCBUF+1 ;GET NEXT WORD
|
||
POPJ P,
|
||
|
||
D.INP:: SKIPN DCBUF ;IF 0 THEN READING FROM CORE
|
||
JRST FXRED1 ;GET NEXT BUFFER
|
||
PUSHJ P,D.CNT ;[1101] DO IN UUO AND COUNT BLOCK
|
||
JRST D.IN1 ;AND RETURN
|
||
D.ERR::
|
||
IFE TOPS20,<
|
||
STATZ DC,IO.EOF ;EOF?
|
||
> ;[1402] IFE TOPS20
|
||
IFN TOPS20,<
|
||
SKIPG RFLEN
|
||
> ;[1402] IFN TOPS20
|
||
JRST EOF ;YES
|
||
E01EIF::
|
||
IFE TOPS20,<
|
||
PUSH P,[DC] ;[1174] SAVE CHANNEL FOR LNKLOG
|
||
.ERR. (ST,0,V%L,L%F,S%F,EIF) ;[1174]
|
||
> ;[1402] IFE TOPS20
|
||
IFN TOPS20,<
|
||
PUSHJ P,JSERR## ;[2301] SET UP THE JSYS ERROR
|
||
.ERR. (MS,.EC,V%L,L%F,S%F,EIF)
|
||
.ETC. (FSP,.EC,,,,DC) ;[2301]
|
||
.ETC. (NLN,.EC) ;[2301] NEW LINE FOR ERROR TEXT
|
||
.ETC. (STR,,,,,ERRJSY) ;[2301] TYPE ERSTR% TEXT
|
||
|
||
> ;[1402] IFN TOPS20
|
||
|
||
;THESE ROUTINES ARE LIKE THE CORRESPONDING D.IN? ROUTINES, EXCEPT
|
||
;THAT THEY RETURN CPOPJ1 WITH DATA OR CPOPJ ON EOF FROM REL FILE.
|
||
|
||
D.RED2::PUSHJ P,D.RED1 ;GET A WORD
|
||
POPJ P, ;NONE TO GET
|
||
MOVE W2,W1 ;SAVE IN W2
|
||
D.RED1::SOSGE DCBUF+2 ;ANYTHING IN BUFFER?
|
||
JRST D.READ ;NO, GO GET ANOTHER BUFFER
|
||
ILDB W1,DCBUF+1 ;YES, GET THE NEXT DATA WORD
|
||
JRST CPOPJ1 ;AND RETURN IT
|
||
|
||
D.READ::SKIPN DCBUF ;READING FROM CORE?
|
||
JRST FXRED2 ;YES, GO GET NEXT BUFFER
|
||
PUSHJ P,D.CNT ;[1101] DO IN UUO AND COUNT BLOCK #
|
||
JRST D.RED1 ;THAT WAS EASY
|
||
IFE TOPS20,<
|
||
STATZ DC,IO.EOF ;EOF?
|
||
> ;[1402] IFE TOPS20
|
||
IFN TOPS20,<
|
||
SKIPG RFLEN
|
||
> ;[1402] IFN TOPS20
|
||
POPJ P, ;YES.
|
||
JRST D.ERR ;NO, INPUT ERROR
|
||
;
|
||
IFE TOPS20,<
|
||
;THIS ROUTINE DOES AN IN UUO AND KEEPS TRACK OF THE CURRENT BLOCK
|
||
;NUMBER. BLOCK NUMBER IS RELATIVE (LIKE USETI) ON DISK, ABSOLUTE
|
||
;ON DTA.
|
||
;RETURNS +1 IF IN UUO WORKED, +2 IF FAILED (LIKE IN UUO DOES).
|
||
;DESTROYS W1 ONLY.
|
||
|
||
|
||
D.CNT:: SKIPN DTAFLG ;[1467] READING FROM DECtape?
|
||
JRST D.CNT2 ;[1101] NO, JUST AOS THE COUNT FOR DISK
|
||
|
||
;HERE ON DECtape
|
||
SKIPGE LSTBLK ;[1101] IS THIS THE FIRST IN FROM DTA?
|
||
JRST D.CNT1 ;[1101] YES, MUST GET THE BLOCK DIFFERENTLY
|
||
MOVE W1,DCBUF ;[1101] NORMAL CASE, GET PTR TO NEXT
|
||
LDB W1,[POINT 18,1(W1),17] ;[1101] OUT OF OLD BUFFER
|
||
MOVEM W1,LSTBLK ;[1101] STORE IN LSTBLK
|
||
JRST D.CNT3 ;[1101] SKIP DISK'S AOS, GO DO IN UUO
|
||
|
||
;HERE ON FIRST IN FROM DECtape. GET FIRST BLOCK NUMBER FROM LOOKUP
|
||
D.CNT1: LDB W1,[POINT 10,FEXT,35] ;[1101] ON FIRST IN,
|
||
MOVEM W1,LSTBLK ;[1101] GET FROM LOOKUP BLOCK
|
||
JRST D.CNT3 ;[1101] GO DO IN UUO
|
||
|
||
;HERE ON DISK
|
||
D.CNT2: AOS LSTBLK ;[1101] ON DISK, JUST AOS LSTBLK
|
||
D.CNT3: IN DC, ;[1101] DO THE IN UUO
|
||
POPJ P, ;[1101] SUCCESS, RETURN
|
||
JRST CPOPJ1 ;[1101] IN UUO SKIPPED, PROPOGATE IT
|
||
> ;[1402] IFE TOPS20
|
||
IFN TOPS20,<
|
||
;
|
||
; THIS ROUTINE MAPS THE REL FILE TO A BUFFER SEVERAL PAGES AT A TIME.
|
||
; CURRENT FILE PAGE IS KEPT IN LSTBLK.
|
||
; COUNT OF BYTES LEFT IN FILE IS KEPT IN RFLEN
|
||
; WHEN RFLEN GOES NEGATIVE END OF FILE HAS BEEN SEEN.
|
||
; DCBUF+1 ( BUFFER BYTE POINTER ) AND DCBUF+2 ( BUFFER LENGTH ) ARE SET UP.
|
||
; T1,T2 AND T3 ARE USED BUT PRESERVED.
|
||
; RETURNS +1 IF ALL OK, +2 IF PMAP FAILED OR END-OF-FILE ON ENTRY.
|
||
|
||
;[2366] NOTE THAT THIS BUILDS A 444400 STYLE BYTE POINTER, WHICH IS NOT
|
||
;[2366] THE SAME AS THE TOPS-10 IN UUO. IF THIS IS CHANGED HERE, CODE
|
||
;[2366] IN X160B2 IN LNKNEW WILL ALSO HAVE TO BE CHANGED.
|
||
|
||
D.CNT:: ;[1467]
|
||
SKIPGE RFLEN ;END OF FILE ENCOUNTERED ALREADY?
|
||
JRST CPOPJ1 ; +2 RETURN
|
||
SPUSH <T1,T2,T3> ;WE'LL NEED THE TEMPS
|
||
MOVE T1,DCBUF ;PICK UP BUFFER BEGINNING
|
||
MOVE T2,T1 ; T2 GETS PAGE #
|
||
LSH T2,-9
|
||
HLL T1,[POINT 36,0] ;AND RESET BUFFER BYTE POINTER
|
||
MOVEM T1,DCBUF+1
|
||
HRLI T2,.FHSLF ;PROCESS IS SELF
|
||
HRL T1,DC.JF ;PICK UP FILE JFN
|
||
HRR T1,LSTBLK ;AND CURRENT FILE BLOCK
|
||
MOVE T3,[PM%CNT!PM%RD!PM%PLD!<LN.BF_-9>]
|
||
PMAP%
|
||
ERJMP [ SPOP <T3,T2,T1> ; RESTORE TEMPS
|
||
JRST CPOPJ1 ; AND PROPAGATE ERROR
|
||
]
|
||
MOVEI T1,<LN.BF_-9> ; INCREMENT CURRENT FILE BLOCK
|
||
ADDM T1,LSTBLK
|
||
MOVEI T1,LN.BF ;
|
||
MOVEM T1,DCBUF+2 ; RESET BUFFER BYTE COUNT
|
||
MOVE T2,RFLEN ; DECREMENT FILE BYTE COUNT
|
||
CAMGE T2,T1 ; IF LESS THAN A BUFFERFUL IS LEFT
|
||
MOVEM T2,DCBUF+2 ; SAY SO
|
||
SUB T2,T1
|
||
MOVEM T2,RFLEN
|
||
SPOP <T3,T2,T1> ; RESTORE TEMPS
|
||
POPJ P,
|
||
> ;[1402] IFN TOPS20
|
||
|
||
IFN TOPS20,<
|
||
|
||
RDSKP::
|
||
|
||
; RDSKP
|
||
; Call:
|
||
; MOVEI T1,<target page>
|
||
; PUSHJ P,RDSKP
|
||
;
|
||
; Action:
|
||
; Moves the rel file buffer to encompass the target page,
|
||
; enabling one to skip intermediate pages.
|
||
; Saves all registers, modifies RFLEN and LSTBLK.
|
||
SPUSH <T2,T3> ;SAVE ACS FOR SCRATCH USE
|
||
MOVE T2,LSTBLK ;T2: BUFFER'S END
|
||
SETZM T3 ;T3: COUNTER
|
||
RDSKP1: CAMG T2,T1 ;BUFFER INCLUDES TARGET PAGE?
|
||
JRST [ MOVEI T2,<LN.BF_-9>(T2)
|
||
MOVEI T3,LN.BF(T3)
|
||
JRST RDSKP1 ]
|
||
MOVEI T2,-<LN.BF_-9>(T2)
|
||
MOVEI T3,-LN.BF(T3) ;BACKUP
|
||
CAML T3,RFLEN ;PAST END OF FILE?
|
||
JRST [ SPOP <T3,T2>
|
||
JRST CPOPJ1 ] ;PROPAGATE ERROR SKIP
|
||
MOVNS T3 ;-COUNT
|
||
ADDM T3,RFLEN ;FUDGE COUNT
|
||
MOVEM T2,LSTBLK ;FUDGE BUFFER'S END
|
||
SPOP <T3,T2> ;RESTORE ACS
|
||
PUSHJ P,D.CNT ;AND CALL THE READER
|
||
JRST CPOPJ ;PROPAGATE SUCCESS
|
||
JRST CPOPJ1 ; OR FAILURE
|
||
; END OF RDSKP
|
||
> ;[1402] IFN TOPS20
|
||
EOF::
|
||
TRZE FL,R.LOD ;ENS BLOCK SEEN?
|
||
PUSHJ P,E$$NEB ;[1174] NO GIVE WARNING
|
||
POP P,(P) ;POP OFF RETURN
|
||
EOF1:: SKIPE XBUF ;USING INDEXED LIBRARY
|
||
PUSHJ P,ZXBUF ;YES, GET RID OF IT
|
||
IFN TOPS20,<
|
||
SPUSH <T1,T2,T3> ;SET REGISTERS ASIDE
|
||
MOVE T2,DCBUF ;PICK UP BUFFER PTR
|
||
LSH T2,-9 ;MAKE IT A PAGE
|
||
MOVEI T1,DC ;PICK UP CHANNEL POINTER
|
||
MOVEM T1,IO.CHN ;FOR DVCLS.
|
||
HRLI T2,.FHSLF
|
||
MOVE T3,[PM%CNT!<LN.BF_-9>]
|
||
SETOM T1
|
||
PMAP ;LET GO THE MAPPED PAGES
|
||
SETZM RFLEN ;[1402] ZERO OUT PAGES
|
||
PUSHJ P,DVCLS.## ;AND CLOSE THE ASSOCIATED FILE
|
||
SPOP <T3,T2,T1> ;RESTORE REGS
|
||
> ; [1402] IFN TOPS20
|
||
JRST LODNXT ;GET NEXT FILE
|
||
|
||
E$$NEB::.ERR. (MS,.EC,V%L,L%W,S%W,NEB,<No end block seen>) ;[1174]
|
||
.ETC. (JMP,,,,,.ETIMF##) ;[1174]
|
||
MOVEI R,1 ;NOW TRY TO FIXUP RELOC TABLES
|
||
MOVE R,@RC.TB ;DO LOW SEG FIRST
|
||
MOVE T1,RC.HL(R) ;HIGHEST LOC SEEN
|
||
CAMLE T1,RC.CV(R) ;GREATER THAN CURRENT?
|
||
MOVEM T1,RC.CV(R) ;STORE HIGHEST
|
||
MOVEI R,2 ;NO FOR HIGH SEGMENT
|
||
SKIPN R,@RC.TB
|
||
JRST CPOPJ ;NO HIGH SEG
|
||
MOVE T1,RC.HL(R) ;HIGHEST LOC SEEN
|
||
CAMLE T1,RC.CV(R) ;GREATER THAN CURRENT?
|
||
MOVEM T1,RC.CV(R) ;STORE HIGHEST
|
||
SETZM LOD37 ;[1114] DONE WITH COBOL SYMBOLS
|
||
SETZM OWNLNG ;[1114] AND ALGOL OWNS
|
||
; SETZM VARLNG ;[1114] AND LVARS
|
||
POPJ P,
|
||
|
||
;HERE TO REMOVE XBUF (FAKE BUFFER USED FOR LIBRARY INDEX)
|
||
|
||
ZXBUF:: HRRZ T1,XBUF ;ADDRESS IN CORE
|
||
MOVEI T2,^D128 ;SIZE
|
||
SETZM XBUF ;DONE WITH IT NOW
|
||
PJRST DY.RET## ;GIVE SPACE BACK AND RETURN
|
||
|
||
IFN DEBSW,<
|
||
$LOCATION:: 0 ;STORE ADDRESS TO BREAK ON
|
||
$SYMBOL:: 0 ;STORE 6BIT SYMBOL TO BREAK ON
|
||
>
|
||
SUBTTL THE END
|
||
|
||
|
||
LITLOD: END LNKLOD
|