mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-02 09:37:06 +00:00
5416 lines
208 KiB
Plaintext
5416 lines
208 KiB
Plaintext
|
||
TITLE LNKXIT - EXIT MODULE FOR LINK
|
||
SUBTTL D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC/DZN/MFB/PAH/PY/HD/JBS/RJF 5-Feb-88
|
||
|
||
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986,1988.
|
||
; ALL RIGHTS RESERVED.
|
||
;
|
||
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
|
||
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
|
||
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
|
||
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
|
||
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
|
||
;TRANSFERRED.
|
||
;
|
||
;
|
||
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
|
||
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
|
||
;CORPORATION.
|
||
;
|
||
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
|
||
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
|
||
|
||
|
||
|
||
SEARCH LNKPAR,LNKLOW,OVRPAR,MACTEN,UUOSYM
|
||
IFN TOPS20,<SEARCH MACSYM, MONSYM>
|
||
SALL
|
||
|
||
ENTRY LNKXIT
|
||
EXTERN LNKCOR,LNKLOG,LNKFIO
|
||
EXTERN .JB41
|
||
|
||
|
||
CUSTVR==0 ;CUSTOMER VERSION
|
||
DECVER==6 ;DEC VERSION
|
||
DECMVR==0 ;DEC MINOR VERSION
|
||
DECEVR==2404 ;DEC EDIT VERSION
|
||
|
||
VERSION
|
||
|
||
|
||
SEGMENT
|
||
|
||
|
||
;LOCAL ACC DEFINITION
|
||
R==R1
|
||
SUBTTL REVISION HISTORY
|
||
|
||
|
||
;START OF VERSION 1A
|
||
;50 HANDLE PAGING DURING LOCAL SYMBOL OUTPUT CORRECTLY
|
||
;51 FIX BUG IF UNDEF SYMBOLS BUT DON'T WANT TO KEEP LOCAL SYMS
|
||
;53 FIX RETURNS FROM DVMOV. ROUTINE
|
||
;54 ADD KIONLY D.P. INST.
|
||
;55 STORE VERSION NUMBER (.JBVER) IN .RBVER OF SAVE FILE
|
||
;56 FIX LOOP AT JBEX2A IF CORE IMAGE IS MULTIPLE OF 2000
|
||
;57 SETUP VESTIGIAL JOB DATA AREA EVEN IF NOT A SAVE FILE
|
||
;63 REMOVE MULTIPLY-DEFINED SYMBOLS FROM SYMBOL TABLE (IN CORE)
|
||
;65 TENEX SPEEDUPS
|
||
;66 SAVE JOB DATA AREA ON /SAVE IF DDT, SYMBOLS AND ALL CODE IN HIGH SEG
|
||
;67 PUT ADDITIVE GLOBAL REQUESTS IN UNDEF TABLE
|
||
;70 FIX ADDRESS CHECK PROBLEM
|
||
;71 MAKE ALL INFO MESSAGES STANDARD FORM
|
||
;73 (11314) PREVENT EXECUTION IF UNDEF SYMBOLS
|
||
;100 FIX ILL MEM REL ON /SAVE IF LAST BLOCK FILLS ALL OF CORE
|
||
;104 OUTPUT FAIL BLOCK HEADER IN LOCAL SYMBOL TABLE
|
||
;106 REMOVE HIORG, REPLACE BY LL.S2
|
||
;115 MAKE /NOSYMBOLS WORK CORRECTLY
|
||
|
||
;START OF VERSION 2
|
||
;135 ADD OVERLAY FACILITY
|
||
;136 FIX VARIOUS BUGS
|
||
;140 (12617) FIX ?IO TO UNASSIGNED CHANNEL ON /SYMBOL:TRIPLET FILE
|
||
;154 (12991) ONLY LOOK AT RIGHT HALF OF .JBERR TO DELETE EXECUTION
|
||
;155 (12988) FIX TEST FOR COBDDT AT RUN UUO TIME
|
||
;166 MAKE RADIX50 SYMBOL FILE TYPE 776
|
||
;177 FIX ADDRESS CHECK BUG IF PAGING SYMBOLS
|
||
;211 FIX ZEROS IN MONITOR SYMBOL TABLE
|
||
;213 (12531) LOW SEG OF TWOSEG CORE IMAGE BAD
|
||
;221 GET PROTECTION CODE RIGHT ON XPN FILE
|
||
|
||
;START OF VERSION 2A
|
||
;244 DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
|
||
;START OF VERSION 2B
|
||
;224 PUT SECOND SYMBOL FOR COMMON BLOCK IN RADIX50 SYMBOL TABLE
|
||
;226 FIX UNDEFINED SYMBOL BUG (117 NOT SET UP)
|
||
;234 FIX VARIOUS BUGS IF HIGH FILE IS MADE RATHER THAN RENAMED
|
||
;235 (13845) FIX ZERO COMPRESSOR IF PAGED AND READING ZEROS
|
||
;241 USE LARGER OF ABS OR LOW REL BREAK FOR .JBFF
|
||
;242 HANDLE USER PAGE FAULT HANDLER CORRECTLY
|
||
;244 DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
|
||
;247 Change all references to DEBUGSW. Now lh is -1 if set,
|
||
; rh is table index for either /DEBUG or /TEST
|
||
;266 Correct problems with loading symbols when LS area
|
||
; overflows to the DSK.
|
||
;267 Get symbol table offest right when core window
|
||
; changes.
|
||
;270 Use the correct initialization routine when high
|
||
; core overflows to the disk during this phase.
|
||
;322 Get LSYM and other core management variables right
|
||
; so LNKCOR doesn't fail
|
||
;324 Don't release the symbol channel if still needed,
|
||
; when loading symbols into root of an overlay program.
|
||
;330 Release the correct channel when done with symbols
|
||
; being loaded into the root of an overlay program.
|
||
;335 Keep LSYM from being clobbered when loading symbols
|
||
; into root of overlay program. Don't confuse LNKCOR
|
||
;336 Fix /RUN switch to work properly
|
||
;337 Insert check for no core to zero before BLT and
|
||
; prevent possible ILL MEM REF
|
||
;353 REMOVE EDIT 225
|
||
;357 LABEL EDITS 224,226,234,235,241,242
|
||
;360 REMOVE EDIT 336
|
||
;401 Remove 5.06 compatability hack setting up vestigial jobdat.
|
||
;403 Fix HALT if generating new style symbol file.
|
||
;423 Fix ?ILL ADDR IN UUO when the zero compressor tried to use
|
||
; the LS area after it had done a CORE UUO to get rid of it.
|
||
;433 Support the /RUN switch.
|
||
;START OF VERSION 2C
|
||
;442 Fix the DVMOV. routine to either RENAME or copy,
|
||
; and delete copy routines called if DVMOV. fails.
|
||
;443 Don't lose part of local symbols if overflowing to disk.
|
||
;467 Correct RT.PT check at SYMO1
|
||
;471 Add code for ALGOL debugging system.
|
||
;476 Insert missing FTOVERLAY conditional.
|
||
;517 Make first word of ALGOL symbol file be 1044,,count.
|
||
;524 Check for symseg area reduced to one page & don't zero rest.
|
||
;530 Get triplet flag definitions right.
|
||
;544 SOUP in LINK version 3 stuff for TOPS-20.
|
||
;547 Make LINK assemble with MACRO 51.
|
||
;555 Don't round .RBSIZ up to block bound for symbol files.
|
||
;557 Clean up the listing for release.
|
||
|
||
;START OF VERSION 3
|
||
;446 CHANGES FOR TENEX
|
||
|
||
;START OF VERSION 3A
|
||
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
|
||
;START OF VERSION 4
|
||
;570 Don't lose local symbols when undefined globals exist.
|
||
;575 On /EXECUTE/SAVE to a two segment program, always run xxx.LOW
|
||
;606 Get the protection of .HGH and .XPN files right.
|
||
;616 Give appropriate error messages when RENAMEs fail
|
||
;621 /SAVE AND /SSAVE GENERATE EXE FILE.
|
||
; /SAVE AND /SSAVE NO LONGER TAKES ANY ARGUMENT. IF THE CORE
|
||
; SIZE IS SPECIFIED, LINK WILL IGNORE IT.
|
||
; THE CODE TO GENERATE .HGH/.SHR/.LOW FILES ARE UNDER THE
|
||
; CONDITIONAL ASSEMBLY SWITCH FTEXE==0.
|
||
;622 Don't set up vestigal JOBDAT unless there's a high segment.
|
||
;641 IF HIGH SEG IS PAGED, WRITE OUT WHAT'S IN CORE BEFORE UPDATING
|
||
; VESTIGAL JOBDAT AND DUMP TO EXE FILE.
|
||
;642 EXE FILE EXTENSION FOR DISK FILE GENERATED FOR NOT HAVING
|
||
; ENOUGH CORE
|
||
;643 FIX BUG WITH SWITCH SETTING FOR P4 IN XCMPRL.
|
||
;644 DON'T DO JSYS 147(RESET) IF WE DO EXIT.
|
||
;645 Loop back topage lc if not more core in LSREQ.
|
||
;646 Don't touch a high seg page again after high seg is removed
|
||
; in %LOW.
|
||
;647 Don't zero unneeded memory (better VM performance).
|
||
;650 Use VM on TOPS-10 if available.
|
||
;652 Avoid bad .SAV file when paging to disk.
|
||
;704 Don't write EXE-directory entries for psect gaps.
|
||
;713 Fix bug with sparse EXE-directory.
|
||
;715 Modify SYMSEG to take psect name.
|
||
;724 Check for symbol table range in INGAP.
|
||
;725 Fix bug with incrementing process page in XCMPOV.
|
||
;726 Fix bug in INGAP routine.
|
||
;727 Give Insufficient space error message when symbol table truncated.
|
||
;731 SEARCH MACTEN,UUOSYM instead of C.
|
||
;732 Use LOWLOC and fix bugs related to page 777.
|
||
;733 Fix bug with allocated high seg pages causing bad EXE format.
|
||
;742 Don't BLT JOBDAT if process page 0 not the first page.
|
||
;744 Fix bug with calculation of EXE file size.
|
||
;754 Don't page LS area when doing symbol table output, if paging is needed for the first time for LC(or HC).
|
||
;762 Page in the LOWLOC page before generating EXE file.
|
||
;764 Update LOWLOC in GETSST incase symbol table is lower than code.
|
||
; Also, corrects a bug in updating upper window in XCMPRS routine.
|
||
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
|
||
;START OF VERSION 4A
|
||
;770 Add code to allow first-time paging in und-symbol table routine.
|
||
;772 Adjust symbol table pointer to after undefined symbol table.
|
||
;773 Fix GSDLT in case the GS area is already gone.
|
||
;774 Fix bad calculation of UW in EXE file writer.
|
||
;776 Fix /SAVE of small program with no data in pages 0 or 1.
|
||
;1110 Output PSECT name as part of error message in GETSST.
|
||
;1111 Fix core management bug introduced by edit 772.
|
||
;1113 See that LINK doesn't shrink on TOPS-20 until really necessary.
|
||
;1121 Fix edit 772 so symbol table and undefined table don't overlap.
|
||
;1125 Don't try to do a RUN UUO to the hiseg file when generating an EXE file.
|
||
;1127 Set up the module length for PAT.. in the runtime symbol table.
|
||
;1132 Teach the EXE file writer about PSECTs above the high segment.
|
||
;1144 Zap PA1050 but not DDT on /EXECUTE, /DEBUG when running from .EXE file.
|
||
;1145 Set up symbol table pointers on TOPS-20 if no .EXE file written; broken by 1144.
|
||
;1146 Force writing an .EXE file more often, especially with PSECTs.
|
||
;1147 Adjust LC.LB when adjusting LW.S1 in JBEXE. Broken by 732.
|
||
;1152 Set RC.HL for .LOW. during initialization when loading overlays.
|
||
;1160 Don't put junk in the undefined table when symbol used in Polish.
|
||
;1170 Fix core management problems when not writing an EXE file.
|
||
;1171 Fix edit 1146 to say LNKPCL if bad PSECT properties, even on TOPS-10.
|
||
;1172 Fix many problems with runtime symbol table generator.
|
||
;1174 Label and clean up all error messages.
|
||
;1202 Fix problems introduced by edits 1172 and 1174.
|
||
;1212 Use E$$SOE label instead of ZCMP7E, broken by 1174 (in off conditional).
|
||
;1214 Fix unmatched angle bracket bug in .EXE file code.
|
||
;1216 Preserve P acs in SYMOUT.
|
||
;1217 Clean up the listings for release.
|
||
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
|
||
;1235 Clear LOGSUB to avoid possible IO TO UNASSIGNED CHANNEL.
|
||
;1242 Make High Segs above 700000 generate .EXE file on TOPS-20
|
||
;1244 Kill PA1050 if executing user program, replace CORE UUO with PMAP JSYS
|
||
;1257 Put Root node location in RC.HL in .ABS. if overlaid.
|
||
;1261 Restore P1 if /SAVE scan block built because of complex program
|
||
;1267 Add ALGDDT to KEYMAC definition.
|
||
;1272 Fix Edit 1244 to remove PA1050 if low seg ends at end of page.
|
||
;1273 Fix RC.HL in .LOW. and .HIGH. to agree with HP.S1 and HP.S2.
|
||
;1300 Check BADCORE, issue LNKCFS if non-zero.
|
||
;1301 Make .OERR. Messages use verbosity bits.
|
||
;1302 Fix bug in 1273, don't use HP.S if RC.HL() is greater.
|
||
;1305 Remove edits 1273, 1302, move code into LNKOLD
|
||
;1314 Fix bug if more than 400 contiguous non-zero pages of .EXE file.
|
||
;1317 Correctly calculate .JBCOR if program ends on page boundary.
|
||
;1321 Make SIMDDT start at .JBREN like ALGDDT.
|
||
;1323 Check for high seg when simulating CORE UUO with PMAP% JSYS.
|
||
;1325 Output secondary fixup chains in undefined symbol table.
|
||
;1326 Use new PA1050 suicide COMPT. instead of PMAP%
|
||
|
||
;START OF VERSION 5
|
||
;1400 Use OVRPAR.MAC.
|
||
;1401 Performance improvements to overflow and EXE file i/o.
|
||
;1415 Write out ALGOL .SYM files on channel TC.
|
||
;1423 Support Program Data Vectors
|
||
;1425 FTFRK2 Extended addressing support.
|
||
;1427 Put ERJMPs after PDVOP%s for pre-Tops-20 Release 5.
|
||
;1437 Defer destroying LC file under TOPS-20 until the last minute.
|
||
;1442 Don't go thru the SSINI code unless nonzero sections have been
|
||
; loaded.
|
||
;
|
||
;1450 Use PRGFRK, fix some FTFRK2 bugs, insert ERJMP after failing SEVEC.
|
||
;1454 Calculate default SYMLIM correctly.
|
||
;1455 Fix infinite loop caused by bad test in TTLLUP.
|
||
;1460 Clean up SSINI code and kill UUO simulation for xaddr programs.
|
||
;1464 Get the right window for the PDV in nonzero sections.
|
||
|
||
;Start of Version 5.1
|
||
;1500-1677 Maintenance edits.
|
||
;1506 Conditionalize remaining UUOs in the overlay-writing code.
|
||
;1516 Fix bad test at CHKRS0+3
|
||
;1521 Get all of overlay links symbol table in .EXE file.
|
||
;1522 Make JBGCM/JBGCMV unmap and remap paged areas on the -20.
|
||
;1524 Add an entry for PASDDT in STLOCN.
|
||
;1531 Handle address before current window in EXE writer
|
||
;1532 Test JOBPTR, not LW.S1, to decide if XCMPRS should write the JOBDAT.
|
||
;1534 Make sure LC/HC.PT is right following calls to LNKCOR from SYMOU2.
|
||
;1536 Handle multi-section LS area without catastrophic failures.
|
||
;1757 Correct 1432. PDV address was too large by one
|
||
;1760 Keep the section number of the last word of the PDV
|
||
;1762 Don't return the PDV prematurely so that start address for programs
|
||
; in non-zero sections is set correctly.
|
||
;1764 Make use specified entry vectors work in non-zero sections.
|
||
;1773 Set up t3 for XSVEC in JBEX1A
|
||
;2000 Don't return nonexistent PDV storage at SSINIG+9.
|
||
;2006 Fix PDVs over page boundary, use 1 not JRST, use SEVEC in section 0
|
||
;2016 Fix /PVBLOCK:HIGH, and set HL.S0(R) and HC.S0(R) if needed.
|
||
;2021 Make pages from overflow file private if not writing .EXE file.
|
||
;2023 If PMAP fails while writing .EXE because Quota exceeded try expunge.
|
||
;2024 Fix edit 2023
|
||
;2026 Update copywrite and strip edit banners.
|
||
;2027 Conditionalize PMAP error handling.
|
||
;2032 Allocate space with LC.IN before reading area from .OVL file.
|
||
;2034 Remove Edit 1531.
|
||
;2035 Don't map in non-existant pages at JBGMV0.
|
||
;2040 Be careful of page boundary when mapping out at SYMINI.
|
||
;2043 Don't call BLTJDA if JOBPTR is zero at JBEXE1.
|
||
;2052 Don't die when making EXE file if directory is protected.
|
||
;2054 Keep the LS overflow area on TOPS-20 if it is still mapped.
|
||
;2055 Put the count in T2 before calling DY.GET.
|
||
;2056 Print LNKXCT message when executing prog in non-zero section.
|
||
;2060 Save the PPN and PATH info for the RUN UUO in RUNEX2.
|
||
;2061 Fix typo in 2060.
|
||
;2066 Fix 2060 to get PPN from right place and check for default [0,0].
|
||
|
||
;Start of Version 6
|
||
;2202 Use 30 bit addresses for xx.IN and xx.OUT, remove NONZER and FTFRK2.
|
||
;2206 Set read-only attributes correctly for non-zero section psects.
|
||
;2211 Implement /NOJOBDAT, change the way JOBDAT is automatically suppressed.
|
||
;2220 Handle long psect names.
|
||
;2232 Don't set .JBREL during exit if user said /NOJOBDAT.
|
||
;2237 Implement PDV memory maps.
|
||
;2241 Setup P1 and P2 even if /NOJOBDAT.
|
||
;2245 Implement the PDV symbol table vector.
|
||
;2247 Use an inferior fork for program on TOPS-20.
|
||
;2250 Allocate PDV space more efficiently, fix various other bugs.
|
||
;2256 Use new-style LS segment triplets to generate the module headers.
|
||
;2260 Fix several things with old edits (see LNKHST).
|
||
;2261 Fix off-by-one in page attribute setting code.
|
||
;2265 Don't set page attributes of null read-only psects.
|
||
;2274 Fix some error messages, don't SSAVE% beyond highest section.
|
||
;2277 Add new /DEBUG code for loading DDT into non-zero sections.
|
||
;2301 Fix error messages for TOPS-20 native files.
|
||
;2304 Change DDT error messages, don't check undef sym ptr if def is there.
|
||
;2306 Add long PDV name, default PDV, move symbol vector to symbol psect.
|
||
;2311 Fix PDVs in high segment, default bit 0 for symbol vector pointer.
|
||
;2312 Store the default PDV memory map address in the PDV.
|
||
;2314 Allow /DEBUG when SPLFK% fails, remove LINK's PDV and PSI table addrs.
|
||
;2317 Fix 2247 to save copy-on-write page attributes correctly.
|
||
;2320 Create empty read-only pages when necessary.
|
||
;2330 Fix conditionals and add label needed under TOPS-10.
|
||
;2335 Fix problems with memory map, TOPS-10 conditionals, add default name.
|
||
;2336 Produce symbol vector properly if no default map requested.
|
||
;2346 Don't try to GET% EXE file if not on disk.
|
||
;2347 Fix arguments to COMPT. to remove PA1050.
|
||
;2350 Map non-existant pages properly.
|
||
;2352 Don't map too large an area in STUFDD.
|
||
;2353 Remove unreachable code, bad AC names, move SPLFK% symbols to LNKPAR.
|
||
;2355 Handle pre-emptive debugger starting addresses properly.
|
||
;2356 Remove unnecessary TOPS20 conditionals, fix overflow in exe writer.
|
||
;2357 Set up DC channel for exe file if splice fork fails.
|
||
;2360 Fix problem in edit 2355, don't change STADDR.
|
||
;2361 Add the PDV map overhead word before storing the map length.
|
||
;2362 Save the DDT start address in EXECSW as well as in STADDR.
|
||
;2363 Check which debugger starts, don't assume DDT.
|
||
;2364 Use HL.S1 to get highest location loaded for SSAVE.
|
||
;2366 Add symbol and entry vectors on TOPS-10.
|
||
;2370 Fix off-by-one if segment ends with allocated but zero pages.
|
||
;2373 Fix long sym support for DDT symbol tables.
|
||
;2402 Print first 6 characters of long program name in the LNKXCT message.
|
||
;2403 New coporate copywrite statement.
|
||
;2404 Use first six charcters of long load name for call to SETNM%.
|
||
;2417 Update copywrite statement to 1988.
|
||
SUBTTL ENTER HERE
|
||
|
||
|
||
LNKXIT: JFCL .+1 ;IN CASE CCL ENTRY
|
||
E$$EXS::.ERR. (MS,0,V%L,L%I,S%I,EXS,<EXIT segment>) ;[1174]
|
||
SKIPN BADCORE ;[1300] CORE IMAGE ALL FIXED UP?
|
||
JRST LNKX0I ;[1300] YES
|
||
E$$CFS::.ERR. (MS,0,V%L,L%F,S%C,CFS,<Chained fixups have been suppressed>);[1300] NO
|
||
LNKX0I: ZAPTMP ;[1300] CLEAR ALL TEMP SPACE
|
||
MOVE T1,HC.S0 ;GET ABS BREAK
|
||
CAMLE T1,HC.S1 ;LARGER THAN LOW SEG?
|
||
MOVEM T1,HC.S1 ;USE LARGER
|
||
MOVE T1,HL.S0 ;GET ABS BREAK
|
||
CAMLE T1,HL.S1 ;LARGER THAN LOW SEG?
|
||
MOVEM T1,HL.S1 ;USE LARGER
|
||
HRRZS LL.S2 ;[2247] CLEAR LH IN CASE /REDIRECT
|
||
IFN FTOVERLAY,<
|
||
SKIPGE LNKMAX ;DID WE LOAD ANY OVERLAYS?
|
||
JRST LNKX1 ;NO
|
||
MOVE T1,PH+PH.OVL ;[1400] GET START OF CODE FOR ROOT
|
||
USETI OC,(T1) ;POSITION ON THE BLOCK
|
||
MOVE P2,PH+PH.LLN ;[1400] LENGTH WE NEED
|
||
ADD P2,LC.LB
|
||
SUB P2,LC.AB ;SEE IF ENOUGH
|
||
JUMPLE P2,LNKX0A ;YES
|
||
MOVEI P1,LC.IX
|
||
PUSHJ P,LNKCOR## ;MUST EXPAND
|
||
JRST LNKX0C ;DO IT THE HARD WAY
|
||
LNKX0A: ;[2247]
|
||
IFN TOPS20,< ;[2247]
|
||
MOVE T2,LC.AB ;[2247] GET THE TOP OF THE LC AREA
|
||
SUB T2,LC.LB ;[2247] MINUS THE BOTTOM IS THE SIZE
|
||
MOVEM T2,UW.LC ;[2247] UPPER WINDOW BOUND
|
||
SETZB T1,LW.LC ;[2247] START AT ZERO
|
||
PUSHJ P,LC.IN## ;[2247] MAP IT IN
|
||
>;[2247] IFN TOPS20
|
||
MOVE T1,LC.LB ;[2247] READ INTO LC AREA
|
||
SUBI T1,1
|
||
HLL T1,PH+PH.OVL ;[1400] SETUP IOWD
|
||
SETZ T2,
|
||
IN OC,T1 ;READ BACK CORE
|
||
LNKX0B: SKIPA T1,OV.S1 ;CORE BOUNDS
|
||
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
|
||
HRRZM T1,HL.S1
|
||
HLRZM T1,HC.S1
|
||
MOVEI R,1 ;[1152] LOW SEGMENT
|
||
MOVE R,@RC.TB ;[1152] POINTER TO RC BLOCK FOR LC AREA
|
||
HRRZM T1,RC.CV(R) ;[1152] SAVE AS CURRENT VALUE OF RELOC COUNTER
|
||
HRRZM T1,RC.HL(R) ;[1152] AND FIRST FREE BEYOND ROOT
|
||
JRST LNKX0G ;[1257]
|
||
|
||
;NOW TO READ BACK FIRST FEW BLOCK
|
||
LNKX0F: SETZB T1,LW.S1 ;[2202] STARTS AT ZERO
|
||
MOVE T2,LC.UB ;[2202] GET MAX SIZE
|
||
MOVEM T2,LC.AB ;[2202] USE IT ALL AGAIN
|
||
SUB T2,LC.LB ;[2202] GET UPPER BOUND
|
||
MOVEM T2,UW.S1 ;[2202] REMEMBER IT
|
||
PUSHJ P,LC.IN## ;READ IT BACK
|
||
JRST LNKX0B ;FIXUP VARIOUS POINTERS
|
||
LNKX0C: SETZM LW.S1 ;SET BACK TO START
|
||
MOVE T1,PH+PH.OVL ;[1400]
|
||
USETI OC,(T1) ;SET ON BLOCK
|
||
MOVE T1,LC.UB
|
||
MOVEM T1,LC.AB ;USE ALL AVAILABLE SPACE
|
||
SUB T1,LC.LB ;GET SIZE OF WINDOW
|
||
MOVEM T1,UW.S1 ;UPPER WINDOW
|
||
ADDI T1,1
|
||
LNKX0D: ;[2032]
|
||
IFN TOPS20,< ;[2032]
|
||
PUSH P,T1 ;[2032] SAVE THE AC
|
||
MOVE T1,LW.LC ;[2202] GET THE LOWER BOUND
|
||
MOVE T2,UW.LC ;[2202] GET THE UPPER BOUND
|
||
PUSHJ P,LC.IN## ;[2032] MAP IN THE WINDOW
|
||
POP P,T1 ;[2032] RESTORE THE AC
|
||
>;[2032] IFN TOPS20
|
||
MOVN T1,T1 ;[2032]
|
||
HRLZ T1,T1
|
||
HRR T1,LC.LB ;IOWD
|
||
SUBI T1,1 ;AT LAST
|
||
SETZ T2,
|
||
IN OC,T1
|
||
SKIPA T1,LC.AB
|
||
PUSHJ P,E$$IOV## ;[1174]
|
||
SUB T1,LC.LB
|
||
ADD T1,LW.S1 ;ADD BASE
|
||
IFE TOPS20,< ;[2032] DON'T BLT ON THE -20
|
||
CAMG T1,PH+PH.LLN ;[1400] REACHED END YET?
|
||
JRST LNKX0E ;NO
|
||
MOVE T1,PH+PH.LLN ;[1400] YES, GET WHAT WE REALLY NEED
|
||
IORI T1,.IPM
|
||
MOVE T2,T1
|
||
SUB T2,LW.S1
|
||
ADD T2,LC.LB
|
||
CAMN T2,LC.UB ;ARE WE IN LAST BLOCK
|
||
JRST LNKX0E ;YES, NO CHANGE
|
||
MOVEM T2,LC.AB ;RESET UPPER BOUND IN USE
|
||
SETZM 1(T2) ;ZERO FIRST WORD
|
||
HRLI T2,1(T2)
|
||
HRRI T2,2(T2)
|
||
BLT T2,@LC.UB ;AND THROUGH REST
|
||
>;[2032] END IFE TOPS20
|
||
LNKX0E: MOVE T2,T1 ;[2202] END OF WINDOW
|
||
MOVE T1,LW.S1 ;[2202] ORIGIN
|
||
PUSHJ P,LC.OUT## ;WRITE OUT THIS MUCH
|
||
MOVE T1,LC.AB
|
||
SUB T1,LC.LB ;GET SIZE OF WINDOW
|
||
MOVE T2,T1
|
||
ADD T2,LW.S1
|
||
CAML T2,PH+PH.LLN ;[1400] MORE TO DO?
|
||
JRST LNKX0F ;NO
|
||
AOS T2,T1 ;PUT COPY IN T2
|
||
ADDM T1,LW.S1 ;NEW WINDOW BASE
|
||
ADDB T2,UW.S1 ;GET NEXT UPPER BOUND
|
||
CAMG T2,PH+PH.LLN ;[1400] DO WE NEED TO READ IT ALL IN?
|
||
JRST LNKX0D ;YES
|
||
MOVE T1,PH+PH.LLN ;[1400] NO, GET HIGHEST WE NEED
|
||
ADDI T1,.DBM ;[650] UP TO NEXT BLOCK
|
||
ANDCMI T1,.DBM ;[650] INCASE WAS ALREADY THERE
|
||
SUB T1,LW.S1 ;NO. OF WORDS
|
||
JRST LNKX0D ;TO INPUT
|
||
LNKX0GA: MOVEI R,0 ;[1257] SET UP TO POINT TO PSECT
|
||
MOVE R,@RC.TB ;[1257] GET POINTER TO .ABS. PSECT BLOCK
|
||
MOVE T1,ROOTAB ;[1257] PICK UP ADDRESS IN ROOT NODE
|
||
MOVEM T1,RC.HL(R) ;[1257] PUT IN .ABS.
|
||
|
||
>;END OF IFN FTOVERLAY
|
||
|
||
LNKX1: ;[2366]
|
||
IFN TOPS20,< ;[2366]
|
||
;Here to determine whether a JOBDAT should be produced. The rule is:
|
||
; If the user said /NOJOBDAT, he won't get one.
|
||
; If the user has non-zero sections he won't get one.
|
||
; If the user has a psect which starts below 140 he won't get one.
|
||
; Otherwise he will.
|
||
|
||
SKIPE NOJBDA ;[2247] User already said /NOJOBDAT?
|
||
JRST LNKX1B ;[2247] Yes, user already made decision
|
||
MOVE T1,FXSBIT ;[2247] Get the section bits
|
||
TXNE T1,^-1B0 ;[2247] Non-zero sections?
|
||
JRST LNKX1A ;[2247] Yes, no JOBDAT for this program
|
||
MOVEI R,2 ;[2247] Get index to lowest psect
|
||
CAMLE R,RC.NO ;[2247] Is there one?
|
||
JRST LNKX1B ;[2247] No, it's single segment and gets JOBDAT
|
||
MOVE T1,@RC.TB ;[2247] Point to the RC block
|
||
MOVE T1,RC.IV(T1) ;[2247] Get the initial value
|
||
CAIG T1,140 ;[2247] Check psect before 140
|
||
LNKX1A: SETOM NOJBDA ;[2247] Remember no JOBDAT
|
||
|
||
;[2306] Here to determine whether a PDV should be produced. The rule is:
|
||
;[2306] If the user program has overlays, he won't get one.
|
||
;[2306] If the user said /PVBLOCK:NONE, he won't get one.
|
||
;[2306] If the user said /PVBLOCK:LOW, /PVBLOCK:HIGH, or /PVBLOCK:PSECT:
|
||
;[2306] he will get one.
|
||
;[2306] If the user said /PVBLOCK:DEFAULT, or did not say anything, he
|
||
;[2306] will get one if he will not get a JOBDAT, or if he specified
|
||
;[2306] a /PVDATA of any type. The type he will get will be identical
|
||
;[2306] to /PVBLOCK:LOW.
|
||
|
||
LNKX1B:
|
||
HLRZ T1,PRGPDV ;[2306] Get the keyword
|
||
IFN FTOVERLAY,< ;[2306]
|
||
SKIPN OVERLW ;[2306] Using overlays?
|
||
>;[2306] IFN FTOVERLAY
|
||
CAIN T1,$SSGNONE ;[2306] /PVBLOCK:NONE?
|
||
JRST LNKX1D ;[2306] Yes, toss block and exit
|
||
JUMPE T1,LNKXIC ;[2306] Never set?
|
||
CAIE T1,$SSGDEFAULT ;[2306] Or /PVBLOCK:DEFAULT?
|
||
JRST LNKX1G ;[2306] No, it's specified - must build one
|
||
|
||
;[2306] Here on /PVBLOCK:DEFAULT - Check for /PVDATA or no JOBDAT
|
||
LNKXIC: HRRZ T1,PRGPDV ;[2306] Get the PDV block address
|
||
SKIPN T1 ;[2306] Block set up (/PVDATA already seen)?
|
||
SKIPE NOJBDA ;[2306] Or no jobdat?
|
||
JRST LNKX1F ;[2306] Yes, create the PDV
|
||
|
||
;[2306] Here if a PDV not wanted - Return the block if there is one
|
||
LNKX1D: HRRZ T1,PRGPDV ;[2306] Get the PDV block address
|
||
JUMPE T1,LNKX1E ;[2306] No block, don't return it
|
||
MOVEI T2,PV.LEN ;[2306] And the length
|
||
PUSHJ P,DY.RET## ;[2306] Return it
|
||
LNKX1E: SETZM PRGPDV ;[2306] Remember there isn't one
|
||
JRST LNKX1H ;[2306] Done
|
||
|
||
;[2306] Here if a default PDV wanted - Set to /PVBLOCK:LOW and continue
|
||
LNKX1F: MOVEI T1,$SSGLOW ;[2306] Get the token
|
||
HRLM T1,PRGPDV ;[2306] Set it
|
||
|
||
;[2306] Here if a PDV is wanted - Create the block if there isn't one yet.
|
||
LNKX1G: HRRZ T1,PRGPDV ;[2306] Get the block address
|
||
SKIPN T1 ;[2306] Is there one?
|
||
PUSHJ P,PVFIX## ;[2306] No, set up the block
|
||
LNKX1H:
|
||
;[2247] Here to determine whether or not to include .LOW. in the map
|
||
MOVE T1,SG.TB+1 ;[2247] Get pointer to .LOW.
|
||
SKIPE NOJBDA ;[2247] Need a JOBDAT?
|
||
SKIPL RC.AT(T1) ;[2247] Or user program put anything in .LOW.?
|
||
JRST LNKX1I ;[2306] Yes, allow for .LOW. in the PDV map
|
||
MOVE T1,RC.NO ;[2247] Get number of psects
|
||
CAIE T1,1 ;[2247] Are there any other than .LOW.?
|
||
SETOM NOLOW ;[2247] Yes, don't put .LOW. in the map
|
||
>;[2330] IFN TOPS20
|
||
LNKX1I: MOVE R,SG.TB+1 ;[2306] Get the low segment RC block
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;IF LOADING OVERLAYS
|
||
SETZM USYM ;IGNORE UNDEFINED SYMBOLS TIL RUN TIME
|
||
>
|
||
MOVEI T1,PATSP. ;IF NOT ALREADY
|
||
SKIPN PATSPC ;SETUP PATCHING SIZE
|
||
MOVEM T1,PATSPC ;IN CASE REQUIRED
|
||
SETZM FRECOR ;NO NEED NOW
|
||
SKIPN FS.SS ;THESE ARE THE ONLY FIXUPS WE CAN DO NOW
|
||
SKIPE USYM ;BUT MAY HAVE GLOBAL REQUESTS
|
||
CAIA
|
||
PUSHJ P,FX.ZAP ;NONE, SO GET RID OF AREA
|
||
IFE TOPS20,< ;[2054]
|
||
;NOW TEST FOR CASE INWHICH SYMBOL FILE WAS
|
||
;OPENED BUT NOT USED (NOT VERY LIKELY)
|
||
SKIPE UW.LS ;NEVER OPENED
|
||
SKIPE LW.LS ;NEVER USED IF STILL ZERO
|
||
JRST CLSMAP ;STILL IN USE, OR NEVER WAS
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;IF LOADING OVERLAYS
|
||
SKIPN UW.LS ; AND PAGING SYMBOLS
|
||
CAIA ;NO
|
||
JRST CLSMAP ;KEEP FILE OPEN RATHER THAN READ IN
|
||
>
|
||
SETZM UW.LS ;CLEAR UNWANTED POINTER
|
||
MOVEI T1,SC ;SYMBOL FILE CHAN #
|
||
PUSHJ P,DVDEL.## ;DELETE FILE AND REMOVE ALL TRACES
|
||
JFCL
|
||
SETZM IO.PTR+SC ;AND FORGET ABOUT IT
|
||
> ;[2054] IFE TOPS20
|
||
CLSMAP: SKIPN IO.PTR+MC ;AN OPEN MAP?
|
||
JRST RDJBDA ;NO
|
||
MOVEI T1,MC ;SET CHAN#
|
||
MOVEM T1,IO.CHN ;IN ACTIVE STATE
|
||
PUSHJ P,DVRLS.## ;CLOSE FILL AND DO POSITIONING
|
||
PUSHJ P,DVZAP.## ;RETURN BUFFERS AND DATA BLOCK
|
||
RDJBDA:
|
||
IFN TOPS20,<
|
||
SKIPE PRGPDV ;[2306] PROGRAM DATA VECTOR?
|
||
PUSHJ P,PDVBLD ;[2306] GO ALLOCATE THE SPACE
|
||
SKIPE NOJBDA ;[2306] JOBDAT NOT WANTED?
|
||
JRST RBJBDX ;[2211] YES, NO JOBDAT
|
||
> ;[1423] IFN TOPS20
|
||
SKIPE PAG.S2 ;HIGH SEG PAGING?
|
||
PUSHJ P,RDJBH ;YES, READ IN .JBHDA
|
||
SKIPE PAG.S1 ;LOW SEG PAGING?
|
||
PUSHJ P,RDJBL ;YES
|
||
RBJBDX: ;[1460]
|
||
HRRZ T1,.JBERR ;GET ERRORS FOR THIS PROCESS
|
||
ADD T1,USYM ;EACH UNDEF COUNTS ONE
|
||
HRRM T1,.JBERR ;WILL STOP EXECUTION IF NON-ZERO
|
||
JRST CHKRST ;[1172] NOW GO DO RUNTIME SYMBOL TABLE
|
||
IFN TOPS20,<
|
||
;PDVBLD - ROUTINE TO ALLOCATE SPACE FOR THE PDV
|
||
;
|
||
|
||
PDVBLD: HRRZ P1,PRGPDV ;[2306] GET THE PDV BLOCK
|
||
SKIPE .PVNAM(P1) ;[2306] ASCIZ NAME ALREADY SET?
|
||
JRST PVBLD1 ;[2306] YES
|
||
SKIPE T3,RUNAME ;[2306] GET PROGNAM
|
||
JRST .+3 ;[2306] SET
|
||
SKIPN T3,SSNAME ;[2306] IF NOT TRY SAVE FILE NAME
|
||
MOVE T3,LODNAM ;[2306] USE DEFAULT IF NOT SET
|
||
HLLZ T2,JOBNUM ;[2335] SIXBIT JOBNUMBER
|
||
HRRI T2,'LNK' ;[2335] REST OF PDV NAME
|
||
SKIPN T3 ;[2335] HAVE A NAME
|
||
MOVE T3,T2 ;[2335] NO, USE NNNLNK AS NAME
|
||
MOVEI T2,1 ;[2306] NEED ONE WORD FOR ASCIZ NAME
|
||
TRNE T3,7777 ;[2306] NAME 5 OR 6 CHARACTERS LONG?
|
||
MOVEI T2,2 ;[2306] YES, NEED 2 WORDS FOR ASCIZ NAME
|
||
PUSH P,T3 ;[2306] SAVE THE SIXBIT NAME
|
||
PUSHJ P,DY.GET## ;[2306] GET SPACE FOR ASCIZ NAME
|
||
POP P,T3 ;[2306] GET THE SIXBIT NAME BACK
|
||
MOVEM T1,.PVNAM(P1) ;[2306] STORE THE ADDRESS
|
||
HRLM T2,.PVNAM(P1) ;[2306] AND THE COUNT
|
||
MOVE T4,T1 ;[2306] GET THE ADDRESS
|
||
HRLI T4,(POINT 7,) ;[2306] MAKE A BYTE POINTER
|
||
PUSHJ P,DVDPB.## ;[2306] SIXBIT TO ASCIZ
|
||
PVBLD1: PUSHJ P,GETPVS ;[2306] FIND OUT WHERE TO PUT IT
|
||
MOVE T1,RC.HL(P4) ;[1423] PICK UP THE DESTINATION ADDRESS
|
||
MOVEM T1,PDVADR ;[1423] AND SAVE IT UNTIL LATER
|
||
;[2237] Calculate length of memory map here. Repeated calls to PDVMAP will
|
||
;[2237] let us compute the maximum length of the memory map. Note that the
|
||
;[2306] map may actually be slightly larger than we calculate, if the symbol
|
||
;[2306] table goes in an empty psect.
|
||
SETZ W3, ;[2306] INIT. MEMORY MAP LENGTH COUNTER
|
||
SKIPE NOPDMP ;[2306] DOING A MAP?
|
||
JRST PDGTNM ;[2306] NO
|
||
MOVEI R,1 ;[2237] START WITH PSECT 1 (.LOW.)
|
||
SKIPE NOLOW ;[2247] NEED TO COUNT .LOW.?
|
||
MOVEI R,2 ;[2247] NO, START WITH SECOND PSECT
|
||
PDLOOP: PUSHJ P,PDVMAP ;[2237] GO FIND A CONTIGUOUS MEMORY BLOCK
|
||
JRST PDGTLN ;[2237] NO MORE, WE HAVE THE LENGTH NOW
|
||
ADDI W3,MM.SLN ;[2306] FOUND ANOTHER BLOCK, ACCOUNT FOR IT
|
||
JRST PDLOOP ;[2237] KEEP COUNTING MEMORY MAP ENTRIES
|
||
|
||
PDGTLN: SKIPE R ;[2237] DON'T PUT NULL LAST PSECT INTO MAP
|
||
ADDI W3,MM.SLN ;[2306] ACCOUNT FOR LAST CALL TO PDVMAP
|
||
MOVE T4,RC.IV(P4) ;[2250] GET INITIAL PSECT VALUE
|
||
CAMN T4,RC.HL(P4) ;[2250] IS THIS CURRENTLY AN EMPTY PSECT?
|
||
ADDI W3,MM.SLN ;[2250] YES, IT WON'T BE ONCE PDV IS IN IT
|
||
ADDI W3,1 ;[2361] ACCOUNT FOR MAP LENGTH
|
||
MOVEM W3,PDMPLN ;[2237] STORE MAP LENGTH FOR USE IN PDVSET
|
||
PDGTNM: HLRZ T1,.PVNAM(P1) ;[2306] GET THE LENGTH OF THE NAME
|
||
ADD W3,T1 ;[2306] ADD IT TO LENGTH OF MAP
|
||
ADDI W3,PV.LEN ;[2306] ADD LENGTH OF THE PDV AND MAP HEADER
|
||
ADDM W3,RC.HL(P4) ;[2306] ACCOUNT FOR PDV+NAME+MAP LENGTH
|
||
MOVEM P4,PVPSEG ;[1423] KEEP TRACK OF THE RELOC COUNTER
|
||
POPJ P, ;[2237]
|
||
|
||
;SUBROUTINE TO FIND CONTIGUOUS BLOCKS OF MEMORY WITH THE SAME ATTRIBUTES.
|
||
;USED IN BUILDING THE PDV MEMORY MAP, AND TO DETERMINE THE MAP'S LENGTH.
|
||
;IF OVERLAPPING PSECTS HAVE CONFLICTING ATTRIBUTES, THEY ARE CONSIDERED TO
|
||
;BOTH BE READ-ONLY.
|
||
;
|
||
; CALL: R/ PSECT # TO START SCANNING IT (MUST BE VALID # OR
|
||
; YOU'LL BE SORRY!)
|
||
;
|
||
; RETURN: +1 NO MORE PSECTS, ACS SAME AS +2 RETURN EXCEPT R
|
||
; IS LAST PSECT #+1, OR 0 IF LAST PSECT WAS EMPTY.
|
||
;
|
||
; +2 T2/ LOW BLOCK ADDR.
|
||
; T3/ HIGH BLOCK ADDR.
|
||
; T4/ BLOCK ATTRIBUTES (EITHER AT.RO OR 0)
|
||
; R/ NEXT PSECT # THAT'S NOT CONTIGUOUS OR HAS
|
||
; DIFFERENT ATTRIBUTES AND IS NOT OVERLAPPING
|
||
;
|
||
; USED ACS: T2, T3, T4, R, W1, W2
|
||
;
|
||
PDVMAP: MOVE W2,@RC.TB ;[2237] GET PSECT TABLE ADDR.
|
||
MOVE T2,RC.IV(W2) ;[2237] GET BLOCK (AND THIS PSECT'S) START ADDR
|
||
MOVE T4,RC.AT(W2) ;[2237] GET ATTRIBUTES
|
||
TXZ T4,^-AT.RO ;[2237] CLEAR EVERYTHING BUT READ-ONLY BIT
|
||
MOVE T3,RC.HL(W2) ;[2237] REMEMBER WHERE THIS PSECT ENDS
|
||
CAMLE T3,T2 ;[2237] EMPTY PSECT (START ADDR .LE. END ADDR)?
|
||
JRST PDMAP2 ;[2237] NOT NULL, JUMP AHEAD
|
||
ADDI R,1 ;[2237] INCREMENT TO NEXT PSECT
|
||
CAMG R,RC.NO ;[2237] ALL DONE WITH PSECTS?
|
||
JRST PDVMAP ;[2237] NO, USE NEXT PSECT AS BLOCK START
|
||
SETZ R, ;[2237] YES, LAST PSECT IS NULL, CLEAR R
|
||
POPJ P, ;[2237] TAKE +1 RETURN
|
||
|
||
PDMAP1: MOVE T3,RC.HL(W2) ;[2237] YES, MAKE IT NEW HIGHEST ADDR. OF BLOCK
|
||
PDMAP2: SUBI T3,1 ;[2237] END ADDR. IS CURRENT ADDR. -1
|
||
PDMAP3: ADDI R,1 ;[2237] INCREMENT TO NEXT PSECT
|
||
CAMLE R,RC.NO ;[2237] ALL DONE WITH PSECTS?
|
||
POPJ P, ;[2237] YES, TAKE +1 RETURN
|
||
MOVE W2,@RC.TB ;[2237] NO, GET NEXT PSECT TABLE ADDR.
|
||
MOVE W1,RC.IV(W2) ;[2237] GET NEXT PSECT START ADDR.
|
||
SUBI W1,1 ;[2237] NO, MAKE ADJACENT ADDRESSES EQUAL
|
||
CAMLE W1,T3 ;[2237] IS PSECT ADJACENT OR OVERLAPPING?
|
||
JRST CPOPJ1 ;[2237] NO, END OF THIS MEMORY MAP ENTRY
|
||
CAML W1,T3 ;[2237] YES, DO THEY OVERLAP?
|
||
JRST PDVADJ ;[2237] NO, THEY'RE ADJACENT
|
||
MOVE W1,RC.AT(W2) ;[2237] YES, GET NEW PSECT'S ATTRIBUTES
|
||
TXZ W1,^-AT.RO ;[2237] CLEAR EVERYTHING BUT READ-ONLY BIT
|
||
CAME W1,T4 ;[2237] SAME ATTRIBUTES AS LAST PSECT?
|
||
MOVX T4,AT.RO ;[2237] NO, MUST BE A CONFLICT - SET BLOCK R.O.
|
||
JRST PDVCOM ;[2237] JOIN COMMON CODE
|
||
|
||
PDVADJ: MOVE W1,RC.AT(W2) ;[2237] YES, GET NEW PSECT'S ATTRIBUTES
|
||
TXZ W1,^-AT.RO ;[2237] CLEAR EVERYTHING BUT READ-ONLY BIT
|
||
CAME W1,T4 ;[2237] SAME ATTRIBUTES AS LAST PSECT?
|
||
JRST CPOPJ1 ;[2237] NO, END OF THIS MEMORY MAP ENTRY
|
||
PDVCOM: CAMGE T3,RC.HL(W2) ;[2237] YES, IS END ADDR. HIGHER THAN BEFORE?
|
||
JRST PDMAP1 ;[2237] YES, GO LOAD NEW END ADDR. AND CONTINUE
|
||
JRST PDMAP3 ;[2237] NO, CONTINUE LOOPING THROUGH ALL PSECTS
|
||
|
||
;GETPVS - ROUTINE TO FIGURE OUT WHERE THE PROGRAM DATA VECTOR GOES.
|
||
;RETURNS WITH:
|
||
;
|
||
; PVPNAM/ NAME (SIXBIT) OF PSECT TO APPEND PDV TO
|
||
; R/ AREA PSECT IS IN, LC.IX OR HC.IX
|
||
; P4/ POINTER TO RC BLOCK OF PSECT NAMED IN PVPNAM
|
||
; RC.HL(P4)/ FIRST ADDRESS TO STORE THE PDV IN
|
||
; PVPLIM/ LAST ADDRESS TO STORE THE PDV IN
|
||
;
|
||
;ALSO UPDATES LOWLOC IF NECESSARY.
|
||
;CLOSE RESEMBLENCE TO GETSST IS NO COINCIDENCE.
|
||
|
||
GETPVS: HLRZ R,PRGPDV ;[1423] PICK UP DESTINATION
|
||
CAIN R,-1 ;[1423] PSECT?
|
||
JRST GETP10 ;[1423] YES, GO FIND IT
|
||
GETP02: CAIN R,2 ;[1423] /PVBLOCK:HIGH?
|
||
JRST GETP08 ;[1423] YES, TREAT LIKE /PVBLOCK:PSECT:.HIGH.
|
||
CAIN R,1 ;[1423] /PVBLOCK:LOW?
|
||
JRST GETP03 ;[1423] YES
|
||
SKIPE LL.S2 ;[1423] DEFAULT -- IS THERE A HIGH SEG?
|
||
JRST GETP08 ;[1423] YES, PUT THE PDV THERE
|
||
|
||
;HERE IF /PVBLOCK:LOW
|
||
; APPEND THE PROGRAM DATA VECTOR TO THE LAST PSECT IN THE IMAGE.
|
||
; OUR FIRST MISSION IS TO FIND THAT PSECT...
|
||
|
||
GETP03: SETZB R,T3 ;[1423] INIT HIGHEST ADDR AND PSECT IDX
|
||
GETP04: MOVE T1,@RC.TB ;[1423] GET POINTER TO RC BLOCK OF NEXT PSECT
|
||
MOVE T2,RC.SG(T1) ;[1423] GET THE SEGMENT THAT THIS PSECT IS IN
|
||
CAIE T2,1 ;[1423] IN THE LOW SEGMENT?
|
||
JRST GETP06 ;[1423] NO, IT DOESN'T COUNT FOR /PVBLOCK:LOW
|
||
MOVE T2,RC.HL(T1) ;[1423] GET THE FIRST FREE AFTER THIS PSECT
|
||
CAMG T2,T3 ;[1423] HIGHEST SO FAR?
|
||
JRST GETP06 ;[1423] NO, CONTINUE
|
||
MOVE T3,T2 ;[1423] SAVE NEW BEST
|
||
MOVE T4,R ;[1423] AND WHAT PSECT IT WAS
|
||
MOVE T2,RC.NM(T1) ;[1423] GET THE WINNER'S NAME
|
||
MOVEM T2,PVPNAM ;[1423] STORE FOR ERROR MESSAGES
|
||
GETP06: CAMGE R,RC.NO ;[1423] ALL DONE?
|
||
AOJA R,GETP04 ;[1423] NO, LOOP
|
||
MOVE R,T4 ;[1423] YES, SAVE PSECT INDEX OF LAST ONE
|
||
JRST GETP14 ;[1423] GO UPDATE THAT PSECT
|
||
;HERE ON /PVBLOCK:HIGH. FAKE /PVBLOCK:PSECT:.HIGH. AND FALL INTO PSECT CODE.
|
||
|
||
GETP08: MOVE T1,['.HIGH.'] ;[1423] /PVBLOCK:HIGH IS JUST LIKE A PSECT
|
||
MOVEM T1,PVPNAM ;[1423] STORE
|
||
|
||
;HERE ON /PVBLOCK:PSECT:xxxxxx. FIND THE PSECT IN THE RC TABLES.
|
||
|
||
GETP10: SETZ R, ;[1423] YES, HAVE PSECT NAME
|
||
MOVE W2,PVPNAM ;[2220] GET THE PDV NAME
|
||
GETP12: MOVE T1,@RC.TB ;[1423]
|
||
MOVE T2,RC.NM(T1) ;[2220] GET PSECT NAME
|
||
PUSHJ P,NAMCMP## ;[2220] IS THIS THE ONE?
|
||
JRST GETP14 ;[1423] YES,
|
||
ADDI R,1 ;[1423] NEXT ONE
|
||
CAMG R,RC.NO ;[1423] ANY MORE?
|
||
JRST GETP12 ;[1423] YES, LOOP
|
||
E$$NPP::.ERR. (MS,.EC,V%L,L%W,S%W,NPP,<Non-existent psect >) ;[1423]
|
||
.ETC. (SBX,.EC!.EP,,,,PVPNAM) ;[1423]
|
||
.ETC. (STR,,,,,,< specified for program data vector>) ;[1423]
|
||
MOVEI R,1 ;[1423] SET TO LOW
|
||
HRLM R,PRGPDV ;[1423]
|
||
JRST GETP02 ;[1423] AND LOOP BACK
|
||
;HERE WITH THE PSECT INDEX TO USE IN R, AND ITS NAME IN PVPNAM.
|
||
;NOW CALCULATE THE UPPER BOUND POSSIBLE FOR THE PDV.
|
||
|
||
|
||
;THE NEXT PSECT ORIGIN WE WOULD CROSS, OR STOP AT 777777 IF NO MORE PSECTS.
|
||
|
||
GETP14: MOVE P4,@RC.TB ;[1423] POINTER TO THIS PSECT'S RC BLOCK
|
||
MOVX T1,AT.RP ;[2247] GET THE RELOCATABLE BIT
|
||
ANDCAM T1,RC.AT(P4) ;[2247] INDICATE IT EXISTS (IN CASE .LOW.)
|
||
MOVE T4,RC.HL(P4) ;[1423] ADDR OF FIRST FREE LOCATION
|
||
ADDI R,1 ;[1423] START THE SEARCH AT THE NEXT PSECT
|
||
;LOOP BACK HERE ON EACH NEW PSECT, LOOKING FOR ONE WHOSE ORIGIN
|
||
;IS .GE. C(T4).
|
||
GETP16: CAMLE R,RC.NO ;[1423] CHECKED THEM ALL YET?
|
||
JRST GETP18 ;[1423] YES, GO USE 777777
|
||
MOVE T1,@RC.TB ;[1423] GET PSECT'S RC BLOCK
|
||
MOVE T2,RC.IV(T1) ;[1423] GET ORIGIN OF THIS PSECT
|
||
CAMGE T2,T4 ;[1423] START ABOVE THE PDV PSECT?
|
||
AOJA R,GETP16 ;[1423] NO, MUST HAVE BEEN OVERLAPPING PSECT
|
||
MOVE T3,RC.HL(T1) ;[1423] YES, CHECK FOR ZERO-LENGTH PSECT
|
||
CAMG T3,T2 ;[1423] WOULD WE OVERWRITE ANYTHING?
|
||
AOJA R,GETP16 ;[1423] NO, IGNORE THIS PSECT
|
||
SOSA T2 ;[1423] YES, LAST ADDR TO USE IS ONE LESS
|
||
GETP18: HLLO T2,RC.HL(P4) ;[1450] ROUND UP TO SECTION BOUNDARY
|
||
MOVEM T2,PVPLIM ;[1423] STORE NEWLY CALCULATED LIMIT
|
||
|
||
;NOW SET UP SOME FINAL THINGS FOR THE REST OF LINK, THEN RETURN.
|
||
|
||
GETP20: MOVE R,RC.SG(P4) ;[1423] FETCH SEGMENT INDEX FOR PSECTS
|
||
MOVE T1,RC.HL(P4) ;[1423] START OF PROGRAM DATA VECTOR
|
||
POPJ P, ;[1423] END OF GETPVS
|
||
|
||
> ;[1423] IFN TOPS20
|
||
;HERE TO READ IN FIRST 10 WORDS OF HIGH SEGMENT
|
||
|
||
;[2247] Under TOPS-20 just map the first high segment page into the DY area.
|
||
;[2247] It is never returned, as there is plenty of memory available,
|
||
;[2247] and by the time it could be there won't be anyone who needs it.
|
||
|
||
RDJBH:
|
||
IFE TOPS20,< ;[2247]
|
||
MOVEI T2,.JBHDA ;NO OF WORDS WE NEED
|
||
PUSHJ P,DY.GET ;GET THEM
|
||
MOVEM T1,JBHPTR ;STORE LOCATION
|
||
SUBI T1,1 ;IOWD IS 1 LESS
|
||
HRLI T1,-10 ;SHOULD BE -.JBHDA BUT MACRO 50 NOT YET OUT
|
||
SETZ T2, ;TERMINATE LIST
|
||
USETI HC,1 ;SET ON BLOCK 1
|
||
IN HC,T1 ;READ FIRST 10 WORDS ONLY
|
||
POPJ P, ;OK
|
||
PUSHJ P,E$$IHC## ;[1174] DIE WITH ERROR
|
||
> ;[1401] IFE TOPS20
|
||
IFN TOPS20,<
|
||
MOVEI T2,2*.IPS ;[2055] 2*.IPS INSURES ONE FULL PAGE
|
||
PUSHJ P,DY.GET ;[1401]
|
||
IORI T1,.IPM ;[2247] END OF THIS PAGE
|
||
ADDI T1,1 ;[2247] SET ON PAGE BOUNDARY
|
||
MOVEM T1,JBHPTR ;[2247] STORE LOCATION
|
||
LSH T1,-9 ;[1401]
|
||
HRLI T1,.FHSLF ;[1401] PROCESS IS SELF
|
||
MOVE T2,T1 ;[1401]
|
||
MOVE T1,LL.S2 ;[2247] GET THE HIGH SEGMENT ORIGIN
|
||
LSH T1,-9 ;[2247] IN PAGES
|
||
HRL T1,HC.JF ;[2247] FORK HANDLE
|
||
MOVE T3,[PM%RWX] ;[1401] MOVE ONE PAGE FOR READING
|
||
PMAP% ;[1401]
|
||
ERCAL E$$IHC## ;[2247] CAN'T DO IT
|
||
POPJ P, ;[1401] AND RETURN
|
||
> ;[1401] IFN TOPS20
|
||
|
||
;HERE IF LOWSEG PAGED, WE NEED BOTH ENDS OF FILE AT ONCE
|
||
;THEREFORE PUT JOBDAT (0-137) IN DY AREA, POINTER IS JOBPTR
|
||
;AND TOP OF FILE IN LC AREA
|
||
|
||
;[2247] Under TOPS-20 just map the first page into the DY area.
|
||
;[2247] It is never returned, as there is plenty of memory available,
|
||
;[2247] and by the time it could be there won't be anyone who needs it.
|
||
|
||
RDJBL:
|
||
IFE TOPS20,<
|
||
MOVEI T2,.JBDA ;NEED ONE BLOCK
|
||
PUSHJ P,DY.GET
|
||
MOVEM T1,JOBPTR ;HOLD OFFSET IN CORE SO WE CAN FIXUP
|
||
; REFERENCES TO JOBDAT SYMBOLS
|
||
SKIPN LW.S1 ;HOWEVER IF 1ST PAGE IS IN CORE
|
||
JRST BLTJBL ;JUST MOVE IT
|
||
SUBI T1,1 ;IOWD IS ONE LESS
|
||
HRLI T1,-140 ;WORD COUNT
|
||
SETZ T2, ;TERMINATE LIST
|
||
USETI LC,1 ;READ BLOCK 1
|
||
IN LC,T1 ;AT LEAST FIRST 140 WORDS
|
||
POPJ P, ;NONE
|
||
PUSHJ P,E$$ILC## ;[1174] DIE WITH ERROR
|
||
> ;[1401] IFE TOPS20
|
||
IFN TOPS20,<
|
||
MOVEI T2,2*.IPS ;[2247] 2*.IPS INSURES ONE FULL PAGE
|
||
PUSHJ P,DY.GET ;[1401]
|
||
IORI T1,.IPM ;[2247] END OF THIS PAGE
|
||
ADDI T1,1 ;[2247] SET ON PAGE BOUNDARY
|
||
MOVEM T1,JOBPTR ;[2247] HOLD OFFSET IN CORE
|
||
LSH T1,-9 ;[1401]
|
||
HRLI T1,.FHSLF ;[1401] PROCESS IS SELF
|
||
MOVE T2,T1 ;[1401]
|
||
HRLZ T1,LC.JF ;[1401] FILEJFN,,PAGE 0
|
||
MOVE T3,[PM%RWX] ;[1401] MOVE ONE PAGE FOR READING
|
||
PMAP% ;[1401]
|
||
ERCAL E$$ILC## ;[2247] CAN'T DO IT
|
||
POPJ P, ;[2247] RETURN
|
||
> ;[1401] IFN TOPS20
|
||
|
||
IFE TOPS20,< ;[2247]
|
||
;HERE TO JUST BLT JOBDAT AREA TO SAFE PLACE
|
||
BLTJBL: HRL T1,LC.LB ;FROM HERE
|
||
HRRI T2,.JBDA(T1) ;TO HERE
|
||
BLT T1,-1(T2) ;WELL ALMOST THERE
|
||
POPJ P,
|
||
SUBTTL RUNTIME SYMBOL TABLE GENERATION
|
||
>;[2247] IFE TOPS20
|
||
|
||
;HERE TO DECIDE IF WE WANT TO PUT A RUNTIME SYMBOL TABLE INTO THE
|
||
;IMAGE, AND IF SO, TO DO IT. WE WANT A RUNTIME SYMBOL TABLE IF ANY
|
||
;OF THE FOLLOWING CONDITIONS ARE TRUE:
|
||
;
|
||
; 1. C(.JBDDT) IS NONZERO
|
||
; 2. USER SAID /SYMSEG
|
||
; 3. USER SAID /SYFILE:RADIX50
|
||
;
|
||
;IF THE USER SAID /NOSYMBOLS, WE NEVER WANT A RUNTIME SYMBOL TABLE.
|
||
|
||
CHKRST:
|
||
IFN TOPS20,< ;[2202]
|
||
SKIPE NOJBDA ;[2306] JOBDAT NOT WANTED?
|
||
JRST CHKRS0 ;[2211] YES, NO JOBDAT
|
||
MOVE T1,JOBPTR ;[2306] POINT TO JOBDAT
|
||
> ;IFN TOPS20 [2202]
|
||
IFE TOPS20,< ;[2306]
|
||
SKIPE PAG.S1 ;[1172] FIND JOBDAT
|
||
SKIPA T1,JOBPTR ;[1172] IN DY IF PAGING
|
||
MOVE T1,LC.LB ;[1172] IN LC AREA IF NOT
|
||
>;[2306] IFE TOPS20
|
||
SKIPN T2,VERNUM ;[1202] /VERSION? (CHECK NOW FOR OLDSYM)
|
||
SKIPA T2,.JBVER(T1) ;[1202] NO, FETCH FROM .JBVER
|
||
MOVEM T2,.JBVER(T1) ;[1202] OVERRIDE IF /VERSION
|
||
MOVEM T2,VERNUM ;[1202] STORE FOR SYMBOL FILES
|
||
SETZM .JBSYM(T1) ;[1172] ASSUME NO SYMBOLS
|
||
SETZM .JBUSY(T1) ;[1172] ..
|
||
CHKRS0: SKIPE NOSYMS ;[1460] /NOSYMBOLS?
|
||
JRST NORST ;[1172] YES, FORGET IT
|
||
IFN TOPS20,< ;[2202]
|
||
SKIPN NOJBDA ;[2306] DOES JOBDAT EXIST?
|
||
> ;[2202] IFN TOPS20
|
||
SKIPN .JBDDT(T1) ;[1172] C(.JBDDT) <> 0?
|
||
CHKRS1: SKIPE SYMSEG ;[2211] OR USER SAY /SYMSEG?
|
||
JRST DORST ;[1172] YES, GO DO IT!
|
||
SKIPL SYMFRM ;[1172] /SYFILE:RADIX50?
|
||
JRST NORST ;[1172] NOPE, NO SYMBOL TABLE
|
||
|
||
;HERE TO GENERATE A RUNTIME SYMBOL TABLE.
|
||
;FIRST, MAKE SURE THE AREA (LC/HC) THAT THE SYMBOLS ARE GOING
|
||
;INTO IS BIG ENOUGH, OR IS PAGING AND THE RIGHT PAGE IS IN.
|
||
|
||
DORST:
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;[1172] LOADING OVERLAYS?
|
||
JRST OVLRST ;[1172] YES, THINGS ARE DIFFERENT
|
||
> ;END IFN FTOVERLAY
|
||
|
||
E$$SST::.ERR. (MS,0,V%L,L%I,S%I,SST,<Sorting symbol table>) ;[1174]
|
||
PUSHJ P,GETSST ;[1172] FIND BASE OF SYMBOLS, SET R AND P4
|
||
IFE TOPS20,< ;[2335]
|
||
SKIPE PAG.S0(R) ;[2335] SYMBOL SEGMENT PAGING?
|
||
> ;[2335] IFE TOPS20
|
||
JRST DORST2 ;[1172] YES, GO GET THE RIGHT PAGE INTO MEMORY
|
||
MOVE P2,RC.HL(P4) ;[1172] GET FIRST WORD OF TABLE
|
||
SUB P2,LL.S0(R) ;[1172] CONVERT TO OFFSET IN SEGMENT
|
||
SUB P2,LW.S0(R) ;[1172] THENCE TO OFFSET IN WINDOW
|
||
ADD P2,TAB.LB(R) ;[1172] FIRST ADDRESS WE'RE GOING TO STORE INTO
|
||
CAMG P2,TAB.AB(R) ;[1172] IS THE AREA BIG ENOUGH?
|
||
JRST DORST4 ;[1172] YES, GO FILL IT IN
|
||
MOVE P1,R ;[1172] WHICH AREA TO EXPAND
|
||
SUB P2,TAB.AB(R) ;[1172] HOW MUCH WE NEED
|
||
PUSHJ P,LNKCOR ;[1172] EXPAND THE AREA
|
||
JRST DORST2 ;[1172] FINE, JUST START PAGING
|
||
JRST DORST3 ;[1172] GO CHECK PAGING FOR THE FIRST TIME
|
||
;HERE IF PAGING TO BRING THE RIGHT LC/HC PAGE INTO MEMORY.
|
||
|
||
DORST2: PUSHJ P,LSYP ;[1172] NOW PAGING, GET RIGHT PAGE IN MEMORY
|
||
DORST3: PUSHJ P,CHKPAG ;[1172] SEE IF WE JUST STARTED PAGING
|
||
DORST4: MOVE T1,RC.HL(P4) ;[1172] NOW TO SET UP XX.PT
|
||
SUB T1,LL.S0(R) ;[1172] FIRST ADDRESS TO STORE INTO
|
||
SUB T1,LW.S0(R) ;[1172] CONVERT TO OFFSET IN AREA
|
||
ADD T1,TAB.LB(R) ;[1172] ADDRESS IN AREA
|
||
MOVEM T1,TAB.PT(R) ;[1172] STORE FOR SYMOUT
|
||
|
||
|
||
;OK, EVERYTHING IS INITIALIZED. NOW WRITE OUT THE SYMBOL TABLE(S).
|
||
|
||
SKIPE USYM ;[1172] ANY UNDEFINED SYMBOLS?
|
||
PUSHJ P,DOUDFS ;[1172] YES, WRITE THEM OUT
|
||
PUSHJ P,GSDLT ;[1172] DELETE THE GS AREA
|
||
SKIPN SYMFUL ;[1172] IF ANY ROOM LEFT
|
||
PUSHJ P,DOLOCS ;[1172] WRITE THE LOCAL SYMBOLS OUT
|
||
|
||
|
||
;THE SYMBOLS HAVE BEEN WRITTEN. NOW UPDATE THE HL/HC WORDS, THEN GO CLEAN UP.
|
||
|
||
MOVE T1,TAB.PT(R) ;[1172] NEXT FREE WORD
|
||
SUB T1,TAB.LB(R) ;[1172] OFFSET IN WINDOW
|
||
ADD T1,LW.S0(R) ;[1172] OFFSET IN SEGMENT
|
||
CAMLE T1,HL.S0(R) ;[1172] BIGGEST WE'VE SEEN?
|
||
MOVEM T1,HL.S0(R) ;[1172] YES, STORE IT
|
||
CAMLE T1,HC.S0(R) ;[1172] BIGGEST LOADED LOC?
|
||
MOVEM T1,HC.S0(R) ;[1172] YES, STORE IT
|
||
ADD T1,LL.S0(R) ;[1172] FORM VIRTUAL ADDRESS
|
||
CAMLE T1,RC.HL(P4) ;[1172] BIGGEST YET FOR THIS PSECT?
|
||
MOVEM T1,RC.HL(P4) ;[1172] YES, REMEMBER IT
|
||
|
||
;[2306] Here to set up the symbol vector
|
||
|
||
IFN TOPS20,< ;[2366]
|
||
SKIPN T2,PRGPDV ;[2306] Get the pointer to the PDV
|
||
JRST SYMVNO ;[2306] No PDV, so no symbol vector
|
||
MOVE W1,.PVSYM(T2) ;[2306] Get the symbol table vector address
|
||
>;[2366] IFN TOPS20
|
||
IFE TOPS20,< ;[2366]
|
||
SKIPN W1,SYMVEC ;[2366] Building a symbol vector?
|
||
JRST SYMVNO ;[2366] No
|
||
>;[2366] IFE TOPS20
|
||
SUB W1,LL.S0(R) ;[2311] Subtract the segment base
|
||
MOVE W2,W1 ;[2306] Get the address
|
||
ADDI W2,SV.LEN-1 ;[2306] Last address needed
|
||
CAMG W2,TAB.UW(R) ;[2306] Is it above the window?
|
||
CAMGE W1,TAB.LW(R) ;[2306] Is it below the window?
|
||
CAIA ;[2306] Must move window
|
||
JRST SYMVST ;[2306] No, no need to move window
|
||
MOVE T1,TAB.LW(R) ;[2306] Get current lower bound
|
||
MOVE T2,TAB.UW(R) ;[2306] And upper bound
|
||
PUSHJ P,@[LC.OUT## ;[2306] Remove it
|
||
HC.OUT##]-1(R) ;[2306] From the window
|
||
MOVE T1,W1 ;[2306] Get the bottom address
|
||
TRZ T1,.IPM ;[2306] Put it on a page bound
|
||
MOVEM T1,TAB.LW(R) ;[2306] Set the bottom of the window
|
||
TRO W2,.IPM ;[2306] Set to top of page
|
||
MOVE T2,W2 ;[2306] Get the high address
|
||
SUB T2,T1 ;[2306] Get the size
|
||
ADD T2,TAB.LB(R) ;[2306] Get the high address in memory
|
||
CAMG T2,TAB.AB(R) ;[2306] Will it fit?
|
||
JRST SYMVGT ;[2306] Yes, just go get it
|
||
PUSH P,T2 ;[2306] Save the upper bound
|
||
SUB T2,TAB.AB(R) ;[2306] How much is needed
|
||
MOVE P1,R ;[2306] Get the index
|
||
MOVE P2,T2 ;[2306] And the amound needed
|
||
PUSHJ P,LNKCOR## ;[2306] Try and get it
|
||
PUSHJ P,E$$MEF## ;[2306] Only wanted a maximum 2 pages
|
||
POP P,T2 ;[2306] Restore the upper bound
|
||
SYMVGT: MOVEM T2,TAB.AB(R) ;[2306] Save the upper bound
|
||
MOVEM W2,TAB.UW(R) ;[2306] And the size
|
||
MOVE T1,TAB.LW(R) ;[2306] Get the lower bound
|
||
MOVE T2,TAB.UW(R) ;[2306] And the upper bound
|
||
PUSHJ P,@[LC.IN## ;[2306] Get it
|
||
HC.IN##]-1(R) ;[2306] Into window
|
||
SYMVST: SUB W1,TAB.LW(R) ;[2306] Get the offset into the window
|
||
ADD W1,TAB.LB(R) ;[2306] Unrelocate
|
||
MOVEI T1,SV.LEN ;[2306] Get the symbol vector length
|
||
MOVEM T1,(W1) ;[2306] Store it
|
||
MOVE T1,DSTADR ;[2366] Get the address of the defined symbols
|
||
IFN TOPS20,< ;[2366]
|
||
MOVE T2,FXSBIT ;[2306] Get the section bits
|
||
TXNN T2,^-1B0 ;[2306] Any non-zero sections?
|
||
HRLI T1,(IFIW) ;[2306] No, make it an IFIW
|
||
>;[2366] IFN TOPS20
|
||
MOVEM T1,2(W1) ;[2306] Store the defined address
|
||
SKIPN USTADR ;[2306] Any undefined symbols?
|
||
JRST SYMVS1 ;[2306] No
|
||
MOVE T1,USTADR ;[2306] Yes, get the undefined symbol address
|
||
IFN TOPS20,< ;[2366]
|
||
TXNN T2,^-1B0 ;[2306] Any non-zero sections?
|
||
HRLI T1,(IFIW) ;[2306] No, make it an IFIW
|
||
>;[2366] IFN TOPS20
|
||
SYMVS1: MOVEM T1,SV.SLN+2(W1) ;[2306] Store the undefined address
|
||
MOVE T1,DSYCNT ;[2306] Get the defined symbol count
|
||
TXO T1,FLD(.R50D,ST%TYP) ;[2306] Set Radix 50 defined type
|
||
MOVEM T1,1(W1) ;[2306] Store the count and zero third word
|
||
MOVE T1,USYCNT ;[2306] Get the undefined symbol count
|
||
TXO T1,FLD(.R50U,ST%TYP) ;[2306] Set Radix 50 undefined type
|
||
MOVEM T1,SV.SLN+1(W1) ;[2306] Store it
|
||
SETZM 3(W1) ;[2306] Zero the defined table third word
|
||
SETZM SV.SLN+3(W1) ;[2306] Zero the undefined table third word
|
||
SYMVNO:
|
||
SKIPGE SYMFRM ;[1172] OLD STYLE SYMBOL FILE WANTED?
|
||
PUSHJ P,OLDSYM ;[1172] YES, WRITE IT OUT
|
||
E$$STC::.ERR. (MS,0,V%L,L%I,S%I,STC,<Symbol table completed>) ;[1174]
|
||
JRST FINRST ;[1172] GO JOIN COMMON CLEAN UP CODE
|
||
;HERE WHEN LOADING OVERLAYS.
|
||
|
||
IFN FTOVERLAY,<
|
||
OVLRST: HLRE T2,PH+PH.RDX ;[1400] GET - NO. OF SYMBOLS
|
||
MOVM T3,T2 ;[1172] +
|
||
ADD T3,HL.S1 ;[1172] HIGHEST LOCATION
|
||
ADD T3,SPACE ;[1172] PLUS BUFFER SPACE
|
||
IOR. T3,.PGSIZ ;[1172] UP TO PAGE BOUND
|
||
ADDI T3,1 ;[1172] NEXT FREE
|
||
ADD T3,T2 ;[1172] START OF SYMBOLS
|
||
HLL T3,PH+PH.RDX ;[1400] - COUNT
|
||
MOVEM T3,JOB116 ;[1172] STORE IN INTERNAL PTR
|
||
MOVEM T3,.JBSYM(T1) ;[1172] STORE SYMBOL TABLE PTR
|
||
|
||
IFN TOPS20,< ;[2247] Read symbols now on TOPS-20
|
||
MOVM P1,T2 ;[2247] Get count of symbols
|
||
HRRZ P2,T3 ;[2247] Save the base address
|
||
MOVE P3,LS.LB ;[2247] Get the start of the symbols
|
||
OVLRS1: MOVE T1,LW.LC ;[2247] Get the lower bound
|
||
MOVE T2,UW.LC ;[2247] And the upper bound
|
||
PUSHJ P,LC.OUT## ;[2247] Remove it from memory
|
||
HRRZ T1,P2 ;[2247] Get base address
|
||
TRZ T1,.IPM ;[2247] Put it on a page boundary
|
||
HRRZ T2,P1 ;[2247] Get the size wanted
|
||
MOVE T3,LC.AB ;[2247] Get the top
|
||
SUB T3,LC.LB ;[2247] Get the size available
|
||
CAMLE T2,T3 ;[2247] We need less than we have?
|
||
MOVE T2,T3 ;[2247] No, use what we have
|
||
ADD T2,T1 ;[2247] Get the max address
|
||
IORX T2,.IPM ;[2247] Set at end of a page boundary
|
||
MOVEM T1,LW.LC ;[2247] Store the new lower bound
|
||
MOVEM T2,UW.LC ;[2247] And the new upper
|
||
PUSHJ P,LC.IN## ;[2247] Get it
|
||
MOVE T3,P2 ;[2247] Get the base address
|
||
SUB T3,LW.LC ;[2247] Minus the window
|
||
ADD T3,LC.LB ;[2247] Locate in memory
|
||
HRRZ T1,T3 ;[2247] Destination for BLT
|
||
HRL T1,P3 ;[2247] Source for BLT
|
||
ADDI T3,-1(P1) ;[2247] How far we want to go
|
||
MOVE T2,T3 ;[2247] Use as last to load
|
||
CAMLE T2,LC.AB ;[2247] More than we have
|
||
MOVE T2,LC.AB ;[2247] Yes, do what we can
|
||
BLT T1,(T2) ;[2247] Copy it
|
||
MOVE T2,UW.LC ;[2247] No, Get highest location done
|
||
SUBI T2,-1(P2) ;[2247] Figure out how much was done
|
||
SUB P1,T2 ;[2247] Reduce the count by that much
|
||
JUMPLE P1,NORST ;[2247] Check for none left (done)
|
||
ADD P2,T2 ;[2247] Where to copy to next
|
||
ADD P3,T2 ;[2247] Where to copy from next
|
||
JRST OVLRS1 ;[2247] Copy some more
|
||
>;[2247] IFN TOPS20
|
||
> ;END IFN FTOVERLAY
|
||
|
||
|
||
;HERE IF NOT WRITING A RUNTIME SYMBOL TABLE. JUST DELETE LINK'S TABLES.
|
||
|
||
NORST: PUSHJ P,GSDLT ;[1172] GET RID OF THE GS AREA
|
||
|
||
|
||
;ALL PATHS REJOIN HERE. DELETE TABLES, SET UP JOBDAT, AND EXIT.
|
||
|
||
FINRST: SKIPLE T1,SYMFRM ;[1172] WANT NEW STYLE SYMBOL FILE?
|
||
PUSHJ P,SAVSYM ;[1172] YES, WRITE IT OUT
|
||
PUSHJ P,AS.ZAP ;[1172] DONE WITH AS AREA
|
||
MOVEI T1,AC ;[1172] ALGOL SYMS CHANNEL
|
||
SKIPE PAG.AS ;[1172] AREA PAGING?
|
||
PUSHJ P,DVDEL.## ;[1172] YES, DELETE OVERFLOW FILE
|
||
JFCL ;[1172] DON'T CARE
|
||
PUSHJ P,FX.ZAP ;[1172] DONE WITH FX AREA
|
||
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;[1172] LOADING OVERLAYS?
|
||
JRST FINRS2 ;[1172] YES, SAVE LS AREA
|
||
> ;END IFN FTOVERLAY
|
||
|
||
PUSHJ P,LS.ZAP ;[1172] KILL OFF THE LS AREA
|
||
MOVEI T1,SC ;[1172] LS OVERFLOW CHANNEL
|
||
SKIPE PAG.LS ;[1172] LS AREA PAGING?
|
||
PUSHJ P,DVDEL.## ;[1172] YES, DELETE OVERFLOW FILE
|
||
JFCL ;[1172] WASN'T PAGING
|
||
|
||
|
||
;NOW UPDATE JOBDAT, THEN EXIT VIA SAVTST.
|
||
|
||
FINRS2:
|
||
IFN TOPS20,<
|
||
SKIPE PRGPDV ;[1423] CREATE A PDV?
|
||
PUSHJ P,PDVSET ;[1423] YES
|
||
> ;[2260]
|
||
SKIPE PAG.S1 ;[2241] LC AREA PAGING?
|
||
SKIPA P1,JOBPTR ;[2241] YES, JOBDAT IS IN DY
|
||
MOVE P1,LC.LB ;[2241] NO, IT'S IN LC
|
||
SKIPE PAG.S2 ;[2241] HC AREA?
|
||
SKIPA P2,JBHPTR ;[2241] YES, FETCH DY PTR
|
||
MOVE P2,HC.LB ;[2241] NO, FETCH HC PTR (OR 0)
|
||
|
||
;COMPUTE ADDRESS AT WHICH TO START PROGRAM. IF A DEBUGGER IS LOADED, THIS IS
|
||
;NOT NECESSARILY THE MAIN PROGRAM'S START ADDRESS, BUT DEPENDS ON THE DEBUGGER.
|
||
|
||
SETZ T1, ;[2211] ASSUME WE DON'T START PROGRAM
|
||
SKIPE EXECSW ;[2211] GO INTO EXECUTION?
|
||
MOVE T1,STADDR ;[2211] YES, ASSUME .JBSA
|
||
HRRZ T2,DEBUGSW ;[2211] IF DEBUGGING, DEBUGGER'S START ADDRESS
|
||
SKIPGE DEBUGSW ;[2211] TAKES PRIORITY SO
|
||
MOVE T1,@STLOCN(T2) ;[2211] FIND IT
|
||
HRRM T1,EXECSW ;[2211] IN ANY CASE STORE BACK IN EXECSW
|
||
|
||
IFN TOPS20,< ;[2366]
|
||
MOVE T1,FXSBIT ;[2211] GET SECTION BITS
|
||
SKIPE NOJBDA ;[2306] JOBDAT NOT WANTED
|
||
JRST JOBST9 ;[2260] YES, DON'T BOTHER WITH JOBDAT
|
||
>;[2366] IFN TOPS20
|
||
|
||
;SUBTTL SET UP JOBDAT AREA
|
||
;HERE TO SET UP THE REST OF THE JOBDAT AREA. ENTER WITH P1 POINTING TO JOBDAT
|
||
;AREA AND P2 TO VESTIGIAL JOBDAT (0 IF NO HIGH SEGMENT).
|
||
|
||
IFE TOPS20,< ;[2366]
|
||
|
||
;[2366] If this is an extended addressing program, then the values must
|
||
;[2366] reflect section zero only. It is necessary to figure out what
|
||
;[2366] those values are.
|
||
|
||
MOVE T1,HL.S1 ;[2366] Get the highest loaded
|
||
MOVE T2,HC.S1 ;[2366] And the highest code
|
||
TLNN T1,-1 ;[2366] Extended addressing?
|
||
JRST FINRS3 ;[2366] No, no problem
|
||
MOVEI R,1 ;[2366] Start at first psect (ignore .abs.)
|
||
SETZ T1, ;[2366] Init highest loaded
|
||
MOVEI T3,777777 ;[2366] Highest location were psect can start
|
||
MOVEI T4,2 ;[2366] Index for high segment
|
||
|
||
FNDSZP: MOVE W1,@RC.TB ;[2366] Get pointer to next psect
|
||
CAMN T4,RC.SG(W1) ;[2366] High segment?
|
||
JRST FNDSZ1 ;[2366] Yes, ignore it
|
||
CAMGE T3,RC.IV(W1) ;[2366] Start outside section zero?
|
||
JRST FNDSZ1 ;[2366] Yes, ignore
|
||
CAMGE T1,RC.HL(W1) ;[2366] Higher than what we have?
|
||
MOVE T1,RC.HL(W1) ;[2366] Yes, new highest
|
||
FNDSZ1: CAMGE R,RC.NO ;[2366] Looked at all psects?
|
||
AOJA R,FNDSZP ;[2366] No, look at next
|
||
CAILE T1,777777 ;[2366] High psect cross section?
|
||
MOVEI T1,777777 ;[2366] Yes UGLY, but only want section zero
|
||
MOVE T2,T1 ;[2366] Use highest loaded as highest code
|
||
|
||
FINRS3: PUSH P,HL.S1 ;[2366] Keep the actual values
|
||
PUSH P,HC.S1 ;[2366] of high loaded and high code
|
||
MOVEM T1,HL.S1 ;[2366] Set up only section zero numbers
|
||
MOVEM T2,HC.S1 ;[2366] For JOBDAT
|
||
>;[2366] IFE TOPS20
|
||
|
||
SKIPE T2,HC.S1 ;[2211] GET HIGHEST DATA LOCATION LOADED
|
||
SUBI T2,1 ;[2211] MAKE IT HIGHEST LOC LOADED
|
||
IFN FTOVERLAY,< ;[2211]
|
||
SKIPL LNKMAX ;[2211] LOADED ANY OVERLAYS?
|
||
SKIPN T1,JOB116 ;[2211] AND SAVED SYMBOLS?
|
||
JRST .+4 ;[2211] NO
|
||
HLRE T2,T1 ;[2211] -LENGTH
|
||
MOVM T2,T2 ;[2211]
|
||
ADDI T2,-1(T1) ;[2211] HIGHEST LOCATION
|
||
> ;[2211]
|
||
HRLZM T2,.JBCOR(P1) ;[2211] PUT HIGHEST LOC IN LEFT HALF
|
||
HRRZ T2,HL.S1 ;[2211] GET HIGHEST LOC REQUIRED
|
||
HRL T2,STADDR ;[2211] GET STARTING ADDRESS
|
||
MOVSM T2,.JBSA(P1) ;[2211] SET .JBSA AND .JBFF
|
||
HRRZM T2,.JBFF(P1) ;[2211] INCASE RESET NOT DONE FIRST
|
||
IOR. T2,.PGSIZ ;[2211] INCLUDE ALL OF THIS PAGE
|
||
HRRZM T2,.JBREL(P1) ;[2211] SET .JBREL
|
||
MOVSI T2,(HALT) ;[2211] PUT A HALT IN .JB41
|
||
SKIPN .JB41(P1) ;[2211] UNLESS ALREADY SETUP
|
||
MOVEM T2,.JB41(P1) ;[2211]
|
||
MOVE T2,.JBSYM(P1) ;[2211] GET SYMBOL TABLE POINTER
|
||
HRRZ T1,T2 ;[2211] GET POINTER
|
||
JUMPE P2,JOBST0 ;[2211] NO HIGH SEG POSSIBLE
|
||
CAML T1,LL.S2 ;[2211] SEE IF IN HIGH SEG
|
||
MOVEM T2,.JBHSM(P2) ;[2211] STORE IN HIGH SEG DATA AREA
|
||
SKIPE T1,HL.S2 ;[2211] GET HIGHEST LOC +1
|
||
SUBI T1,1 ;[2211] HIGHEST LEGAL ADDRESS
|
||
ADD T1,LL.S2 ;[2211] PLUS ORIGIN
|
||
IOR. T1,.PGSIZ ;[2211] PUT ON PAGE BOUND
|
||
SKIPN T2,HL.S2 ;[2211] LENGTH TO SAVE
|
||
JRST JOBST1 ;[2211] NONE?
|
||
SKIPN .JBDDT##(P1) ;[2211] DDT LOADED?
|
||
JRST JOBST1 ;[2211] NO, NUMBER IS OK
|
||
SUBI T2,1 ;[2211] YES, BE LIKE MONITOR
|
||
IOR. T2,.PGSIZ ;[2211] ROUND UP TO TOP OF PAGE
|
||
ADDI T2,1 ;[2211] THENCE TO BOTTOM OF NEXT
|
||
JOBST1: HRL T1,T2 ;[2211] LENGTH TO SAVE,,HIGHEST ADDR
|
||
MOVEM T1,.JBHRL(P1) ;[2211] LENGTH,,HIGHEST ADDRESS
|
||
JOBST0: MOVE T1,.JBERR ;[2211] GET NO OF PREVIOUS ERRORS
|
||
MOVEM T1,.JBERR(P1) ;[2211] COUNT AS EXECUTION ERRORS
|
||
HRRZM T1,ERRNO ;[2070] PROHIBIT EXECUTION IF NON-ZERO
|
||
PUSHJ P,HJBSET ;[1172] VESTIGAL JOBDAT
|
||
|
||
IFE TOPS20,< ;[2366]
|
||
POP P,HC.S1 ;[2366] Restore actual highest code
|
||
POP P,HL.S1 ;[2366] And highest loaded
|
||
>;[2366] IFE TOPS20
|
||
|
||
JRST SAVTST ;[1172] DONE WITH CHKRST, GO CHECK /SAVE
|
||
|
||
IFN TOPS20,< ;[2366]
|
||
JOBST9: MOVE T1,.JBERR ;[2260] GET # OF PREVIOUS ERRORS
|
||
HRRZM T1,ERRNO ;[2260] PROHIBIT EXECUTION IF NON-ZERO
|
||
JRST SAVTST ;[2260]
|
||
>;[2366] IFN TOPS20
|
||
|
||
;TABLE OF WHERE TO START FOR EACH DEBUGGER
|
||
|
||
DEFINE KEYMAC(A,B)<
|
||
XALL ;;[2211] GIVE A GOOD LISTING
|
||
IFIDN <A><DEB>,< ;;[2211] SELECT ONLY DEBUGGING KEYWORDS
|
||
%%1==-1 ;;[2211] SKIP DUMMY ENTRY
|
||
IRP B,< ;;[2211] CHECK EACH KEYWORD
|
||
IFGE %%1,< ;;[2211] THAT IS NOT THE DUMMY
|
||
IFN <%%1&1>,< ;;[2211] AND IS A DEBUGGER NAME
|
||
%%2==0 ;;[2211] ASSUME WON'T FIND A DEBUGGER
|
||
IFN TOPS20,< ;;[2211] TOPS-20 UDDT IS SPECIAL
|
||
IFIDN <B><DDT>,< ;;[2211] CHECK FOR DDT DEBUGGER
|
||
[770000] ;UDDT STARTS AT 770000
|
||
DEB$DDT==%%1_<-1> ;[2363] SET UP A SYMBOLIC NAME
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
>
|
||
IFIDN <B><FORDDT>,< ;;[2211] FORDDT IS SPECIAL
|
||
STADDR ;FORDDT FORCES START ADDRESS TO ITSELF
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
IFIDN <B><COBDDT>,< ;;[2211] COBDDT IS SPECIAL
|
||
STADDR ;COBDDT GETS CONTROL FROM COBOL PROGRAM
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
IFIDN <B><ALGDDT>,< ;;[2211] ALGDDT IS SPECIAL
|
||
.JBREN(P1) ;[2211] ALGDDT STARTS FROM REENTER ADDRESS
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
IFIDN <B><SIMDDT>,< ;;[2211] SIMDDT IS SPECIAL
|
||
.JBREN(P1) ;[2211] SIMDDT STARTS FROM REENTER ADDRESS
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
IFIDN <B><PASDDT>,< ;;[2211] PASDDT IS SPECIAL
|
||
STADDR ;[2211] PASDDT FORCES START ADDRESS TO ITSELF
|
||
%%2==1 ;;[2211] REMEMBER WE FOUND A DEBUGGER
|
||
>
|
||
IFE %%2,< ;;[2211] IF IT WASN'T ABOVE DEBUGGERS
|
||
.JBDDT(P1) ;OTHER DEBUGGERS SET .JBDDT
|
||
>
|
||
>
|
||
>
|
||
%%1==%%1+1 ;;[2211] ADVANCE TO NEXT ENTRY
|
||
>
|
||
>
|
||
PURGE %%1,%%2 ;;[2211] CLEAN UP AFTERWARD
|
||
SALL ;;[2211] ..
|
||
>
|
||
|
||
STLOCN: KEYWORDS
|
||
;GETSST - ROUTINE TO FIGURE OUT WHERE THE SYMBOL TABLE GOES
|
||
;CALLED ONLY WHEN A RUNTIME SYMBOL TABLE IS DEFINITELY NEEDED.
|
||
;RETURNS WITH:
|
||
;
|
||
; SSGNAM/ NAME (SIXBIT) OF PSECT TO APPEND SYMBOLS TO
|
||
; R/ AREA PSECT IS IN, LC.IX OR HC.IX
|
||
; P4/ POINTER TO RC BLOCK OF PSECT NAMED IN SSGNAM
|
||
; RC.HL(P4)/ FIRST ADDRESS TO STORE A SYMBOL IN
|
||
; SYMLIM/ LAST ADDRESS TO STORE A SYMBOL IN
|
||
;
|
||
;ALSO UPDATES LOWLOC IF NECESSARY.
|
||
|
||
GETSST: SKIPGE R,SYMSEG ;[1172] /SYMSEG TO A PSECT?
|
||
JRST GETS10 ;[1132] YES, GO FIND IT
|
||
GETS2: CAIN R,2 ;[1172] /SYMSEG:HIGH?
|
||
JRST GETS8 ;[1172] YES, TREAT IT LIKE /SYMSEG:PSECT:.HIGH.
|
||
|
||
|
||
;HERE IF /SYMSEG:LOW OR NO /SYMSEG (E.G., C(.JBDDT<>0).
|
||
;WE WANT TO APPEND PAT.. AND THE SYMBOL TABLE TO THE LAST PSECT IN THE IMAGE.
|
||
;OUR FIRST MISSION IS TO FIND THAT PSECT...
|
||
|
||
SETZB R,T3 ;[1172] INIT HIGHEST ADDR AND PSECT IDX
|
||
GETS4: MOVE T1,@RC.TB ;[1172] GET POINTER TO RC BLOCK OF NEXT PSECT
|
||
MOVE T2,RC.SG(T1) ;[1172] GET THE SEGMENT THAT THIS PSECT IS IN
|
||
CAIE T2,1 ;[1172] IN THE LOW SEGMENT?
|
||
JRST GETS6 ;[1172] NO, IT DOESN'T COUNT FOR /SYMSEG:LOW
|
||
MOVE T2,RC.HL(T1) ;[1172] GET THE FIRST FREE AFTER THIS PSECT
|
||
CAMG T2,T3 ;[1132] HIGHEST SO FAR?
|
||
JRST GETS6 ;[1132] NO, CONTINUE
|
||
MOVE T3,T2 ;[1132] SAVE NEW BEST
|
||
MOVE T4,R ;[1132] AND WHAT PSECT IT WAS
|
||
MOVE T2,RC.NM(T1) ;[1172] GET THE WINNER'S NAME
|
||
MOVEM T2,SSGNAM ;[1172] STORE FOR ERROR MESSAGES
|
||
GETS6: CAMGE R,RC.NO ;[1132] ALL DONE?
|
||
AOJA R,GETS4 ;[1132] NO, LOOP
|
||
MOVE R,T4 ;[1132] YES, SAVE PSECT INDEX OF LAST ONE
|
||
JRST GETS14 ;[1132] GO UPDATE THAT PSECT
|
||
;HERE ON /SYMSEG:HIGH. FAKE /SYMSEG:PSECT:.HIGH. AND FALL INTO PSECT CODE.
|
||
|
||
GETS8: MOVE T1,['.HIGH.'] ;[1132] /SYMSEG:HIGH IS JUST LIKE A PSECT
|
||
MOVEM T1,SSGNAM ;[1132] STORE
|
||
|
||
|
||
;HERE ON /SYMSEG:PSECT:xxxxxx. FIND THE PSECT IN THE RC TABLES.
|
||
|
||
GETS10: SETZ R, ;[727] YES, HAVE PSECT NAME
|
||
MOVE W2,SSGNAM ;[2220] GET THE SYMBOL TABLE PSECT NAME
|
||
GETS12: MOVE T1,@RC.TB ;[1132]
|
||
MOVE T2,RC.NM(T1) ;[2220] GET PSECT NAME
|
||
PUSHJ P,NAMCMP## ;[2220] IS THIS THE ONE?
|
||
JRST GETS14 ;[1132] YES,
|
||
ADDI R,1 ;[715] NEXT ONE
|
||
CAMG R,RC.NO ;[715] ANY MORE?
|
||
JRST GETS12 ;[1132] YES, LOOP
|
||
E$$NPS::.ERR. (MS,.EC,V%L,L%W,S%W,NPS,<Non-existent psect >) ;[1110] ;[1174]
|
||
.ETC. (SBX,.EC!.EP,,,,SSGNAM) ;[1174] OUTPUT PSECT NAME
|
||
.ETC. (STR,,,,,,< specified for symbol table>) ;[1174]
|
||
MOVEI R,1 ;[1132] SET TO LOW
|
||
MOVEM R,SYMSEG ;[1132]
|
||
JRST GETS2 ;[1132] AND LOOP BACK
|
||
;HERE WITH THE PSECT INDEX TO USE IN R, AND ITS NAME IN SSGNAM.
|
||
;WE NOW WANT TO CALCULATE HOW FAR THE SYMBOL TABLE IS ALLOWED TO EXTEND.
|
||
;BELIEVE THE USER'S /UPTO SWITCH IF HE GAVE ONE, OTHERWISE STOP ONE BELOW
|
||
;THE NEXT PSECT ORIGIN WE WOULD CROSS, OR STOP AT 777777 IF NO MORE PSECTS.
|
||
|
||
GETS14:
|
||
MOVE P4,@RC.TB ;[1172] POINTER TO THIS PSECT'S RC BLOCK
|
||
MOVX T1,AT.RP ;[2247] GET THE RELOCATABLE BIT
|
||
ANDCAM T1,RC.AT(P4) ;[2247] INDICATE IT EXISTS (IN CASE .LOW.)
|
||
SKIPE SYMLIM ;[1172] USER TYPE /UPTO?
|
||
JRST GETS20 ;[1172] YES, BELIEVE IT
|
||
MOVE T4,RC.HL(P4) ;[1172] ADDR OF START OF PATCH AREA
|
||
ADDI R,1 ;[1172] START THE SEARCH AT THE NEXT PSECT
|
||
|
||
|
||
;LOOP BACK HERE ON EACH NEW PSECT, LOOKING FOR ONE WHOSE ORIGIN
|
||
;IS .GE. C(T4).
|
||
|
||
GETS16: CAMLE R,RC.NO ;[1172] CHECKED THEM ALL YET?
|
||
JRST GETS18 ;[1172] YES, GO USE 777777
|
||
MOVE T1,@RC.TB ;[1172] GET PSECT'S RC BLOCK
|
||
MOVE T2,RC.IV(T1) ;[1172] GET ORIGIN OF THIS PSECT
|
||
CAMGE T2,T4 ;[1172] START ABOVE THE SYMSEG PSECT?
|
||
AOJA R,GETS16 ;[1172] NO, MUST HAVE BEEN OVERLAPPING PSECT
|
||
MOVE T3,RC.HL(T1) ;[1172] YES, CHECK FOR ZERO-LENGTH PSECT
|
||
CAMG T3,T2 ;[1172] WOULD WE OVERWRITE ANYTHING?
|
||
AOJA R,GETS16 ;[1172] NO, IGNORE THIS PSECT
|
||
SOSA T2 ;[1172] YES, LAST ADDR TO USE IS ONE LESS
|
||
GETS18:
|
||
SOS T2,RC.LM(P4) ;[1454] ROUND UP TO SECTION BOUNDARY
|
||
MOVEM T2,SYMLIM ;[1172] STORE NEWLY CALCULATED LIMIT
|
||
|
||
|
||
;NOW SET UP SOME FINAL THINGS FOR THE REST OF LINK, THEN RETURN.
|
||
|
||
GETS20: MOVE R,RC.SG(P4) ;[1172] FETCH SEGMENT INDEX FOR PSECTS
|
||
MOVE T1,RC.HL(P4) ;[1172] START OF PATCH AREA
|
||
IFN TOPS20,< ;[2306]
|
||
SKIPN T2,PRGPDV ;[2306] WANT A PDV?
|
||
JRST GETS22 ;[2335] NO, DON'T HAVE TO ALLOW FOR SIZE
|
||
MOVEM T1,.PVSYM(T2) ;[2306] YES, REMEMBER IT'S ADDRESS
|
||
>;[2366] IFN TOPS20
|
||
IFE TOPS20,< ;[2366]
|
||
SETZM SYMVEC ;[2366] NOT BUILDING A SYMBOL VECTOR (YET)
|
||
MOVE T2,HL.S1 ;[2366] GET THE HIGHEST LOADED
|
||
TLNN T2,-1 ;[2366] LOADED OUTSIDE SECTION ZERO?
|
||
JRST GETS22 ;[2366] NO, DON'T HAVE SYMBOL VECTOR
|
||
MOVEM T1,SYMVEC ;[2366] YES, REMEMBER IT'S ADDRESS
|
||
>;[2366] IFE TOPS20
|
||
IFN TOPS20,< ;[2366]
|
||
MOVEI T2,MM.SLN ;[2306] GET THE SIZE OF A PSECT
|
||
SKIPN NOPDMP ;[2336] WANT DEFAULT MAP?
|
||
CAMLE T1,RC.IV(P4) ;[2306] EMPTY PSECT?
|
||
JRST GETS21 ;[2306] NO, NO PROBLEM
|
||
MOVEI T2,MM.SLN ;[2306] YES, GET THE SIZE OF A MAP ENTRY
|
||
ADDM T2,PDMPLN ;[2306] ADD TO SIZE OF MAP
|
||
MOVE T1,PVPSEG ;[2306] GET THE RC POINTER FOR THE PDV PSECT
|
||
ADDM T2,RC.HL(T1) ;[2306] ACCOUNT FOR ANOTHER PSECT
|
||
>;[2366] IFN TOPS20
|
||
GETS21: MOVEI T1,SV.LEN ;[2306] SIZE OF SYMBOL VECTOR
|
||
ADDB T1,RC.HL(P4) ;[2306] UPDATE SIZE OF PSECT
|
||
GETS22: MOVEM T1,PATLOC ;[2366] REMEMBER FOR RST
|
||
ADD T1,PATSPC ;[1172] START OF REAL SYMBOL TABLE
|
||
MOVEM T1,RC.HL(P4) ;[1172] UPDATE SIZE OF PSECT
|
||
IFE TOPS20,< ;[2247]
|
||
TRZ T1,777 ;[1172] ROUND DOWN TO PAGE BOUND
|
||
CAMGE T1,LOWLOC ;[1172] LOWEST LOCATION YET LOADED?
|
||
MOVEM T1,LOWLOC ;[1172] YES, SAVE FOR EXE FILE WRITER.
|
||
>;[2247] IFE TOPS20
|
||
POPJ P, ;[1172] END OF GETSST
|
||
;HERE IF PAGING TO SETUP LC/HC AREA TO INSERT SYMBOLS INTO.
|
||
;WRITE OUT ENTIRE WINDOW, THEN SET UP LAST PAGE ONLY.
|
||
;AREA WILL EXPAND AS REQUIRED IN SYMOUT.
|
||
|
||
LSYP: MOVE T1,LW.S0(R) ;[2202] BOTTOM OF WINDOW
|
||
MOVE T2,UW.S0(R) ;[2202] TOP
|
||
PUSHJ P,@TB.OUT##(R) ;[1172] WRITE ENTIRE WINDOW TO DISK
|
||
IFE TOPS20,<
|
||
MOVE T1,TAB.AB(R) ;[1172] REDUCE WINDOW TO ONE PAGE
|
||
ANDCMI T1,.IPM ;[1172] NEW BOTTOM OF AREA
|
||
SUBI T1,1 ;[1172] FIRST WORD BELOW NEW BASE
|
||
CAML T1,TAB.LB(R) ;[1172] AREA ALREADY ONE PAGE?
|
||
PUSHJ P,GBCK.L## ;[1172] NO, SHRINK IT DOWN
|
||
> ;[1401] IFE TOPS20
|
||
IFN TOPS20,<
|
||
MOVE T1,TAB.LB(R) ;[1401] SHRINK WINDOW TO ONE PAGE
|
||
ADDI T1,.IPS-1 ;[1401]
|
||
MOVEM T1,TAB.AB(R) ;[1401]
|
||
> ;[1401] IFN TOPS20
|
||
MOVE T2,RC.HL(P4) ;[2202] GET FIRST ADDR TO STORE A SYMBOL IN
|
||
SUB T2,LL.S0(R) ;[2202] RELATIVE TO SEGMENT START
|
||
ANDCMI T2,.IPM ;[2202] NEW BOTTOM OF WINDOW
|
||
MOVEM T2,LW.S0(R) ;[2202] STORE
|
||
IORI T2,.IPM ;[2202] NEW TOP OF WINDOW
|
||
IFE TOPS20,<
|
||
CAMN T2,UW.S0(R) ;[2202] WHERE IT WAS ALREADY?
|
||
POPJ P, ;[2202] YES, DONE
|
||
> ;[1401] IFE TOPS20
|
||
MOVEM T2,UW.S0(R) ;[2202] NO, MUST READ IN THE DATA
|
||
MOVE T1,LW.S0(R) ;[2202] GET THE UPPER BOUND
|
||
PJRST @TB.IN(R) ;[1172] READ IN DATA AND RETURN
|
||
;HERE TO WRITE THE UNDEFINED SYMBOL TABLE. THE TABLE IS GENERATED
|
||
;BY SCANNING THE GLOBAL SYMBOL TABLE LOOKING FOR UNDEFINED SYMBOLS.
|
||
;WE GENERATE ONE RADIX50 PAIR FOR EACH UNDEFINED SYMBOL, AND ADDITIONAL
|
||
;PAIRS IF ANY ADDITIVE FIXUPS ARE ENCOUNTERED.
|
||
;
|
||
;THE ONLY FIXUP TYPES HANDLED ARE ADDITIVE AND RIGHT AND LEFT HALF CHAINED.
|
||
;OTHER TYPES, SUCH AS SYMBOL FIXUPS AND POLISH, ARE DISCARDED HERE. THIS
|
||
;IS DUE TO LACK OF A SYMBOL TABLE FORMAT SPEC, AND LACK OF DDT SUPPORT.
|
||
;
|
||
;ENTERED WITH:
|
||
;
|
||
; P4/ POINTER TO RC BLOCK OF /SYMSEG PSECT
|
||
; R/ INDEX TO /SYMSEG AREA, LC OR HC
|
||
|
||
|
||
DOUDFS: MOVE T1,TAB.PT(R) ;[1172] LINK'S ADDRESS OF NEXT WORD
|
||
SUB T1,TAB.LB(R) ;[1172] FIND OFFSET IN WINDOW
|
||
ADD T1,LW.S0(R) ;[1172] FIND OFFSET IN SEGMENT
|
||
ADD T1,LL.S0(R) ;[1172] FORM ABSOLUTE ADDRESS
|
||
MOVEM T1,USTADR ;[2245] SAVE ADDR FOR PDV SYM TABLE VECTOR
|
||
HRLZM T1,JOB117 ;[1172] STORE IN LH(JOB117) FOR A WHILE
|
||
SETZM SYMDEW ;[1172] DON'T NEED EXTRA ROOM FROM SYMOUT
|
||
MOVE P2,HT.PRM ;GET HASH SIZE
|
||
SKIPE T1,@HT.PTR ;GET POINTER IF NON-ZERO
|
||
JRST UDFTRY ;SEE IF A REQUEST
|
||
UDFNXT: SOJGE P2,.-2 ;MORE?
|
||
JRST UDFDN ;NO
|
||
|
||
UDFTRY: ADD T1,GS.LB ;ADD IN BASE
|
||
MOVE W1,(T1) ;GET FLAGS
|
||
TXNN W1,PS.REQ ;GLOBAL REQUEST
|
||
JRST UDFNXT ;NO, TRY NEXT SYMBOL
|
||
DMOVE W2,1(T1) ;GET SIXBIT SYMBOL & VALUE (REQUEST POINTER)
|
||
TLNN W2,770000 ;[2373] IS IT A LONG SYMBOL?
|
||
PUSHJ P,LUNDF ;[2373] YES - GO GET 1ST SXI CHARACTERS
|
||
PUSHJ P,SXBR50 ;CONVERT TO SIXBIT
|
||
TXO W2,R5.GLB ;MAKE GLOBAL DEFINITION
|
||
PUSHJ P,SYMOUT ;[1172] STORE W2/W3 IN IMAGE
|
||
JRST UDFDN ;[1172] NO MORE ROOM, CLOSE UP SHOP
|
||
AOS USYCNT ;[2306] ANOTHER ONE STORED, BUMP COUNT
|
||
TXNE W1,PS.FXP ;ANY ADDITIVE GLOBAL FIXUPS
|
||
JRST UDFGB ;YES, RECREATE THE REQUESTS
|
||
JRST UDFNXT ;[1172] NO, LOOK FOR ANOTHER SYMBOL
|
||
|
||
LUNDF: HRRZ T1,W2 ;[2373] GET THE GS OFFSET TO LONG NAME
|
||
ADD T1,GS.LB ;[2373] ADD IN GS BASE
|
||
MOVE W2,(T1) ;[2373] 1ST 6 CHARACTERS TO W2
|
||
POPJ P, ;[2373] RETURN
|
||
|
||
;THE LOOP BELOW FINDS THE S.FXP TRIPLET IN THE GS AREA, THEN CHASES
|
||
;THE CHAIN OF FIXUPS DEPENDING ON THIS SYMBOL THROUGH THE FX AREA,
|
||
;WRITING UNDEFINED SYMBOL TABLE ENTRIES FOR APPLICABLE FIXUPS AS IT GOES.
|
||
;
|
||
;ENTER AT UDFGB.
|
||
|
||
UDFGB0: TXNE W1,S.LST ;IS THIS THE LAST BLOCK
|
||
JRST UDFNXT ;[1172] YES
|
||
ADDI T1,.L ;NO, GET NEXT TRIPLET
|
||
UDFGB: HRRZ T1,@HT.PTR ;GET POINTER AGAIN
|
||
ADD T1,GS.LB ;ADD IN BASE
|
||
SKIPG W1,.L(T1) ;GET NEXT FLAG WORD
|
||
JRST UDFERR ;MUST HAVE SIGN BIT ON
|
||
TXNN W1,S.FXP ;AND A FIXUP
|
||
JRST UDFGB0 ;NOT YET
|
||
MOVE T1,.L+2(T1) ;[1172] GET VALUE
|
||
UDFGB1: ADD T1,FX.LB ;RELOCATE IN FIXUP TABLE
|
||
SKIPL W1,0(T1) ;GET FLAGS
|
||
JRST UDFERR ;JUST INCASE
|
||
TXNE W1,FP.SYM ;[1160] FIXUP BASED ON UNDEFINED SYMBOL?
|
||
TXNN W1,FS.FXR!FS.FXL!FS.FXC ;[1325] CHECK FOR CHAINED OR ADDITIVE
|
||
JRST UDFGB2 ;[1160] CAN'T OUTPUT POLISH, SYM FIXUPS, ETC.
|
||
DMOVE W2,1(T1) ;GET DATA WORDS
|
||
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
|
||
TXO W2,R5.GLB ;MAKE INTO A GLOBAL DEFINITION
|
||
TXNN W1,FS.FXC ;[1325] IS IT A SECONDARY CHAINED FIXUP?
|
||
TXO W3,R5.FXA ;AND TURN ON ADDITIVE BIT
|
||
TXNE W1,FS.FXL ;LEFT HALF?
|
||
TXO W3,R5.FXL ;YES
|
||
PUSHJ P,SYMOUT ;[1172] WRITE W2/W3 INTO THE IMAGE
|
||
JRST UDFDN ;[1172] SPACE EXCEEDED, STOP
|
||
AOS USYCNT ;[2306] OK, WROTE ANOTHER ONE
|
||
UDFGB2: HRRZ T1,W1 ;GET POINTER
|
||
JUMPE T1,UDFNXT ;[1172] ALL DONE IF ZERO
|
||
JRST UDFGB1 ;GET NEXT BLOCK
|
||
|
||
|
||
;HERE WHEN AN UNDEFINED SYMBOL WITH PS.FXP SET IS NOT FOLLOWED BY A
|
||
;SECONDARY TRIPLET WITH S.FXP SET.
|
||
|
||
UDFERR: JRST UDFNXT ;[1172] SYMBOL TABLE FOULED UP
|
||
;HERE WHEN FINISHED WRITING THE UNDEFINED SYMBOL TABLE.
|
||
;SET UP .JBUSY AND RETURN.
|
||
|
||
UDFDN: SKIPE PAG.S1 ;[1172] PAGING?
|
||
SKIPA T1,JOBPTR ;[1172] YES, LOAD CORRECT OFFSET
|
||
MOVE T1,LC.LB ;[1172] CODE OFFSET
|
||
MOVE T2,USYCNT ;[2306] GET NUMBER OF UNDEFINED SYMBOLS
|
||
ADD T2,T2 ;[2306] TWO WORDS PER SYMBOL
|
||
MOVEM T2,USYCNT ;[2245] SAVE FOR PDV SYM TABLE VECTOR
|
||
MOVNS T2 ;[2306] WANT -LENGTH OF TABLE
|
||
HRRM T2,JOB117 ;[1172] FORM ADDR,,-LEN
|
||
MOVSS T2,JOB117 ;[1172] FORM -LEN,,ADDR
|
||
IFN TOPS20,< ;[2366]
|
||
SKIPE NOJBDA ;[2211] JOBDAT WANTED?
|
||
POPJ P, ;[2211] NO
|
||
>;[2366] IFN TOPS20
|
||
MOVEM T2,.JBUSY(T1) ;NO, STORE IN IMAGE
|
||
POPJ P, ;[1172] DONE WITH UNDEFINED TABLE, RETURN
|
||
;SUBROUTINE TO DELETE THE GS AREA, AND CUT BACK MEMORY IF POSSIBLE.
|
||
|
||
GSDLT:
|
||
IFE TOPS20,< ;[1113] DON'T SHRINK BACK ON TOPS-20
|
||
SKIPN .JBDDT(T1) ;SEE IF WE NEED LOCAL SYMBOLS
|
||
SKIPE SYMSEG ;EITHER FOR /DEB OR /SYMSEG
|
||
JRST GSNRED ;YES, DON'T CUT BACK CORE YET
|
||
MOVEI T1,GS.IX-1 ;START AT AREA JUST LOWER
|
||
SKIPN TAB.LB(T1) ;FIND HIGHEST AREA IN USE
|
||
SOJA T1,.-1 ;WILL GET THERE EVENTUALLY
|
||
MOVE T2,TAB.AB(T1) ;GET HIGHEST LOC IN USE IN IT
|
||
IORI T2,1777 ;K BOUND
|
||
ADDI T2,2000 ;EXTRA K FOR SAFETY
|
||
CAML T2,.JBREL ;ANYTHING TO GIVE BACK?
|
||
JRST GSNRED ;NO, REDUCED ALREADY
|
||
CORE T2, ;DELETE TOP PART
|
||
JRST GSNRED ;NEVER CAN HAPPEN
|
||
MOVE T2,.JBREL ;GET NEW TOP
|
||
SKIPN GS.LB ;[773] GS AREA ALREADY GONE?
|
||
JRST GSDLT1 ;[773] YES, DON'T RECREATE IT
|
||
MOVEM T2,GS.AB ;RESET TABLE
|
||
MOVEM T2,GS.UB
|
||
CAMLE T2,GS.LB ;INCASE WE REDUCED IT ALL
|
||
JRST E$$RED ;[1174] NO, ALL IS WELL
|
||
GSDLT1: MOVEM T2,TAB.UB(T1) ;[773] RESET HIGHEST FREE LOC AGAIN
|
||
SETZM GS.LB ;SO XX.ZAP CAN WORK
|
||
E$$RED::.ERR. (MS,.EC,V%L,L%I,S%I,RED,<Reducing low segment to >) ;[1174]
|
||
.ETC. (COR,.EP,,,,.JBREL)
|
||
> ;END OF IFE TOPS20
|
||
GSNRED: PUSHJ P,GS.ZAP ;GET RID OF GS
|
||
POPJ P, ;[1172] END OF GSDLT
|
||
;HERE TO WRITE THE DEFINED SYMBOLS INTO THE IMAGE.
|
||
|
||
DOLOCS: SKIPE PAG.LS ;[1172] PAGING?
|
||
PUSHJ P,SYMINI ;[1172] YES, SET WINDOW TO END OF LS AREA
|
||
MOVEI T1,2 ;[1172] NEED ENOUGH WARNING TO PUT A TITLE OUT
|
||
MOVEM T1,SYMDEW ;[1172] STORE FOR SYMOUT
|
||
MOVE T1,TAB.PT(R) ;[1172] COMPUTE START OF THIS TABLE
|
||
SUB T1,TAB.LB(R) ;[1172] OFFSET IN WINDOW TO FIRST AFTER USY
|
||
ADD T1,LW.S0(R) ;[1172] OFFSET IN SEGMENT
|
||
ADD T1,LL.S0(R) ;[1172] FORM ABSOLUTE ADDRESS FOR RH(.JBSYM)
|
||
MOVEM T1,DSTADR ;[2245] SAVE FOR PDV SYM TABLE VECTOR
|
||
HRLZM T1,JOB116 ;[1172] STORE IN LH(JOB116) A WHILE
|
||
PUSHJ P,PATOUT ;[1172] WRITE THE PAT.. SYMBOL AND MODULE
|
||
SKIPN SYMFUL ;[1172] ANY ROOM LEFT?
|
||
PUSHJ P,LSLOOP ;[1172] DO THE WORK
|
||
|
||
|
||
;HERE WHEN THE SYMBOLS HAVE BEEN INSERTED INTO THE IMAGE. UPDATE .JBSYM.
|
||
|
||
SKIPE PAG.S1 ;[1172] PAGING?
|
||
SKIPA T1,JOBPTR ;[1172] YES, JOBDAT'S IN DY
|
||
MOVE T1,LC.LB ;[1172] NO, IT'S IN LC
|
||
MOVE T2,DSYCNT ;[2306] GET HOW MANY SYMBOLS
|
||
ADD T2,T2 ;[2306] TWO WORDS PER SYMBOL
|
||
MOVEM T2,DSYCNT ;[2245] SAVE FOR PDV SYMBOL TABLE VECTOR
|
||
MOVNS T2 ;[2306] WANT -COUNT
|
||
HRRM T2,JOB116 ;[1172] ADDR,,-LEN
|
||
MOVSS T2,JOB116 ;[1172] -LEN,,ADDR
|
||
IFN TOPS20,< ;[2366]
|
||
SKIPE NOJBDA ;[2211] JOBDAT WANTED?
|
||
POPJ P, ;[2211] NO
|
||
>;[2366] IFN TOPS20
|
||
IFE TOPS20,< ;[2366]
|
||
SKIPE SYMVEC ;[2366] BUILDING A SYMBOL VECTOR
|
||
MOVE T2,SYMVEC ;[2366] YES, GET THE VECTOR ADDRESS
|
||
>;[2366] IFE TOPS20
|
||
MOVEM T2,.JBSYM(T1) ;[2211] NO, STORE IN JOBDAT
|
||
POPJ P, ;[1172] DONE WITH DOLOCS
|
||
;HERE TO MOVE SYMBOLS TO TOP OF CORE
|
||
;IF SORTING PUT SORT BUFFER IN AREA GS
|
||
|
||
SYMINI: SKIPL UW.LS ;[1172] IF -1 THEN SYMBOL TABLE NOT OUTPUT YET
|
||
JRST RDSYM ;JUST READ IT BACK IN
|
||
MOVE T2,LSYM ;[2202] ADDRESS OF LAST SYMBOL STORED +1
|
||
SUBI T2,1 ;[2202] HIGHESE ADDRESS STORED TO
|
||
IORI T2,.IPM ;[2202] BLOCK BOUND
|
||
MOVEM T2,UW.LS ;[2202] REMEMBER WHAT'S THERE
|
||
IFN TOPS20,<
|
||
CAMG T2,LW.LS ;[2202] Check for current page never used
|
||
ADDI T2,.IPS ;[2202] Must write out one page anyways
|
||
> ;[1536]
|
||
MOVE T1,LW.LS ;[2202] FORM BLT WORD
|
||
PUSHJ P,LS.OUT## ;AND OUTPUT IT
|
||
;FALL INTO RDSYM TO READ IT BACK
|
||
|
||
RDSYM: PUSHJ P,FR.CNT## ;[1172] SEE HOW MUCH IS FREE
|
||
LSH T1,-1 ;[1172] TAKE HALF OF IT FOR LS WINDOW
|
||
ANDCMI T1,.IPM ;[1172] KEEP ON A PAGE BOUND
|
||
CAIGE T1,2*.IPS ;[1172] BUT NEED AT LEAST TWO PAGES
|
||
MOVEI T1,2*.IPS ;[1172] SO FORCE AT LEAST THAT MANY
|
||
MOVE T2,LS.AB ;[1172] CALCULATE CURRENT SIZE OF LS AREA
|
||
SUB T2,LS.LB ;[1172] LAST - FIRST
|
||
ADDI T2,1 ;[1172] PLUS 1
|
||
CAML T2,T1 ;[1172] HAVE LESS THAN WE WANT?
|
||
JRST RDSYM2 ;[1172] ALREADY BIG ENOUGH
|
||
SUB T1,T2 ;[1172] HOW MUCH MORE WE NEED
|
||
MOVEI P1,LS.IX ;[1172] ARRANGE TO GET IT
|
||
MOVE P2,T1 ;[1172] HOW MUCH TO GET
|
||
PUSHJ P,LNKCOR## ;[1172] SHUFFLE
|
||
PUSHJ P,E$$MMF## ;[2202] CANNOT HAPPEN
|
||
PUSHJ P,LS.FXR## ;[1401] DO ANY SYMBOL TABLE FIXUPS REMAINING
|
||
|
||
;NOW READ THE LAST PAGE OF SYMBOLS INTO THE FIRST PAGE OF THE LS AREA.
|
||
;LSLOOP WILL QUICKLY FALL OFF THE BOTTOM (READING BACKWARDS), AND
|
||
;FILL THE ENTIRE WINDOW WITH THE NEXT LOWER PIECE.
|
||
|
||
RDSYM2:
|
||
MOVE T1,LSYM ;[1172] LAST WORD OF SYMBOLS + 1
|
||
SUBI T1,1 ;[1172] LAST WORD IN USE
|
||
ANDCMI T1,.IPM ;[1172] BOTTOM OF NEW WINDOW
|
||
MOVEM T1,LW.LS ;[1172] SET FOR PAGING ROUTINES
|
||
ADD T1,LS.AB ;[1172] ADD WINDOW SIZE
|
||
SUB T1,LS.LB ;[1172] TO GET TOP OF WINDOW
|
||
MOVEM T1,UW.LS ;[1172] STORE FOR PAGING ROUTINES
|
||
MOVE T1,LSYM ;[1172] FIRST UNUSED WORD AGAIN
|
||
SUB T1,LW.LS ;[1172] HOW FAR INTO WINDOW IT IS
|
||
ADD T1,LS.LB ;[1172] FIX IN MEMORY
|
||
MOVEM T1,LS.PT ;[1172] SAVE FOR GETSYM
|
||
MOVE T1,LW.LS ;[2202] NOW FILL BOTTOM PAGE
|
||
MOVE T2,LW.LS ;[2202] REST WILL BE FILLED BY PAGSYM
|
||
IORI T2,.IPM ;[2202] ROUND UP TO TOP OF PAGE
|
||
PJRST LS.IN## ;[1172] FILL THE WINDOW AND RETURN
|
||
|
||
;LNKOV2 FILLS THE LS AREA WITH SYMBOL TRIPLETS, ZEROES THE LC AREA,
|
||
;AND THEN PUSHJ'S DIRECTLY TO LSLOOP TO CONVERT THE SYMBOLS TO
|
||
;RADIX50 AND PUT A RUNTIME SYMBOL TABLE INTO THE LC AREA. IT
|
||
;THEN WRITES THE LC AREA TO THE APPROPRIATE PLACE IN THE OVERLAY FILE.
|
||
;
|
||
;THIS IS AN INITIALIZATION ROUTINE CALLED BY LNKOV2 TO SET THINGS UP
|
||
;BEFORE CALLING LSLOOP.
|
||
|
||
IFN FTOVERLAY,<
|
||
|
||
LSOVX:: MOVX T1,.INFIN ;[1172] DON'T STOP FOR A SYMBOL LIMIT
|
||
MOVEM T1,SYMLIM ;[1172] SINCE NOT REALLY LOADING INTO MEMORY
|
||
SETZM SYMDEW ;[1172] DON'T NEED ANY WARNING
|
||
SETZM SYMFUL ;[1172] HAVE LOTS OF ROOM FOR SYMBOLS
|
||
SETZM DSYCNT ;[2306] LSLOOP AOSES THIS FOR EVERY SYMBOL
|
||
SKIPN LNKNO. ;[1172] IS THIS THE ROOT?
|
||
PJRST PATOUT ;[1172] YES, WRITE PAT.. AND RETURN
|
||
MOVNI T1,2 ;[1172] NO, INIT TTLPTR
|
||
MOVEM T1,TTLPTR ;[1172] SO FIRST MODULE WILL BE RIGHT
|
||
POPJ P, ;[1172] RETURN TO LNKOV2
|
||
> ;END IFN FTOVERLAY
|
||
;HERE TO WRITE THE PAT.. SYMBOL AND MODULE TO THE SYMBOL TABLE.
|
||
|
||
PATOUT: MOVE W2,[RADIX50 04,PAT..] ;[1172] NAME
|
||
MOVE W3,PATLOC ;[1172] VALUE
|
||
PUSHJ P,SYMOUT ;[1172] WRITE IT OUT
|
||
JRST [HRLI W3,-2 ;[1172] SYMBOL WON'T FIT, JUST WRITE NAME
|
||
SETZM SYMDEW ;[1172] IF IT WILL FIT
|
||
JRST PATOU2] ;[1172] RE-JOIN COMMON CODE
|
||
AOS DSYCNT ;[2306] A SYMBOL PAIR SUCCESSFULLY WRITTEN
|
||
HRLI W3,-4 ;[1172] FOUR WORDS IN THIS MODULE
|
||
PATOU2: MOVE T1,TAB.PT(R) ;[1172] BEFORE WRITING THE TITLE,
|
||
SUB T1,TAB.LB(R) ;[1172] FIGURE OUT WHERE IT GOES
|
||
ADD T1,LW.S0(R) ;[1172] AS AN OFFSET INTO THE SEGMENT
|
||
MOVEM T1,TTLPTR ;[1172] SAVE FOR LTITLE
|
||
TLZ W2,740000 ;[1172] MAKE 0,PAT.. BE THE TITLE
|
||
PUSHJ P,SYMOUT ;[1172] WRITE THE TITLE
|
||
CAIA ;[1172] OOPS! SEE WHAT WENT WRONG
|
||
JRST PATOU4 ;[1172] OK, NOW GO WRITE THE REAL SYMBOLS
|
||
SKIPN SYMDEW ;[1172] 4,PAT.. FAILED ABOVE? (DON'T USE SYMFUL)
|
||
JRST [SETZM JOB116 ;[1172] YES, THERE WON'T BE A SYMBOL TABLE
|
||
POPJ P,] ;[1172] JUST RETURN
|
||
SETZM SYMDEW ;[1172] USE OUR RESERVE FOR PAT..'S TITLE
|
||
PUSHJ P,SYMOUT ;[1172] WRITE IT
|
||
JFCL ;[1172] CAN'T HAPPEN
|
||
PATOU4: AOS DSYCNT ;[2306] ANOTHER SYMBOL WRITTEN
|
||
POPJ P, ;[1172] DONE
|
||
LSLOOP::PUSHJ P,GETSYM ;GET SYMBOL IN W1,W2,W3
|
||
POPJ P, ;ALL DONE
|
||
JUMPGE W1,LSLOOP ;IGNORE ALL EXTENDED BLOCK
|
||
TXNE W1,PT.TTL ;SPECIAL IF TITLE BLOCK
|
||
JRST LTITLE ;NEED TO KEEP POINTERS ETC
|
||
SKIPE SYMFUL ;[1172] SKIPPING FOR LAST MODULE NAME?
|
||
JRST LSLOOP ;[1172] YES, REJECT ALL OTHER RANDOM SYMBOLS
|
||
TXNE W1,PT.SYM ;ONLY WANT REAL SYMBOLS
|
||
TXNE W1,PS.MDF ;BUT NOT MULTIPLE DEFINITION
|
||
JRST LSLOOP ;MUST BE SOME THING ELSE
|
||
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
|
||
TXNE W1,PS.GLB ;GLOBAL?
|
||
TXO W2,R5.GLB ;YES
|
||
TXNE W1,PS.COM ;COMMON?
|
||
JRST LSLUPC ;YES, NEEDS TWO SYMBOLS
|
||
TXNE W1,PS.LCL ;THEN LOCAL?
|
||
TXO W2,R5.LCL ;YES
|
||
TXNE W1,PS.DDT ;NO DDT OUTPUT?
|
||
TXO W2,R5.DDT ;YES SET BIT
|
||
LSLUP1: PUSHJ P,SYMOUT ;PUT SYMBOL IN CORE
|
||
JRST [SETZM SYMDEW ;[1172] GO INTO FIND MODULE NAME MODE
|
||
JRST LSLOOP] ;[1172] START THE HUNT
|
||
AOS DSYCNT ;[2306] ANOTHER SYMBOL STORED
|
||
JRST LSLOOP ;AND BACK FOR MORE
|
||
|
||
LSLUPC: MOVEI T1,4 ;[1172] NEED FOUR WORDS OR NOTHING
|
||
MOVEM T1,SYMDEW ;[1172] SO BUMP WARNING LEVEL
|
||
PUSHJ P,SYMOUT ;OUTPUT IT
|
||
JRST [SETZM SYMDEW ;[1172] WON'T BOTH FIT
|
||
JRST LSLOOP] ;[1172] CLOSE OFF TABLE AND STOP
|
||
AOS DSYCNT ;[2306] ANOTHER PAIR OUT
|
||
MOVEI T1,2 ;[1172] PUT SYMOUT CUTOFF BACK
|
||
MOVEM T1,SYMDEW ;[1172] NEXT PAIR GUARANTEED TO FIT
|
||
PUSH P,W3 ;SAVE ADDRESS
|
||
MOVX T1,S.COM ;PART WE WANT
|
||
PUSHJ P,GETAST ;GET REST OF SYMBOL
|
||
JRST [POP P,W3 ;TOO BAD
|
||
JRST LSLOOP] ;JUST IGNORE
|
||
PUSHJ P,SXBR50 ;IN RADIX50
|
||
TXO W2,R5.DDT!R5.GLB ;CODE 44
|
||
POP P,T1 ;GET ADDRESS
|
||
HRL T1,W3 ;LENGTH ,, ADDRESS
|
||
MOVE W3,T1 ;...
|
||
JRST LSLUP1 ;OUTPUT IT
|
||
;HERE ON A TITLE IN THE LS AREA.
|
||
|
||
LTITLE: TXNE W1,PT.PSC ;[1132] JUST A PSECT DEFINITION?
|
||
JRST LSLOOP ;[1132] YES, DON'T PUT IN SYMBOL TABLE
|
||
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
|
||
TXNE W1,PT.BLK ;ONLY A FAIL BLOCK HEADER?
|
||
JRST BTITLE ;YES
|
||
MOVE T2,TTLPTR ;GET ADDRESS OF LAST PROG
|
||
HRRZ T1,TAB.PT(R) ;GET THIS ADDRESS
|
||
SUB T1,TAB.LB(R) ;MINUS OFFSET
|
||
ADD T1,TAB.LW(R) ;PLUS BASE OF WINDOW
|
||
MOVEM T1,TTLPTR ;SAVE FOR NEXT
|
||
SUB T1,T2 ;GET DIFFERENCE
|
||
MOVN T1,T1 ;NEGATE
|
||
HRL W3,T1 ;FIXUP POINTER
|
||
PUSH P,W2 ;SAVE SYMBOLS
|
||
PUSH P,W3
|
||
TTLLUP: MOVX T1,S.TTL!S.SEG ;FLAGS
|
||
PUSHJ P,GETAST ;GET EXTENSION TRIPLET
|
||
SETZ W2, ;[2256] ONLY HERE IF DEFINED BY /SWITCH
|
||
PUSH P,W2 ;[2256] SAVE THE LOW SEG ORIGIN
|
||
MOVX T1,S.TTL!S.SEG!S.SHI ;[2256] FLAGS
|
||
PUSHJ P,GETAST ;[2256] GET EXTENSION TRIPLET
|
||
SETZ W2, ;[2256] THERE ISN'T ONE
|
||
MOVE W3,W2 ;[2256] HIGH SEG BREAK IN W3
|
||
POP P,W2 ;[2256] GET BACK LOW SEG BREAK
|
||
SKIPE W3 ;IF ANY HIGH SEG STUFF
|
||
MOVE W2,W3 ;USE IT
|
||
POP P,W3 ;GET W3 BACK
|
||
HRR W3,W2 ;[2256] FIX IT UP
|
||
POP P,W2
|
||
PUSHJ P,SYMOUT ;OUTPUT PSEUDO SYMBOL
|
||
JRST [
|
||
SKIPN SYMDEW ;[1455] ALREADY EXHAUSED RESERVE?
|
||
POPJ P, ;[1455] DON'T KEEP TRYING
|
||
SETZM SYMDEW ;[1172] USE THE RESERVE TO STORE THIS TITLE
|
||
JRST .-1] ;[1172] TRY AGAIN
|
||
AOS DSYCNT ;[2306] COUNT ANOTHER SYMBOL PAIR
|
||
SKIPE SYMFUL ;[1172] WAS THIS OUR LAST TITLE?
|
||
POPJ P, ;[1172] YES, QUIT, SINCE NO MORE ROOM
|
||
JRST LSLOOP ;RETURN
|
||
|
||
|
||
|
||
BTITLE: SKIPE SYMFUL ;[1172] ROOM FOR THIS?
|
||
JRST LSLOOP ;[1172] NO, DON'T STORE IT
|
||
TXO W2,R5.LCL!R5.GLB ;MAKE RADIX50 14,SYM
|
||
HRRZ W3,W3 ;BLOCK LEVEL ONLY
|
||
JRST LSLUP1 ;AND TREAT AS LOCAL SYMBOL
|
||
;HERE TO GET NEXT SYMBOL BLOCK
|
||
;CALLED BY
|
||
; PUSHJ P,GETSYM
|
||
;RETURNS
|
||
;W1, W2, W3 WITH SYMBOL INFO
|
||
;USES T1
|
||
;READS SYMBOL TABLE IN REVERSE ORDER
|
||
|
||
GTSYM1: PUSHJ P,PAGSYM ;SEE IF PAGING
|
||
POPJ P, ;NO, ALL DONE
|
||
;FALL INTO GETSYM
|
||
|
||
|
||
GETSYM: MOVNI T1,3 ;BACKUP POINTET TO
|
||
ADD T1,LS.PT ;GET NEXT TRIPLET
|
||
CAMGE T1,LS.LB ;DON'T GO TOO FAR
|
||
JRST GTSYM1 ;SEE IF PAGING
|
||
MOVEM T1,LS.PT ;SAFE TO STORE NOW
|
||
TMOVE W1,0(T1) ;FLAGS, SYMBOL, VALUE
|
||
JRST CPOPJ1 ;SKIP RETURN
|
||
;HERE TO READ MORE SYMBOLS IF THEY ARE ON DSK
|
||
|
||
PAGSYM: SKIPE UW.LS ;NEVER WERE
|
||
SKIPN LW.LS ;WERE BUT ALL DONE
|
||
POPJ P, ;IN EITHER CASE JUST RETURN CPOPJ
|
||
IFE TOPS20,<
|
||
HRLZ T1,LS.LB ;[1172] MOVE FIRST BLOCK OF SYMBOLS
|
||
HRR T1,LS.AB ;[1172] UP TO LAST BLOCK OF LS AREA
|
||
ANDCMI T1,.IPM ;[1172] NOW HAVE SRC,,DEST
|
||
BLT T1,@LS.AB ;[1172] MOVE THE DATA
|
||
MOVE T1,LS.AB ;[1172] CHECK TO SEE IF LAST TIME
|
||
ANDCMI T1,.IPM ;[1172] ACCOUNT FOR PAGE WE KEPT
|
||
MOVEI T2,.IPM ;[1172] MASK FOR PAGE OFFSET
|
||
ANDM T2,LS.PT ;[1172] OFFSET TO CURRENT SYMBOL
|
||
ADDM T1,LS.PT ;[1172] MOVE POINTER TO LAST PAGE OF AREA
|
||
SUB T1,LW.LS ;[1172] BOTTOM ADDR IF WE FINISHED THIS TIME
|
||
SUBI T1,1 ;[1172] GET LOCATION BELOW FIRST USED
|
||
CAML T1,LS.LB ;[1172] LS AREA TOO BIG (LAST TIME)?
|
||
PUSHJ P,GBCK.L## ;[1172] YES, GET RID OF BOTTOM PART
|
||
MOVE T1,LW.LS ;[1172] GET OLD LOWER WINDOW ADDRESS
|
||
IORI T1,.IPM ;[1172] THE END OF THAT PAGE
|
||
MOVEM T1,UW.LS ;[1172] FORM NEW UPPER WINDOW
|
||
ADD T1,LS.LB ;[1172] SUBTRACT LENGTH OF AREA
|
||
SUB T1,LS.AB ;[1172] TO FORM LOWER WINDOW
|
||
MOVEM T1,LW.LS ;[1172] STORE FOR PAGING ROUTINES
|
||
MOVE T2,UW.LS ;[2202] TRANSFER WORD TO WHOLE AREA
|
||
SUBI T2,.IPS ;[2202] BUT WE ALREADY HAVE LAST PAGE
|
||
PUSHJ P,LS.IN ;[1172] FILL UP THE AREA
|
||
JRST CPOPJ1 ;[1172] SKIP RETURN
|
||
> ;[1401] IFE TOPS20
|
||
IFN TOPS20,<
|
||
MOVE T2,LS.PT ;[1510]
|
||
SUB T2,LS.LB ;[1510]
|
||
ADD T2,LW.LS ;[1510]
|
||
MOVEM T2,LS.PT ;[1510] SAVE LS.PT AS VIRTUAL ADDR
|
||
MOVE T1,LW.LS ;[2202] SEND OUT CURRENT PAGES
|
||
MOVE T2,UW.LS ;[2202] ALL OF THEM
|
||
PUSHJ P,LS.OUT ;[1401] DO IT
|
||
MOVE T1,LS.AB ;[2202] WHAT'S AVAILABLE?
|
||
SUB T1,LS.LB ;[2202] SIZE OF LS AREA
|
||
MOVE T2,LW.LS ;[2202] WHAT'S LEFT?
|
||
ADDI T2,.IPS-1 ;[2202] SYMBOLS FROM HERE BACK TO 0
|
||
SUBM T2,T1 ;[2202] GET THE LOWER BOUND IN T1
|
||
SKIPGE T1 ;[2202] GREATER THAN ZERO?
|
||
SETZ T1, ;[2202] NO, EVERYTHING UP TO HERE WILL FIT
|
||
MOVEM T1,LW.LS ;[2202] NEW LOWER BOUND
|
||
MOVEM T2,UW.LS ;[2202] NEW UPPER BOUND
|
||
PUSHJ P,LS.IN ;[1401] DO IT
|
||
MOVE T1,UW.LS ;[2202] GET THE UPPER BOUND
|
||
SUB T1,LW.LS ;[2202] GET THE SIZE
|
||
ADD T1,LS.LB ;[2202] ADD THE BASE
|
||
MOVEM T1,LS.AB ;[2202] CURRENT BOUND
|
||
MOVE T2,LS.PT ;[1510]
|
||
SUB T2,LW.LS ;[1510]
|
||
ADD T2,LS.LB ;[1510]
|
||
MOVEM T2,LS.PT ;[1510]
|
||
JRST CPOPJ1 ;[1401] SKIP RETURN
|
||
> ;[1401] IFN TOPS20
|
||
;HERE TO GET ASSOCIATED SECONDARY TRIPLET
|
||
;CALLED BY
|
||
; MOVE T1,FLAGS
|
||
; PUSHJ P,GETAST
|
||
;RETURNS
|
||
;+1 FAILED
|
||
;+2 SUCCESS
|
||
;USES T1, T2, T3
|
||
;SETS UP W1, W2, W3
|
||
|
||
GETAST: MOVE T2,LS.PT ;GET POINTER
|
||
GETNAS: ADDI T2,.L ;ENTER HERE WITH T2 SETUP
|
||
CAMLE T2,LS.AB ;STILL IN CORE?
|
||
JRST FNDNIC ;NOT IN CORE
|
||
SKIPGE T3,(T2) ;GET FLAGS
|
||
POPJ P, ;FOUND A PRIMARY (FAILED)
|
||
XOR T3,T1 ;IFF ALL BITS MATCH
|
||
TXZ T3,S.LST ;IGNORE THIS BIT HOWEVER
|
||
JUMPN T3,GETNAS ;TRY AGAIN
|
||
TMOVE W1,(T2) ;FLAGS, SYMBOL, VALUE
|
||
CPOPJ1: AOS (P)
|
||
CPOPJ: POPJ P,
|
||
|
||
|
||
FNDNIC: SKIPN UW.LS
|
||
POPJ P, ;ALL DONE
|
||
E03CNW::.ERR. (MS,.EC,V%L,L%F,S%F,CNW) ;[1174]
|
||
.ETC. (STR,,,,,,<FNDNIC>)
|
||
;SXBR50 -- SUBROUTINE TO CONVERT SIXBIT TO RADIX-50
|
||
;CALLED BY
|
||
; MOVE W2,SIXBIT WORD
|
||
; PUSHJ P,SXBR50
|
||
;RETURN
|
||
; RADIX-50 IN W2
|
||
;USES T1, T2
|
||
|
||
SXBR50: MOVE T2,W2 ;GET SIXBIT SYMBOL
|
||
SETZ W2, ;WHERE TO STORE RADIX50 SYMBOL
|
||
SETZ T1, ;CLEAR RECEIVING ACC
|
||
LSHC T1,6 ;GET NEXT CHAR
|
||
IMULI W2,50 ;MULTIPLE BY 50
|
||
ADD W2,SXBTAB(T1) ;ADD IN NEW CHAR
|
||
JUMPN T2,.-4 ;NOT DONE YET
|
||
POPJ P,
|
||
|
||
DEFINE SXBCHR (CHR)<
|
||
IRPC CHR,<
|
||
RADIX50 0,CHR
|
||
>>
|
||
|
||
|
||
XALL
|
||
SXBTAB: SXBCHR (....$%..........0123456789.......ABCDEFGHIJKLMNOPQRSTUVWXYZ.....) ;[2373] substitute . for non-sixbit characters
|
||
SALL
|
||
|
||
;HERE TO WRITE THE RADIX-50 SYMBOL IN W2/W3 TO THE IMAGE.
|
||
;RETURNS NON-SKIP, MESSAGE PRINTED, IF SYMBOL WON'T FIT BELOW SYMLIM.
|
||
;SYMBOL WON'T FIT IF IT IS WITHIN C(SYMDEW) WORDS OF PASSING SYMLIM.
|
||
|
||
SYMOUT: MOVE T1,TAB.PT(R) ;[1172] ADDRESS TO STORE INTO NEXT
|
||
AOS T2,T1 ;[1172] LAST ADDRESS THIS SYMBOL WILL USE
|
||
SUB T2,TAB.LB(R) ;[1172] CONVERT TO OFFSET IN SEGMENT
|
||
ADD T2,TAB.LW(R) ;[1172] (USUALLY SAME AS VIRTUAL ADDRESS)
|
||
ADD T2,LL.S0(R) ;[1172] MAKE SURE IT'S A VIRTUAL ADDRESS
|
||
ADD T2,SYMDEW ;[1172] RESPECT DISTANT EARLY WARNING FACTOR
|
||
CAMG T2,SYMLIM ;[1172] WOULD WE STORE BEYOND LEGAL BOUNDS?
|
||
JRST SYMOU2 ;[1172] NO, CONTINUE
|
||
SKIPE SYMFUL ;[1172] ALREADY ISSUED A MESSAGE?
|
||
POPJ P, ;[1172] YES, DONT SAY IT AGAIN
|
||
SETOM SYMFUL ;[1172] REMEMBER FOR NEXT TIME & CALLERS
|
||
E$$ISS::.ERR. (MS,.EC,V%L,L%W,S%W,ISS,<Insufficient space for symbol table after psect >) ;[1174]
|
||
.ETC. (SBX,.EP!.EC,,,,SSGNAM)
|
||
.ETC. (STR,,,,,,< -- table truncated>)
|
||
POPJ P, ;[1172] ERROR RETURN
|
||
;HERE IF NOT PAST SYMLIM. CHECK TO SEE IF THE AREA/WINDOW IS BIG ENOUGH.
|
||
|
||
SYMOU2: CAMG T1,TAB.AB(R) ;[1172] STILL ROOM IN THE AREA?
|
||
AOJA T1,SYMOU8 ;[1172] YES, GO STORE THE SYMBOL
|
||
SETOM LS.PP ;[1172] DON'T SHRINK THE LS AREA
|
||
SPUSH <P1,P2> ;[1216] PRESERVE OVER LNKCOR
|
||
MOVE T1,TAB.PT(R) ;[1534] RENDER TAB.PT VIRTUAL
|
||
SUB T1,TAB.LB(R) ;[1534] TAKE OFF AREA BASE
|
||
ADD T1,TAB.LW(R) ;[1534] ADD IN WINDOW OFFSET
|
||
PUSH P,T1 ;[1534] AND KEEP IT
|
||
MOVE P1,R ;[1172] SEGMENT TO EXPAND
|
||
MOVEI P2,.IPS ;[1172] BY ONE PAGE
|
||
PUSHJ P,LNKCOR## ;[1172] EXPAND
|
||
PUSHJ P,E$$MEF## ;[1174] SHOULD NEVER GET HERE
|
||
POP P,T1 ;[1534] GET VIRT TAB.PT
|
||
SUB T1,TAB.LW(R) ;[1534] AND FIX IN MEMORY AGAIN
|
||
ADD T1,TAB.LB(R) ;[1534] IN CASE THINGS MOVED
|
||
MOVEM T1,TAB.PT(R) ;[1534]
|
||
SPOP <P2,P1> ;[1216] RESTORE SACRED COWS
|
||
SETZM LS.PP ;[1172] RESTORE
|
||
|
||
IFE TOPS20,< ;[2247]
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;[1172] LSLOOP CALLED FROM LNKOV2?
|
||
SKIPN PAG.S0(R) ;[1172] AND LNKCOR STARTED AREA PAGING?
|
||
CAIA ;[1172] NO
|
||
PUSHJ P,E$$MEF## ;[1174] YES, LNKOV2 CAN'T HANDLE THAT
|
||
> ;END IFN FTOVERLAY
|
||
>;[2247] IFE TOPS20
|
||
|
||
PUSHJ P,CHKPAG ;[1172] FIX JOBDAT IF JUST STARTED PAGING
|
||
SKIPN TAB.PG(R) ;[1172] AREA NOW PAGING?
|
||
JRST SYMOUT ;[1172] NO, GO TRY AGAIN
|
||
MOVE T1,LW.S0(R) ;[1172] YES, MUST UPDATE UW
|
||
ADD T1,TAB.AB(R) ;[1172] LNKCOR SOMETIMES DOES
|
||
SUB T1,TAB.LB(R) ;[1172] BUT SOMETIMES IT DOESN'T
|
||
MOVEM T1,UW.S0(R) ;[1172] SO MAKE SURE IT'S RIGHT
|
||
IFE TOPS20,<
|
||
ANDCMI T1,.IPM ;[1172] FIRST ADDRESS IN PAGE WE JUST ADDED
|
||
CAML T1,HC.S0(R) ;[1172] ANY DATA FURTHER ON IN OVERFLOW FILE?
|
||
JRST SYMOUT ;[1172] NO, JUST LEAVE NEW PAGE ZERO
|
||
MOVE T2,UW.S0(R) ;[2202] OTHERWISE WE LOSE DATA
|
||
PUSHJ P,@TB.IN(R) ;[1172] DO THE I/O
|
||
> ;[1401] IFE TOPS20
|
||
JRST SYMOUT ;[1172] AND TRY AGAIN
|
||
|
||
|
||
;HERE WHEN ALL IS OK TO STORE THE NEW SYMBOL.
|
||
|
||
SYMOU8: DMOVEM W2,-2(T1) ;[1172] DO THE STORE
|
||
MOVEM T1,TAB.PT(R) ;[1172] UPDATE THE PT FOR NEXT TIME
|
||
|
||
IFN FTOVERLAY,<
|
||
SKIPE T1,RT.PT ;RELOCATABLE?
|
||
CAMN T1,RT.LB ;MAYBE, IS IT?
|
||
JRST CPOPJ1 ;[715] NO, SKIP RETURN
|
||
IBP RT.PT ;SYMBOL IS NOT
|
||
TXNN W1,PS.REL ;IS IT RELOCATABLE?
|
||
TDZA T1,T1 ;NO
|
||
MOVEI T1,1 ;YES
|
||
IDPB T1,RT.PT ;SET BIT
|
||
>
|
||
JRST CPOPJ1 ;[715] SKIP RETURN
|
||
;HERE FOR OLD FORM SYMBOLS (RADIX-50)
|
||
;IF IN CORE WRITE THEM OUT WITH THREE INFORMATION WORDS AT FRONT
|
||
;HEADER, .JBSYM (116) AND .JBUSY (117)
|
||
;HEADER IS 776(TYPE) ,, LENGTH
|
||
;OTHER TWO WORDS ARE RELATIVE TO ZERO
|
||
;.JBSYM MUST HAVE A NEGATIVE LEFT HALF
|
||
;.JBUSY IS ZERO IF NO UNDEFINED SYMBOLS
|
||
|
||
OLDSYM: MOVEI T1,MC ;USE MAP CHAN INCASE PAGING LC
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%SC ;POINT TO CORRECT DATA
|
||
MOVEM T1,IO.PTR+MC
|
||
PUSHJ P,DVCHN.##
|
||
MOVSI T2,(Z MC,) ;RESET CHAN #
|
||
MOVEM T2,I.CHN(T1) ;SINCE %SC IS THERE CURRENTLY
|
||
HLRO T2,JOB116 ;NUMBER OF SYMBOLS
|
||
MOVM T2,T2
|
||
LSH T2,-.DBS2W ;[650] INTO BLOCKS (ASSUME FEW UNDEFS)
|
||
MOVEM T2,I.EST(T1)
|
||
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
|
||
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
|
||
MOVEM T2,I.VER(T1) ;NO, SO SET IT
|
||
PUSHJ P,DVNAM.## ;MAKE SURE NAME SETUP
|
||
PUSHJ P,DVOPN.## ;INIT DEV
|
||
PUSHJ P,DVENT.## ;DO ENTER
|
||
;NOW TO STORE THREE INFO WORDS
|
||
HLRE T1,JOB116 ;NO. OF DEFINED SYMBOLS
|
||
HLRE T2,JOB117 ;NO. OF UNDEFS
|
||
MOVM T1,T1 ;+
|
||
MOVM T2,T2
|
||
ADDI T2,2(T1) ;PLUS TWO EXTRA WORDS
|
||
HRLI T2,776 ;BLOCK TYPE FOR LINK
|
||
SKIPN T1,JOB117 ;.JBUSY IF NON-ZERO
|
||
MOVE T1,JOB116 ;OTHERWISE .JBSYM
|
||
HRRZ T1,T1 ;REMOVE NEG LEFT HALF
|
||
SUB T1,LL.S0(R) ;REMOVE ORIGIN
|
||
SUB T1,LW.S0(R) ;INCASE PAGING
|
||
ADD T1,TAB.LB(R) ;FIX IN CORE
|
||
;NOW PUT HEADER WORDS IN CORE IMAGE SO WE CAN DUMP IT ALL WITH
|
||
;ONE IOWD. PUSH REAL CONTENTS OF THOSE LOCATIONS (USUALLY 0) FIRST,
|
||
;THEN RESTORE THEM LATER
|
||
|
||
SUBI T1,3 ;BACKUP 3
|
||
PUSH P,0(T1) ;SAVE WORDS INCASE NOT ZERO
|
||
PUSH P,1(T1)
|
||
PUSH P,2(T1)
|
||
MOVEM T2,0(T1) ;SAVE HEADER
|
||
HLLZ T2,JOB117 ;COPY INFO WORDS
|
||
MOVEM T2,2(T1) ;TO NEXT 2 LOCS
|
||
HLRE T2,T2 ;GET - LENGTH (OR 0)
|
||
MOVM T2,T2 ;+
|
||
HLL T2,JOB116 ;-LENGTH,,OFFSET
|
||
MOVEM T2,1(T1) ;FIRST INFO WORD
|
||
HLRE T2,JOB116 ;FIND TOTAL LENGTH TO OUTPUT
|
||
HLRE T3,JOB117 ;.JBSYM+.JBUSY
|
||
ADD T2,T3
|
||
SUBI T2,3 ;+3 INFO WORDS
|
||
HRLZ T2,T2 ;-LENGTH
|
||
HRRI T2,-1(T1) ;IOWD LENGTH,ADDRESS
|
||
SETZ T3, ;TERMINATE
|
||
OUT MC,T2 ;DUMP IT
|
||
JRST [POP P,2(T1) ;RESTORE DATA
|
||
POP P,1(T1)
|
||
POP P,0(T1)
|
||
PJRST DVRLS.##] ;CLOSE FILE
|
||
POP P,2(T1) ;RESTORE DATA
|
||
POP P,1(T1)
|
||
POP P,0(T1)
|
||
E$$OES::PUSH P,[MC] ;[1174]
|
||
.ERR. (ST,,V%L,L%W,S%W,OES,<Output error on symbol file, file closed, load continuing>)
|
||
POPJ P,
|
||
;HERE TO SAVE NEW FORM SYMBOL TABLE
|
||
;IF ALL IN CORE JUST OPEN AND WRITE OUT
|
||
;IF ON DSK EITHER RENAME OR COPY THEM
|
||
|
||
SAVSYM: PUSHJ P,.SAVE1## ;NEED AN AC
|
||
CAIN T1,1 ;SIXBIT SYM FILE WANTED?
|
||
MOVEI P1,LS.IX ;YES, STORED IN LS AREA
|
||
CAIN T1,2 ;HOW ABOUT ALGOL .SYM FILE?
|
||
MOVEI P1,AS.IX ;YES, USE AS AREA INSTEAD
|
||
SKIPN TAB.UW(P1) ;PAGING?
|
||
JRST WRTSYM ;NO
|
||
MOVE T1,TAB.AB(P1) ;MAKE SURE UW.XX IS OK
|
||
SUB T1,TAB.LB(P1) ;MIGHT BE -1 IF LS AREA
|
||
ADD T1,TAB.LW(P1) ;NOW HAVE HIGHEST LOC IN CORE
|
||
MOVEM T1,TAB.UW(P1) ;UPDATE UW.XX
|
||
SETCM T2,TAB.LB(P1) ;[2202] ALSO MAKE SURE DISK FILE IS OK
|
||
ADD T2,TAB.PT(P1) ;[2202] IN CASE NEVER OUTPUT BEFORE
|
||
JUMPE T2,.+4 ;[2202] FORGET IT IF NOTHING TO OUTPUT
|
||
ADD T2,TAB.LW(P1) ;[2202] NOTE WE'RE GETTING EXACT WORD CNT
|
||
MOVE T1,TAB.LW(P1) ;[2202] ALGOL 7 NEEDS .RBSIZ EXACT
|
||
PUSHJ P,@TB.OUT##(P1) ;SO USE XX.PT INSTEAD OF XX.AB
|
||
MOVE T2,TAB.AB(P1) ;[2202] NOW READ IN FRONT OF FILE
|
||
SUB T2,TAB.LB(P1) ;[2202] SO CAN SET UP 10??,,COUNT
|
||
SETZB T1,TAB.LW(P1) ;[2366] ?W.?S MUST BE UP TO DATE
|
||
MOVEM T2,TAB.UW(P1) ;[2202] FOR FOLLOWING CALL
|
||
PUSHJ P,@TB.IN##(P1) ;AS FIRST WORD OF FILE
|
||
CAIE P1,AS.IX ;ALGOL?
|
||
JRST SAVSY0 ;NO, DO IT FOR LS AREA
|
||
MOVE T3,ASYM ;YES, GET SYMBOL COUNT
|
||
HRLI T3,1044 ;AND BLOCK TYPE
|
||
JRST SAVSY1 ;AND CONTINUE
|
||
SAVSY0: MOVE T3,LSYM ;COUNT FOR LS AREA
|
||
HRLI T3,1700 ;AND BLOCK TYPE
|
||
SAVSY1: SUBI T3,1 ;WORDS FOLLOWING IS 1 LESS
|
||
MOVEM T3,@TAB.LB(P1) ;STORE COUNT WORD
|
||
SETZ T1, ;[2366] GET LOWER WINDOW (ALWAYS ZERO)
|
||
MOVE T2,TAB.UW(P1) ;[2366] AND UPPER WINDOW
|
||
PUSHJ P,@TB.OUT##(P1) ;AND UPDATE FILE
|
||
MOVEI T1,SC ;FROM CHAN#
|
||
CAIN P1,AS.IX ;UNLESS AS AREA
|
||
MOVEI T1,AC ;IN WHICH CASE ALGOL CHANNEL
|
||
MOVE T2,IO.PTR+%SC ;TO CHANNEL
|
||
PUSHJ P,DVPRO. ;GET PROTECTION RIGHT
|
||
MOVEI T2,%SC ;TO CHAN#
|
||
MOVE T3,IO.PTR+%SC ;GET POINTER TO NEW FILE
|
||
MOVE T4,VERNUM ;GET VERSION OF PROGRAM
|
||
SKIPN I.VER(T3) ;UNLESS ALREADY SET BY SWITCH...
|
||
MOVEM T4,I.VER(T3) ;SAVE FOR ENTER
|
||
PJRST DVMOV. ;GO COPY PAGED FILE TO SYMBOL FILE
|
||
WRTSYM:
|
||
MOVEI T1,TC ;[1415] USE TEMPORARY CHANNEL
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%SC ;HIDE DATA BLOCK HERE
|
||
MOVEM T1,IO.PTR+TC ;[1415] NOW USE IT
|
||
PUSHJ P,DVCHN.## ;PUT ADDRESS OF BLOCK IN T1
|
||
MOVSI T2,(Z TC,) ;[1415] RESET CHANNEL NUMBER IN I/O FIELD
|
||
MOVEM T2,I.CHN(T1) ;SINCE %SC IS THERE CURRENTLY
|
||
CAIE P1,AS.IX ;ALGOL?
|
||
JRST WRTSY0 ;NO, SETUP 1ST WORD FOR LS
|
||
MOVE T3,ASYM ;YES, SETUP COUNT WORD
|
||
HRLI T3,1044 ;AND BLOCK TYPE
|
||
JRST WRTSY1 ;CONTINUE
|
||
WRTSY0: MOVE T3,LSYM ;LS AREA COUNT
|
||
HRLI T3,1700 ;BLOCK TYPE FOR TRIPLET SYMBOLS
|
||
WRTSY1: HRRZ T2,T3 ;SAVE COUNT FOR ESTIMATE
|
||
SUBI T3,1 ;WORDS FOLLOWING IS 1 LESS
|
||
MOVEM T3,@TAB.LB(P1) ;SAVE WORD COUNT IN AREA
|
||
LSH T2,-.DBS2W ;[650] INTO BLOCKS
|
||
MOVEM T2,I.EST(T1) ;WE NEED THIS MUCH
|
||
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
|
||
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
|
||
MOVEM T2,I.VER(T1) ;NO, SO SET IT
|
||
PUSHJ P,DVNAM.## ;MAKE SURE NAME IS SET UP
|
||
PUSHJ P,DVOPN.## ;INIT DEVICE
|
||
PUSHJ P,DVENT.## ;ENTER FILE
|
||
;NOW FOR OUTPUT
|
||
WRTSY2: MOVE T1,TAB.LB(P1) ;GET BOTTOM ADDR IN CORE
|
||
SUB T1,TAB.PT(P1) ;-LENGTH
|
||
HRLZ T1,T1 ;-LENGTH,,0
|
||
HRR T1,TAB.LB(P1) ;FIRST ADDR OF BUFFER
|
||
HRRI T1,-1(T1) ;-LENGTH,,ADDR-1
|
||
SETZ T2,
|
||
OUT TC,T1 ;[1415] WRITE IT
|
||
PJRST DVRLS.## ;PAGING NO LONGER HANDLED HERE
|
||
E01OES::
|
||
PUSH P,[TC] ;[1415]
|
||
.ERR. (ST,,V%L,L%W,S%W,OES)
|
||
POPJ P,
|
||
SUBTTL SET UP PROGRAM DATA VECTOR
|
||
|
||
; PDVSET - ROUTINE TO SET UP THE PROGRAM DATA VECTOR
|
||
; THE COPY IS INITIALIZED AND READ INTO THE PROGRAM IMAGE.
|
||
|
||
IFN TOPS20,<
|
||
PDVSET:
|
||
HRRZ P1,PRGPDV ;[2306] GET THE PDV BLOCK
|
||
HLRZ W3,.PVNAM(P1) ;[2306] GET THE LENGTH OF THE NAME
|
||
ADDI W3,PV.LEN ;[2306] ADD THE PDV BLOCK SIZE
|
||
ADDM W3,PDMPLN ;[2306] SAVE THE MAXIMUM PDV SIZE
|
||
SOS T1,PDMPLN ;[2306] MAX OFFSET IS ONE LESS
|
||
ADD T1,PDVADR ;[2306] ADD THE ADDRESS
|
||
CAMLE T1,PVPLIM ;[2306] TOO MUCH?
|
||
JRST E$$NPD ;[2306] YES, COMPLAIN
|
||
ADD W3,PDVADR ;[2306] ADD THE PDV ORIGIN
|
||
MOVE T1,W3 ;[2306] GET THE START OF THE MEMORY MAP
|
||
SKIPE NOPDMP ;[2306] NO DEFAULT MAP?
|
||
SKIPA T1,.PVMEM(P1) ;[2312] GET USER SUPPLIED VALUE
|
||
MOVEM T1,.PVMEM(P1) ;[2312] PUT IT IN THE PDV
|
||
MOVE T2,FXSBIT ;[2306] GET THE SECTION BITS
|
||
JUMPE T1,PDVST1 ;[2306] DON'T BOTHER IF ZERO
|
||
TLNN T1,-1 ;[2306] ANYTHING IN LEFT HALF?
|
||
HRLI T1,(IFIW) ;[2237] NO, USE IFIW FORMAT
|
||
TXNN T2,^-1B0 ;[2237] ANY NON-ZERO SECTIONS EXIST?
|
||
MOVEM T1,.PVMEM(P1) ;[2306] NO, PUT IFIW IN THE PDV
|
||
PDVST1: SKIPN T1,.PVSTR(P1) ;[2306] GET THE START/EXPORT ADDRESS, IF ANY
|
||
JRST PDVST2 ;[2306] NONE FOUND
|
||
TLNN T1,-1 ;[2306] ANYTHING IN LEFT HALF?
|
||
HRLI T1,(IFIW) ;[2306] NO, SET AS AN IFIW
|
||
TXNN T2,^-1B0 ;[2306] SECTION ZERO ONLY?
|
||
MOVEM T1,.PVSTR(P1) ;[2306] YES, STORE AS IFIW
|
||
PDVST2: SKIPN T1,.PVCST(P1) ;[2306] GET THE CUSTOMER BLOCK ADDRESS, IF ANY
|
||
JRST PDVST3 ;[2306] NONE FOUND
|
||
TLNN T1,-1 ;[2306] ANYTHING IN LEFT HALF?
|
||
HRLI T1,(IFIW) ;[2306] NO, SET AS AN IFIW
|
||
TXNN T2,^-1B0 ;[2306] SECTION ZERO ONLY?
|
||
MOVEM T1,.PVCST(P1) ;[2306] YES, STORE AS IFIW
|
||
PDVST3: SKIPN T1,.PVPRG(P1) ;[2306] GET THE PROGRAM BLOCK ADDRESS, IF ANY
|
||
JRST PDVST4 ;[2306] NONE FOUND
|
||
TLNN T1,-1 ;[2306] ANYTHING IN LEFT HALF?
|
||
HRLI T1,(IFIW) ;[2306] NO, SET AS AN IFIW
|
||
TXNN T2,^-1B0 ;[2306] SECTION ZERO ONLY?
|
||
MOVEM T1,.PVPRG(P1) ;[2306] YES, STORE AS IFIW
|
||
PDVST4: SKIPN T1,.PVSYM(P1) ;[2311] GET THE SYMBOL VECTOR ADDRESS, IF ANY
|
||
JRST PDVST5 ;[2311] NONE FOUND
|
||
TLNN T1,-1 ;[2311] ANYTHING IN LEFT HALF?
|
||
HRLI T1,(IFIW) ;[2311] NO, SET AS AN IFIW
|
||
TXNN T2,^-1B0 ;[2311] SECTION ZERO ONLY?
|
||
MOVEM T1,.PVSYM(P1) ;[2311] YES, STORE AS IFIW
|
||
PDVST5: MOVE T1,VERNUM ;[2311] SET VERSION NUMBER
|
||
SKIPN .PVVER(P1) ;[1423] UNLESS EXPLICITLY SET
|
||
MOVEM T1,.PVVER(P1) ;[1423]
|
||
MOVE T1,COMPDT ;[1423] SET COMPILATION TIME
|
||
MOVEM T1,.PVCTM(P1) ;[1423]
|
||
;[1423] WHEN COMPILERS BEGIN INCLUDING VERSION NUMBERS ADD HERE TWO LINES TO
|
||
;[1423] SET .PVCVR(P1) ALSO.
|
||
PUSHJ P,PDVGET ;[2306] GET THE USER'S PDV ADDRESSES IN MEMORY
|
||
PUSHJ P,PDVNAM ;[2306] STORE THE NAME
|
||
SKIPN NOPDMP ;[2306] USER SUPPLY MAP?
|
||
PUSHJ P,PDVMMP ;[2306] NO, BUILD THE MEMORY MAP
|
||
PJRST PDVSTO ;[2306] STORE THE PDV ITSELF
|
||
|
||
;[2306] Store the PDV name, and set the PDV pointer to it
|
||
;[2306] Return first address after name in W3
|
||
PDVNAM: HRRZ P1,PRGPDV ;[2306] GET THE PDV ADDRESS AGAIN
|
||
MOVE T1,PDVADR ;[2306] DESTINATION IN IMAGE MEMORY
|
||
ADDI T1,PV.LEN ;[2306] AT END OF PDV BLOCK
|
||
MOVE W3,T1 ;[2306] HOLD ONTO THIS ADDRESS
|
||
SUB T1,TAB.LW(R) ;[2306] SUBTRACT THE OFFSET
|
||
ADD T1,TAB.LB(R) ;[2306] FIXED IN LINK'S MEMORY
|
||
HLRZ T2,.PVNAM(P1) ;[2306] GET THE LENGTH OF THE NAME
|
||
ADDI T2,-1(T1) ;[2306] NAME END IN LINK'S MEMORY
|
||
HRL T1,.PVNAM(P1) ;[2306] BASE OF NAME
|
||
BLT T1,(T2) ;[2306] COPY IN THE NAME
|
||
HLRZ T2,.PVNAM(P1) ;[2306] GET THE SIZE OF THE NAME
|
||
HRRZ T1,.PVNAM(P1) ;[2306] AND THE ADDRESS
|
||
PUSHJ P,DY.RET## ;[2306] RETURN THE SPACE
|
||
MOVE T1,W3 ;[2306] GET BACK THE ADDRESS
|
||
ADD W3,T2 ;[2306] ADD LENGTH, POINT TO NEXT AFTER NAME
|
||
ADD T1,LL.S0(R) ;[2311] MAKE THE ADDRESS ABSOLUTE
|
||
MOVE T2,FXSBIT ;[2306] GET THE SECTION BITS
|
||
TXNN T2,^-1B0 ;[2306] ANY NON-ZERO SECTIONS EXIST?
|
||
HRLI T1,(IFIW) ;[2306] NO, USE IFIW FORMAT
|
||
MOVEM T1,.PVNAM(P1) ;[2306] SAVE THE POINTER
|
||
POPJ P, ;[2306] RETURN
|
||
|
||
;[2237] Build memory map. The map length must be recalculated, since it
|
||
;[2237] could have changed since we allocated space for the PDV, etc.
|
||
;[2335] Expects the address of the map in W3.
|
||
PDVMMP: SUB W3,TAB.LW(R) ;[2306] SUBTRACT THE OFFSET
|
||
ADD W3,TAB.LB(R) ;[2306] FIXED IN LINK'S MEMORY
|
||
PUSH P,R ;[2306] KEEP THE SEGMENT INFO
|
||
PUSH P,W3 ;[2306] AND KEEP THE FIRST WORD OF THE MAP
|
||
ADDI W3,1 ;[2306] THE FIRST WORD IS THE COUNT
|
||
PUSH P,[0] ;[2237] INIT. MEMORY MAP LENGTH COUNTER
|
||
MOVEI R,1 ;[2237] START WITH PSECT 1 (.LOW.)
|
||
SKIPE NOLOW ;[2247] NEED TO COUNT .LOW.?
|
||
MOVEI R,2 ;[2247] NO, START WITH SECOND PSECT
|
||
PDSLOP: PUSHJ P,PDVMAP ;[2237] GO FIND A CONTIGUOUS MEMORY BLOCK
|
||
JRST PDSTLN ;[2237] NO MORE, ALL DONE SCANNING PSECTS
|
||
PUSHJ P,MAKXFW ;[2237] CONVERT TO XFIW'S AND STORE ADDRS.
|
||
AOS (P) ;[2237] FOUND ANOTHER BLOCK, ACCOUNT FOR IT
|
||
JRST PDSLOP ;[2237] KEEP COUNTING MEMORY MAP ENTRIES
|
||
|
||
PDSTLN: JUMPE R,PDVNUL ;[2237] DON'T PUT NULL LAST PSECT INTO MAP
|
||
AOS (P) ;[2237] ACCOUNT FOR LAST CALL TO PDVMAP
|
||
PUSHJ P,MAKXFW ;[2237] CONVERT TO XFIW'S AND STORE ADDRS.
|
||
PDVNUL: POP P,T1 ;[2237] RESTORE # OF MEMORY MAP ENTRIES
|
||
IMULI T1,MM.SLN ;[2250] NUMBER OF WORDS PER SUB-TABLE
|
||
ADDI T1,1 ;[2237] ACCOUNT FOR LENGTH WORD (+MISC. WORDS)
|
||
;[2237] T1 contains memory map length now.
|
||
POP P,W3 ;[2306] GET THE POINTER TO THE FIRST WORD
|
||
MOVEM T1,.MMLEN(W3) ;[2306] STORE MAP LENGTH WORD IN MAP
|
||
POP P,R ;[2306] RESTORE THE SEGMENT
|
||
POPJ P, ;[2306] DONE
|
||
|
||
;[1423] VERIFY THAT THE NEEDED PAGES ARE CURRENTLY MAPPED IN
|
||
;[2306] USES T1-T4, P1, P2
|
||
PDVGET: MOVE P2,PVPSEG ;[1423] PICK UP RELOC COUNTER
|
||
MOVE R,RC.SG(P2) ;[2006] GET THE SEGMENT NUMBER
|
||
MOVN T1,LL.S0(R) ;[2016] GET THE SEGMENT BASE
|
||
ADDB T1,PDVADR ;[2016] T1 IS (OFFSET) UPPER BOUND
|
||
MOVE P2,T1 ;[1760] T2 IS UPPER BOUND
|
||
ADD P2,PDMPLN ;[2237] COMPUTE LAST ADDRESS
|
||
CAMLE P2,HC.S0(R) ;[2016] HIGHER THAN HIGHEST CODE?
|
||
MOVEM P2,HC.S0(R) ;[2016] YES, MAKE IT HIGHEST
|
||
CAMLE P2,HL.S0(R) ;[2016] HIGHER THAN HIGHEST LOADED?
|
||
MOVEM P2,HL.S0(R) ;[2016] YES, MAKE IT HIGHEST
|
||
SUB P2,TAB.LW(R) ;[2006] SUBTRACT OFFSET
|
||
ADD P2,TAB.LB(R) ;[2006] ADD LOWER BOUND
|
||
IORI P2,.PGSIZ ;[2006] SET TO END OF PAGE
|
||
CAML T1,TAB.LW(R) ;[2006] T1 ABOVE WINDOW BOTTOM?
|
||
CAMLE P2,TAB.AB(R) ;[2006] AND T2 BELOW WINDOW TOP?
|
||
TRNA ;[2237] NO, REMAP WINDOW
|
||
POPJ P, ;[2306] YES
|
||
|
||
;[1423] CHANGE THE WINDOW MAP TO INCLUDE THE ALLOCATED PDV STORAGE.
|
||
SKIPN T2,TAB.UW(R) ;[2202] CHECK FOR PAGING
|
||
JRST PDVSNP ;[2006] NOT PAGING - SPECIAL CASE
|
||
MOVE T1,TAB.LW(R) ;[2202] MAP OUT CURRENT WINDOW
|
||
PUSHJ P,@[LC.OUT##
|
||
HC.OUT##]-1(R) ;[1423] AND UNMAP PAGES
|
||
MOVE T1,PDVADR ;[2237] GET PDV ADDRESS
|
||
ANDCMI T1,.PGSIZ ;[2006] SET TO BEGINNING OF PAGE
|
||
MOVEM T1,TAB.LW(R) ;[2006] START AT BEGINNING OF PAGE
|
||
MOVE P2,PDVADR ;[2006] GET BACK THE PDV ADDRESS
|
||
ADD P2,PDMPLN ;[2237] COMPUTE LAST ADDRESS
|
||
IORI P2,.PGSIZ ;[2006] SET TO END OF PAGE
|
||
MOVE T2,T1 ;[2006] GET THE BASE
|
||
ADD T2,TAB.AB(R) ;[2006] ADD THE UPPER BOUND
|
||
SUB T2,TAB.LB(R) ;[2006] MINUS LOWER GIVES MAX SIZE
|
||
CAMLE T2,P2 ;[2006] MORE THAN NEEDED?
|
||
MOVE T2,P2 ;[2006] NO, USE SMALLER AMOUNT
|
||
MOVEM T2,TAB.UW(R) ;[2006] NEW UPPER WINDOW
|
||
SUB T2,TAB.LW(R) ;[2006] GET SIZE
|
||
ADD T2,TAB.LB(R) ;[2006] GET NEW UPPER BOUND
|
||
MOVEM T2,TAB.AB(R) ;[2006] REMEMBER THE NEW BOUND
|
||
MOVE T2,TAB.UW(R) ;[2202] GET UPPER WINDOW
|
||
PUSHJ P,@[LC.IN##
|
||
HC.IN##]-1(R) ;[1423] AND REMAP PAGES
|
||
CAMG P2,TAB.UW(R) ;[2006] WILL IT FIT?
|
||
POPJ P, ;[2306] YES
|
||
SUB P2,TAB.LW(R) ;[2006] REMOVE THE OFFSET
|
||
ADD P2,TAB.LB(R) ;[2006] FIND OUT WHERE IT SHOULD GO
|
||
PDVSNP: SUB P2,TAB.AB(R) ;[2006] GET THE DIFFERENCE
|
||
MOVE P1,R ;[2006] GET THE SEGMENT
|
||
PUSHJ P,LNKCOR## ;[2006] EXPAND MEMORY
|
||
JRST E$$MEF## ;[2006] NOT EXPECTED TO FAIL
|
||
POPJ P, ;[2306] DONE
|
||
|
||
;[2306] Here to store the actual PDV.
|
||
PDVSTO: MOVE T1,PDVADR ;[2006] DESTINATION IN IMAGE MEMORY
|
||
SUB T1,TAB.LW(R) ;[2006] SUBTRACT THE OFFSET
|
||
ADD T1,TAB.LB(R) ;[2006] FIXED IN LINK'S MEMORY
|
||
MOVEI T2,PV.LEN ;[2306] GET THE PDV LENGTH
|
||
ADDI T2,-1(T1) ;[2237] PDV END IN LINK'S MEMORY
|
||
HRL T1,PRGPDV ;[2006] BASE OF STORED PDV
|
||
BLT T1,(T2) ;[1423] COPY IN THE PDV
|
||
MOVE T1,LL.S0(R) ;[2016] GET BACK THE OFFSET
|
||
ADDM T1,PDVADR ;[2016] ADJUST THE PDV ADDRESS
|
||
POPJ P, ;[1423] RETURN
|
||
|
||
;SUBROUTINE TO CONVERT ADDRESSES TO XFIW'S FOR MEMORY MAP.
|
||
;
|
||
; CALL: W3/ PDV MEMORY MAP ADDR. TO STORE SUB-TABLE ENTRY INTO
|
||
;
|
||
; DATA AS RETURNED BY PDVMAP IS STORED IN PROPER FORMAT INTO MEMORY MAP.
|
||
; THIS SUBROUTINE ASSUMES THE MAP SUB-TABLES ARE 3 WORDS LONG.
|
||
;
|
||
; USED ACS: W1, AND T2 AND T3 IF THEY ARE CONVERTED TO IFIW'S
|
||
; W3 IS LEFT POINTING TO THE NEXT SUB-TABLE ADDR.
|
||
;
|
||
MAKXFW: MOVEI W1,MM.SLN ;[2250] INIT. TO R.O., DEFAULT LENGTH
|
||
TXNN T4,AT.RO ;[2237] IS BLOCK READ-ONLY?
|
||
TXO W1,PM%WR ;[2237] NO, SET "WRITABLE" BIT
|
||
MOVEM W1,.MMDAT(W3) ;[2245] STORE ATTRIBUTES,,SUB-TABLE LENGTH
|
||
MOVE W1,FXSBIT ;[2237] GET SECTION BITS
|
||
TXNE W1,^-1B0 ;[2237] ANY NON-ZERO SECTIONS?
|
||
JRST MAKEFW ;[2237] YES, USE EFIW FORMAT
|
||
HRLI T2,(IFIW) ;[2237] NO, USE IFIW FORMAT
|
||
HRLI T3,(IFIW) ;[2237]
|
||
MAKEFW: MOVEM T2,.MMLOW(W3) ;[2245] STORE BLOCK START ADDR.
|
||
MOVEM T3,.MMHGH(W3) ;[2245] STORE BLOCK END ADDR.
|
||
ADDI W3,MM.SLN ;[2250] STEP TO NEXT SUB-TABLE
|
||
POPJ P, ;[2237]
|
||
|
||
E$$NPD::.ERR. (MS,.EC,V%L,L%W,S%W,NPD,<No space for program data vector in psect >) ;[2306]
|
||
.ETC. (SBX,.EP,,,,PVPNAM) ;[2306]
|
||
> ;[1423] IFN TOPS20
|
||
;HERE TO SETUP REST OF VESTIGIAL JOBDAT AREA
|
||
;ENTER WITH P1 POINTING TO JOBDAT AREA
|
||
|
||
HJBSET: JUMPE P2,CPOPJ ;DON'T NEED TO DO THIS IF NO HIGH SEG
|
||
HRRZ T1,HL.S2 ;GET HIGHEST HIGH SEG LOCATION+1
|
||
SKIPE .JBDDT(P1) ;IF DDT LOADED
|
||
SOJA T1,[IOR. T1,.PGSIZ ;INCLUDE ALL OF THIS PAGE
|
||
AOJA T1,.+1] ;IN LENGTH
|
||
HRL T1,.JBREN(P1) ;GET .JBREN
|
||
MOVSM T1,JOBHRN(P2) ;SET BOTH HALVES OF JOBHRN
|
||
MOVE T1,.JBSA(P1) ;PUT .JBSA
|
||
MOVEM T1,JOBHSA(P2) ;IN HIGH SEG
|
||
MOVE T1,.JB41(P1)
|
||
MOVEM T1,JOBH41(P2)
|
||
MOVS T1,.JBCOR(P1)
|
||
SKIPN .JBDDT(P1) ;TEST FOR RARE CASE OF DDT, SYMBOLS AND CODE
|
||
JRST .+3 ; ALL IN HIGH SEGMENT
|
||
TRNN T1,-140 ;TRUE IF HIGHEST LOC IS 137 OR LESS
|
||
ADDI T1,1 ;IF SO MAKE IT 140 IN HIGH SEG
|
||
MOVSM T1,.JBHCR(P2) ; SO WE LOAD LOW
|
||
MOVE T1,.JBVER(P1)
|
||
MOVEM T1,.JBHVR(P2)
|
||
SKIPE T1,RUNAME ;GET PROGNAM
|
||
JRST .+3 ;SET
|
||
SKIPN T1,SSNAME ;IF NOT TRY SAVE FILE NAME
|
||
MOVE T1,LODNAM ;USE DEFAULT IF NOT SET
|
||
MOVEM T1,.JBHNM(P2) ;INTO HIGH SEG
|
||
MOVE T1,HL.S1 ;HIGHEST LOC +1 IN LOW SEG
|
||
SUBI T1,1
|
||
IOR. T1,.PGSIZ ;ROUND UP TO PAGE BOUNDARY
|
||
ADDI T1,1 ;NEXT PAGE
|
||
CAMGE T1,LL.S2 ;GREATER THAN HI-ORG?
|
||
MOVE T1,LL.S2 ;NO
|
||
LSH T1,-9 ;PAGE #
|
||
HRLZM T1,JOBHSO(P2) ;STORE IN HIGH
|
||
HRRZM T1,.JBHSO(P1) ;AND STORE
|
||
POPJ P,
|
||
;HERE TO SEE IF WE JUST STARTED PAGING AND IF SO, COPY
|
||
;JOBDAT OR VESTIGAL JOBDAT INTO DY AREA, SO WE CAN ALWAYS
|
||
;REFERENCE THEM EVEN IF THEY ARE PAGED OUT.
|
||
|
||
CHKPAG:
|
||
IFN TOPS20,< ;[2366]
|
||
SKIPE NOJBDA ;[2247] /NOJOBDAT OR NON-ZERO SECTIONS?
|
||
POPJ P, ;[2247] YES
|
||
>;[2366] IFN TOPS20
|
||
SKIPE PAG.S1 ;IF WE ARE PAGING
|
||
SKIPE JOBPTR ;FOR FIRST TIME
|
||
CAIA ;NO
|
||
PUSHJ P,RDJBL ;MUST SETUP JOB DATA AREA
|
||
SKIPE PAG.S2 ;SAME FOR HIGH SEG
|
||
SKIPE JBHPTR
|
||
POPJ P, ;[1172] DONE
|
||
PUSHJ P,RDJBH ;SET UP JOBDAT IN HIGH
|
||
POPJ P,
|
||
|
||
;HERE TO GET RID OF VARIOUS AREAS
|
||
|
||
GS.ZAP: MOVEI T1,GS.IX ;GET AREA
|
||
PJRST XX.ZAP## ;GENERAL ROUTINE
|
||
|
||
FX.ZAP: MOVEI T1,FX.IX
|
||
PJRST XX.ZAP##
|
||
|
||
LS.ZAP: MOVEI T1,LS.IX
|
||
PJRST XX.ZAP##
|
||
|
||
AS.ZAP: MOVEI T1,AS.IX
|
||
PJRST XX.ZAP##
|
||
SUBTTL PROGRAM LOAD IN NONZERO SECTIONS
|
||
|
||
IFN TOPS20,< ;[2202]
|
||
|
||
;[2247] Note that P1 points to the user's low segment JOBDAT
|
||
;[2247] and P2 points to the user's high segment JOBDAT.
|
||
SAVTST: SKIPE NOJBDA ;[2247] Suppressing JOBDAT?
|
||
JRST SSINI ;[2247] Yes, don't bother with this
|
||
HLRZ T1,.JBSA(P1) ;[2247] Setup right half of .JBCOR
|
||
SUBI T1,1 ;[2247] Point at last word used
|
||
IFN FTOVERLAY,< ;[2247]
|
||
SKIPL LNKMAX ;[2247] Seen any?
|
||
SKIPN JOB116 ;[2247] Yes, and want symbols?
|
||
CAIA ;[2247] No
|
||
HLRZ T1,.JBCOR(P1) ;[2247] Include symbols
|
||
> ;[2247] IFN FTOVERLAY
|
||
IOR. T1,.PGSIZ ;[2247] To highest loc required
|
||
HRRM T1,.JBCOR(P1) ;[2247] So save get works
|
||
PUSHJ P,HJBSET ;[2247] And update the vestigial jobdat area
|
||
|
||
;Now, step through RC.TB checking each PSECT's attributes. If any are
|
||
;read-only, set the page access accordingly. If two PSECTS with conflicting
|
||
;read/write attributes are on the same page, set the page read-only.
|
||
|
||
SSINI: MOVEI R,2 ;[2247] START WITH PSECT 2 (.LOW. ALWAYS R/W)
|
||
STACC1: CAMLE R,RC.NO ;[2206] YES, FINISHED CHECKING ALL PSECTS?
|
||
JRST STDONE ;[2206] YES, EXIT ROUTINE
|
||
MOVE W2,@RC.TB ;[2206] NO, GET NEXT PSECT TABLE ADDR.
|
||
MOVE T1,RC.AT(W2) ;[2206] GET PSECT ATTRIBUTES
|
||
TXNN T1,AT.RO ;[2206] READ-ONLY?
|
||
AOJA R,STACC1 ;[2206] NO, STEP TO NEXT PSECT
|
||
|
||
;A read-only psect has been found. Determine the start page and repeat
|
||
;count for setting all the psect pages to read/execute access. Assume
|
||
;all psect pages are contiguous, but allow non-existent pages within it.
|
||
|
||
MOVE T1,RC.IV(W2) ;[2206] YES, GET PSECT INITIAL VALUE
|
||
LSH T1,-^D9 ;[2206] TURN INTO PAGE NUMBER
|
||
MOVE T3,RC.HL(W2) ;[2206] GET HIGHEST PSECT ADDR. LOADED
|
||
SUBI T3,1 ;[2261] GO BACK TO LAST ADDR. ACTUALLY LOADED
|
||
LSH T3,-^D9 ;[2206] TURN INTO PAGE NUMBER
|
||
SUB T3,T1 ;[2261] MAKE REPEAT COUNT-1 IN T3
|
||
JUMPL T3,STACC4 ;[2265] DON'T SET ATTRIBUTES OF NULL PSECTS
|
||
HRL T1,LC.JF ;[2206] GET PROCESS DESIGNATOR
|
||
STACC2: RPACS% ;[2206] GET PAGE ACCESSIBILITY
|
||
ERNAM RPACS% ;[2261] CATCH FATAL ERRORS
|
||
TXNE T2,PA%PEX ;[2320] DOES PAGE EXIST?
|
||
JRST STACC5 ;[2320] YES, GO DEAL WITH IT
|
||
HRRZ P1,T1 ;[2350] GET THE PAGE NUMBER
|
||
LSH P1,^D9 ;[2350] MAKE IT AN ADDRESS
|
||
MOVE P2,RC.SG(W2) ;[2350] GET THE SEGMENT
|
||
PUSHJ P,QMAP ;[2350] MAP IT IN
|
||
SETZM (P1) ;[2350] TOUCH THE PAGE
|
||
|
||
STACC5: MOVX T2,PA%RD+PA%EX ;[2320] SET ACCESS TO READ AND EXECUTE
|
||
SPACS% ;[2206] DO IT
|
||
ERNAM SPACS% ;[2260] CATCH FATAL ERRORS
|
||
STACC3: ADDI T1,1 ;[2206] INCREMENT TO NEXT PAGE
|
||
SOJGE T3,STACC2 ;[2261] DECREMENT PAGE CTR. AND CONTINUE
|
||
STACC4: AOJA R,STACC1 ;[2265] DONE WITH THIS PSECT, GO TO NEXT ONE
|
||
|
||
;[2350] Routine to get an address into memory.
|
||
;[2350] On entry, P1 contains the address and P2 contains the segment
|
||
;[2350] (1=low, 2=high). On return, P1 points to the addressed word
|
||
;[2350] in memory.
|
||
|
||
QMAP: CAMLE P1,TAB.LW(P2) ;[2350] Is it already within the window?
|
||
CAML P1,TAB.UW(P2) ;[2350] (between lower and upper limits?)
|
||
CAIA ;[2350] No
|
||
JRST QMAP1 ;[2350] Yes, simple case
|
||
|
||
SPUSH <T1,T2,T3,T4> ;[2350] No, get some ACs
|
||
MOVE T1,TAB.LW(P2) ;[2350] Get the lower window
|
||
MOVE T2,TAB.UW(P2) ;[2350] And the upper
|
||
PUSHJ P,@[LC.OUT## ;[2350]
|
||
HC.OUT##]-1(P2) ;[2350] Unmap the window
|
||
|
||
MOVE T1,TAB.LB(P2) ;[2350] Get the area bottom
|
||
TRO T1,.IPM ;[2350] Need one page
|
||
MOVEM T1,TAB.AB(P2) ;[2350] Set it (always available)
|
||
|
||
MOVE T1,P1 ;[2350] Get the address
|
||
TRZ T1,.IPM ;[2350] Bottom of a page
|
||
MOVE T2,T1 ;[2350] Get it again
|
||
TRO T2,.IPM ;[2350] Top of page
|
||
MOVEM T1,TAB.LW(P2) ;[2350] Set the bottom of the window
|
||
MOVEM T2,TAB.UW(P2) ;[2350] And the top
|
||
PUSHJ P,@[LC.IN## ;[2350]
|
||
HC.IN##]-1(P2) ;[2350] Map the window
|
||
SPOP <T4,T3,T2,T1> ;[2350] Restore the ACs
|
||
|
||
QMAP1: SUB P1,TAB.LW(P2) ;[2350] Get the offset into the window
|
||
ADD P1,TAB.LB(P2) ;[2350] Add the base
|
||
POPJ P,
|
||
|
||
STDONE: ;[2206] ALL DONE, FALL THROUGH
|
||
|
||
; If there is a Program Data Vector, use the PDVOP% JSYS to
|
||
; declare its existence.
|
||
SETOM XJFLG ;[2277] Assume that extended JSYSes are OK
|
||
SKIPN T3,STADDR ;[2247] Address
|
||
JRST SSINIG ;[2247] None continue on
|
||
SKIPE T2,ENTLEN ;[2247] Entry vector length specified?
|
||
JRST SSINIA ;[2247] Yes, don't default it
|
||
MOVEI T2,1 ;[2247] Default one word vector
|
||
SKIPN NOJBDA ;[2247] Doing a JOBDAT?
|
||
MOVEI T2,(JRST) ;[2247] Yes, default TOPS-10 entry vector
|
||
SSINIA: MOVE T1,LC.JF ;[2247] Pick up fork handle
|
||
XSVEC% ;[1764] Set entry vector
|
||
ERCAL [TLNE T3,-1 ;[2247] A section zero address?
|
||
JRST [MOVX P2,'XSVEC%' ;[2274] No, a JSYS failure
|
||
PJRST E$$UMF##] ;[2274] Go report it
|
||
HRL T2,T3 ;[2247] Put args in T2
|
||
MOVSS T2 ;[2247] As length,,address
|
||
SEVEC% ;[2247] Try the old way
|
||
ERNAM (SEVEC%) ;[2247] Catch errors
|
||
SETZM XJFLG ;[2277] Extended JSYSes are not OK now
|
||
POPJ P,] ;[2247] Success
|
||
JRST SSINIB ;[2277] Don't check extended JSYSes again
|
||
SSINIG: MOVX T1,.FHSLF ;[2277] Point to LINK
|
||
XGVEC% ;[2277] Try fake extended JSYS
|
||
ERJMP [SETZM XJFLG ;[2277] Simple case failed, can't do
|
||
JRST SSINIB] ;[2277] extended JSYSes any more
|
||
SSINIB: SKIPN PRGPDV ;[2277] Is there a PDV?
|
||
JRST JBFORK ;[2247] No, don't set it up
|
||
MOVEI T1,.POADD ;[2247] Set up PDV
|
||
MOVEI T2,P1 ;[2247] Point to argument block
|
||
MOVEI P1,4 ;[2247] Four arguments
|
||
MOVE P2,LC.JF ;[2247] Get fork handle
|
||
MOVEI P3,1 ;[2247] One PDV to set
|
||
MOVEI P4,PDVADR ;[2247] Point to the address
|
||
PDVOP% ;[1425] [1423]
|
||
ERJMP .+1 ;[1427]
|
||
HRRZ T1,PRGPDV ;[1762] POINT TO PRIVATE COPY OF PDV
|
||
MOVEI T2,PV.LEN ;[2306] GET ITS LENGTH
|
||
PUSHJ P,DY.RET## ;[1762] RETURN IT
|
||
|
||
; At this point three courses are open:
|
||
; 1. Remove linker and leave program fork in place.
|
||
; 2. Remove linker and start program fork.
|
||
; 3. Remove linker, load and start debugger in the program fork.
|
||
;
|
||
|
||
; Set the name of the program fork to be the jobwide program name.
|
||
JBFORK: SKIPE IO.PTR+%VC ;[2247] .EXE requested?
|
||
PUSHJ P,SAVEXE ;[2247] Yes, do it
|
||
MAPDDT: SKIPN GETDDT ;[2277] NEED TO GET DDT?
|
||
JRST NODDT ;[2277] NO
|
||
SETZM UDDFLG ;[2277] YES, CLEAR "UDDT LOADED" FLAG
|
||
MOVEI T3,0 ;[2277] SAY DDT IS IN SECTION 0 FOR NOW
|
||
MOVE T1,LC.JF ;[2277] GET FORK JFN
|
||
GEVEC% ;[2277] GET LENGTH (DON'T NEED 30 BIT ADDR)
|
||
ERNAM GEVEC% ;[2277] CATCH ERRORS
|
||
MOVEM T2,EVLEN ;[2277] SAVE IN CASE NEEDED LATER FOR KS
|
||
SKIPN XJFLG ;[2277] ARE EXTENDED JSYSES ALLOWED?
|
||
JRST TRYUDD ;[2277] NO, ALWAYS USE UDDT
|
||
MOVE T4,FXSBIT ;[2277] YES, GET SECTION BITS
|
||
TXNE T4,^-1B0 ;[2277] ANY NON-ZERO SECTIONS EXIST?
|
||
JRST DOXDDT ;[2277] YES, USE EXTENDED DDT
|
||
HLRZS T2 ;[2277] NO, PUT LENGTH ONLY IN RIGHT HALF
|
||
CAIN T2,(JRST) ;[2277] TOPS-10 ENTRY VECTOR?
|
||
JRST TRYUDD ;[2277] YES, USE UDDT
|
||
DOXDDT: MOVX T1,GJ%OLD!GJ%SHT ;[2277] NO, USE XDDT FOR TOPS-20 ENTRY VECTOR
|
||
HRROI T2,[ASCIZ/SYS:XDDT.EXE/] ;[2277]
|
||
MOVEM T2,DDTASC ;[2314] SAVE ASCIZ DDT FILESPEC
|
||
GTJFN% ;[2277] FIND XDDT
|
||
ERJMP TRYUDD ;[2277] FAILED, TRY UDDT
|
||
MOVEM T1,DDTJFN ;[2277] SAVE JFN
|
||
SETCA T4,T4 ;[2277] FIND HIGHEST FREE SECTION FOR XDDT
|
||
TRZ T4,17 ;[2277] CLEAR BITS FOR SECTIONS 32-35
|
||
MOVN T3,T4 ;[2277] TURN THE BITS UPSIDE-DOWN
|
||
AND T3,T4 ;[2277] LEAVES A BIT POINTING TO 1ST FREE SEC.
|
||
JFFO T3,.+1 ;[2277] TURN INTO SECTION #
|
||
JUMPE T4,E$$NFS ;[2277] 0=NO FREE SECT. FOR XDDT (CAN'T USE 0)
|
||
HRL T3,T4 ;[2277] T3 HAS DESIRED (1ST FREE) SECTION # NOW
|
||
JRST DDTCOM ;[2277] JOIN COMMON CODE
|
||
|
||
TRYUDD: MOVX T1,GJ%OLD!GJ%SHT ;[2277] SHORT FORM, FILE MUST EXIST
|
||
HRROI T2,[ASCIZ/SYS:UDDT.EXE/] ;[2277]
|
||
MOVEM T2,DDTASC ;[2314] SAVE ASCIZ DDT FILESPEC
|
||
GTJFN% ;[2277] TRY TO FIND UDDT
|
||
ERJMP E$$DNA ;[2277] FAILED, DEBUGGER NOT AVAILABLE
|
||
MOVEM T1,DDTJFN ;[2277] SAVE JFN
|
||
SETOM UDDFLG ;[2277] FLAG THAT UDDT PTRS. MUST BE STUFFED
|
||
DDTCOM: MOVE T1,LC.JF ;[2277] GET PROGRAM FORK HANDLE
|
||
SKIPN XJFLG ;[2277] HAVE TO DO NON-EXTENDED CODE?
|
||
JRST GVEC0 ;[2277] YES, GO DO IT (FOR KS)
|
||
GOTXDD: SKIPN UDDFLG ;[2277] NO, UDDT OR XDDT?
|
||
PUSH P,T3 ;[2277] XDDT, SAVE DESIRED SECTION #
|
||
XGVEC% ;[2277] GET ENTRY VECTOR
|
||
ERNAM XGVEC% ;[2277] TRAP ERRORS
|
||
DMOVEM T2,EVLEN ;[2277] REMEMBER ENTRY VECTOR LENGTH & ADDR.
|
||
SKIPN UDDFLG ;[2277] UDDT OR XDDT?
|
||
POP P,T3 ;[2277] XDDT, RESTORE DDT'S SECTION #
|
||
HRR T1,DDTJFN ;[2277] GET DDT JFN
|
||
HRL T1,LC.JF ;[2277] GET FORK HANDLE
|
||
TXO T1,GT%NOV!GT%ARG ;[2277] DON'T OVERLAY, USE ARG BLOCK
|
||
MOVX T2,GT%BAS ;[2277] WE WANT TO SPECIFIY SECTION
|
||
MOVEM T2,GETBLK+.GFLAG ;[2277] SET FLAG BITS
|
||
HLRZM T3,GETBLK+.GBASE ;[2277] SPECIFY SECTION TO LOAD INTO
|
||
MOVEI T2,GETBLK ;[2277] POINT TO ARG BLOCK
|
||
GET% ;[2277] NOW BRING IN DDT
|
||
ERJMP E$$CLD ;[2277] CANNOT LOAD DDT
|
||
HLRZS T3 ;[2314] PUT SECTION # IN T3 RIGHT
|
||
MOVNS T3 ;[2314] AND MAKE IT NEGATIVE
|
||
MOVX T1,1B0 ;[2314] SECTION # BIT
|
||
LSH T1,(T3) ;[2314] SET APPROPRIATE BIT FOR THE SECTION #
|
||
IORM T1,FXSBIT ;[2314] DECLARE SECTION TO EXIST
|
||
MOVE T1,LC.JF ;[2277] GET PROGRAM FORK HANDLE
|
||
SKIPE DEBUGSW ;[2277] WANT TO EXECUTE DDT?
|
||
SKIPN EXECSW ;[2277] (ONLY WITH /DEBUG)
|
||
JRST NOEXDD ;[2277] NO
|
||
HRRZ T4,DEBUGSW ;[2363] WHICH DEBUGGER STARTS PROGRAM?
|
||
CAIE T4,DEB$DDT ;[2363] IS IT DDT?
|
||
JRST NOEXDD ;[2363] NO, /TEST:DDT ONLY
|
||
XGVEC% ;[2277] YES, PICKUP DDT'S ENTRY VECTOR
|
||
ERNAM XGVEC% ;[2277] CATCH ERRORS
|
||
MOVEM T3,STADDR ;[2277] START ADDR. IS DDT NOW
|
||
HRRM T3,EXECSW ;[2362] STORE IN BOTH PLACES
|
||
NOEXDD: DMOVE T2,EVLEN ;[2277] RESTORE VECTOR LENGTH & ADDR.
|
||
XSVEC% ;[2277] SET IT AGAIN
|
||
ERNAM XSVEC% ;[2277] TRAP ERRORS
|
||
JRST STUFDD ;[2277] ALL DONE, CONTINUE LINK
|
||
|
||
;Section 0 style load. This is necessary for KS processors which don't
|
||
;have the extended JSYSes. This code is identical in function to the
|
||
;above code.
|
||
GVEC0: HRR T1,DDTJFN ;[2277] GET DDT JFN
|
||
HRL T1,LC.JF ;[2277] GET FORK HANDLE
|
||
TXO T1,GT%NOV ;[2277] DON'T OVERLAY
|
||
GET% ;[2277] NOW BRING IN DDT
|
||
ERJMP E$$CLD ;[2277] CANNOT LOAD DDT
|
||
MOVX T1,1B0 ;[2314] SAY THAT SECTION 0 NOW EXISTS
|
||
IORM T1,FXSBIT ;[2314] DO IT
|
||
MOVE T1,LC.JF ;[2277] GET PROGRAM FORK HANDLE
|
||
SKIPE DEBUGSW ;[2277] WANT TO EXECUTE DDT?
|
||
SKIPN EXECSW ;[2277] (ONLY WITH /DEBUG)
|
||
JRST NOEXS0 ;[2277] NO
|
||
GEVEC% ;[2277] YES, GET DDT'S START ADDR.
|
||
ERNAM GEVEC% ;[2277] CATCH ERRORS
|
||
HRRZM T2,STADDR ;[2277] START PROGRAM AT 0,,ADDR
|
||
HRRM T2,EXECSW ;[2362] STORE IT IN BOTH PLACES
|
||
NOEXS0: MOVE T2,EVLEN ;[2277] RECOVER OLD ENTRY VECTOR
|
||
SEVEC% ;[2277] SET IT (DDT CHANGED IT WHEN GET%'ING)
|
||
ERNAM SEVEC% ;[2277] CATCH ERRORS
|
||
STUFDD: SKIPN UDDFLG ;[2277] NEED TO STUFF UDDT SYMBOL TABLE PTRS?
|
||
JRST NODDT ;[2277] NO, SKIP THIS
|
||
MOVEI P2,LC.IX ;[2352] DDT IS ALWAYS IN THE LOW SEGMENT
|
||
HLLZ P1,T3 ;[2352] GET DDT'S SECTION #
|
||
HRRI P1,DDTSA+1 ;[2352] NEED WORD AFTER DDT START ADDRESS
|
||
PUSHJ P,QMAP ;[2352] MAP IT
|
||
MOVE P1,(P1) ;[2352] GET SYMBOL TABLE POINTER ADDR
|
||
HLL P1,T3 ;[2352] GET THE SECTION NUMBER
|
||
PUSH P,P1 ;[2352] REMEMBER THIS ADDRESS
|
||
PUSHJ P,QMAP ;[2352] MAP IT IN
|
||
MOVE T1,JOB116 ;[2352] GET DEFINED SYM TABLE PTR
|
||
MOVEM T1,(P1) ;[2352] STUFF DDT'S SYMBOL TABLE PTR
|
||
ERCAL E$$CSP ;[2277] CANNOT SET UDDT'S POINTERS?
|
||
POP P,P1 ;[2352] GET ADDRESS BACK
|
||
ADDI P1,1 ;[2352] NEXT ADDRESS FOR UNDEFINED
|
||
PUSHJ P,QMAP ;[2352] MAP IT IN
|
||
MOVE T1,JOB117 ;[2352] GET UNDEFINED SYM TABLE PTR
|
||
MOVEM T1,(P1) ;[2352] STUFF DDT'S SYMBOL TABLE PTR
|
||
ERCAL E$$CSP ;[2277] CANNOT SET UDDT'S POINTERS?
|
||
|
||
NODDT: PUSHJ P,ENDEXE ;[2277] Finish up, close log file
|
||
SETZM F.EDIT ;[2247] Keep LNKSCN happy
|
||
SKIPN EXECSW ;[2247] execute preempts run switch
|
||
SKIPN N.ZER## ;[2247] Run switch pending?
|
||
CAIA ;[2247] No
|
||
JRST LNKSCN## ;[2247] Yes, go do the run switch
|
||
|
||
;[2247] Here to build the SPLFK% Argument block
|
||
|
||
MOVEI T1,6 ;[2247] Six arguments
|
||
MOVEM T1,ARGBLK+.SFLEN ;[2247] Store in arg block
|
||
MOVEI T1,.SFUNS ;[2247] Get function code
|
||
MOVEM T1,ARGBLK+.SFCOD ;[2247] Store in arg block
|
||
MOVE T1,LC.JF ;[2247] Get the fork handle
|
||
MOVEM T1,ARGBLK+.SFUIN ;[2247] Store in arg block
|
||
SETZM ARGBLK+.SFUA1 ;[2247] No PC flags
|
||
MOVE T1,STADDR ;[2247] Get the start address
|
||
HRR T1,EXECSW ;[2355] Debugger may change address
|
||
MOVEM T1,ARGBLK+.SFUA2 ;[2247] Store in arg block
|
||
|
||
PUSHJ P,DOXMES ;[2247] Type the execute message
|
||
|
||
MOVX T1,SF%ADR ;[2247] Get the "start" bit
|
||
SKIPN EXECSW ;[2247] Want to execute this?
|
||
SETZ T1, ;[2247] No
|
||
MOVEM T1,ARGBLK+.SFUFL ;[2247] Set the flag
|
||
|
||
MOVEI T1,[KILPAT] ;[2347] Tell PA1050 To go away
|
||
COMPT. T1, ;[1460]
|
||
JFCL ;[1460] Error return not possible
|
||
|
||
SKIPE T1,RUNAME ;[1425] Get program name
|
||
JRST .+3 ;[1425] Got a name
|
||
SKIPN T1,SSNAME ;[1425] If not try save file name
|
||
MOVE T1,LODNAM ;[1425] Use default if not set
|
||
;**; Insert 2 lines at NODDT+35
|
||
TLNN T1,770000 ;[2404] Is it a long name?
|
||
MOVE T1,(T1) ;[2404] Yes - use 1st 6 characters
|
||
SETNM% ;[1425] Set it
|
||
|
||
MOVX T1,<SF%EXT!ARGBLK> ;[2247] Get the splice fork arg
|
||
SPLFK% ;[2247] Go for the user's program
|
||
ERJMP JBNONE ;[2247] Failure!
|
||
|
||
;[2247] The splice fork failed, probably because the monitor
|
||
;[2247] does not have the extended code. Tell the user, and
|
||
;[2247] Save the program if it has not already been. Then get
|
||
;[2247] and optionally start the user's program.
|
||
|
||
;[2247] Since this code is not expected to be used, it was
|
||
;[2247] designed to be small rather than efficient. In
|
||
;[2247] particular, the routine it calls to get the JFN on
|
||
;[2247] the .EXE file also opens the file, which them must
|
||
;[2247] be closed. This is done to prevent having to write
|
||
;[2247] a new routine which would get the JFN without opening
|
||
;[2247] the file.
|
||
|
||
JBNONE: MOVEI T1,DC ;[2357] Set up channel
|
||
MOVEM T1,IO.CHN ;[2357] For EXE file
|
||
SKIPE R,IO.PTR+%VC ;[2357] .EXE requested?
|
||
JRST E$$SPF ;[2247] Yes
|
||
MOVEI T2,F.LEN ;[2247] Set up file spec
|
||
PUSHJ P,DY.GET## ;[2247] As though we had seen /SAVE
|
||
MOVE P1,T1 ;[2247] Store pointer to "scan" block
|
||
HLLZ T2,JOBNUM ;[2247] Sixbit jobnumber
|
||
HRRI T2,'LNK' ;[2247] Rest of name
|
||
MOVEM T2,F.NAME(T1) ;[2247] In the scan block
|
||
MOVEM T2,SSNAME ;[2247] Here also
|
||
MOVSI T2,'EXE' ;[2247] Get extension
|
||
MOVEM T2,F.EXT(T1) ;[2247] Store it in scan block
|
||
MOVEM T2,SSEXT ;[2247] For save file
|
||
MOVSI T2,'DSK' ;[2247] Make sure it goes on DSK
|
||
MOVEM T2,F.DEV(T1) ;[2247] Incase defaults screwed up
|
||
PUSHJ P,DVOUT.## ;[2247] Setup data block
|
||
%VC,,.IODPR ;[2247] On fake chan in dump mode
|
||
SETZ R, ;[2247] In case DVOUT. set it
|
||
|
||
E$$SPF::.ERR. (MS,.EC,V%L,L%F,S%W,SPF,<Splice fork failed>) ;[2247]
|
||
.ETC. (XCT,.EC,,,,<[SKIPE R]>) ;[2247] Already had save file?
|
||
.ETC. (JMP,.EC,,,,JBNON1) ;[2247] Yes, don't say "saving on..."
|
||
.ETC. (STR,.EC,,,,,<, saving on file >) ;[2247]
|
||
.ETC. (FSP,.EC,,,,%VC) ;[2247] Type the filespec
|
||
JBNON1: .ETC. (NOP) ;[2247] End
|
||
;Remove DDT from the user's core image before creating the .EXE file.
|
||
SETZM UDPTRS ;[2314] CLEAR "POKE UDDT IN SEC. 0" FLAG
|
||
SKIPN GETDDT ;[2314] DID USER HAVE DDT IN MEMORY?
|
||
JRST JBNON3 ;[2314] NO
|
||
SETO T1, ;[2314] YES, PREPARE TO DELETE PAGES/SECTION
|
||
SKIPE UDDFLG ;[2314] XDDT (ITS OWN SECTION) OR UDDT?
|
||
JRST JBNONU ;[2314] UDDT, GO UNMAP JUST UDDT'S PAGES
|
||
HRL T2,LC.JF ;[2314] XDDT, GET FORK HANDLE
|
||
HRR T2,GETBLK+.GBASE ;[2314] GET SECTION NUMBER
|
||
MOVEI T3,1 ;[2314] DELETE 1 SECTION
|
||
SMAP% ;[2314] BLOW AWAY XDDT AND ITS SECTION
|
||
ERNAM SMAP% ;[2314] CATCH ERRORS
|
||
JRST JBNON3 ;[2314] DONE
|
||
JBNONU: HRR T2,GETBLK+.GBASE ;[2314] GET SECTION #
|
||
LSH T2,^D9 ;[2314] MOVE IT OVER
|
||
TXO T2,DDTPAG ;[2314] BEGIN UNMAPPING UDDT AT THIS PAGE
|
||
HRL T2,LC.JF ;[2314] GET FORK HANDLE
|
||
MOVX T3,PM%CNT+1000-DDTPAG ;[2314] # OF PAGES TO REMOVE FROM PROCESS
|
||
PMAP% ;[2314] BLOW AWAY UDDT
|
||
ERNAM PMAP% ;[2314] CATCH ERRORS
|
||
|
||
JBNON3: SKIPN R ;[2314] ALREADY GOT AN .EXE FILE?
|
||
PUSHJ P,SAVEXE ;[2314] NO, GO MAKE ONE
|
||
SKIPN GETDDT ;[2314] YES, NEED TO LOAD A DDT?
|
||
JRST JBNON2 ;[2314] NO
|
||
SKIPN UDDFLG ;[2314] YES, UDDT OR XDDT?
|
||
JRST JBNONX ;[2314] XDDT, GO DO IT
|
||
SKIPE T3,GETBLK+.GBASE ;[2314] UDDT, GET SECTION # TO LOAD IT INTO
|
||
JRST JBNONX ;[2314] NON-ZERO, NO CONFLICT WITH LINK & DDT
|
||
MOVX T1,<.FHSLF,,770> ;[2314] PREPARE TO SEE IF WE'RE DDT'ING LINK
|
||
RPACS% ;[2314] SEE IF UDDT'S FIRST PAGE IS THERE
|
||
ERNAM RPACS% ;[2314] CATCH ERRORS
|
||
TXNN T2,PA%PEX ;[2314] DOES PAGE EXIST?
|
||
JRST JBNONX ;[2314] NO, NO CONFLICT POSSIBLE
|
||
MOVE T2,770000 ;[2314] YES, GET FIRST WORD OF PAGE 770
|
||
CAMN T2,[JRST 770002] ;[2314] DOES IT LOOK LIKE UDDT?
|
||
JRST JBNON4 ;[2314] YES, SPECIAL CASE - DON'T GET% UDDT
|
||
JBNONX: MOVX T1,GJ%OLD!GJ%SHT ;[2314] GET GTJFN% BITS
|
||
MOVE T2,DDTASC ;[2314] GET ASCIZ DDT FILESPEC
|
||
GTJFN% ;[2314] FIND X/UDDT (WE FOUND IT BEFORE)
|
||
ERNAM GTJFN% ;[2314] THIS WORKED BEFORE, SHOULD'VE HERE TOO!
|
||
HRLI T1,.FHSLF ;[2314] GET FORK HANDLE (LINK)
|
||
SKIPN XJFLG ;[2314] EXTENDED JSYSES ALLOWED?
|
||
JRST JBNONZ ;[2314] NO, DO IT THE SIMPLE WAY
|
||
TXO T1,GT%NOV!GT%ARG ;[2314] YES, DON'T OVERLAY, USE ARG BLOCK
|
||
MOVEI T2,GETBLK ;[2314] POINT TO ARG BLOCK
|
||
GET% ;[2314] NOW BRING X/UDDT INTO PROPER SECTION
|
||
ERNAM GET% ;[2314] THIS WORKED BEFORE, SHOULD'VE HERE TOO!
|
||
JRST JBNON2 ;[2314] DDT LOADED, START ADDRS. ALREADY SET
|
||
|
||
;Here when DDT is loaded with LINK and we want UDDT in section 0.
|
||
JBNON4: DMOVE T1,JOB116 ;[2314] GET SYMBOL TABLE PTRS.
|
||
DMOVEM T1,UDPTRS ;[2314] SAVE THEM AND REMEMBER TO POKE LATER
|
||
JRST JBNON2 ;[2314]
|
||
|
||
;Here for non-extended (KS) case.
|
||
JBNONZ: TXO T1,GT%NOV ;[2314] DON'T OVERLAY
|
||
GET% ;[2314] NOW BRING UDDT INTO SECTION 0
|
||
ERNAM GET% ;[2314] THIS WORKED BEFORE, SHOULD'VE HERE TOO!
|
||
|
||
JBNON2: MOVE T1,LC.JF ;[2314] Get the inferior
|
||
KFORK% ;[2247] Kill it
|
||
ERNAM (KFORK%) ;[2274] Should not fail
|
||
|
||
PUSHJ P,DVLKP.## ;[2247] Open the exe file
|
||
PUSHJ P,E$$EOI ;[2357] Unexpected failure
|
||
MOVX T1,CO%NRJ ;[2247] Don't want to lose the JFN
|
||
HRR T1,DC.JF ;[2247] Get the JFN
|
||
CLOSF% ;[2247] Close it
|
||
ERNAM (CLOSF%) ;[2274] Should not fail
|
||
|
||
MOVE T1,[R%ACS,,ACS] ;[2247] Copy run code to writable place
|
||
BLT T1,ACS+R%17 ;[2247]
|
||
MOVE T1,DC.JF ;[2247] Get the EXE file JFN
|
||
HRRM T1,ACS+R%16 ;[2247] Put JFN in get JSYS argument
|
||
MOVE T1,STADDR ;[2247] Get the start address
|
||
HRR T1,EXECSW ;[2360] Debugger may change address
|
||
SKIPE EXECSW ;[2247] Want to execute?
|
||
MOVEM T1,ACS+R%12 ;[2247] Yes, store address
|
||
MOVE T2,[JRST @R%12] ;[2247] Get the short JRST
|
||
TLNN T1,-1 ;[2247] Doing extended addressing?
|
||
MOVEM T2,ACS+R%10 ;[2247] No, use JRST (in case KS10)
|
||
MOVX T1,.POREM ;[2314] PREPARE TO REMOVE LINK'S PDV ADDR.
|
||
MOVEI T2,[.POADE+1 ;[2353] LENGTH OF ARG BLOCK
|
||
.FHSLF ;[2353] DO IT TO OUR FORK (LINK)
|
||
0 ;[2353] NO RETURNED VALUES EXPECTED
|
||
0 ;[2353] NO BLOCK FOR RETURNED VALUES
|
||
20 ;[2353] START ADDR. TO REMOVE PDV ADDR. FROM
|
||
<DDTPAG*1000>-1] ;[2353] END ADDR. IS JUST BELOW UDDT
|
||
PDVOP% ;[2314] REMOVE LINK'S PDV
|
||
ERNAM PDVOP% ;[2314] CATCH ERRORS
|
||
MOVEI T1,.FHSLF ;[2314] POINT TO OUT PROCESS
|
||
SETO T2, ;[2314] PREPARE TO DISABLE ALL PSI CHANNELS
|
||
DIC% ;[2314] TO PREVENT PROBLEMS WHEN ZEROING
|
||
ERNAM DIC% ;[2314] TABLE ADDRESSES OUT
|
||
MOVEI T2,0 ;[2314] PREPARE TO CLEAR PSI TABLE ADDRS.
|
||
SIR% ;[2314] DO IT (RESET% DOESN'T CLEAR ADDRS.)
|
||
ERNAM SIR% ;[2314] CATCH ERRORS
|
||
DMOVE T1,UDPTRS ;[2314] GET FLAG/PTRS. TO POKE UDDT
|
||
SKIPE T1 ;[2314] HAVE TO POKE SECTION 0 UDDT?
|
||
DMOVEM T1,@770001 ;[2314] YES, DO IT (CAN'T SEE LINK SYMS. NOW)
|
||
MOVE R%17,[ACS,,R%0] ;[2247] Copy poked code to ACS
|
||
BLT R%17,R%17 ;[2247] ..
|
||
JRST R%4 ;[2247] Go start program
|
||
|
||
;[2247] Final suicide code for running a program
|
||
|
||
R%ACS: PHASE 0 ;[2247] Get into the ACS
|
||
R%0:! 0 ;[2247] Unused
|
||
R%1:! -1 ;[2247] PMAP% arguments to unmap all of memory
|
||
R%2:! .FHSLF,,0 ;[2247] ..
|
||
R%3:! PM%CNT+DDTPAG ;[2314] Don't unmap DDT (if debugging LINK)
|
||
R%4:! PMAP% ;[2247] Beginning of suicide code--unmap pages
|
||
R%5:! MOVE R%1,R%16 ;[2247] Load GET% argument
|
||
R%6:! GET% ;[2247] Bring in program
|
||
R%7:! RESET% ;[2247] Do RESET JSYS to clear PSI, etc.
|
||
R%10:! XJRSTF R%11 ;[2247] Start the program
|
||
R%11:! 0 ;[2247] PC Flags
|
||
R%12:! R%13 ;[2247] Where to start program
|
||
R%13:! HALTF% ;[2247] Start of program if no /EXECUTE
|
||
R%14:! JRST R%13 ;[2247] Not a continuable halt
|
||
R%15:! 0 ;[2247] Unused
|
||
R%16:! .FHSLF,,.-. ;[2247] Poked with GET% JSYS argument
|
||
R%17:! 0 ;[2247] Unused
|
||
DEPHASE
|
||
|
||
SAVEXE:
|
||
E$$CSF::.ERR. (MS,0,V%L,L%I,S%I,CSF,<Creating saved file>) ;[2247]
|
||
PUSHJ P,EXEINI ;[2247] Get a JFN
|
||
MOVE T1,T3 ;[2247] Fetch spare JFN
|
||
HRL T1,LC.JF ;[2247] Get the fork handle
|
||
MOVE T3,HL.S1 ;[2364] Get the highest loaded
|
||
IORI T3,777777 ;[2274] Set to top of section
|
||
ADDI T3,1 ;[2274] Number of words to transfer
|
||
LSH T3,-^D9 ;[2274] Convert it to pages
|
||
MOVNS T3 ;[2274] Negate it
|
||
MOVX T2,<SS%UCA!SS%CPY!SS%RD!SS%WR!SS%EXE!SS%EPN> ;[2317] Get flags
|
||
HRL T2,T3 ;[2274] Save all pages
|
||
SETZ T3, ;[2247] Starting with page zero
|
||
SSAVE% ;Save the pages
|
||
ERJMP E$$EOE ;[2247] Too bad
|
||
|
||
HRRZ T1,DC.JF ;[2346] Get other JFN on exe file
|
||
DVCHR% ;[2346] Get the device charisterics
|
||
ERNAM (DVCHR%) ;[2346] Very unhealthy device
|
||
LDB T2,[POINTR T2,DV%TYP] ;[2346] Get the device type
|
||
CAIE T2,.DVDSK ;[2346] Is it a disk?
|
||
JRST [HRRZ T1,DC.JF ;[2346] No, get the JFN again
|
||
RLJFN% ;[2346] Give it back
|
||
ERNAM (RLJFN%) ;[2346] Unexpected problem
|
||
SETZM IO.PTR+%VC ;[2346] Remember no usable EXE
|
||
POPJ P,] ;[2346] Return
|
||
|
||
HRRZ T1,DC.JF ;[2346] Get JFN on exe file again
|
||
HRL T1,LC.JF ;[2346] And the fork handle
|
||
GET% ;[2247] Map them back in
|
||
ERNAM (GET%) ;[2247] Unexpected failure
|
||
POPJ P, ;[2247] File saved
|
||
|
||
;[2247] Here to make the final decision about execution, and to type
|
||
;[2247] the appropriate messages. Don't execute the program if there
|
||
;[2247] are errors unless /DEBUG is set.
|
||
DOXMES: SKIPN STADDR ;[2247] Is there a start addr?
|
||
PUSHJ P,E02NSA ;[2247] No
|
||
SKIPN EXECSW ;[2247] Start it?
|
||
POPJ P, ;[2247] No
|
||
SKIPE ERRNO ;[2247] Don't run if errors
|
||
SKIPGE DEBUGSW ;[2247] Unless debugging
|
||
PJRST EXEMES ;[2247] No, announce execution
|
||
E02DLT::.ERR. (MS,0,V%L,L%F,S%W,DLT,<Execution deleted>) ;[2247]
|
||
SETZM EXECSW ;[2247] Don't execute
|
||
POPJ P, ;[2247] Return
|
||
|
||
E02NSA::.ERR. (MS,0,V%L,L%F,S%I,NSA,<No start address>) ;[2247]
|
||
AOS ERRNO ;[2247] Don't execute
|
||
POPJ P, ;[2247] Return
|
||
|
||
|
||
> ;[2202] IFN TOPS20
|
||
IFE TOPS20,< ;[2247]
|
||
SUBTTL DECIDE TO LOAD OR SAVE
|
||
|
||
|
||
;DETERMINE IF WE CAN LOAD THE PROGRAM INTO MEMORY OR MUST WRITE AN .EXE FILE
|
||
;INSTEAD. WE MUST WRITE AN .EXE FILE IF ANY OF THE FOLLOWING ARE SATISFIED:
|
||
;
|
||
; 1. USER SPECIFIED /SAVE (SCAN BLOCK ALREADY SET UP).
|
||
; 2. THERE ARE PAGE GAPS BETWEEN PSECTS, EXCEPT BELOW .HIGH. (BEWARE THAT
|
||
; OVERLAPS DO NOT COUNT AS GAPS).
|
||
; 3. THERE ARE ANY PSECTS ABOVE THE HIGH SEGMENT.
|
||
; 4. ANY PSECT HAS NON-DEFAULT WRITEABILITY.
|
||
; 5. THE PROGRAM WILL NOT FIT IN MEMORY WITH LINK'S FINAL PLACEMENT CODE
|
||
; (THIS INCLUDES THE CASE IN WHICH THE REMAP UUO WOULD HAVE TO MOVE THE
|
||
; HIGH SEGMENT DOWN).
|
||
|
||
SAVTST:
|
||
SKIPE IO.PTR+%VC ;[1146] SAVE FILE REQUIRED?
|
||
JRST JBSAVE ;YES
|
||
|
||
;TEST FOR GAPS BETWEEN PSECTS, PSECTS ABOVE THE HIGH SEGMENT AND PSECT
|
||
;PROPERTIES THAT WE CAN'T HANDLE EXCEPT IN AN EXE FILE.
|
||
|
||
MOVE T1,HL.S1 ;[1146] SEE IF LOW SEG (CONTAINS ALL PSECTS)
|
||
SKIPE LL.S2 ;[1170] HITS HIGH SEG (IF ANY) WHICH CHECKS
|
||
CAMG T1,LL.S2 ;[1146] FOR PSECTS ABOVE HIGH SEG ORIGIN
|
||
SKIPA ;[1146] NO--OK SO FAR
|
||
JRST JBCMPX ;[1146] YES--CAN'T LOAD IT
|
||
MOVEI R,0 ;[1146] START AT .ABS.
|
||
MOVE W1,@RC.TB ;[1146] GET POINTER TO ITS RELOC BLOCK
|
||
MOVE T1,RC.HL(W1) ;[1146] START WITH ITS HIGH LIMIT
|
||
ADDI R,1 ;[1146] ADVANCE TO .LOW. FOR CHECKS
|
||
MOVX T4,2 ;[1146] # OF SEG CONTAINING ONLY .HIGH.
|
||
|
||
|
||
;BACK HERE FOR EACH NEW PSECT.
|
||
|
||
SAVTS1: MOVE W2,@RC.TB ;[1146] GET POINTER TO THIS RELOC BLOCK
|
||
MOVE T2,RC.AT(W2) ;[1171] GET THIS PSECT'S ATTRIBUTES
|
||
|
||
CAMN T4,RC.SG(W2) ;[1171] TOPS-10 HIGH SEGMENT?
|
||
JRST [TXNE T2,AT.RW ;[1171] YES, USER ASKED FOR WRITEABLE?
|
||
JRST JBCMPX ;[1171] YES, LET MONITOR FIGURE IT OUT
|
||
JRST SAVTS2] ;[1171] NO, ATTRIBUTES ARE OK
|
||
|
||
TXNE T2,AT.RO ;[1171] NON-HI SEG PAGE TO BE READ ONLY?
|
||
JRST JBCMPX ;[1171] YES, WE CAN'T HANDLE IT
|
||
SAVTS2: CAML T1,RC.HL(W2) ;[1171] DOES PREVIOUS PSECT ENGULF THIS ONE?
|
||
JRST SAVTS6 ;[1171] YES--NO GAP POSSIBLE YET
|
||
CAMN T4,RC.SG(W2) ;[1146] POSSIBLE GAP BELOW .HIGH.?
|
||
JRST SAVTS5 ;[1171] YES--OK. USUAL CASE
|
||
MOVEI T2,-1(T1) ;[1146] COMPUTE LAST PAGE USED
|
||
LSH T2,-9 ;[1146] ..
|
||
LDB T3,[POINTR RC.IV(W2),^-^O777] ;[1146] GET FIRST PAGE USED BY NEXT PSECT
|
||
SUB T3,T2 ;[1146] COMPUTE # PAGES BETWEEN THIS AND LAST
|
||
SOJG T3,JBCMPX ;[1146] CAN'T LEAVE GAPS IN MEMORY
|
||
SAVTS5: MOVE T1,RC.HL(W2) ;[1171] SO FAR SO GOOD--ADVANCE TO NEXT PSECT
|
||
SAVTS6: MOVE W1,W2 ;[1171] ADVANCE TO NEXT PSECT
|
||
CAMGE R,RC.NO ;[1146] LOOKED AT ALL PSECTS?
|
||
AOJA R,SAVTS1 ;[1146] NO--LOOK AT NEXT
|
||
; ..
|
||
; ..
|
||
|
||
;COMPUTE HOW MUCH MEMORY IT WILL TAKE TO HOLD THE PROGRAM DURING THE LAST STAGES
|
||
;OF LOADING, AND MAKE SURE THAT WE CAN GET THAT MUCH. IF WE CAN'T, THEN THE
|
||
;PROGRAM IS TOO COMPLEX. THERE ARE TWO SIZES TO WORRY ABOUT:
|
||
;
|
||
; 1. LINK'S LOW SEGMENT + THE PROGRAM'S ACTUALLY LOADED LOW SEGMENT (DOESN'T
|
||
; COUNT BLOCK'S AT THE END OF THE LOW SEGMENT) + THE PROGRAM'S ACTUALLY
|
||
; LOADED HIGH SEGMENT. THIS IS THE MEMORY REQUIREMENT IN JBLOAD.
|
||
;
|
||
; 2. THE PROGRAM'S ENTIRE LOW SEGMENT + HIGH SEGMENT. THIS IS THE MEMORY
|
||
; REQUIREMENT IN THE FINAL EXIT CODE AT %5. NOTE THAT WE MUST REMEMBER
|
||
; THAT WE HAVE A HIGH SEGMENT NOW BUT WON'T THEN.
|
||
|
||
MOVE T1,DY.AB ;[1146] START WITH HIGHEST ADDR LINK NEEDS
|
||
ADD T1,HC.S1 ;[1146] ADD LENGTH OF ACTUALLY LOADED CODE
|
||
IOR. T1,.PGSIZ ;[1146] ..
|
||
SKIPE LL.S2 ;[1170] HIGH SEG EXISTS
|
||
CAMGE T1,LL.S2 ;[1146] AND ORIGIN BELOW WHERE WE CAN PUT IT?
|
||
SKIPA ;[1146] NO--OK
|
||
JRST JBCMPX ;[1146] YES--REMAP WOULD FAIL SO TOO COMPLEX
|
||
ADD T1,HC.S2 ;[1170] ADD LENGTH OF HIGH SEGMENT
|
||
IOR. T1,.PGSIZ ;[1146] ..
|
||
HRRZ T2,.JBHRL## ;[1170] DON'T COUNT SIZE OF CURRENT HIGH SEG
|
||
SUB T2,HIORGN ;[1170] ..
|
||
MOVNI T2,2(T2) ;[1170] ..
|
||
ADD T2,HL.S1 ;[1170] + ENTIRE PROGRAM LOW SEG
|
||
IOR. T2,.PGSIZ ;[1170] ROUNDED TO A PAGE
|
||
ADD T2,HL.S2 ;[1170] + ENTIRE PROGRAM HIGH SEG
|
||
IOR. T2,.PGSIZ ;[1170] ROUNDED TO A PAGE TOO
|
||
CAMGE T1,T2 ;[1170] PICK MAX OF TWO
|
||
MOVE T1,T2 ;[1170] ..
|
||
TLNE T1,-1 ;[732] OVERFLOWED INTO THE LH?
|
||
JRST JBCMPX ;[1146] YES--CAN'T FIT SO WRITE .EXE FILE
|
||
CAMG T1,.JBREL ;DO WE HAVE ENOUGH ALREADY?
|
||
JRST JBLOAD ;[1146] YES, READ IN REST OF TEMP FILE
|
||
CORE T1, ;NO TRY FOR IT
|
||
JRST JBCMPX ;[1146] WON'T FIT--WRITE .EXE FILE
|
||
MOVEI T1,HG.TAB ;OK, BUT DON'T FORGET TO GIVE IT TO SOMEONE
|
||
SKIPN TAB.LB(T1) ;USUAL LOOP
|
||
SOJA T1,.-1
|
||
MOVE T2,.JBREL
|
||
MOVEM T2,TAB.UB(T1)
|
||
JRST JBLOAD ;[1146] PROGRAM WILL FIT--GO BRING IT IN
|
||
SUBTTL FORCE nnnLNK/SAVE
|
||
|
||
|
||
;HERE IF USER DID NOT SPECIFY /SAVE BUT PROGRAM IS TOO COMPLEX (TOO LARGE, PSECT
|
||
;GAPS, ETC.) TO LOAD. DUMMY UP A SCAN BLOCK AS IF THE USER TYPED nnnLNK/SAVE,
|
||
;PRINT A WARNING AND FALL INTO .EXE WRITING CODE.
|
||
|
||
JBCMPX: MOVEI T2,F.LEN ;[1146] SET UP FILE SPEC
|
||
PUSHJ P,DY.GET## ;AS THOUGH WE HAD SEEN /SAVE
|
||
PUSH P,P1 ;[1261] Save pointer to users JOBDAT area
|
||
MOVE P1,T1 ;STORE POINTER TO "SCAN" BLOCK
|
||
HLLZ T2,JOBNUM ;SIXBIT JOBNUMBER
|
||
HRRI T2,'LNK' ;REST OF NAME
|
||
MOVEM T2,F.NAME(T1)
|
||
MOVEM T2,SSNAME ;HERE ALSO
|
||
IFE FTEXE,<
|
||
MOVSI T2,'HGH' ;MARK NON-SHAREABLE
|
||
SKIPN HL.S2 ;IF NO HIGH
|
||
MOVSI T2,'SAV' ;SO MESSAGE IS CORRECT
|
||
>
|
||
IFN FTEXE,<
|
||
MOVSI T2,'EXE' ;SO MESSAGE IS CORRECT
|
||
>
|
||
MOVEM T2,F.EXT(T1)
|
||
MOVEM T2,SSEXT ;FOR SAVE FILE
|
||
MOVSI T2,'DSK' ;MAKE SURE IT GOES ON DSK
|
||
MOVEM T2,F.DEV(T1) ;INCASE DEFAULTS SCREWED UP BY NOW
|
||
PUSHJ P,DVOUT.## ;SETUP DATA BLOCK
|
||
%VC,,.IODPR ;ON FAKE CHAN IN DUMP MODE
|
||
SKIPE EXECSW ;WANT TO EXECUTE?
|
||
JRST E$$PCX ;[1174] YES--LNKPCX
|
||
E$$PCL::.ERR. (MS,.EC,V%L,L%W,S%W,PCL,<Program too complex to load, saving as file >) ;[1174]
|
||
.ETC. (JMP,.EC,,,,JBCMP2)
|
||
E$$PCX::.ERR. (MS,.EC,V%L,L%W,S%I,PCX,<Program too complex to load and execute, will run from file >) ;[1174]
|
||
JBCMP2: .ETC. (FSP,,,,,%VC)
|
||
POP P,P1 ;[1261] RESTORE USERS JOBDAT POINTER
|
||
; JRST JBSAVE ;[1146] FALL THROUGH TO WRITE .EXE FILE
|
||
SUBTTL GENERATE .EXE (OR .XPN/.SHR/.HGH/.LOW) FILE
|
||
|
||
>;[2247] IFE TOPS20
|
||
;SOME JOBDAT LOCATIONS WE NEED TO KNOW
|
||
.JBHSO==75 ;PAGE # OF HIGH SEG ORIGIN
|
||
.JBSDD==114 ;SAVED .JBDDT
|
||
.JBS41==122 ;SAVED .JB41
|
||
EXTERN .JBREN
|
||
JOBHSA==0 ;HIGH .JBSA
|
||
JOBH41==1 ;HIGH .JB41
|
||
JOBHRN==3 ;HIGH .JBHRL & .JBREN
|
||
JOBHSO==7 ;PAGE # OF HIGH SEG ORIGIN IN HIGH
|
||
|
||
IFE TOPS20,< ;[2247]
|
||
;HERE TO SETUP SAVED LOCATIONS
|
||
JBSAVE: ;[1174] WRITE A SAVED FILE
|
||
E$$CSF::.ERR. (MS,0,V%L,L%I,S%I,CSF,<Creating saved file>) ;[1174]
|
||
IFE FTEXE,<
|
||
MOVE T2,.JBDDT(P1) ;GET DDT START
|
||
MOVEM T2,.JBSDD(P1) ;TO SAFE PLACE
|
||
MOVE T2,.JB41(P1) ;SAME FOR UUO HANDLER
|
||
MOVEM T2,.JBS41(P1)
|
||
>
|
||
HLRZ T1,.JBSA(P1) ;ALSO SETUP RIGHT HALF OF .JBCOR
|
||
SUBI T1,1 ;[1317] POINT AT LAST WORD USED
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;SEEN ANY?
|
||
SKIPN JOB116 ;YES, AND WANT SYMBOLS?
|
||
CAIA ;NO
|
||
HLRZ T1,.JBCOR(P1) ;INCLUDE SYMBOLS
|
||
>
|
||
IOR. T1,.PGSIZ ;TO HIGHEST LOC REQUIRED
|
||
HRRM T1,.JBCOR(P1) ;SO SAVE GET WORKS
|
||
SKIPL SYMSEG ;[1132] SYMBOLS IN A PSECT?
|
||
JRST JBSAVX ;[1132] NO, SKIP THIS
|
||
HLRE T1,.JBSYM(P1) ;[1132] YES, GET -LENGTH OF TABLE
|
||
HRRZ T2,.JBSYM(P1) ;[1132] GET FIRST ADDR OF TABLE
|
||
SUB T2,T1 ;[1132] COMPUTE FIRST FREE AFTER TABLE
|
||
CAMLE T2,HC.S1 ;[1132] UPDATE AMOUNT OF CODE IN LC AREA
|
||
MOVEM T2,HC.S1 ;[1132] BUT NEVER DECREASE
|
||
CAMLE T2,HL.S1 ;[1132] ALSO UPDATE SIZE OF SEGMENT
|
||
MOVEM T2,HL.S1 ;[1132] NEVER DECREASE
|
||
JBSAVX:
|
||
IFN FTEXE,<JRST JBEXE> ;SET UP TO WRITE AN EXE FILE
|
||
IFE FTEXE,<
|
||
SKIPN HC.LB ;ANYTHING IN HIGH SEG?
|
||
JRST JBNOHI ;NO, JUST SAVE LOW SEG
|
||
SKIPN PAG.S2 ;PAGING HIGH SEG?
|
||
JRST JBSHGH ;NO, JUST SAVE IT
|
||
;JUST WRITE OUT LAST PAGES
|
||
;AND JBHDA (0-7 RELATIVE)
|
||
;AND EITHER RENAME OR COPY FILE
|
||
;TO RIGHT F/S
|
||
MOVE T1,LW.S2 ;[2202] LOWER WINDOW
|
||
MOVE T2,UW.S2 ;[2202] UPPER WINDOW
|
||
PUSHJ P,HC.OUT## ;OUTPUT LAST BLOCKS
|
||
|
||
SETZB T1,LW.S2 ;[2202] START BACK AT ZERO
|
||
MOVEI T2,.IPM ;[2202] READ IN FIRST
|
||
PUSHJ P,HC.IN## ;READ IT BACK
|
||
PUSHJ P,BLTJHA ;COPY FIRST 10 WORDS BACK
|
||
;WE NOW HAVE A HIGH SEG FILE ON DSK
|
||
;BUT IS IT THE RIGHT W/S
|
||
MOVE T2,IO.PTR+%VC ;[606] TO CHANNEL
|
||
PUSHJ P,DVPRO. ;[606] GET THE PROTECTION RIGHT
|
||
MOVEI T1,HC ;FROM HIGH CODE OVERFLOW
|
||
MOVEI T2,%VC ;TO SAVE FILE
|
||
PUSHJ P,DVMOV. ;RENAME OR COPY
|
||
JRST JBSHDL ;RENAMED, REMOVE HC AREA
|
||
|
||
;HERE IF NOT PAGING. WRITE OUT THE HIGH SEGMENT FILE.
|
||
JBSHGH: MOVEI R,2 ;POINT TO HIGH SEGMENT
|
||
PUSHJ P,SAVINI ;OPEN SAVE FILE
|
||
JBSHG1: MOVE T1,HC.AB ;GET LENGTH OF HIGH CODE AREA
|
||
SUB T1,HC.LB
|
||
SKIPN PAG.S2 ;PAGING (NOT ALL IN CORE)
|
||
SKIPE .JBDDT(P1) ;OR DDT LOADED?
|
||
JRST JBSHGN ;USE ALL OF AREA
|
||
CAMLE T1,HL.S2 ;UNLESS SMALLER THAN HIGHEST LOC
|
||
MOVE T1,HL.S2 ;USE HIGHEST LOC LOADED
|
||
JBSHGN: MOVN T1,T1 ;IOWD IS NEG
|
||
HRLZ T1,T1 ;IN LEFT HALF
|
||
HRR T1,HC.LB ;GET ADDRESS OF FIRST WORD
|
||
HRRI T1,-1(T1) ;-1
|
||
SETZ T2, ;TERMINATE LIST
|
||
OUT DC,T1 ;DUMP CORE IMAGE AS IS
|
||
JRST JBSHGR ;OK
|
||
E$$SOE::PUSH P,[DC] ;[1174]
|
||
.ERR. (ST,,V%L,L%F,S%F,SOE,<Saved file output error>) ;[1174]
|
||
JBSHGR: MOVEI T1,DC ;MAKE SURE CHAN# SETUP
|
||
MOVEM T1,IO.CHN
|
||
PUSHJ P,DVRLS.## ;RELEASE DEVICE
|
||
|
||
|
||
;HERE AFTER HI SEG SAVED. DELETE POSSIBLE .HGH/.SHR & .LOW FILES
|
||
JBSHDL: MOVEI T1,TC ;CHAN#
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%VC ;PSEUDO CHAN#
|
||
MOVEM T1,IO.PTR+TC ;INCASE OF ERROR
|
||
PUSHJ P,DVCHN.## ;T1 POINTS TO DATA BLOCK ON RETURN
|
||
MOVSI T2,(Z TC,) ;RESET CHAN # IN AC FIELD
|
||
MOVEM T2,I.CHN(T1) ;SINCE %VC IS THERE CURRENTLY
|
||
SKIPE T2,SSNAME ;GET REQUIRED NAME
|
||
JRST .+3 ;USUALLY ITS GIVEN
|
||
SKIPN T2,RUNAME ;IF NOT TRY /RUNAME
|
||
MOVE T2,LODNAM ;DEFAULT AS LAST RESORT
|
||
MOVEM T2,I.NAM(T1) ;DELETE THIS FILE
|
||
PUSH P,T2 ;SAVE NAME FOR .LOW
|
||
HLLZ T2,SSEXT ;GET EXT WE WANT
|
||
TLC T2,331732 ;DELETE OTHER ONE
|
||
MOVEM T2,I.EXT(T1)
|
||
PUSHJ P,DVOPN.## ;OPEN DEVICE
|
||
MOVEI T1,TC ;SET CHAN#
|
||
PUSHJ P,DVDEL.##
|
||
JFCL
|
||
PUSHJ P,DVCHN.##
|
||
POP P,I.NAM(T1) ;RESTORE NAME
|
||
PUSH P,I.EXT(T1) ;[575] SAVE EXTENSION IN CASE /EXEC
|
||
HRLZ T2,SSEXT ;INCASE USER SUPPLIED EXT
|
||
SKIPN T2 ;DELETE IT INCASE ONLY HIGH
|
||
MOVSI T2,'LOW'
|
||
MOVEM T2,I.EXT(T1) ;AND DELETE THIS ALSO
|
||
PUSHJ P,DVOPN.## ;OPEN CHAN AGAIN
|
||
MOVEI T1,TC ;SET CHAN#
|
||
PUSHJ P,DVDEL.##
|
||
JFCL
|
||
;FALL THROUGH TO NEXT PAGE
|
||
;HERE TO SETUP LOW SEG FILE SPEC
|
||
PUSHJ P,DVCHN.## ;[575] POINT BACK AT I/O DATA BLOCK
|
||
POP P,I.EXT(T1) ;[575] RESTORE EXTENSION IN CASE /EXEC
|
||
HRLZ T1,SSEXT ;INCASE USER SUPPLIED
|
||
SKIPN T1
|
||
MOVSI T1,'LOW' ;IF ANY LOW SEG STUFF
|
||
MOVEM T1,SSEXT ;EXT IS NOW LOW NOT SAV
|
||
MOVEI T1,HC.IX ;ALL DONE WITH HIGH SEG CODE AREA
|
||
PUSHJ P,XX.ZAP ;SO GET RID OF IT
|
||
MOVE T1,IO.PTR+DC ;BUT SAVE FILE SPEC
|
||
MOVEM T1,IO.PTR+HC ;IN CASE /EXEC
|
||
JRST JBSLOW ;NOW SAVE LOW SEG
|
||
JBNOHI: HRLZ T1,SSEXT ;INCASE USER SUPPLIED IT
|
||
SKIPN T1
|
||
MOVSI T1,'SAV' ;EXT IS NOW SAV NOT LOW
|
||
MOVEM T1,SSEXT
|
||
;FALL INTO JBSLOW
|
||
;JOBDAT IS NOW SETUP - IF PAGING WRITE OUT REST OF CORE IMAGE
|
||
;AND READ IN AS MUCH AS POSSIBLE FOR CORE COMPRESSOR
|
||
JBSLOW: SKIPN PAG.S1 ;PAGING?
|
||
JRST JBSAV3 ;NO, JUST OUTPUT CORE IMAGE
|
||
MOVE T1,LW.S1 ;[2202] GET LOWER WINDOW
|
||
MOVE T2,UW.S1 ;[2202] TO UPPER
|
||
PUSHJ P,LC.OUT## ;OUTPUT IT ALL
|
||
;NOW TO SEE IF WE CAN READ ALL OF CORE FILE BACK INTO CORE
|
||
; IF NOT READ IN AS MUCH AS POSSIBLE
|
||
SETZB T1,LW.S1 ;START AT LOWEST LOCATION
|
||
MOVE T2,DY.AB ;HIGHEST LOC WE CAN NOT USE
|
||
MOVEM T2,DY.UB ;TELL LNKCOR ABOUT IT
|
||
ADDI T2,1
|
||
MOVEM T2,LC.LB ;BACKUP IF WE CAN
|
||
SKIPN T2,LS.LB ;CAN ONLY USE TO BOTTOM OF LS
|
||
;AREA IF IT'S STILL THERE
|
||
SKIPA T2,.JBREL ;IF IT'S NOT, CAN USE ALL OF CORE
|
||
SUBI T2,1 ;LAST TO USE IS START OF LS - 1
|
||
MOVEM T2,LC.UB ;RESET POINTERS
|
||
MOVEM T2,LC.AB ;FOR CONSISTENCY
|
||
SUB T2,LC.LB ;MINUS WHAT WE ALREADY HAVE
|
||
MOVEM T2,UW.S1 ;ASSUME IT WON'T FIT
|
||
CAMGE T2,HC.S1 ;ENOUGH EXTRA FOR ALL OF FILE?
|
||
JRST JBSAV1 ;NO, DO IT THE HARD WAY
|
||
MOVE T2,HC.S1 ;WE NEED ONLY THIS MUCH
|
||
IORI T2,.IPM ;ROUNDED UP
|
||
MOVE T3,T2 ;CAN ALSO CUT BACK LC.AB
|
||
ADD T3,LC.LB ;TO WHAT WE ACTUALLY NEED
|
||
MOVEM T3,LC.AB ;TO SAVE TIME
|
||
PUSHJ P,LC.IN## ;READ WHAT WE CAN
|
||
PUSHJ P,LC.DLT ;DELETE LC FILE UNLESS .XPN WANTED
|
||
JRST JBSAV2 ;AND COPY 0-137 BACK INTO CORE
|
||
|
||
JBSAV1: PUSHJ P,LC.IN## ;READ BACK AS MUCH CORE AS WE CAN
|
||
JBSAV2: PUSHJ P,BLTJDA ;[2366] BLT .JBDA TO LOW SEG
|
||
JBSAV3: MOVE T1,LC.LB ;JOBDAT NOW SETUP IN CORE
|
||
SKIPN .JBDDT(T1) ;ALWAYS SAVE IF DDT LOADED
|
||
SKIPN HC.S2 ;ANY HIGH SEG (HC.LB IS ZERO BY NOW)
|
||
JRST JBSAV4 ;NO, SO MUST WANT LOW SEG
|
||
MOVE T1,HC.S1 ;YES, SEE IF LOW SEG CONTAINS DATA
|
||
CAIG T1,.JBDA ;IF .JBCOR GREATER THAN 137
|
||
JRST ENDSAV ;NO, SO NO LOW SEG FILE
|
||
JBSAV4: MOVEI R,1 ;POINT TO LOW SEGMENT
|
||
PUSHJ P,SAVINI ;INIT/ENTER SAV FILE
|
||
SKIPE IO.PTR+%XC ;WANT .XPN FILE?
|
||
SKIPE IO.PTR+LC ;BUT NOT PAGING
|
||
JRST ZCMPRS ;NO, NOW FOR ZERO COMPRESSOR
|
||
PUSHJ P,WRTXPN ;WRITE IT OUT
|
||
JRST ZCMPRS ;AND COMPRESS CORE IMAGE
|
||
|
||
> ;END OF IFE FTEXE
|
||
;HERE TO DELETE LC FILE
|
||
;CALLED BY
|
||
; PUSHJ P,LC.DLT
|
||
;USES T1
|
||
|
||
LC.DLT: SETZM PAG.S1 ;NOT PAGING NOW
|
||
SKIPE IO.PTR+%XC ;WANT .XPN FILE?
|
||
POPJ P, ;YES, LEAVE OVERFLOW FILE
|
||
MOVEI T1,LC
|
||
PUSHJ P,DVDEL.## ;DELETE FILE
|
||
JFCL ;TOO BAD
|
||
POPJ P,
|
||
|
||
;HERE TO DELETE HC FILE
|
||
|
||
HC.DLT: SETZM PAG.S2
|
||
MOVEI T1,HC
|
||
PUSHJ P,DVDEL.##
|
||
JFCL
|
||
POPJ P,
|
||
|
||
>;[2247] IFE TOPS20
|
||
IFN FTOVERLAY,<
|
||
;HERE TO DELETE LS FILE
|
||
LS.DLT: SETZM PAG.LS
|
||
MOVEI T1,SC
|
||
PUSHJ P,DVDEL.##
|
||
JFCL
|
||
POPJ P,
|
||
>
|
||
IFE TOPS20,<
|
||
BLTJDA: MOVS T1,JOBPTR ;FORM BLT POINTER
|
||
HRR T1,LC.LB ;TO MOVE MODIFIED JOBDAT AREA
|
||
HRRZI T2,.JBDA-1(T1) ;BACK INTO FRONT OF CORE
|
||
BLT T1,(T2)
|
||
MOVE T1,JOBPTR ;GIVE AREA BACK
|
||
MOVEI T2,.JBDA
|
||
PUSHJ P,DY.RET
|
||
SETZM JOBPTR ;AND FORGET ABOUT AREA
|
||
SKIPN IO.PTR+%XC ;IF WE WANT .XPN FILE
|
||
POPJ P, ;NO
|
||
SETZ T1, ;[2202] YES, START AT THE BEGINNING
|
||
MOVEI T2,.DBM ;[2202] NOW WRITE IT BACK
|
||
PJRST LC.OUT## ;WRITE OUT JOBDATA AREA AGAIN
|
||
|
||
;NOW READ BACK FIRST 10 WORDS (.JBHDA)
|
||
BLTJHA: MOVS T1,JBHPTR ;FORM BLT POINTER
|
||
HRR T1,HC.LB ;TO MOVE MODIFIED JOBDAT AREA
|
||
HRRZI T2,.JBHDA-1(T1) ;BACK INTO FRONT OF CORE
|
||
BLT T1,(T2)
|
||
MOVE T1,JBHPTR ;GIVE AREA BACK
|
||
MOVEI T2,.JBHDA
|
||
PUSHJ P,DY.RET##
|
||
SETZM JBHPTR ;AND FORGET ABOUT AREA
|
||
SETZ T1, ;[2202] START AT THE BEGINNING
|
||
MOVEI T2,.DBM ;[2202] NOW WRITE IT BACK
|
||
PJRST HC.OUT## ;WRITE IT BACK
|
||
IFE FTEXE,<
|
||
;HERE TO OPEN SAVE FILE (USING DC)
|
||
;ENTER WITH :-
|
||
;R = 1 (LOW) OR 2 (HIGH)
|
||
|
||
SAVINI: MOVEI T1,DC ;CHAN#
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%VC ;PSEUDO CHAN#
|
||
MOVEM T1,IO.PTR+DC ;INCASE OF ERROR
|
||
PUSHJ P,DVCHN.## ;T1 POINTS TO DATA BLOCK ON RETURN
|
||
MOVSI T2,(Z DC,) ;RESET CHAN # IN AC FIELD
|
||
MOVEM T2,I.CHN(T1) ;SINCE %VC IS THERE CURRENTLY
|
||
SKIPE T2,SSNAME ;GET REQUIRED NAME
|
||
JRST .+3 ;USUALLY ITS GIVEN
|
||
SKIPN T2,RUNAME ;IF NOT TRY /RUNAME
|
||
MOVE T2,LODNAM ;DEFAULT AS LAST RESORT
|
||
MOVEM T2,I.NAM(T1) ;SAVE IT
|
||
HLLZ T2,SSEXT ;EXT IS EITHER SAV OR LOW
|
||
MOVEM T2,I.EXT(T1)
|
||
MOVX T2,RB.PRV ;[606] PRESERVE PROTECTION
|
||
ANDM T2,I.PRV(T1) ;[606] MAKE CREATION DATE TODAY
|
||
MOVE T2,HC.S0(R) ;GET HIGHEST LOC TO SAVE
|
||
LSH T2,-.DBS2W ;[650] INTO BLOCKS
|
||
ADDI T2,3 ;1 FOR REMAINDER, 2 FOR RIBS
|
||
MOVEM T2,I.EST(T1) ;AT LEAST THIS IS ENOUGH
|
||
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
|
||
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
|
||
MOVEM T2,I.VER(T1) ;NO, SO SET IT
|
||
PUSHJ P,DVOPN.## ;OPEN DEVICE
|
||
PUSHJ P,DVNAM.## ;MAKE SURE WE HAVE A NAME
|
||
PJRST DVENT.## ;ENTER FILE NAME
|
||
>;END OF IFE FTEXE
|
||
;HERE TO OPEN XPN FILE (IF NOT PAGING) USING LC
|
||
|
||
XPNINI: MOVEI T1,LC ;CHAN#
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%XC ;PSEUDO CHAN#
|
||
MOVEM T1,IO.PTR+LC ;INCASE OF ERROR
|
||
SETZM IO.PTR+%XC ;DONE WITH .XPN CHAN NOW
|
||
PUSHJ P,DVCHN.## ;T1 POINTS TO DATA BLOCK ON RETURN
|
||
MOVSI T2,(Z LC,) ;RESET CHAN # IN AC FIELD
|
||
MOVEM T2,I.CHN(T1) ;SINCE %VC IS THERE CURRENTLY
|
||
MOVE T2,HC.S1 ;GET HIGHEST LOC TO SAVE
|
||
LSH T2,-.DBS2W ;[650] INTO BLOCKS
|
||
ADDI T2,3 ;1 FOR REMAINDER, 2 FOR RIBS
|
||
MOVEM T2,I.EST(T1) ;AT LEAST THIS IS ENOUGH
|
||
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
|
||
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
|
||
MOVEM T2,I.VER(T1) ;NO, SO SET IT
|
||
PUSHJ P,DVOPN.## ;OPEN DEVICE
|
||
PUSHJ P,DVNAM.## ;MAKE SURE FILE NAME SETUP
|
||
PJRST DVENT.## ;ENTER FILE NAME
|
||
|
||
|
||
;HERE TO WRITE OUT .XPN FILE IF NOT PAGING
|
||
;NOTE, MUST BE DONE BEFORE ZERO COMPRESSION
|
||
|
||
WRTXPN: PUSHJ P,XPNINI ;OPEN/ENTER FILE
|
||
MOVE T1,HC.S1 ;HIGHEST LOC TO OUTPUT
|
||
MOVN T1,T1 ;-LENGTH
|
||
HRLZ T1,T1 ;IN LEFT HALF
|
||
HRR T1,LC.LB ;FORM IOWD
|
||
HRRI T1,-1(T1) ;ALMOST
|
||
SETZ T2, ;END WORD
|
||
OUT LC,T1 ;DUMP OUTPUT
|
||
CAIA ;OK
|
||
PUSHJ P,E$$OEX ;[1174]
|
||
PUSHJ P,DVRLS.## ;RELEASE DEV
|
||
PJRST DVZAP.## ;FORGET ABOUT .XPN FILE NOW
|
||
|
||
E$$OEX::PUSH P,[LC] ;[1174]
|
||
.ERR. (ST,,V%L,L%W,S%W,OEX,<Output error on XPN file, file closed, load continuing>) ;[1174]
|
||
POPJ P,
|
||
>;[2247] IFE TOPS20
|
||
IFN FTEXE,<
|
||
IFE TOPS20,< ;[2247]
|
||
;HERE TO WRITE THE EXE FILE.
|
||
;THE STRATEGY IS:
|
||
;RESERVE ONE PAGE FOR THE DIRECTORY.
|
||
;WRITE OUT EACH PSECT (POINTED TO BY RC.TB), COMPRESSING OUT ZERO PAGES,
|
||
; AND ACCUMULATING THE EXE DIRECTORY IN A BLOCK IN THE DY AREA.
|
||
;GO BACK TO THE BEGINNING OF THE FILE AND WRITE OUT THE EXE DIRECTORY.
|
||
;NOTES:
|
||
;PAGE 0 IS ALWAYS WRITTEN, AND IF A HIGH SEG EXIST, SO IS ITS FIRST PAGE.
|
||
;IF THE EXE DIRECTORY PAGE IN THE DY AREA OVERFLOWS, LINK WRITES IT OUT
|
||
; AT THE BEGINNING OF THE FILE, THEN FREES UP ANOTHER PAGE IN THE FILE BY
|
||
; MAKING A BACKWARDS PASS OVER THE EXE FILE, MOVING EACH PAGE DOWN ONE.
|
||
|
||
|
||
JBEXE: SKIPN HC.LB ;ANY HIGH SEGMENT?
|
||
JRST JBEXEN ;NO,
|
||
SKIPN T2,UW.S2 ;[2202] IS IT PAGED?
|
||
JRST JBEXEH ;NO,
|
||
MOVE T1,LW.S2 ;[2202] OUTPUT WORD
|
||
PUSHJ P,HC.OUT ;MAKE SURE IT GET OUT
|
||
MOVE T2,UW.S2 ;[2202]
|
||
SUB T2,LW.S2 ;[2202] GET LENGTH
|
||
MOVEM T2,UW.S2 ;[2202] RESET IT
|
||
SETZB T1,LW.S2 ;[2202] BACK TO FRONT OF FILE
|
||
PUSHJ P,HC.IN ;READ IT BACK
|
||
JBEXEH: PUSHJ P,HJBSET ;[2366] SETUP VESTIGIAL JOBDAT
|
||
SKIPE JBHPTR ;WAS IT PAGED?
|
||
PUSHJ P,BLTJHA ;YES, READ IT BACK NOW
|
||
JBEXEN: MOVEI T2,1000 ;NEED SPACE FOR DIRECTORY
|
||
PUSHJ P,DY.GET## ;GO GET IT
|
||
DMOVEM T1,EXEDIR ;SAVE BASE
|
||
IFN FTOVERLAY,<
|
||
|
||
;IF LOADING OVERLAYS, IT IS THE EXE FILE GENERATOR'S RESPONSIBILITY
|
||
;TO INSERT THE SYMBOLS INTO THE PROGRAM ON THE FLY WHILE IT IS WRITING
|
||
;THE EXE FILE. THE SYMBOLS ARE IN THE LS AREA IN RADIX50 FORM.
|
||
;THE EXE FILE WRITING LOOP IS VERY PAGE ORIENTED, SO TO MAKE THINGS
|
||
;EASIER, WE WILL COPY THE FIRST PARTIAL PAGE OF SYMBOLS INTO THE
|
||
;LC AREA HERE.
|
||
|
||
SKIPL LNKMAX ;[1132] LOADING OVERLAYS?
|
||
SKIPN JOB116 ;[1132] AND SYMBOLS TO PROCESS?
|
||
JRST JBEXEE ;[1132] NO, SKIP THIS
|
||
HRRZ P3,JOB116 ;[1132] GET FIRST ADDRESS TO COPY INTO
|
||
HRRZ P4,P3 ;[1132] COMPUTE LAST ADDRESS IN P4
|
||
ADDI P4,777 ;[1132] ROUND UP TO PAGE BOUND
|
||
ANDCMI P4,777 ;[1132] ADDRESS OF FIRST FULL PAGE OF SYMS
|
||
CAMLE P4,HL.S1 ;[1132] MAKE SURE EXE FILE WRITER GOES THIS FAR
|
||
MOVEM P4,HL.S1 ;[1132] SO OVERLAY CODE CAN JUST CONTINUE
|
||
MOVEI R,1 ;[1132] POINTER TO .LOW. RC BLOCK
|
||
MOVE R,@SG.TB ;[1132] SINCE OVERLAY SYMBOLS ARE IN .LOW.
|
||
CAMLE P4,RC.HL(R) ;[1132] UPDATE .LOW. TO SYMBOLS WRITTEN HERE
|
||
MOVEM P4,RC.HL(R) ;[1132] BUT NEVER SHRINK IT
|
||
ANDI P3,777 ;[1132] OFFSET TO FIRST WORD TO WRITE
|
||
JUMPE P3,JBEXEE ;[1132] IF PAGE-ALIGNED, NOTHING TO DO
|
||
CAMLE P4,HC.S1 ;[1132] SINCE COPYING SYMS, UPDATE NON-ZERO PTR
|
||
MOVEM P4,HC.S1 ;[1132] ALSO REMEMBERS HOW LONG LC AREA IS
|
||
SKIPE PAG.S1 ;[1132] IS LC AREA PAGING?
|
||
JRST JBEXEB ;[1132] YES, GO SET ON CORRECT PAGE
|
||
MOVE P2,P4 ;[1132] EXTEND LC AREA TO WHERE SYMS GO
|
||
ADD P2,LC.LB ;[1132] MIGHT BE QUITE A WAY IF BIG /SPACE
|
||
SUB P2,LC.AB ;[1132] DISTANCE = LAST ADDR - SIZE OF LC AREA
|
||
SUBI P2,1 ;[1132] SIZE IS LAST-FIRST+1
|
||
JUMPLE P2,JBEXEC ;[1132] ALREADY THERE
|
||
MOVEI P1,LC.IX ;[1132] TELL LNKCOR TO EXPAND LC AREA
|
||
PUSHJ P,LNKCOR ;[1132] DO IT
|
||
JRST JBEXEB ;[1132] FAILED, BUT LC AREA IS PAGING NOW
|
||
JRST JBEXEC ;[1132] OK, GO DO THE COPY
|
||
;HERE IF THE LC AREA IS PAGING, EITHER FROM THE START, OR BECAUSE
|
||
;IT COULDN'T EXPAND FAR ENOUGH. JUST SET UP A ONE-PAGE WINDOW TO
|
||
;THE PAGE WE WANT TO COPY INTO.
|
||
|
||
JBEXEB: MOVE T1,LW.S1 ;[2202] WRITE ENTIRE LC AREA
|
||
MOVE T2,UW.S1 ;[2202] TO AVOID LOST DATA
|
||
PUSHJ P,LC.OUT## ;[1132] DUMP IT TO THE OVERFLOW FILE
|
||
MOVE T1,LC.LB ;[1132] REDUCE LC WINDOW TO ONE PAGE
|
||
ADDI T1,777 ;[1132] AVOIDS CHECKS FOR OVER 256K
|
||
MOVEM T1,LC.AB ;[1132] AREA IS NOW 1 PAGE
|
||
MOVEI T1,-1000(P4) ;[2202] LOWEST LOCATION TO READ
|
||
MOVEM T1,LW.S1 ;[2202] UPDATE LOWER WINDOW
|
||
HRRI T2,-1(P4) ;[2202] HIGHEST LOCATION TO READ
|
||
MOVEM T2,UW.S1 ;[2202] UPDATE UPPER WINDOW
|
||
PUSHJ P,LC.IN## ;[2202] READ IN CODE IN THAT PAGE
|
||
|
||
|
||
;HERE WHEN THE LC AREA INCLUDES THE PAGE THAT WE WANT TO UPDATE.
|
||
;NOW GET THE PAGE OF SYMBOLS WE WANT TO PUT HERE INTO THE LS AREA.
|
||
|
||
JBEXEC: PUSHJ P,CHKPAG ;[1132] IN CASE WE JUST STARTED PAGING
|
||
SKIPN LW.LS ;[1132] ARE THE FIRST PAGE OF SYMBOLS IN?
|
||
JRST JBEXED ;[1132] YES, GO DO THE COPY
|
||
MOVE T2,LW.LS ;[2202] WRITE CURRENT LS WINDOW
|
||
ADD T2,LS.AB ;[2202] SO SYMBOLS WON'T BE LOST
|
||
SUB T2,LS.LB ;[2202] T1 HAS NEW UPPER BOUND
|
||
MOVEM T2,UW.LS ;[2202] STORE IN CASE IT WAS -1
|
||
MOVE T1,LW.LS ;[2202] ARG TO LS.OUT
|
||
PUSHJ P,LS.OUT ;[1132] WRITE THE LS AREA OUT
|
||
MOVE T1,LS.LB ;[1132] REDUCE LS WINDOW TO 1 PAGE
|
||
ADDI T1,777 ;[1132] WILL BE EXPANDED LATER IF NEEDED
|
||
MOVEM T1,LS.AB ;[1132] AB IS LB+1P
|
||
SETZM T1,LW.LS ;[2202] WANT FIRST PAGE OF SYMBOLS
|
||
MOVEI T2,777 ;[2202] FROM 0 TO 777
|
||
MOVEM T2,UW.LS ;[2202] UPDATE UPPER WINDOW
|
||
PUSHJ P,LS.IN ;[1132] READ IN THE SYMBOLS
|
||
|
||
;HERE WHEN BOTH THE LC AND LS AREAS HAVE THE PAGE IN MEMORY THAT WE CARE
|
||
;ABOUT. NOW TO BLT THE FIRST PARTIAL PAGE OF SYMBOLS INTO THE LC AREA.
|
||
|
||
JBEXED: MOVE T3,LC.LB ;[1132] CALCULATE OFFSET FROM VIRTUAL
|
||
SUB T3,LW.S1 ;[1132] TO PHYSICAL ADDRESSES
|
||
HRRZ T1,JOB116 ;[1132] FIRST VIRTUAL ADDRESS TO WRITE
|
||
ADD T1,T3 ;[1132] FIRST PHYSICAL ADDRESS
|
||
HRL T1,LS.LB ;[1132] FROM START OF LS AREA
|
||
MOVE T2,P4 ;[1132] FIRST VIRTUAL ADDRESS NOT TO WRITE
|
||
ADD T2,T3 ;[1132] FIRST PHYSICAL ADDRESS
|
||
BLT T1,-1(T2) ;[1132] COPY THE SYMBOLS
|
||
|
||
JBEXEE:
|
||
> ;END IFN FTOVERLAY
|
||
|
||
;FALL INTO NEXT PAGE
|
||
;FALL IN FROM ABOVE
|
||
|
||
SKIPN PAG.S1 ;READY TO DUMP CORE, FIRST SEE IF PAGED?
|
||
JRST EXEINI ;NO, GO OPEN EXE FILE AND DUMP
|
||
;YES, IT'S PAGED. IF NEEDED, FIRST OUTPUT ALL, THEN TRY READ BACK ALL
|
||
;OF CORE FILE BACK INTO CORE (OR AS MUCH AS POSSIBLE).
|
||
SKIPE T1,LOWLOC ;[732] LOWEST LOCATION IN PAGE0?
|
||
JRST [CAMGE T1,LW.S1 ;[732] NO, OUT ON DISK?
|
||
JRST .+1 ;[732] YES, GO DO OUTPUT & READ
|
||
SUB T1,LW.S1 ;[1147] NO, FIND HOW FAR TO SHRINK
|
||
ADDM T1,LW.S1 ;[1147] MOVE VIRTUAL WINDOW UP
|
||
ADDM T1,LC.LB ;[1147] GIVE AWAY BOTTOM OF AREA
|
||
ADDM T1,DY.UB ;[1147] GIVE TO AREA JUST BELOW
|
||
JRST JBEXE1] ;[732]
|
||
MOVE T1,LW.S1 ;[2202] GET LOWER WINDOW
|
||
MOVE T2,UW.S1 ;[2202] TO UPPER
|
||
PUSHJ P,LC.OUT## ;OUTPUT IT ALL
|
||
MOVE T1,LOWLOC ;[762] GET LOWLOC PAGES INTO THE WINDOW
|
||
MOVEM T1,LW.S1 ;[762]
|
||
MOVE T1,DY.AB ;HIGHEST LOC WE CAN NOT USE
|
||
MOVEM T1,DY.UB ;TELL LNKCOR ABOUT IT
|
||
ADDI T1,1
|
||
MOVEM T1,LC.LB ;BACKUP IF WE CAN
|
||
SKIPN HC.S2 ;HOW ABOUT HIGH SEGMENT?
|
||
JRST JBEXEA ;NO HIGH SEG, JUMP
|
||
MOVE T2,HC.LB ;[2202] YES, HIGH SEG STILL EXISTS
|
||
SUBI T2,1 ;[2202] TOP OF LOW
|
||
MOVEM T2,LC.UB ;[2202] RESTORE POINTERS
|
||
JRST JBEXER ;GO MAKE PAGE BOUND AND CHECK ROOM
|
||
JBEXEA: SKIPN T2,LS.LB ;[2202] TO BOTTOM OF LS, IF IT'S THERE
|
||
SKIPA T2,.JBREL ;[2202] IF NOT, ALL OF CORE
|
||
SUBI T2,1
|
||
MOVEM T2,LC.UB ;[2202] RESERVE
|
||
JBEXER: SUB T2,LC.LB ;[2202] MAKE SURE
|
||
SUBI T2,777 ;[2202] WE ARE ON A PAGE BOUND
|
||
IORI T2,777 ;[2202] ...
|
||
ADD T2,LC.LB ;[2202] ADD IN BASE
|
||
MOVEM T2,LC.AB ;[2202] FOR CONSISTANCY
|
||
SUB T2,LC.LB ;[2202] MINUS WHAT WE ALREADY HAVE
|
||
MOVE T3,HC.S1 ;[762]
|
||
SUB T3,LOWLOC ;[762] GET ACTUALLY NEEDED LENGTH
|
||
IORI T3,777 ;[762]
|
||
MOVE T1,LW.S1 ;[2202] GET THE LOWER WINDOW BOUND
|
||
CAMGE T2,T3 ;[2202] COMPARE WHAT WE HAVE AND WHAT WE NEED
|
||
JRST [ADD T2,LW.S1 ;[2202] WE HAVE LESS THAN WE NEED
|
||
MOVEM T2,UW.S1 ;[2202] UPDATE UPPER WINDOW VALUE
|
||
PUSHJ P,LC.IN## ;[2202] READ IN AS MUCH AS WE CAN
|
||
JRST JBEXE1]
|
||
MOVE T2,T3 ;[2202] WE HAVE MORE THAN WE NEED
|
||
ADD T2,LW.S1 ;[2202] UPDATE UPPER WINDOW VALUE
|
||
MOVEM T2,UW.S1 ;[2202]
|
||
ADD T3,LC.LB ;[762] CAN CUT BACK LC.AB TO WHAT WE NEED
|
||
MOVEM T3,LC.AB ;TO SAVE TIME
|
||
PUSHJ P,LC.IN## ;READ WHAT WE CAN
|
||
PUSHJ P,LC.DLT ;DELETE FILE UNLESS .XPN WANTED
|
||
JBEXE1: SKIPN LW.LC ;[742] WE HAVE PAGE 0 IN CORE?
|
||
SKIPN JOBPTR ;[2043] DON'T BLT .JBDA IF ALREADY IN PLACE
|
||
CAIA ;[2043] DON'T GO TO BLTJDA IF JOBPTR IS ZERO
|
||
;[2043] OR PAGE 0 IS IN CORE
|
||
PUSHJ P,BLTJDA ;BLT .JBDA TO LOW SEG
|
||
|
||
; JRST EXEINI
|
||
>;[2247] IFE TOPS20
|
||
;HERE TO OPEN EXE FILE
|
||
|
||
;[2247] Note that on TOPS-20 the file is not opened, and two JFNs are
|
||
;[2247] returned, one in DC.JF and the other in T3.
|
||
|
||
EXEINI:
|
||
MOVEI T1,DC ;CHAN#
|
||
MOVEM T1,IO.CHN
|
||
MOVE T1,IO.PTR+%VC ;PSEUDO CHAN#
|
||
MOVEM T1,IO.PTR+DC ;INCASE OF ERROR
|
||
PUSHJ P,DVCHN.## ;T1 POINTS TO DATA BLOCK ON RETURN
|
||
MOVSI T2,(Z DC,) ;RESET CHAN # IN AC FIELD
|
||
MOVEM T2,I.CHN(T1) ;SINCE %VC IS THERE CURRENTLY
|
||
SKIPE T2,SSNAME ;GET REQUIRED NAME
|
||
JRST .+3 ;USUALLY ITS GIVEN
|
||
SKIPN T2,RUNAME ;IF NOT TRY /RUNAME
|
||
MOVE T2,LODNAM ;DEFAULT AS LAST RESORT
|
||
MOVEM T2,I.NAM(T1) ;SAVE IT
|
||
MOVE T2,SSEXT ;GET EXT AND FLAGS
|
||
HLLZM T2,I.EXT(T1) ;STORE EXT
|
||
IFE TOPS20,< ;[2247]
|
||
SETZM I.PRV(T1) ;MAKE THE CREATION DATE TODAY
|
||
MOVE T2,HC.S1 ;[744] GET HIGHEST LOW CORE TO SAVE
|
||
ADD T2,HC.S2 ;[744] PLUS THE HIGH CORE TO SAVE
|
||
LSH T2,-7 ;INTO BLOCKS
|
||
ADDI T2,7 ;[1132] 1 FOR REM, 4 FOR EXE DIR, 2 FOR RIBS
|
||
MOVEM T2,I.EST(T1) ;AT LEAST THIS IS ENOUGH
|
||
MOVE T2,VERNUM ;GET VERSION OF CORE IMAGE
|
||
SKIPN I.VER(T1) ;SKIP IF SET BY SWITCH
|
||
MOVEM T2,I.VER(T1) ;NO, SO SET IT
|
||
>;[2247] IFE TOPS20
|
||
PUSHJ P,DVOPN.## ;OPEN DEVICE
|
||
PUSHJ P,DVNAM.## ;MAKE SURE WE HAVE A NAME
|
||
MOVE T1,IO.CHN ;YES, NEED UPDATE MODE
|
||
PUSHJ P,DVUPD.## ;INCASE LARGE DIRECTORY
|
||
JRST E$$ECE ;[1174] CAN'T
|
||
IFN TOPS20,< ;[2202]
|
||
POPJ P, ;[1450] RETURN
|
||
E$$ECE::PUSH P,IO.CHN ;[2301] GIVE OFFENDING CHANNEL TO LNKLOG
|
||
.ERR. (LRE,.EC,V%L,L%F,S%F,ECE,<Error creating EXE file>) ;[2301]
|
||
.ETC. (NLN,.EC) ;[2301] CRLF
|
||
.ETC. (STR,,,,,ERRJSY) ;[2301] TYPE ERROR TEXT
|
||
> ;[2202] IFN TOPS20
|
||
IFE TOPS20,< ;[2202]
|
||
SKIPE IO.PTR+%XC ;WANT .XPN FILE?
|
||
SKIPE IO.PTR+LC ;BUT NOT PAGING
|
||
JRST XCMPRS ;GO WRITE OUT EXE
|
||
PUSHJ P,WRTXPN ;WRITE OUT XPN
|
||
; JRST XCMPRS
|
||
;HERE TO WRITE THE EXE FILE, COMPRESSING OUT ALL-ZERO PAGES
|
||
;USES ACS AS FOLLOWS:
|
||
;
|
||
;P1 FLAGS,,FILE PAGE
|
||
;P2 REPEAT COUNT,,PROCESS PAGE
|
||
;P3 ADDRESS WITHIN SEGMENT (PROCESS ADDRESS - LL.S0(R))
|
||
;P4 FLAGS TO DETERMINE WHAT TO DO WITH THE DIRECTORY ENTRY,,FILE PAGE COUNT
|
||
;
|
||
; ZEROF TO ZEROF : BUMP REPEAT COUNT
|
||
; ZEROF TO DATAF : WRITE OUT CURRENT DIR; START NEW DIR
|
||
; ZEROF TO GAPF : WRITE OUT DURRENT DIR
|
||
; DATAF TO ZEROF: WRITE OUT CURRENT DIR; START NEW DIR
|
||
; DATAF TO DATAF: BUMP REPEAT COUNT
|
||
; DATAF TO GAPF: WRITE OUT CURRENT DIR
|
||
; GAPF TO ZEROF/DATAF: IGNORE CURRENT ENTRY; START NEW DIR
|
||
; GAPF TO GAPF: IGNORE
|
||
;
|
||
;R INDEX TO SEGMENT EITHER 1 OR 2
|
||
;R2 POINTER TO RC BLOCK FOR CURRENT PSECT
|
||
;W1 STORE PTR
|
||
;W2 IOWD TO DATA NOT YET WRITTEN
|
||
;W3 IOWD LIST TERMINATOR (0)
|
||
|
||
ZEROF==1B0 ;[1132] LAST THING FOUND WAS A ZERO PAGE
|
||
DATAF==1B1 ;[1132] LAST THING FOUND WAS A NON-ZERO PAGE
|
||
GAPF==1B2 ;[1132] LAST THING FOUND WAS AN INTER-PSECT GAP
|
||
|
||
XCMPRS: SETZ R, ;[1132] START WITH .ABS.
|
||
MOVEM R,RC.CUR ;[1132] STORE CUURENT PSECT INDEX IN RC.CUR
|
||
MOVEI T1,1 ;[1132] CURRENT BLOCK OF EXE DIR
|
||
MOVEM T1,EXEBLK ;[1132] SAVE FOR XCMPXD
|
||
USETO DC,5 ;[1132] START WRITING DATA AT BLOCK 5
|
||
MOVEI P1,1 ;[1132] NEXT FILE PAGE TO WRITE IS 1
|
||
MOVE R2,@RC.TB ;[1132] POINTER TO RC BLOCK FOR .ABS.
|
||
MOVE R,RC.SG(R2) ;[1132] KEEP R POINTING TO SEGMENT INDEX
|
||
MOVE T1,RC.AT(R2) ;[1132] GET ITS PSECT ATTRIBUTES
|
||
TXNN T1,AT.RO ;[1132] READ-ONLY?
|
||
TXO P1,SV%WRT ;[1132] NO, LOWSEG IS USUALLY WRITABLE
|
||
SETZB P2,P3 ;[1132] CORE PAGE 0, CURRENT ADDR IS 0
|
||
MOVX P4,GAPF ;[1132] FLAG NO OLD EXE DIR ENTRY TO WRITE
|
||
MOVE R,RC.SG(R2) ;[1132] POINT TO AREA CONTAINING THIS PSECT
|
||
MOVSI W1,-1000 ;[1132] W1 IS AOBJN PTR TO COPY OF EXE DIR
|
||
HRR W1,EXEDIR ;[1132] BEING BUILT IN DY AREA
|
||
SETZB W2,W3 ;[1132] INIT IOWD
|
||
SKIPN JOBPTR ;[1532] IS JOBDAT STILL IN DY AREA?
|
||
JRST XCMLUP ;[1132] NO (NORMAL CASE), GO START WRITING
|
||
|
||
|
||
;FALL THROUGH TO NEXT PAGE
|
||
;FALL IN FROM ABOVE
|
||
|
||
;HERE IF THE LOWEST LOCATION IS IN PAGE 1 OR HIGHER, AND THE
|
||
;LC AREA IS PAGING TO DISK.
|
||
;IF THAT IS THE CASE, THEN JOBDAT IS IN A BLOCK IN THE DY AREA
|
||
;POINTED TO BY JOBPTR, INSTEAD OF IN THE LC AREA.
|
||
;WHAT WE WANT TO DO NOW IS WRITE JOBDAT INTO THE EXE FILE DIRECTLY
|
||
;FROM THE DY AREA, THEN JUMP INTO THE MAIN LOOP BELOW TO FINISH THE SAVE.
|
||
|
||
HRLOI W2,-.JBDA-1 ;[1132] FORM IOWD TO JOBDAT
|
||
ADD W2,JOBPTR ;[1132] ..
|
||
OUT DC,W2 ;[1132] WRITE JOBDAT TO THE EXE FILE
|
||
TXCA P4,DATAF!GAPF!1 ;[1132] CLEAR GAPF, SET DATAF, 1 PAGE WRITTEN
|
||
PUSHJ P,E$$EOE ;[1174] I/O ERROR
|
||
USETO DC,9 ;[1132] WRITE ZEROS INTO THE REST OF PAGE 0
|
||
SETZ W2, ;[1132] FLAG NO DATA TO WRITE
|
||
JRST XCMADP ;[1132] GO FIND NEXT PSECT
|
||
E$$ECE::PUSH P,IO.CHN ;[2052] GIVE OFFENDING CHANNEL TO LNKLOG
|
||
.ERR. (LRE,0,V%L,L%F,S%F,ECE,<Error creating EXE file>) ;[1174]
|
||
;THIS IS THE MAIN LOOP FOR THE EXE FILE WRITER.
|
||
;WE GET BACK HERE ON EACH NEW PSECT, ON EACH NEW BLOCK OF PAGES
|
||
;READ IN IF AN AREA HAS OVERFLOWED TO DISK, AND ON EACH PAGE OF
|
||
;EACH PSECT.
|
||
|
||
XCMLUP: SKIPE PAG.S0(R) ;[1132] AREA OVERFLOWING TO DISK
|
||
CAMG P3,UW.S0(R) ;[1132] AND OFF END OF WINDOW?
|
||
CAML P3,HC.S0(R) ;[1132] NO, BUT OFF END OF SEGMENT?
|
||
JRST XCMADV ;[1132] OFF END OF SOMETHING
|
||
MOVE T1,RC.HL(R2) ;[1132] FIRST ADDRESS BEYOND PSECT
|
||
SUB T1,LL.S0(R) ;[1132] CONVERT TO OFFSET IN SEGMENT, LIKE P3
|
||
CAML P3,T1 ;[1132] OFF END OF PSECT?
|
||
JRST XCMADV ;[1132] YES, GO FIND THE NEXT ONE
|
||
|
||
|
||
;TIME TO SAVE THE PAGE WHOSE ADDRESS IS IN P3. SEE IF IT'S ALL ZERO
|
||
|
||
MOVE T1,P3 ;[2356] OFFSET INTO SEGMENT
|
||
SUB T1,LW.S0(R) ;[1132] OFFSET INTO CURRENT WINDOW
|
||
ADD T1,TAB.LB(R) ;[1132] ADDRESS OF PAGE IN LINK'S VAS
|
||
SKIPN W2 ;[1132] KNOW BASE OF IOWD YET?
|
||
MOVEI W2,-1(T1) ;[1132] NO, SET IT UP NOW
|
||
HRLI T1,-1000 ;[1132] SET UP AN AOBJN PTR TO THE PAGE
|
||
SKIPN (T1) ;[1132] NEXT WORD ZERO?
|
||
AOBJN T1,.-1 ;[1132] YES, LOOP OVER ALL THE PAGES
|
||
JUMPGE T1,XCMZER ;[1132] JUMP IF PAGE IS ALL ZERO
|
||
|
||
|
||
;HERE WHEN THE PAGE IS NON-ZERO
|
||
|
||
TXON P4,DATAF ;[1132] FLAG IN REAL DATA, FIRST TIME?
|
||
JRST XCMNWD ;[1132] YES, START A NEW DIRECTORY ENTRY
|
||
ADD W2,[-1000,,0] ;[1132] NO, JUST BUMP OUTPUT IOWD
|
||
ADDI P4,1 ;[1132] REMEMBER DATA PAGES WRITTEN
|
||
ADD P2,[1B8] ;[1132] AND REPEAT COUNT FOR THIS ENTRY
|
||
TLNE P2,777000 ;[2356] OVERFLOW THE COUNT FIELD (1000 PAGES)?
|
||
JRST XCMLWD ;[2356] NO, OK
|
||
TLO P2,777000 ;[2356] YES, SET COUNT TO 1000 PAGES
|
||
TXO P4,ZEROF ;[2356] SET FLAG SO PAGE NUMBER WILL GO OUT
|
||
PUSHJ P,XCMPRD ;[2356] WRITE A DIRECTORY ENTRY
|
||
TXZ P4,ZEROF ;[2356] RESET FLAG
|
||
HRRZI P2,1000(P2) ;[2356] RESET COUNT, ACCOUNT FOR 1000 PAGES
|
||
ADDI P1,1000 ;[2356] ACCOUNT FOR 1000 PAGES IN FILE
|
||
XCMLWD: JUMPL W2,XCMADP ;[2356] ADVANCE IF IOWD HAS NOT OVERFLOWED
|
||
SUB W2,[-1000,,0] ;[1314] REDUCE IOWD
|
||
OUT DC,W2 ;[1314] WRITE 177 PAGES OF EXE FILE
|
||
MOVEI W2,-1(P3) ;[1314] OFFSET INTO SEGMENT - 1
|
||
SUB W2,LW.S0(R) ;[1314] OFFSET INTO CURRENT WINDOW
|
||
ADD W2,TAB.LB(R) ;[1314] ADDRESS OF PAGE IN LINK'S VAS
|
||
HRLI W2,-1000 ;[1314] FINISH IOWD FOR ONE PAGE
|
||
JRST XCMADP ;[1132] ADVANCE TO THE NEXT PAGE
|
||
|
||
XCMNWD: TXZ P4,ZEROF ;[1132] NO LONGER IN A ZERO AREA
|
||
TXZN P4,GAPF ;[1132] WERE WE IN A GAP?
|
||
PUSHJ P,XCMPRD ;[1132] NO, WRITE DIR ENTRY OUT
|
||
MOVE W2,P3 ;[2356] START A NEW IOWD
|
||
SUB W2,LW.S0(R) ;[1132] MAKE ADDR INTO OFFSET FROM WINDOW START
|
||
ADD W2,TAB.LB(R) ;[1132] AND THENCE TO ADDR IN LINK
|
||
SUB W2,[1000,,1] ;[1132] CONVERT TO ONE PAGE IOWD
|
||
MOVE P2,P3 ;[1132] COMPUTE NEW PROCESS PAGE
|
||
ADD P2,LL.S0(R) ;[1132] BY FINDING PROCESS ADDRESS
|
||
LSH P2,-9 ;[1132] THEN SHIFTING TO GET A PAGE NUMBER
|
||
ADDI P4,1 ;[1132] WILL WRITE 1 MORE DATA PAGE
|
||
JRST XCMADP ;[1132] GO ADVANCE TO NEXT PAGE
|
||
;HERE ON AN ALL-ZERO PAGE
|
||
|
||
XCMZER: TXON P4,ZEROF ;[1132] IS THIS THE FIRST ALL-ZERO PAGE?
|
||
JRST XCMNWZ ;[1132] YES, GO SETUP A NEW DIR ENTRY
|
||
ADD P2,[1B8] ;[1132] JUST BUMP REPEAT COUNT
|
||
TLNE P2,777000 ;[2356] OVERFLOW THE COUNT FIELD (1000 PAGES)?
|
||
JRST XCMADP ;[2356] NO, ADVANCE TO THE NEXT PAGE
|
||
TLO P2,777000 ;[2356] YES, SET COUNT TO 1000 PAGES
|
||
TXZ P4,ZEROF ;[2356] TURN OFF ZEROF SO PAGE WILL BE ZEROED
|
||
PUSHJ P,XCMPRD ;[2356] WRITE A DIRECTORY ENTRY
|
||
TXO P4,ZEROF ;[2356] SET THE FLAG AGAIN
|
||
HRRZI P2,1000(P2) ;[2356] RESET COUNT, ACCOUNT FOR 1000 PAGES
|
||
JRST XCMADP ;[1132] ADVANCE TO THE NEXT PAGE
|
||
|
||
|
||
;HERE IF THE ALL-ZERO PAGE IS THE FIRST ONE AFTER DATA OR A GAP.
|
||
;IF DATA, WRITE IT OUT AND STORE THE DIR ENTRY. ALWAYS SET UP A NEW ENTRY.
|
||
|
||
XCMNWZ: TXZ P4,DATAF ;[1132] NO LONGER WRITING DATA
|
||
TXZN P4,GAPF ;[1132] NOT IN A GAP. WERE WE?
|
||
PUSHJ P,XCMPRD ;[1132] NO, WRITE THE DATA DIR ENTRY
|
||
ADDI P1,(P4) ;[1132] BUMP FILE PAGE COUNT
|
||
HLLZS P4 ;[1132] CLEAR ACCUMULATED COUNT
|
||
SKIPGE W2 ;[1132] SEEN ANY DATA PAGES?
|
||
OUT DC,W2 ;[1132] YES, WRITE THEM
|
||
TDZA W2,W2 ;[1132] SUCCESS, CLEAR IOWD
|
||
JRST E$$EOE ;[1174] I/O ERROR
|
||
MOVE P2,P3 ;[1132] SET UP NEW PROCESS PAGE
|
||
ADD P2,LL.S0(R) ;[1132] BY COMPUTING PROCESS ADDRESS
|
||
LSH P2,-9 ;[1132] THEN SHIFTING TO A PAGE NUMBER
|
||
|
||
|
||
;HERE TO ADVANCE TO THE NEXT PAGE.
|
||
|
||
XCMADP: ADDI P3,1000 ;[1132] POINT TO NEXT PAGE
|
||
JRST XCMLUP ;[1132] LOOP BACK TO PROCESS IT
|
||
|
||
;HERE WHEN WE RAN OFF THE END OF THE PSECT, THE SEGMENT, OR THE WINDOW.
|
||
;FIGURE OUT WHAT TO PROCESS NEXT.
|
||
|
||
XCMADV: SKIPGE W2 ;[1132] ANY DATA STILL TO WRITE?
|
||
OUT DC,W2 ;[1132] YES, WRITE IT
|
||
TDZA W2,W2 ;[1132] SUCCESS, CLEAR IOWD POINTER
|
||
JRST E$$EOE ;[1174] I/O ERROR
|
||
CAML P3,HC.S0(R) ;[1132] OFF THE END OF THE SEGMENT?
|
||
JRST XCMBLK ;[1132] YES, GO WRITE ABZ PAGES AND ADVANCE
|
||
CAML P3,RC.HL(R2) ;[1132] OFF END OF PSECT?
|
||
JRST XCMNXP ;[1132] YES, GO FIND THE NEXT ONE
|
||
|
||
|
||
;HERE IF PAGING AND WE RAN OFF THE END OF THE CURRENT LC/HC WINDOW.
|
||
;ADVANCE THE WINDOW AND LOOP BACK.
|
||
|
||
MOVEM P3,LW.S0(R) ;[1132] STORE NEW LOWER WINDOW BOUND
|
||
MOVE T2,P3 ;[2202] VIRTUAL ADDRESS OF 1ST WORD TO READ
|
||
ADD T2,TAB.AB(R) ;[2202] CONVERT TO VIRTUAL ADDRESS OF LAST WORD
|
||
SUB T2,TAB.LB(R) ;[2202] BY ADDING SIZE OF LC/HC AREA
|
||
MOVEM T2,UW.S0(R) ;[2202] STORE NEW UPPER WINDOW BOUND
|
||
CAMGE T2,HC.S0(R) ;[2202] DOES THE AREA CONTAIN THAT MUCH?
|
||
JRST XCMRED ;[1132] YES, JUST GO READ IT IN
|
||
SUB T2,HC.S0(R) ;[2202] NO, FIGURE OUT HOW MUCH EXTRA WE HAVE
|
||
ADDI T2,1 ;[2202] SUBTRACTED ONE TOO MUCH, HC IS FF FORMAT
|
||
ANDCMI T2,.IPM ;[2202] PUT ON THE PAGE BOUND
|
||
MOVN T2,T2 ;[2202] DECREMENT THE AB OF THE AREA
|
||
ADDM T2,TAB.AB(R) ;[2202] SO EXTRA SPACE IS AVAILABLE TO OTHERS
|
||
ADDM T2,UW.S0(R) ;[2202] AREN'T GOING TO READ THAT MUCH AFTER ALL
|
||
MOVE T2,UW.S0(R) ;[2202] LAST ADDRESS TO READ
|
||
XCMRED: MOVE T1,P3 ;[2202] GET LOWER BOUND
|
||
PUSHJ P,@TB.IN(R) ;[2202] READ IN THE NEXT WINDOW
|
||
JRST XCMLUP ;[1132] LOOP BACK TO PROCESS THE NEXT PAGE
|
||
;HERE IF WE RAN OFF THE END OF THIS SEGMENT (LC OR HC). WRITE ENOUGH
|
||
;ALLOCATED BUT ZERO PAGES INTO THE EXE DIRECTORY TO ALLOCATE THE REST
|
||
;OF THE CURRENT PSECT AS ALL ZEROS.
|
||
|
||
XCMBLK: MOVE R3,RC.HL(R2) ;[1132] GET FIRST WORD BEYOND PSECT END
|
||
ADDI R3,777 ;[1132] LAST WORD TO ALLOCATE + A PAGE
|
||
ANDCMI R3,777 ;[1132] GET START OF THAT PAGE
|
||
SUB R3,P3 ;[1132] COMPUTE EXTRA PAGES THAT NEED ALLOCATING
|
||
SUB R3,LL.S0(R) ;[1132] P3 IS AN OFFSET, BUT R3 IS AN ADDRESS
|
||
JUMPLE R3,XCMNXP ;[1132] NONE, GO FIND THE NEXT PSECT TO PROCESS
|
||
TXON P4,ZEROF ;[1132] WERE WE WRITING ZEROS BEFORE THIS?
|
||
JRST XCMBL2 ;[1132] NO, MUST START A NEW DIR ENTRY
|
||
ADD P3,R3 ;[1132] KEEP OFFSET INTO SEGMENT CORRECT
|
||
JRST XCMBL3 ;[2356] GO SET UP COUNT
|
||
|
||
;HERE WHEN WE WANT TO WRITE AN ABZ DIRECTORY ENTRY, BUT WE HAVE ANOTHER
|
||
;TYPE OF ENTRY IN PROGRESS. WRITE THE CURRENT ENTRY, THEN START A NEW ONE.
|
||
|
||
XCMBL2: TXZ P4,DATAF ;[1132] REMEMBER NO LONGER WRITING DATA
|
||
TXZN P4,GAPF ;[1132] WERE WE IN A GAP?
|
||
PUSHJ P,XCMPRD ;[1132] NO, WRITE THE DIRECTORY ENTRY
|
||
ADDI P1,(P4) ;[1132] BUMP FILE PAGE POINTER
|
||
HLLZS P4 ;[1132] RESET FILE PAGE COUNT
|
||
MOVE P2,P3 ;[1132] FIRST OFFSET TO WRITE
|
||
ADD P2,LL.S0(R) ;[1132] FIRST ADDRESS TO WRITE
|
||
LSH P2,-^D9 ;[1132] FIRST PAGE NOT YET WRITTEN
|
||
ADD P3,R3 ;[1132] KEEP OFFSET INTO SEGMENT CORRECT
|
||
XCMBL3: HLRZ T1,P2 ;[2356] GET THE CURRENT COUNT
|
||
ADD R3,T1 ;[2356] ADD NEW COUNT
|
||
XCMBL1: HRLI P2,-1000(R3) ;[2370] PUT COUNT IN EXE DIRECTORY
|
||
TLNN R3,-1 ;[2356] MORE THAN ONE SECTION?
|
||
JRST XCMNXP ;[2356] NO, GO PROCESS THE NEXT PSECT
|
||
HRLI P2,777000 ;[2356] SET MAXIMUM REPEAT COUNT
|
||
TXZ P4,ZEROF ;[2356] TELL THE EXE FILE WRITER TO ZERO ENTRY
|
||
PUSHJ P,XCMPRD ;[2356] WRITE THE DIRECTORY
|
||
TXO P4,ZEROF ;[1132] RESET INCORRECT FLAG
|
||
ADDI P2,1000 ;[2356] UPDATE PAGE NUMBER
|
||
SUB R3,[1,,0] ;[2356] CORRECT THE COUNT
|
||
JRST XCMBL1 ;[2356] TRY AGAIN (MAY NEED SEVERAL
|
||
|
||
;HERE TO ADVANCE TO THE NEXT PSECT, IF ANY
|
||
|
||
XCMNXP: PUSHJ P,ADVPSC ;[1132] CALL A SUBROUTINE TO DO THE WORK
|
||
JRST XCMPRX ;[1132] ALL DONE, GO CLOSE THE FILE
|
||
JRST XCMLUP ;[1132] FOUND ANOTHER PSECT, LOOP BACK FOR IT
|
||
;ADVPSC -- SUBROUTINE TO ADVANCE TO THE NEXT PSECT.
|
||
;CALL:
|
||
; SET UP P1-P4 AS IN XCMPRS
|
||
; PUSHJ P,ADVPSC
|
||
; ALL DONE
|
||
; ANOTHER PSECT FOUND
|
||
;
|
||
;ON THE SKIP RETURN, P1-P4 HAVE BEEN SET UP TO POINT TO THE START OF
|
||
;THE NEXT PSECT, INCLUDING PSECT PROPERTIES IN P1.
|
||
;THIS ROUTINE ALSO CHECKS TO SEE IF THE OVERLAY SYMBOL TABLE NEEDS TO
|
||
;BE APPENDED AFTER THE PSECT OR SEGMENT THAT JUST GOT WRITTEN, AND
|
||
;APPENDS IT IF SO.
|
||
|
||
|
||
ADVPSC:
|
||
IFN FTOVERLAY,<
|
||
CAIN R,1 ;[1132] IN LOW SEGMENT?
|
||
CAMGE P3,HL.S1 ;[1132] AND JUST FINISHED IT?
|
||
JRST ADVPS1 ;[1132] NO, PROCEED
|
||
SKIPL LNKMAX ;[1132] YES, LOADING OVERLAYS?
|
||
SKIPN JOB116 ;[1132] AND SYMBOLS NEED INSERTING?
|
||
JRST ADVPS1 ;[1132] NO, PROCEED
|
||
PUSHJ P,XCMPOV ;[1132] YES, PUT SYMBOLS INTO EXE FILE
|
||
ADVPS1:
|
||
> ;END IFN FTOVERLAY
|
||
|
||
ADD P3,LL.S0(R) ;[1132] P3 WILL BE AN ADDRESS FOR THIS ROUTINE
|
||
AOS R,RC.CUR ;[1132] GET PSECT INDEX OF NEXT PSECT
|
||
CAMG R,RC.NO ;[1132] IS THERE A NEXT ONE?
|
||
JRST ADVPS2 ;[1132] YES, GO PROCESS IT
|
||
SOS (P) ;[1132] GIVE NON-SKIP RETURN
|
||
JRST ADVPS6 ;[1132] BUT WRITE CURRENT ENTRY FIRST
|
||
|
||
|
||
;HERE WHEN THERE IS ANOTHER PSECT, AND R CONTAINS ITS INDEX.
|
||
;POINT R AND R2 TO IT, THEN SET UP ITS PSECT PROPERTIES IN R3
|
||
|
||
ADVPS2: MOVE R2,@RC.TB ;[1132] POINT TO RC BLOCK FOR PSECT
|
||
MOVE R,RC.SG(R2) ;[1132] PUT SEGMENT PSECT IS IN INTO R
|
||
MOVX R3,SV%WRT ;[1132] GET ASSUMED PSECT PROPERTY
|
||
MOVE T1,RC.AT(R2) ;[1132] GET REAL PSECT PROPERTIES
|
||
TXNE T1,AT.RO ;[1132] EXPLICITLY READ-ONLY?
|
||
TXZ R3,SV%WRT ;[1132] YES, CLEAR WRITE BIT
|
||
CAIE R,2 ;[1132] IS THIS THE HIGH SEGMENT?
|
||
JRST ADVPS4 ;[1132] NO, PSECT PROPERTIES OK AS THEY ARE
|
||
TXO R3,SV%HIS ;[1132] TOPS-10 HIGH SEG, READ-ONLY
|
||
TXNN T1,AT.RW ;[1132] EXPLICITLY WRITE-ENABLED?
|
||
TXZ R3,SV%WRT ;[1132] NO, WRITE-LOCK IT
|
||
MOVE T1,SSEXT ;[1132] GET SAVE/SSAVE FLAGS
|
||
TXNE T1,SS.SHR ;[1132] USER TYPE /SSAVE?
|
||
TXO R3,SV%SHR ;[1132] /SSAVE OR TOPS-20, MARK SHARABLE
|
||
|
||
;FALL INTO NEXT PAGE
|
||
;HERE WHEN PSECT PROPERTIES COMPUTED IN R3.
|
||
;NOW DETERMINE WHETHER TO STORE THIS DIRECTORY ENTRY AND START ANOTHER,
|
||
;OR TO JUST LET THIS ONE CONTINUE.
|
||
;CAN ONLY LET THIS ONE CONTINUE IF NEXT PSECT IS ADJACENT WITH SAME PROPERTIES.
|
||
|
||
ADVPS4: MOVE T1,RC.IV(R2) ;[1132] GET BOTTOM OF NEW PSECT
|
||
ANDCMI T1,777 ;[1132] ROUND DOWN TO PAGE BOUND
|
||
CAMLE T1,P3 ;[1132] IS THERE A PSECT GAP HERE?
|
||
JRST [MOVE P3,T1 ;[1132] YES, START NEXT LOOP AT BASE OF NEW ONE
|
||
JRST ADVPS6] ;[1132] AND GO DUMP THIS DIRECTORY ENTRY
|
||
MOVE T2,R3 ;[1132] COPY OF PSECT PROPERTIES
|
||
XOR T2,P1 ;[1132] COMPARE WITH OLD
|
||
TXNN T2,777B8 ;[1132] SAME AS LAST TIME?
|
||
JRST ADVPS8 ;[1132] YES, CAN CONTINUE CURRENT DIR ENTRY
|
||
|
||
|
||
;ENTER HERE IF ALL DONE TO WRITE OUT THE LAST DIRECTORY ENTRY AND RETURN.
|
||
|
||
ADVPS6: TXC P4,DATAF!ZEROF ;[1132] XCMPRD WANTS THE FLAGS REVERSED
|
||
TXNN P4,GAPF ;[1132] IN A GAP FROM LAST TIME?
|
||
PUSHJ P,XCMPRD ;[1132] NO, WRITE CURRENT DIR ENTRY
|
||
ADDI P1,(P4) ;[1132] BUMP FILE PAGE COUNT
|
||
MOVX P4,GAPF ;[1132] FLAG NOW IN A GAP, CLEAR RH P4
|
||
ADVPS8: SUB P3,LL.S0(R) ;[1132] MAKE P3 AN OFFSET INTO NEW SEGMENT
|
||
TXZ P1,777B8 ;[1132] CLEAR OLD PSECT PROPERTIES
|
||
IOR P1,R3 ;[1132] SET NEW PSECT PROPERTIES
|
||
JRST CPOPJ1 ;[1132] GIVE GOOD RETURN TO CALLER
|
||
;HERE TO WRITE OUT A DIRECTORY ENTRY
|
||
|
||
XCMPRD: PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
|
||
MOVEM P1,(W1) ;STORE DIRECTORY PTRS
|
||
TXNN P4,ZEROF ;[1132] ZERO PAGE? (FLAGS ALREADY CHANGED)
|
||
HLLZS (W1) ;YES, SO NO FILE PAGES
|
||
PUSHJ P,XCMPXD ;SECOND WORD
|
||
MOVEM P2,(W1) ;[1132]
|
||
POPJ P, ;[1132]
|
||
;HERE TO ALLOCATE A DIRECTORY ENTRY IF SUFFICIENT ROOM EXISTS.
|
||
;IF NOT, EXTEND THE FILE BY ONE PAGE TO MAKE ROOM FOR ANOTHER
|
||
;PAGE OF DIRECTORY.
|
||
|
||
XCMPXD: AOBJN W1,CPOPJ ;ALLOCATE IF ENOUGH ROOM
|
||
|
||
|
||
;WRITE THE CURRENT PAGE OF THE EXE DIRECTORY TO DISK.
|
||
;THEN START FROM THE FRONT OF THE FILE, AND FIX ALL PAGES OF
|
||
;EXE DIRECTORY PRESENT, INCLUDING THE ONE WE JUST WROTE.
|
||
|
||
HRLOI T3,-1000-1 ;[1132] FORM IOWD TO IN CORE EXE DIRECTORY
|
||
ADD T3,EXEDIR ;[1132] ..
|
||
SETZ T4, ;[1132] TERMINATE IO LIST
|
||
USETO DC,@EXEBLK ;[1132] SET TO LATEST EXE DIRECTORY BLOCK
|
||
OUT DC,T3 ;[1132] WRITE THE DIRECTORY
|
||
CAIA ;[1132] SUCCESS
|
||
JRST E$$EOE ;[1174] IO ERROR
|
||
MOVEI W1,1 ;[1132] NOW LOOP OVER DIR, STARTING AT BLOCK 1
|
||
XCMPXE: USETI DC,@W1 ;[1132] SET ON NEXT PAGE OF EXE DIR
|
||
IN DC,T3 ;[1132] READ IT INTO SCRATCH PAGE
|
||
CAIA ;[1132] OK
|
||
JRST E$$EOE ;[1174] FAILED
|
||
MOVE T2,EXEDIR ;[1132] NOW SETUP AOBJN PTR TO EXE DIR PAGE
|
||
HRLI T2,-400 ;[1132] COUNT OF DIR ENTRIES THIS PAGE
|
||
XCMPXF: MOVE T1,1(T2) ;[1132] GET 1ST WORD OF NEXT ENTRY
|
||
TRNE T1,-1 ;[1132] AN ABZ POINTER?
|
||
AOS 1(T2) ;[1132] NO, BUMP THE FILE PAGE NUMBER
|
||
ADDI T2,1 ;[1132] SKIP 2ND WORD OF THIS DIR ENTRY
|
||
AOBJN T2,XCMPXF ;[1132] LOOP OVER THE ENTIRE PAGE
|
||
USETO DC,@W1 ;[1132] POINT TO WHERE WE GOT THE PAGE
|
||
OUT DC,T3 ;[1132] PUT IT BACK, SLIGHTLY MODIFIED
|
||
CAIA ;[1132] OK
|
||
JRST E$$EOE ;[1174] I/O ERROR
|
||
ADDI W1,4 ;[1132] BLOCK NUMBER OF NEXT PAGE
|
||
CAMG W1,EXEBLK ;[1132] MORE DIRECTORY PAGE(S) TO PROCESS?
|
||
JRST XCMPXE ;[1132] YES, PROCESS THEM
|
||
MOVEM W1,EXEBLK ;[1132] PAGE WE'RE FREEING UP FOR MORE DIRECTORY
|
||
;FALL IN FROM ABOVE
|
||
|
||
;NOW TO LOOP OVER THE FILE BACKWARDS, MOVING ALL OF THE DATA PAGES
|
||
;ONE PAGE HIGHER.
|
||
|
||
MOVEI W1,-1(P1) ;[1132] LAST PAGE WRITTEN
|
||
ADDI W1,0(P4) ;[1132] PLUS ANY FOUND IN THIS DIR ENTRY
|
||
ASHC W2,-^D27 ;[1132] NEED TO LOOK AT IOWD, SINCE PAGES
|
||
ADD W1,W2 ;[1132] IT POINTS TO HAVEN'T BEEN WRITTEN
|
||
ASHC W2,^D27 ;[1132] RESET IOWD TO PREVIOUS VALUE
|
||
SETZ W3, ;[1132] CLEAR SIGN BIT LEFT FROM ASHC
|
||
LSH W1,2 ;[1132] CONVERT PAGE TO BLOCK NUMBET
|
||
ADDI W1,1 ;[1132] BLOCK NUMBERS START AT 1
|
||
MOVEI T2,10(W1) ;[1132] REMEMBER NEXT BLOCK TO WRITE FOR LATER
|
||
XCMPXG: CAMGE W1,EXEBLK ;[1132] ANY DATA PAGES LEFT TO COPY?
|
||
JRST XCMPXH ;[1132] NO, GO FINISH UP
|
||
USETI DC,@W1 ;[1132] POINT TO NEXT DATA PAGE
|
||
IN DC,T3 ;[1132] READ IT
|
||
CAIA ;[1132] OK
|
||
JRST E$$EOE ;[1174] ERROR
|
||
OUT DC,T3 ;[1132] WRITE IT INTO THE NEXT PAGE
|
||
CAIA ;[1132] OK
|
||
JRST E$$EOE ;[1174] ERROR
|
||
SUBI W1,4 ;[1132] BACK UP ONE MORE DATA BLOCK
|
||
JRST XCMPXG ;[1132] LOOP OVER ALL DATA PAGES
|
||
|
||
;HERE WHEN THE DIRECTORY AND THE FILE HAVE BEEN UPDATED.
|
||
;FIX THE POINTERS THAT OUR CALLERS LOOK AT, THEN RETURN.
|
||
|
||
XCMPXH:
|
||
USETO DC,@T2 ;[1132] NEXT WRITE TO NEXT FREE BLOCK
|
||
ADDI P1,1 ;[1132] THIS DIR ENTRY IS ONE OFF TOO
|
||
MOVE W1,EXEDIR ;[1132] RESET DIR AOBJN PTR FOR NEXT CALL
|
||
HRLI W1,-1000 ;[1132] SET UP COUNT FOR INITIAL AOBJN
|
||
HRLZ T1,W1 ;[1132] NOW ZERO THE DY AREA BLOCK
|
||
HRRI T1,1(W1) ;[1132] ..
|
||
SETZM 0(W1) ;[1132] ..
|
||
BLT T1,777(W1) ;[1132] ..
|
||
POPJ P, ;[1132] RETURN TO CALLER
|
||
IFN FTOVERLAY,<
|
||
|
||
;HERE WHEN GENERATING AN EXE FILE FOR THE ROOT OF AN OVERLAID PROGRAM,
|
||
;AND IT IS TIME TO INSERT THE LOCAL SYMBOLS FROM THE LS AREA INTO THE
|
||
;EXE FILE. ALL ZEROS BEFORE THE SYMBOLS AND THE FIRST PARTIAL PAGE OF
|
||
;SYMBOLS HAVE ALREADY BEEN COPIED INTO THE EXE FILE, SINCE THEY WERE
|
||
;PUT INTO THE LC AREA AT JBEXE.
|
||
|
||
XCMPOV: HRRZ T1,JOB116 ;[1132] SYMBOLS ARE NOT PAGE ALIGNED IN LS
|
||
ANDI T1,777 ;[1132] SO PUT OFFSET TO FIRST SYM IN R3
|
||
MOVEI R3,1000 ;[1132] OFFSET IS REST OF PAGE NOT COPIED
|
||
SUB R3,T1 ;[1132] AT JBEXE
|
||
SETZB R2,P3 ;[1132] ASSUME LS AREA ISN'T PAGING
|
||
SKIPN PAG.LS ;[1132] IS THE LS AREA PAGING?
|
||
JRST XOVDMP ;[1132] NO, JUST DUMP IT TO THE EXE FILE
|
||
MOVE T2,LW.LS ;[2202] CALCULATE UPPER WINDOW
|
||
ADD T2,LS.AB ;[2202] FROM LOWER WINDOW + SIZE
|
||
SUB T2,LS.LB ;[2202] SO WE CAN WRITE OUT CURRENT LS AREA
|
||
MOVEM T2,UW.LS ;[2202] SAVE IT IN CASE IT WAS -1
|
||
MOVE T1,LW.LS ;[2202] FIRST ADDRESS FOR LS.OUT
|
||
PUSHJ P,LS.OUT## ;[2202] UPDATE THE DISK COPY
|
||
PUSHJ P,FR.CNT## ;[1132] SEE HOW MUCH ROOM IS LEFT
|
||
MOVE T2,LSYM ;[1132] COUNT OF WORDS IN THE LS AREA
|
||
SUBI T2,1 ;[1132] CONVERT FIRST FREE TO LAST USED
|
||
IORI T2,777 ;[1132] ROUND UP TO PAGE END
|
||
MOVE T3,LS.AB ;[1132] FIND CURRENT SIZE OF LS AREA
|
||
SUB T3,LS.LB ;[1132] AS END - START
|
||
CAMG T2,T3 ;[1132] IS AREA BIG ENOUGH?
|
||
JRST XOVNXW ;[1132] YES, JUST DUMP IT TO THE FILE
|
||
SUB T2,T3 ;[1132] EXTRA WE NEED
|
||
CAMLE T1,T2 ;[1132] LESS THAN WE HAVE?
|
||
MOVE T1,T2 ;[1132] YES, DON'T ASK FOR MORE THAN WE NEED
|
||
SETOM LS.PP ;[1132] DON'T PAGE THE LS AREA TO SATISFY THIS
|
||
SPUSH <P1,P2> ;[1132] SAVE CURRENT EXE DIR ENTRY
|
||
MOVEI P1,LS.IX ;[1132] EXPAND THE LS AREA
|
||
MOVE P2,T1 ;[1132] BY THIS MUCH
|
||
PUSHJ P,LNKCOR## ;[1132] GO SHUFFLE
|
||
PUSHJ P,E$$MMF## ;[2202] FR.CNT LIED!!
|
||
SPOP <P2,P1> ;[1132] RESTORE THE SACRED COWS
|
||
SETZM LS.PP ;[1132] LS AREA CAN PAGE NOW
|
||
|
||
;FALL INTO NEXT PAGE
|
||
;FALL IN FROM ABOVE
|
||
|
||
;HERE WHEN THE LS AREA IS PAGING TO BRING THE NEXT WINDOW OF SYMBOLS
|
||
;IN TO BE WRITTEN TO THE EXE FILE. P3 HAS THE FIRST ADDRESS TO READ IN
|
||
;STORED IN IT, AND WE WILL PUT THE COUNT OF HOW FAR THIS PASS FAILED TO
|
||
;FINISH BY IN R2.
|
||
|
||
XOVNXW: MOVEM P3,LW.LS ;[1132] INIT LOWER WINDOW
|
||
ADD P3,LS.AB ;[1132] NOW COMPUTE UPPER WINDOW
|
||
SUB P3,LS.LB ;[1132] AS LOWER+SIZE
|
||
MOVEM P3,UW.LS ;[1132] STORE FOR LS.IN
|
||
ANDCMI P3,777 ;[1132] FIRST TO READ NEXT TIME
|
||
MOVE R2,LSYM ;[1132] END OF SYMBOLS
|
||
SUBI R2,1 ;[1132] LAST WORD CONTAINING SYMBOLS
|
||
IORI R2,777 ;[1132] THE END OF THAT PAGE
|
||
SUB R2,UW.LS ;[1132] FIND OUT HOW FAR YET TO GO
|
||
JUMPGE R2,XOVNX2 ;[1132] ALL OK UNLESS THIS TIME WILL END IT
|
||
ADDM R2,LS.AB ;[1132] REDUCE SIZE OF WINDOW
|
||
ADDM R2,UW.LS ;[1132] AND LAST ADDRESS IN WINDOW
|
||
XOVNX2: MOVE T1,LW.LS ;[2202] SET UP LOWEST
|
||
MOVE T2,UW.LS ;[2202] AND HIGHEST FOR LS.IN
|
||
PUSHJ P,LS.IN## ;[1132] READ IN THE NEXT BLOCK OF SYMBOLS
|
||
JUMPLE R2,XOVDMP ;[1132] IF LAST TIME, WRITE ALL OF LS AREA
|
||
MOVE T1,UW.LS ;[1132] NOT LAST TIME, ONLY WRITE THROUGH
|
||
ANDCMI T1,777 ;[1132] FIRST PART OF LAST PAGE
|
||
TROA T1,R3 ;[1132] WILL GET REST OF THAT PAGE NEXT PASS
|
||
XOVDMP: MOVE T1,LSYM ;[1132] LAST TIME, WRITE THROUGH THE END
|
||
MOVE W2,LW.LS ;[1132] PUT IOWD TO SYMBOLS TO WRITE IN W2
|
||
ADD W2,R3 ;[1132] DON'T START AT BEGINNING OF LS
|
||
SUB W2,T1 ;[1132] -COUNT IS FIRST-LAST
|
||
HRLZ W2,W2 ;[1132] -COUNT,,0
|
||
HRR W2,LS.LB ;[1132] -COUNT,,BOTTOM OF LS AREA
|
||
ADDI W2,-1(R3) ;[1132] BUT DON'T START WRITING AT START
|
||
OUT DC,W2 ;[1132] WRITE THE SYMBOLS
|
||
TDZA W2,W2 ;[1132] CLEAR W2 AGAIN IN CASE DONE
|
||
JRST E$$EOE ;[1174] I/O ERROR
|
||
JUMPG R2,XOVNXW ;[1132] IF NOT DONE, LOOP BACK TO TRY AGAIN
|
||
SKIPE PAG.LS ;[1132] ALL DONE, ANY TEMP FILE?
|
||
PUSHJ P,LS.DLT ;[1132] YES, DELETE IT
|
||
PUSHJ P,LS.ZAP ;[1132] ALL DONE WITH LS AREA
|
||
|
||
;FALL INTO NEXT PAGE
|
||
;FALL IN FROM ABOVE
|
||
|
||
;NOW THAT THE DATA HAS BEEN WRITTEN, UPDATE THE EXE DIRECTORY TO
|
||
;REFLECT THE CHANGE. ALSO ZERO THE REST OF THE LAST PAGE WITH A USETO.
|
||
|
||
HRRZ R3,JOB116 ;[1132] START OF SYMBOL TABLE
|
||
HLRE T1,JOB116 ;[1132] - COUNT
|
||
SUB R3,T1 ;[1132] FIRST WORD BEYOND TABLE
|
||
ADDI R3,777 ;[1132] ROUND UP TO NEXT PAGE BOUND
|
||
ANDCMI R3,777 ;[1132] FIRST PAGE NOW FREE
|
||
HRRZ P3,JOB116 ;[1132] FIRST WORD WRITTEN
|
||
ADDI P3,777 ;[1132] ROUND UP TO PAGE BOUND
|
||
ANDCMI P3,777 ;[1132] SO WE DON'T COUNT SYMS WRITTEN AT JBEXE
|
||
SUB R3,P3 ;[1132] R3 NOW HAS COUNT OF WORDS WRITTEN HERE
|
||
HRRZ T1,P1 ;[1132] FIRST DISK PAGE FREE BEFORE XCMPOV
|
||
ADDI T1,(P4) ;[1132] ACCOUNT FOR EXTRA OUTS DONE
|
||
MOVE R2,R3 ;[1132] NUMBER OF WORDS WRITTEN HERE
|
||
LSH R2,-^D9 ;[1132] NUMBER OF PAGES WE ADDED TO THE EXE FILE
|
||
|
||
ADD T1,R2 ;[1132] NEW FIRST FREE = OLD + COUNT
|
||
LSH T1,2 ;[1132] CONVERT TO BLOCKS FOR USETO
|
||
USETO DC,1(T1) ;[1132] SET FILE POINTER TO FIRST FREE BLOCK
|
||
TXON P4,DATAF ;[1132] NOW IN A DATA DIR ENTRY, FIRST TIME?
|
||
JRST XOVNWD ;[1132] YES, GO DUMP OLD DIR ENTRY AND START NEW
|
||
ADD P3,R3 ;[1132] MAKE P3 BE THE FIRST FREE ADDRESS
|
||
MOVSI R3,(R3) ;[1132] TURN WORD COUNT INTO PAGE COUNT IN LH
|
||
ADD P2,R3 ;[1132] BUMP COUNT IN DIR ENTRY
|
||
ADD P4,R2 ;[1132] COUNT FILE PAGES WRITTEN HERE
|
||
POPJ P, ;[1132] DONE, BACK TO ADVPSC
|
||
|
||
|
||
;HERE TO START A NEW EXE DIRECTORY ENTRY
|
||
|
||
XOVNWD: TXZ P4,ZEROF ;[1132] NO LONGER WRITING AN ABZ ENTRY
|
||
TXZN P4,GAPF ;[1132] NOR IN A GAP. WERE WE?
|
||
PUSHJ P,XCMPRD ;[1132] NO, WRITE CURRENT DIR ENTRY
|
||
ADDI P1,(P4) ;[1132] BUMP FILE PAGE NUMBER
|
||
HRR P4,R2 ;[1132] ACCOUNT FOR PAGES WRITTEN HERE
|
||
MOVE P2,P3 ;[1132] FIRST WORD WE WROTE HERE
|
||
LSH P2,-^D9 ;[1132] FIRST PAGE WE WROTE HERE
|
||
ADD P3,R3 ;[1132] MAKE P3 POINT TO FIRST WORD BEYOND SYMS
|
||
MOVSI R3,-1000(R3) ;[1132] CONVERT WORD CNT INTO EXE DIR PAGE CNT
|
||
ADD P2,R3 ;[1132] NOW HAVE A NEW EXE DIR SLOT
|
||
POPJ P, ;[1132] DONE
|
||
>;[1214] END IFN FTOVERLAY
|
||
;HERE WHEN DONE WRITING THE MEMORY IMAGE TO THE EXE FILE.
|
||
;WRITE THE START ADDRESS BLOCK, DELETE THE TEMP FILES, AND
|
||
;RETURN THE EXE DIRECTORY STORAGE TO FREE SPACE.
|
||
|
||
XCMPRX: SKIPE PAG.S1 ;[1132] STILL GOT AN LC TEMP FILE?
|
||
PUSHJ P,LC.DLT ;[1132] YES, DELETE IT
|
||
SKIPE PAG.S2 ;[1132] HOW ABOUT AN HC TEMP FILE?
|
||
PUSHJ P,HC.DLT ;[1132] YES, DELETE IT
|
||
|
||
;[2366] If it's an extended addressing program, write an entry vector.
|
||
|
||
MOVE T1,HL.S1 ;[2366] Get the highest loaded
|
||
TLNN T1,-1 ;[2366] Loaded outside section zero?
|
||
JRST XCMPRV ;[2366] No, JOBDAT is sufficient
|
||
PUSHJ P,XCMPXD ;[2366] See if enough room
|
||
MOVE T2,[.SVEVC,,.ELEV] ;[2366] Two word entry vector
|
||
MOVEM T2,(W1) ;[2366] Store header
|
||
PUSHJ P,XCMPXD ;[2366] See if enough room
|
||
SKIPN T1,ENTLEN ;[2366] Entry vector length specified?
|
||
MOVEI T1,(JRST) ;[2366] No, TOPS-10 wants a JRST here
|
||
MOVEM T1,(W1) ;[2366] Store it
|
||
PUSHJ P,XCMPXD ;[2366] See if room for address
|
||
MOVE T1,STADDR ;[2366] GET START ADDRESS
|
||
MOVEM T1,(W1) ;[2366] STORE ADDRESS
|
||
|
||
XCMPRV: MOVE T1,[.SVEND,,1] ;[2366] END MARKER
|
||
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
|
||
MOVEM T1,(W1) ;STORE IT
|
||
MOVEI W1,(W1)
|
||
SUB W1,EXEDIR ;GET LENGTH
|
||
MOVE T1,HL.S1 ;[2366] Check for entry vector
|
||
TLNE T1,-1 ;[2366] Created if outside section zero
|
||
SUBI W1,.ELEV ;[2366] Don't count entry vector in directory
|
||
HRLI W1,.SVDIR ;HEADER
|
||
MOVE T3,EXEBLK ;SEE WHICH DIRECTORY BLOCK
|
||
CAIG T3,1 ;[1401] INCASE NOT FIRST
|
||
MOVEM W1,@EXEDIR ;COMPLETE BLOCK
|
||
|
||
USETO DC,@EXEBLK ;NOW TO WRITE THE DIRECTORY
|
||
HRRZ T1,EXEDIR
|
||
SUBI T1,1
|
||
HRLI T1,-1000 ;IOWD
|
||
SETZ T2,
|
||
OUT DC,T1 ;WRITE IT
|
||
CAIA ;OK
|
||
JRST E$$EOE ;[1174] ERROR
|
||
CAIE T3,1 ;WAS IT JUST SIMPLE CASE?
|
||
JRST [USETI DC,1 ;NO
|
||
IN DC,1 ;READ BACK FIRST DIRECTORY BLOCK
|
||
LSH T3,-2 ;SEE HOW MANY PAGES
|
||
IMULI T3,1000 ;ACCOUNT FOR ALL WORDS
|
||
ADDI W1,(T3) ;GRAND TOTAL
|
||
MOVEM W1,@EXEDIR ;NOW STORE
|
||
USETO DC,1 ;WRITE IT BACK
|
||
OUT DC,T1
|
||
JRST .+1 ;OK
|
||
JRST E$$EOE] ;[1174] ERROR
|
||
MOVE T1,EXEDIR ;GET BASE AGAIN
|
||
MOVEI T2,1000 ;LENGTH
|
||
PUSHJ P,DY.RET## ;GIVE SPACE BACK
|
||
JRST ENDCMP ;CLOSE FILE
|
||
>;[2247] IFE TOPS20
|
||
E$$EOE::
|
||
IFE TOPS20,< ;[2274]
|
||
PUSH P,[DC] ;[1174]
|
||
.ERR. (ST,,V%L,L%F,S%F,EOE,<EXE file output error>) ;[1174]
|
||
>;[2274] IFE TOPS20
|
||
IFN TOPS20,< ;[2274]
|
||
PUSHJ P,JSERR## ;[2274] Get the JSYS error
|
||
.ERR. (MS,.EC,V%L,L%F,S%F,EOE,<EXE file output error>) ;[2274]
|
||
.ETC. (NLN,.EC) ;[2274] New line for error text
|
||
.ETC. (STR,,,,,ERRJSY) ;[2274] Type ERSTR% text
|
||
>;[2274] IFN TOPS20
|
||
>;END OF IFN FTEXE
|
||
IFE TOPS20,< ;[2247]
|
||
IFE FTEXE,<
|
||
|
||
;HERE FOR ZERO COMPRESSOR
|
||
;NOTE! LIKE THE MONITOR WE REMOVE ALL ZEROS (FILEX LEAVES SINGLE ZEROS)
|
||
|
||
ZCMPRS: MOVE P2,LC.LB ;OUTPUT POINTER
|
||
MOVEI P1,.JBSDD-1(P2) ;INPUT POINTER
|
||
HRLZ T1,P2 ;FORM BLT POINTER
|
||
HRRI T1,1(P2) ;TO CLEAR NON-SAVED PART OF FILE
|
||
SETZM (P2) ;CLEAR
|
||
BLT T1,-1(P1)
|
||
MOVE P3,P2 ;POINT TO PARTIAL IOWD
|
||
;EXCEPT WE HAVEN'T SET IT UP YET
|
||
;HOWEVER SINCE SOME OF JOBDAT IS NON-ZERO
|
||
SKIPN T1,1(P1) ;WE WILL EVENTUALLY FIND A DATUM
|
||
AOJA P1,.-1 ;IF WE LOOK LONG ENOUGH
|
||
MOVE T2,P1 ;GET ADDRESS
|
||
SUB T2,LC.LB ;MINUS CORE OFFSET
|
||
ADD T2,LW.S1 ;PLUS WINDOW OFFSET
|
||
HRRZM T2,(P3) ;STORE USER ADDRESS
|
||
ZCMPR0: SETO P4, ;INITIALIZE ZERO COUNTER
|
||
ZCMPR1: ADDI P2,1 ;BUMP COUNT
|
||
MOVEM T1,0(P2) ;STORE DATUM
|
||
ZCMPR2: ADDI P1,1 ;INCREMENT READIN POINTER
|
||
CAML P1,LC.AB ;BUT NOT TOO FAR
|
||
JRST ZCMPR5 ;FINISHED OR GET NEXT WINDOW FULL
|
||
ZCMPR3: SKIPN T1,1(P1) ;GET NEXT DATUM
|
||
AOJA P4,ZCMPR2 ;COUNT A ZERO
|
||
JUMPL P4,ZCMPR1 ;NO ZEROS SEEN
|
||
MOVE T2,P1 ;GET ADDRESS
|
||
SUB T2,LC.LB ;MINUS CORE OFFSET
|
||
ADD T2,LW.S1 ;PLUS WINDOW
|
||
HRRZM T2,1(P2) ;STORE NEXT IOWD TO BE
|
||
MOVEI T2,(P3) ;LAST IOWD
|
||
SUBI T2,(P2) ;MINUS CURRENT GIVES -LENGTH
|
||
SKIPE T2 ;ALREADY BEEN DONE IF 0
|
||
HRLM T2,(P3) ;FIXUP IOWD
|
||
AOS P3,P2 ;POINT TO THIS NEW POINTER
|
||
JRST ZCMPR0 ;AND GET NEXT DATUM
|
||
;HERE WHEN CURRENT WINDOW IS FULL
|
||
ZCMPR5: SKIPN LSTPAG ;LAST PAGE IN CORE IF PAGING
|
||
SKIPN PAG.S1 ;ALWAYS IN CORE IF NOT
|
||
JRST ZCMPR6 ;YES, CAN WRITE OUT ALL OF CORE NOW
|
||
MOVE T1,P3 ;HIGHEST ADDRESS WE CAN OUTPUT
|
||
IORI T1,.IPM ;HOWEVER IT MAY NOT BE IN LAST BLOCK
|
||
CAML T1,P2 ;IN WHICH CASE CREATE AN IOWD AND OUTPUT
|
||
;IT ANYWAY. THIS MEANS SAVE FILES
|
||
;WILL NOT BE BIT IDENTICAL UNTIL EXPANDED.
|
||
JRST ZCMPR7 ;OK, ZERO SEEN IN THIS BLOCK
|
||
MOVEI T2,(P3) ;LAST IOWD
|
||
SUBI T2,(P2) ;MINUS CURRENT GIVES -LENGTH
|
||
HRLM T2,(P3) ;FIXUP IOWD
|
||
MOVEI T1,1(P2) ;[652] THIS IS THE HIGHEST TO OUTPUT
|
||
MOVE P3,P2 ;MAKE NEW IOWD POINT TO CURRENT POSITION
|
||
SKIPGE P4 ;IF WE ARE NOT READING ZEROS
|
||
SETZ P4, ;SIGNAL NEW IOWD NEEDED
|
||
JRST ZCMPR7 ;OUTPUT WHAT WE HAVE
|
||
|
||
|
||
;HERE TO FIXUP FINAL POINTER AND SET TO WRITE OUT LAST OF CORE IMAGE
|
||
ZCMPR6: MOVEI T2,(P2) ;GET ADDRESS
|
||
SUBI T2,(P3) ;GIVES LENGTH
|
||
MOVN T2,T2 ;NEGATE
|
||
HRLM T2,(P3) ;FIXUP IOWD
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;SEEN ANY OVERLAYS?
|
||
SKIPN T1,JOB116 ;AND WANT SYMBOLS?
|
||
JRST ZCMP6S ;NO
|
||
SUBI T1,1 ;IOWD IS 1 LESS
|
||
MOVEM T1,1(P2) ;STORE IOWD
|
||
HLRE T2,T1 ;- LENGTH
|
||
MOVM T2,T2
|
||
SKIPN PAG.LS ;PAGING SYMBOLS?
|
||
JRST ZCMP6R ;NO
|
||
SETZM LW.LS ;BRING IN THE BASE
|
||
SETOM LS.PP ;CERTAINLY CAN'T PAGE IT NOW
|
||
PUSHJ P,FR.CNT## ;THERE SHOULD BE SOME MORE ROOM
|
||
SUB P2,LC.LB ;MAKE P2 RELATIVE FOR SHUFFLING
|
||
PUSH P,P2 ;SAVE IT OVER LNKCOR
|
||
MOVEI P1,LS.IX ;WANT ROOM IN LS AREA
|
||
MOVE P2,T1 ;USE IT ALL
|
||
PUSHJ P,LNKCOR## ;DO SOME BLT'S
|
||
PUSHJ P,E$$MMF## ;[2202] CANNOT HAPPEN
|
||
POP P,P2 ;RESTORE RELATIVE ADDRESS
|
||
ADD P2,LC.LB ;MAKE ABSOLUTE
|
||
MOVE T2,LS.UB ;[2202] SETUP T1 FOR LS.IN
|
||
SUB T2,LS.LB ;[2202] GET THE SIZE
|
||
MOVEM T2,UW.LS ;[2202] UPPER WINDOW
|
||
SETZ T1, ;[2202] LOWER WINDOW - START AT BEGINNING
|
||
ZCMP6A: PUSHJ P,LS.IN## ;READ BACK
|
||
MOVE T2,UW.LS ;UPPER BOUND
|
||
CAMLE T2,LSYM ;UNLESS TOO MANY
|
||
MOVE T2,LSYM ;YES, USE ACTUAL NUMBER
|
||
SUB T2,LW.LS ;LENTH OF THIS
|
||
MOVEI T1,2(P2) ;NEXT FREE AFTER IOWD
|
||
HRL T1,LS.LB ;FROM
|
||
ADDI P2,1(T2) ;WHERE TO STOP
|
||
BLT T1,(P2) ;MOVE DOWN
|
||
MOVE T1,P2 ;GET END
|
||
ANDCMI T1,.DBM ;[650] BUT NOT LAST BLOCK
|
||
SUB T1,LC.LB ;LENGTH
|
||
MOVN T1,T1
|
||
HRL T1,T1
|
||
HRR T1,LC.LB
|
||
SUBI T1,1 ;IOWD
|
||
SETZ T2,
|
||
OUT DC,T1
|
||
SKIPA T1,P2 ;OK
|
||
JRST E$$SOE ;[1212] NO
|
||
ANDCMI T1,.DBM ;[650]
|
||
HRLZ T1,T1 ;FROM
|
||
HRR T1,LC.LB ;TO
|
||
ANDI P2,.DBM ;[650] KEEP LAST BLOCK
|
||
ADD P2,LC.LB ;FIX IT UP AGAIN
|
||
BLT T1,(P2) ;MOVE BLOCK DOWN
|
||
MOVE T1,UW.LS
|
||
SUB T1,LW.LS
|
||
ADDI T1,1 ;LENGTH
|
||
ADDM T1,UW.LS
|
||
ADDB T1,LW.LS
|
||
CAML T1,LSYM ;DONE
|
||
JRST [MOVEI T1,SC ;SYBMOL CHANNEL:
|
||
PUSHJ P,DVDEL.## ; DISCARD IT
|
||
JFCL ;DON'T CARE
|
||
JRST ZCMP6S] ;AND SETUP START ADDRESS
|
||
MOVE T1,LW.LS ;[2202] GET LOWER AND UPPER WINDOW
|
||
MOVE T2,UW.LS ;[2202] READ IN REST
|
||
JRST ZCMP6A ; OF FILE
|
||
ZCMP6R: MOVEI T1,2(P2) ;NEXT FREE
|
||
HRL T1,LS.LB ;FROM WHERE
|
||
ADDI P2,1(T2) ;ACCOUNT FOR SYMBOLS PLUS IOWD
|
||
BLT T1,(P2) ;MOVE SYMBOLS DOWN
|
||
ZCMP6S:>
|
||
MOVE T1,STADDR ;GET STARTING ADDRESS
|
||
HRLI T1,(JRST) ;FORM TRANSFER WORD
|
||
MOVEM T1,1(P2) ;STORE AFTER LAST WORD IN FILE
|
||
AOS T1,P2 ;WRITE OUT ALL OF CORE
|
||
AOJA T1,.+2 ;ONE MORE FOR TRANS WORD
|
||
ZCMPR7: ANDCMI T1,.IPM ;GET TO START OF THIS BLOCK
|
||
SUB T1,LC.LB ;LENGTH TO OUTPUT
|
||
JUMPE T1,ZCMPR8 ;IGNORE IF BLOCK OF ZERO'S
|
||
MOVN T1,T1 ;NEGATE IT
|
||
HRLZ T1,T1 ;PUT IN LEFT HALF
|
||
HRR T1,LC.LB ;FORM IOWD
|
||
HRRI T1,-1(T1) ;IOWD IS 1 LESS
|
||
SETZ T2, ;TERMINATE LIST
|
||
OUT DC,T1 ;DO OUTPUT
|
||
JRST ZCMPR8 ;OK
|
||
JRST E$$SOE ;[1174] PRINT ERROR AND DIE
|
||
;NOW TO MOVE DOWN THE REMAINING DATA IN THE BUFFER PRIOR TO
|
||
;READING IN MORE. IF NOT PAGING THIS IS END
|
||
ZCMPR8: SKIPE PAG.S1 ;WELL ARE WE PAGING
|
||
SKIPE LSTPAG ;BUT DONE IF ON LAST PAGE
|
||
JRST ENDCMP ;NO, ALL DONE
|
||
MOVE T1,P1 ;GET LOWEST LOCATION TO LEAVE
|
||
ANDCMI T1,.IPM ;ON BOUND
|
||
SUB T1,LC.LB ;REMOVE CORE OFFSET
|
||
ADDM T1,LW.S1 ;ADJUST WINDOW POINTERS
|
||
ADDB T1,UW.S1 ;MAY AS WELL
|
||
MOVE T2,HC.S1 ;GET HIGHEST LOCATION WE NEED TO SAVE
|
||
IORI T2,.IPM ;PUT ON BOUND
|
||
CAMLE T2,T1 ;TOO MUCH OR JUST ENOUGH ROOM AVAILABLE?
|
||
JRST ZCMPR9 ;NO
|
||
SUB T2,T1 ;YES, FIND DIFFERENCE
|
||
ADDM T2,UW.S1 ;SO WE DON'T WASTE TIME COUNTING ZEROS
|
||
ADDB T2,LC.AB ;OR GET ERRORS ON INPUT
|
||
MOVEM T2,LSTPAG ;SIGNAL LAST PAGE WILL SOON BE IN CORE
|
||
ZCMPR9: MOVE T1,P3 ;FORM BLT POINTER
|
||
ANDCMI T1,.IPM
|
||
CAMN T1,LC.LB ;CHECK FOR BLT IN PLACE
|
||
JRST ZCMP9A ;AND DON'T WASTE TIME ON IT
|
||
HRLZ T1,T1
|
||
HRR T1,LC.LB ;TO MOVE DOWN
|
||
HRRZI T2,.IPM(T1) ;TO THIS FAR
|
||
BLT T1,0(T2)
|
||
ZCMP9A: SKIPE T1,LSTPAG ;NOW CUT BACK CORE
|
||
IFN FTOVERLAY,<
|
||
SKIPL LNKMAX ;UNLESS LOADING OVERLAYS
|
||
SKIPA ;IN WHICH CASE WOULD ZAP LS AREA
|
||
> ;END IFN FTOVERLAY
|
||
CORE T1, ;TRY TO CUT BACK CORE
|
||
JRST .+3 ;TOO BAD
|
||
MOVE T1,.JBREL ;SETUP
|
||
MOVEM T1,LC.UB ;TO BE CONSISTENT
|
||
ANDI P3,.IPM ;KEEP OFFSET
|
||
CAIN P3,.IPM ;[652] FIRST PAGE ALREADY FINISHED?
|
||
SUBI P3,.IPS ;[652] YES, RE-USE IT FOR COMPRESSION
|
||
ADD P3,LC.LB ;[652] ADD IN BASE
|
||
ANDI P2,.IPM ;SAME AGAIN
|
||
CAIN P2,.IPM ;[652] FINISHED?
|
||
SUBI P2,.IPS ;[652] YES, RE-USE
|
||
ADD P2,LC.LB ;[652] ADD IN BASE
|
||
ANDI P1,.IPM
|
||
IOR P1,LC.LB
|
||
;NOW FOR DATA NOT READ
|
||
MOVE T1,LW.S1 ;[2202] THIS IS WINDOW BASE
|
||
ADDI T1,.IPS ;[2202] BUT WE ALREADY HAVE THIS MUCH
|
||
MOVE T2,UW.S1 ;[2202] FOR GENERAL INPUT ROUTINE
|
||
PUSHJ P,LC.IN## ;READ IN NEW CORE IMAGE
|
||
SKIPE LSTPAG ;HAVE WE READ LAST PAGES YET?
|
||
PUSHJ P,LC.DLT ;YES, GET RID OF FILE
|
||
JRST ZCMPR3 ;AND CONTINUE
|
||
|
||
> ;END OF IFE FTEXE
|
||
SUBTTL FINAL LOADING CLEAN-UP
|
||
ENDCMP:: ;[2330]
|
||
MOVEI T1,DC ;MAKE SURE
|
||
MOVEM T1,IO.CHN
|
||
PUSHJ P,DVRLS.##
|
||
SKIPE IO.PTR+%XC ;NEED TO RENAME .XPN FILE?
|
||
PUSHJ P,XPNREN ;YES
|
||
MOVE T1,IO.PTR+DC ;BUT SAVE FILE SPEC
|
||
MOVEM T1,IO.PTR+LC ;IN CASE /EXEC
|
||
> ;[1401] IFE TOPS20
|
||
ENDEXE:
|
||
IFN FTOVERLAY,<
|
||
SKIPGE LNKMAX ;DID WE SEE ANY LINKS?
|
||
JRST ENDSAV ;NO
|
||
MOVEI T1,OC ;YES, RENAME FILE TO WHAT WE WANT
|
||
MOVEM T1,IO.CHN
|
||
MOVE T2,IO.PTR+%OC ;PTR TO REAL NAME
|
||
PUSHJ P,DVPRO. ;SETUP CORRECT PROTECTION
|
||
MOVE T1,T2 ;OLD IN IO.CHN, NEW IN T1
|
||
PUSHJ P,DVRNF.##
|
||
JRST E01FRE ;[1174] REPORT RENAME ERROR
|
||
SKIPE PLOTSW ;WANT PLOT PACKAGE?
|
||
JRST LNKPLT## ;YES
|
||
JRST ENDSAV ;[1144] NO, RUN PROGRAM OR EXIT
|
||
|
||
;HERE ON A RENAME ERROR FOR THE OVERLAY FILE
|
||
E01FRE::PUSH P,[%OC] ;[1174] SET UP CORRECT CHANNEL
|
||
.ERR. (LRE,,V%L,L%F,S%F,FRE) ;[616] GIVE A FATAL ERROR
|
||
>
|
||
ENDSAV::PUSHJ P,TERMES ;PRINT FINAL MESSAGES
|
||
IFN TOPS20,< ;[2247]
|
||
POPJ P, ;[2247] Return
|
||
>;[2247] IFN TOPS20
|
||
IFE TOPS20,<
|
||
SKIPE EXECSW ;GO INTO EXECUTION?
|
||
JRST RUNEXE ;[1144] YES, RUN THE .EXE FILE
|
||
SKIPN N.ZER## ;RUN SWITCH PENDING?
|
||
JRST ENDZAP ;NO, JUST EXIT
|
||
SETZM F.EDIT ;MAKE SURE LNKSCN WON'T GET UPSET
|
||
JRST LNKSCN## ;AND GO DO THE RUN SWITCH
|
||
|
||
;NO, CUT CORE BACK TO MINIMUM AND EXIT
|
||
ENDZAP: MOVSI 17,ENDCLR ;LOAD ACCS
|
||
BLT 17,17 ;WITH EXIT CODE
|
||
JRST $4 ;AND JUMP TO THEM
|
||
ENDCLR: PHASE 0
|
||
1,,20 ; 0 - CORE UUO ARG /SETNAM ARG
|
||
20,,21 ; 1 - ZERO BLT PTR
|
||
EXP 0,0 ;FUTURE
|
||
$4:! CORE 0, ; 4 - CUT CORE TO MINIMUM
|
||
JFCL ; 5 - ERROR RETURN
|
||
SETZB 0,20 ; 6 - FOR SETNAM AND ZERO BLT
|
||
BLT 1,@.JBREL ; 7 - CLEAR ALL BUT ACCS
|
||
SETNAM 0, ;10 - CHANGE NAME TO NULL
|
||
SETDDT 0, ;11 - CLEAR DDT INCASE DEBUGGING VERSION
|
||
MOVEM $15,.JBBLT ;12 - LOAD .JBBLT WITH FINAL ACC BLT
|
||
MOVEM $16,.JBBLT+1 ;13 - AND EXIT
|
||
JRST .JBBLT ;14 - JUMP TO EXEC PDL
|
||
$15:! BLT 17,17 ;15 - CLEAR ACCS
|
||
$16:! EXIT ;16 - AND GO AWAY
|
||
0,,1 ;17 - BLT PTR TO CLEAR ACCS
|
||
|
||
DEPHASE
|
||
> ;[1401] IFE TOPS20
|
||
|
||
DEFINE KEYMAC (A,B)<
|
||
IFIDN <A><DEB>,<
|
||
%%==-1
|
||
IRP B,<
|
||
IFGE %%,<
|
||
IFN %%&1,<
|
||
[ASCIZ \B\]
|
||
>>
|
||
%%==%%+1
|
||
>>
|
||
PURGE %%
|
||
>
|
||
DEBNAM: KEYWORDS
|
||
IFE TOPS20,< ;[2247]
|
||
SUBTTL RUN THE PROGRAM
|
||
|
||
|
||
RUNEXE: SKIPE STADDR ;[1144] INFORM USER IF NO START ADDRESS
|
||
JRST RUNEX1 ;[1144] NO
|
||
AOS ERRNO ;[1144] DON'T START PROGRAM IF NO START ADDR
|
||
E$$NSA::.ERR. (MS,0,V%L,L%F,S%I,NSA,<No start address>) ;[1174]
|
||
RUNEX1: SKIPE ERRNO ;[1144] DON'T RUN IF ANY ERRORS
|
||
SKIPGE DEBUGSW ;[1144] UNLESS DEBUGGING
|
||
JRST RUNEX2 ;[1144] DO RUN PROGRAM
|
||
E$$DLT::.ERR. (MS,0,V%L,L%F,S%W,DLT,<Execution deleted>) ;[1174]
|
||
JRST ENDZAP ;[1144] JUST ZERO MEMORY AND EXIT
|
||
|
||
SUBTTL RUN THE PROGRAM FROM EXE FILE -- TOPS-10
|
||
|
||
|
||
RUNEX2: MOVE T1,[U%LOW,,LOW] ;[1144] MOVE DOWN FINAL RUN UUO CODE
|
||
BLT T1,U%END ;[1144] ..
|
||
IFE FTEXE,<
|
||
SKIPN T1,IO.PTR+HC ;[1144] GET HIGH SEG POINTER
|
||
> ;END IFE FTEXE
|
||
MOVE T1,IO.PTR+LC ;[1144] SETTLE FOR LOW SEG IF NO HIGH
|
||
MOVE T2,I.DEV(T1) ;[1144] SET UP RUN UUO DEVICE
|
||
MOVEM T2,U%RUNB+0 ;[1144] ..
|
||
MOVE T2,I.NAM(T1) ;[1144] SET UP FILE NAME
|
||
MOVEM T2,U%RUNB+1 ;[1144] ..
|
||
SKIPN T2,I.PPN(T1) ;[2066] SET UP PPN - DEFAULT?
|
||
JRST RUNEX9 ;[2066] YES, USE IT
|
||
TLNN T2,-1 ;[2066] IS THERE A PATH BLOCK?
|
||
PUSHJ P,SETPTH ;[2060] YES, SET IT UP
|
||
RUNEX9: MOVEM T2,U%RUNB+4 ;[2066] PUT IT IN RUN BLOCK
|
||
IFE FTEXE,<
|
||
SKIPN T1,IO.PTR+LC ;[1144] MAKE SURE POINTING AT LOW SEG
|
||
JRST RUNEX3 ;[1144] HISEG ONLY, USE .LOW
|
||
MOVE T2,I.EXT(T1) ;[1144] MAY AS WELL USE KNOWN EXT
|
||
TLNN T2,-1 ;[1144] EXTENSION KNOWN?
|
||
RUNEX3: MOVSI T2,'LOW' ;[1144] NO, USE .LOW
|
||
> ;END IFE FTEXE
|
||
IFN FTEXE,<
|
||
MOVE T2,I.EXT(T1) ;[1144] GET EXTENSION OF EXE FILE
|
||
> ;END IFN FTEXE
|
||
HLLM T2,U%RUNB+2 ;[1144] STORE EXTENSION
|
||
MOVE T1,RUNCOR ;[1144] LOW SEGMENT SIZE FROM /RUNCOR:
|
||
ADD T1,RUNCOR+1 ;[1144] AND HIGH SEG SIZE
|
||
MOVEM T1,U%RUNB+5 ;[1144] STORE AS RUN UUO ARGUMENT
|
||
CAIGE T1,U%END ;[1144] PREPARE TO SHRINK MEMORY TO LARGER
|
||
MOVEI T1,U%END ;[1144] OF WHAT WE NEED AND WHAT PROGRAM NEEDS
|
||
HRRM T1,U%CORA ;[1144] STORE AS CORE UUO ARGUMENT
|
||
HRRZ T1,EXECSW ;[1144] COMPUTE RUN UUO OFFSET
|
||
SUB T1,STADDR ;[1144] IN CASE WE START A DEBUGGER
|
||
HRLM T1,U%RUNA ;[1144] STORE IN RUN UUO ARGUMENT
|
||
PUSHJ P,EXEMES ;[1144] PRINT PROGRAM EXECUTION MESSAGES
|
||
JRST LOW ;[1144] GO SHRINK AND RUN PROGRAM
|
||
SETPTH: HRL T1,T2 ;[2061] SET START ADDR OF PATH BLOCK FOR BLT
|
||
HRRI T1,U%PTH ;[2060] DEST ADDR FOR BLT
|
||
BLT T1,<U%PTH+<LN.IO-1>> ;[2060] MOVE IT WHERE IT WILL BE SAVE
|
||
MOVEI T2,U%PTH ;[2060] ADDRESS FOR RUN BLOCK
|
||
POPJ P, ;[2060]
|
||
;FINAL SUICIDE CODE FOR RUNNING A PROGRAM ON TOPS-10.
|
||
|
||
U%LOW: PHASE .TEMP ;[1144] LOW MUST BE FIRST IN .TEMP
|
||
DMOVE T1,U%CORA ;[1144] LOAD UP CORE AND RUN UUO ARGS
|
||
CORE T1, ;[1144] REMOVE HIGH SEG AND SHRINK LOW SEG
|
||
JFCL ;[1144] DON'T WORRY IF FAILURE
|
||
RUN T2, ;[1144] RUN THE PROGRAM
|
||
HALT ;[1144] CAN'T--MONITOR PRINTS USEFUL MESSAGE
|
||
EXIT ;[1144] IN CASE USER TYPES CONTINUE
|
||
U%RUNB: .-. ;[1144] RUN UUO DEVICE
|
||
.-. ;[1144] FILE NAME
|
||
.-.,,0 ;[1144] EXTENSION
|
||
0 ;[1144] UNUSED
|
||
0 ;[1144] PPN (FILE WRITTEN ON [-])
|
||
.-. ;[1144] MEMORY ARGUMENT
|
||
U%PTH: BLOCK LN.IO ;[2060] PATH BLOCK
|
||
U%CORA: 1,,.-. ;[1144] CORE UUO ARG, POKED WITH LOW SEG SIZE
|
||
U%RUNA: .-.,,U%RUNB ;[1144] RUN UUO ARG, POKED WITH RUN OFFSET
|
||
U%END=.-1 ;[1144] LAST LOCATION IN PHASED CODE
|
||
DEPHASE ;[1144] BACK TO THE REAL WORLD
|
||
LOWLEN==.-U%LOW ;[1144] LENGTH OF PHASED CODE FOR LATER
|
||
> ;[2247] IFE TOPS20
|
||
SUBTTL RUN THE PROGRAM FROM EXE FILE -- SUBROUTINES
|
||
|
||
|
||
;TERMES GIVES THE LINK TERMINATION MESSAGE AND CLOSES THE LOG FILE IF ANY. IF
|
||
;NECESSARY, THE LOG FILE IS RENAMED TO THE PROPER NAME AS WELL.
|
||
|
||
TERMES:
|
||
E$$FIN::.ERR. (MS,0,V%L,L%I,S%I,FIN,<LINK finished>) ;[1174]
|
||
SKIPN IO.PTR+RC ;[1202] A REAL LOG FILE?
|
||
SKIPGE LOGTTY ;[1202] OR USER'S TERMINAL?
|
||
JRST E$$ELF ;[1202] YES, TYPE MESSAGE
|
||
POPJ P, ;[1202] NO, DONE
|
||
E$$ELF::.ERR. (MS,,V%L,L%I,S%I,ELF,<End of log file>) ;[1174]
|
||
SKIPN IO.PTR+RC ;SEE IF A LOG FILE?
|
||
POPJ P, ;NO
|
||
SETZM LOGSUB ;[1235] SAY LOG FILE IS CLOSED
|
||
MOVEI T1,RC
|
||
MOVEM T1,IO.CHN
|
||
SKIPN T1,IO.PTR+%RC ;[616] DO WE NEED TO RENAME FILE?
|
||
PJRST DVRLS.## ;[616] NO, JUST RELEASE IT
|
||
PUSHJ P,DVRNF.## ;YES, DO IT
|
||
CAIA ;[616] GIVE AN ERROR MESSAGE
|
||
PJRST DVRLS.## ;CLOSE FILE
|
||
E02FRE::PUSH P,[%RC] ;[1174] CHANNEL FOR ERROR
|
||
.ERR. (LRE,,V%L,L%F,S%F,FRE) ;[616] SEND THE MESSAGE
|
||
|
||
|
||
;EXEMES GIVES THE PROGRAM EXECUTION MESSAGE. THIS INCLUDES THE NAME OF THE
|
||
;PROGRAM, OR THE DEBUGGER IF /DEBUG WAS SPECIFIED.
|
||
|
||
EXEMES: SKIPE T1,DEBUGSW ;[1144] IF DEBUGGING
|
||
JRST EXEME1 ;[1144] THEN [LNKDEB debugger execution]
|
||
SKIPN T1,RUNAME ;[1144] ELSE [LNKXCT program execution]
|
||
MOVE T1,LODNAM ;[1144] GET PROGRAM NAME TO PRINT
|
||
E$$XCT::.ERR. (MS,.EC!.EN,V%L,L%F,S%I,XCT) ;[1174]
|
||
.ETC. (SBX,.EC!.EP,,,,T1)
|
||
.ETC. (JMP,.EC,,,,EXEME2)
|
||
|
||
EXEME1: MOVEI T1,@DEBNAM(T1) ;[1144] LOAD UP ASCIZ DEBUGGER NAME
|
||
E$$DEB::.ERR. (MS,.EC!.EN,V%L,L%F,S%I,DEB) ;[1174]
|
||
.ETC. (STR,.EC!.EP,,,,T1)
|
||
EXEME2: .ETC. (STR,,,,,,< execution>)
|
||
POPJ P, ;[1144] DONE
|
||
;ROUTINE TO CAUSE THE DATA IN A FILE TO BE MOVED FROM ONE FILE SPEC
|
||
;TO ANOTHER, EITHER BY A RENAME (IF POSSIBLE), OR BY COPYING THE FILE.
|
||
;USES DUMP MODE ON CHANNEL TC FOR OUTPUT IF COPYING NECESSARY.
|
||
;CALL IS:
|
||
; MOVE T1,OLD CHAN #
|
||
; MOVE T2,NEW CHAN #
|
||
; PUSHJ P,DVMOV.
|
||
; <ALWAYS RETURN>
|
||
;PRINTS FATAL ERROR AND STOPS IF RENAME OR COPY CANNOT BE PERFORMED.
|
||
;NOTE: THIS SHOULD REALLY BE IN LNKFIO, BUT IT IS HERE FOR NOW,
|
||
; SINCE NOBODY CALLS IT BUT LNKXIT, AND THERE IS NO USE MAKING
|
||
; ALL OF THE SEGMENTS BE A LOT BIGGER.
|
||
|
||
DVMOV.::MOVEM T1,IO.CHN ;POINT I/O ROUTINES TO OLD FILE
|
||
PUSH P,T2 ;SAVE NEW ONE
|
||
MOVE T1,IO.PTR(T1) ;GET POINTER TO OLD DATA BLOCK
|
||
MOVE T2,IO.PTR(T2) ;AND TO NEW ONE
|
||
MOVE T3,I.DEV(T1) ;GET OLD DEVICE
|
||
CAME T3,I.DEV(T2) ;SAME AS NEW ONE?
|
||
JRST DVCOPY ;NO, GO COPY FILE
|
||
POP P,T2 ;RESTORE NEW CHANNEL
|
||
MOVE T1,IO.PTR(T2) ;GET POINTER TO NEW DATA BLOCK
|
||
PUSHJ P,DVRNF. ;DO THE RENAME
|
||
SKIPA ;FAILED, GIVE ERROR
|
||
POPJ P, ;SUCCESS, RETURN
|
||
E03FRE::PUSH P,IO.CHN ;[1174] SAVE CHANNEL FOR LNKLOG
|
||
.ERR. (LRE,,V%L,L%F,S%F,FRE)
|
||
|
||
;HERE WHEN CANNOT RENAME THE FILE. MUST DO THE COPY.
|
||
DVCOPY: PUSHJ P,DVCLS.## ;MAKE SURE THE INPUT FILE EXISTS
|
||
MOVEI T3,I.RIB(T1) ;LOOK IT UP AGAIN
|
||
TLO T3,(LOOKUP) ;..
|
||
IOR T3,I.CHN(T1) ;..
|
||
XCT T3 ;SHOULDN'T FAIL
|
||
JRST E01FLE## ;[1174] ???
|
||
MOVE T3,I.SIZ(T1) ;GET INPUT FILE SIZE FOR LATER
|
||
LSH T3,-.DBS2W ;[650] CONVERT TO BLOCKS (FOR ESTIMATE)
|
||
ADDI T3,3 ;2 RIBS PLUS REMAINDER
|
||
POP P,T2 ;RESTORE NEW CHANNEL
|
||
SPUSH <P1,P2,P3> ;NEED LOTS OF ACS FOR THIS
|
||
PUSH P,IO.CHN ;SAVE OLD CHANNEL FOR LATER
|
||
MOVE P1,T1 ;SAVE POINTER TO OLD DATA BLOCK
|
||
MOVE T1,IO.PTR(T2) ;GET POINTER TO NEW DATA BLOCK
|
||
MOVEM T1,IO.PTR+TC ;USE THE TEMP CHAN FOR THE COPY
|
||
MOVEM T3,I.EST(T1) ;SET UP ESTIMATE FOR FILSER
|
||
MOVSI T2,(Z TC,) ;POINT THE OUTPUT CHAN TO CHAN TC
|
||
MOVEM T2,I.CHN(T1) ;SINCE THE PSEUDO-CHANNEL IS THERE
|
||
MOVEI T2,TC ;POINT ALL I/O TO THE OUTPUT
|
||
MOVEM T2,IO.CHN ;CHANNEL, SO CAN ENTER THE FILE.
|
||
PUSHJ P,DVNAM. ;SETUP THE OUTPUT FILE NAME
|
||
PUSHJ P,DVOPN. ;GET THE OUTPUT DEVICE
|
||
PUSHJ P,DVENT. ;CREATE THE OUTPUT FILE
|
||
PUSHJ P,FR.CNT## ;FIND OUT HOW MUCH CORE IS FREE
|
||
MOVE T2,I.SIZ(P1) ;AND HOW MUCH WE NEED
|
||
ADDI T2,.DBM ;ROUND UP TO DISK BLOCK
|
||
ANDCMI T2,.DBM ;SINCE WE NEED THAT MUCH
|
||
ANDCMI T1,.DBM ;ALSO, ROUND FREE COUNT DOWN
|
||
CAMLE T2,T1 ;HAVE AS MUCH AS WE NEED?
|
||
MOVE T2,T1 ;NO, USE WHAT WE HAVE
|
||
SKIPN T2 ;BUT IF NONE FREE AT ALL
|
||
MOVEI T2,.DBS ;NEED AT LEAST ONE DISK BLOCK
|
||
PUSHJ P,DY.GET## ;GET IT ALL
|
||
MOVE T3,I.SIZ(P1) ;RESTORE EXACT FILE SIZE
|
||
CAMLE T2,T3 ;IS BUFFER BIGGER THAN FILE?
|
||
MOVE T2,T3 ;NO, USE FILE SIZE FOR IOWD
|
||
MOVN P2,T2 ;FORM AN INPUT IOWD
|
||
HRLZ P2,P2 ;LH CONTAINS - COUNT
|
||
HRRI P2,-1(T1) ;RH CONTAINS START - 1
|
||
SETZ P3, ;IOWD LIST TERMINATED BY ZERO
|
||
MOVE T3,I.CHN(P1) ;ASSEMBLE 'IN CH,P2' IN T3
|
||
TDO T3,[IN P2] ;SO CAN READ DATA WITH XCT T3
|
||
DVMOV1: XCT T3 ;READ NEXT BLOCK OF DATA
|
||
JRST DVMOV3 ;GOT DATA, GO OUTPUT IT
|
||
MOVE T3,I.CHN(P1) ;NOW NEED TO SEE IF EOF OR ERROR
|
||
TDO T3,[STATZ IO.ERR] ;SO ASSEMBLE INSTRUCTION
|
||
XCT T3 ;EOF OR ERROR?
|
||
JRST E$$EOI ;[1174] ERROR, GIVE UP
|
||
MOVE T3,I.SIZ(P1) ;RETRIEVE FILE SIZE
|
||
IDIV T3,T2 ;FIND HOW MANY WORDS SHOULD REMAIN
|
||
JUMPE T4,DVMOV2 ;NONE, WE'RE ALL DONE
|
||
MOVN T4,T4 ;T4 HAS COUNT OF DATA IN BUFFER
|
||
HRL P2,T4 ;SO GENERATE AN IOWD TO SEND IT
|
||
OUT TC,P2 ;SEND THE DATA
|
||
SKIPA ;MADE IT!
|
||
JRST E$$EOO ;[1174]OH WELL, GIVE ERROR
|
||
DVMOV2: PUSHJ P,DY.RET## ;DONE WITH THE BUFFER, SO FREE IT
|
||
PUSHJ P,DVRLS. ;CLOSE THE OUTPUT FILE
|
||
POP P,T1 ;RESTORE INPUT CHANNEL
|
||
PUSHJ P,DVDEL. ;NOW DELETE INPUT FILE
|
||
JFCL ;DON'T CARE IF FAILED
|
||
SPOP <P3,P2,P1> ;RESTORE SAVED AC'S
|
||
POPJ P, ;AND RETURN
|
||
;HERE TO OUTPUT NEXT CHUNK OF FILE
|
||
DVMOV3: OUT TC,P2 ;SEND IT
|
||
JRST DVMOV1 ;MADE IT, GET NEXT PIECE OF DATA
|
||
E$$EOO::PUSH P,[TC] ;[1174] TELL WHICH CHANNEL HAD THE ERROR
|
||
.ERR. (ST,,V%L,L%F,S%F,EOO,<Error on output>)
|
||
|
||
E$$EOI::;PUSH P,IO.CHN ;[1174] CHANNEL ALREADY ON STACK
|
||
.ERR. (ST,,V%L,L%F,S%F,EOI,<Error on input>)
|
||
|
||
IFN TOPS20,< ;[2277] TOPS-20 ONLY
|
||
;Here when DDT cannot be GET%ed into memory for some reason.
|
||
E$$CLD: PUSHJ P,JSERR## ;[2353] SETUP ERROR STRING
|
||
.ERR. (MS,.EC,V%L,L%F,S%C,CLD,<Cannot load DDT>) ;[2304]
|
||
.ETC. (NLN,.EC) ;[2277] CRLF
|
||
.ETC. (STR,,,,,ERRJSY) ;[2277] TYPE LAST PROCESS ERROR
|
||
MOVE T1,DDTJFN ;[2277] GET DDT'S JFN BACK
|
||
GTSTS% ;[2277] GET JFN INFO
|
||
ERNAM GTSTS% ;[2277] CATCH ERRORS
|
||
TXNE T2,GS%NAM ;[2277] GOT THE JFN ANY MORE?
|
||
TXNE T2,GS%OPN ;[2277] YES, IS FILE OPEN ALREADY?
|
||
JRST DDTNRL ;[2277] NO, DON'T TOUCH JFN
|
||
JRST DDTRLS ;[2277] YES, DO COMMON CODE TO RELEASE DDT
|
||
|
||
;Can't GTJFN% a DDT.
|
||
E$$DNA: PUSHJ P,JSERR## ;[2353] SETUP ERROR STRING
|
||
.ERR. (MS,.EC,V%L,L%F,S%C,DNA,<DDT not available>) ;[2304]
|
||
.ETC. (NLN,.EC) ;[2277] CRLF
|
||
.ETC. (STR,,,,,ERRJSY) ;[2277] TYPE LAST PROCESS ERROR
|
||
SETZM GETDDT ;[2314] SAY WE DON'T WANT A DDT ANY MORE
|
||
JRST NODDT ;[2277] AND PRETEND WE NEVER WANTED DDT
|
||
|
||
;No nonexistant section to put XDDT into.
|
||
E$$NFS: .ERR. (MS,,V%L,L%F,S%C,NFS,<No free section for XDDT>) ;[2304]
|
||
MOVE T1,DDTJFN ;[2277] GET DDT'S JFN
|
||
DDTRLS: RLJFN% ;[2277] FORGET IT
|
||
ERNAM RLJFN% ;[2277] CATCH WEIRD ERRORS
|
||
SETZM DDTJFN ;[2277] REMEMBER THAT WE FORGOT IT
|
||
DDTNRL: SKIPE DEBUGSW ;[2277] WERE WE GOING TO START DDT?
|
||
SETZM EXECSW ;[2277] YES, DON'T DO IT
|
||
SETZM GETDDT ;[2314] SAY WE DON'T WANT A DDT ANY MORE
|
||
JRST NODDT ;[2277] CONTINUE AS IF DDT ISN'T WANTED
|
||
|
||
;UDDT's sym ptrs cannot be set for some reason (probably write-protected).
|
||
E$$CSP: PUSHJ P,JSERR## ;[2252] SETUP ERROR STRING
|
||
.ERR. (MS,.EC,V%L,L%F,S%C,CSP,<Cannot setup UDDT symbol table pointers>) ;[2304]
|
||
.ETC. (NLN,.EC) ;[2277] CRLF
|
||
.ETC. (STR,,,,,ERRJSY) ;[2277] TYPE LAST PROCESS ERROR
|
||
POPJ P, ;[2353] CONTINUE
|
||
|
||
> ;[2277] END IFN TOPS20
|
||
;HERE TO GET PROTECTION CODE RIGHT
|
||
;CALLED BY
|
||
; MOVE T2,NEW DATA BLOCK
|
||
; PUSHJ P,DVPRO.
|
||
;RETURN
|
||
;+1 ALWAYS
|
||
|
||
DVPRO.: LDB T3,[POINT 9,I.PRV(T2),8] ;GET USER SUPPLIED CODE
|
||
JUMPN T3,CPOPJ ;OK
|
||
;BUT WE MUST REPLACE 077 BY STANDARD
|
||
HRROI T3,<.GTDFL==140>;[606] DEFAULT WORD
|
||
GETTAB T3, ;[606] GET IT
|
||
SETZ T3, ;[606] CERTAINLY NOT SET
|
||
TXNE T3,<<JD.SDP==1B9>>;[606] USER HAVE DEFAULT PROTECTION?
|
||
TXNN T3,<<JD.PRT==777B8>>;[606] YES, BUT WE CAN'T HANDLE 0
|
||
JRST DVPRO1 ;[606] NOTHING USEFUL, GET SYS DEFAULT
|
||
ANDX T3,JD.PRT ;[606] CLEAR EXTRANEOUS BITS
|
||
IORM T3,I.PRV(T2) ;[606] SET
|
||
POPJ P, ;[606]
|
||
|
||
;HERE IF NO DEFAULT PROTECTION OR OLD MONITOR
|
||
DVPRO1: MOVE T3,[%LDSTP] ;[606] GET STANDARD
|
||
GETTAB T3,
|
||
MOVSI T3,057000 ;IN CASE OF FAILURE
|
||
IORM T3,I.PRV(T2) ;SET IT
|
||
POPJ P,
|
||
|
||
IFE TOPS20,< ;[2247]
|
||
;HERE TO RENAME .XPN FILE
|
||
|
||
XPNREN: MOVEI T1,LC ;FROM
|
||
MOVEM T1,IO.CHN ;SET CHAN#
|
||
PUSHJ P,DVCHN.## ;T1 = DATA BLOCK
|
||
PUSHJ P,DVOPN.## ;AND AN OPEN CHAN
|
||
PUSHJ P,DVNAM.## ;MAKE SURE A GOOD NAME
|
||
MOVEI T1,LC
|
||
MOVE T2,IO.PTR+%XC ;POINT TO NEW FILE SPEC
|
||
MOVE T3,VERNUM ;GET FILE VERSION
|
||
SKIPN I.VER(T2) ;UNLESS SET BY PREVIOUS SWITCH
|
||
MOVEM T3,I.VER(T2) ;SET UP FOR RENAME OR ENTER
|
||
MOVE T2,IO.PTR+%XC ;[606] OUTPUT DATA BLOCK ADDR
|
||
PUSHJ P,DVPRO. ;[606] GET THE OUTPUT PROTECTION RIGHT
|
||
MOVEI T2,%XC ;TO
|
||
PUSHJ P,DVMOV. ;TRY RENAME OR COPY
|
||
SETZM IO.PTR+LC ;NOT THERE NOW
|
||
POPJ P,
|
||
SUBTTL LOAD PROGRAM INTO MEMORY
|
||
|
||
|
||
;HERE TO BRING THE ENTIRE PROGRAM INTO MEMORY. IF NOT PAGING, THIS ONLY INVOLVES
|
||
;COMPACTING THE LC AND HC AREAS DOWN TOWARD 0 AS FAR AS POSSIBLE. IF PAGING,
|
||
;MINIMIZE DISK TRANSFERS BY MOVING THE WINDOW (VIA BLT OR POP LOOP) TO ITS FINAL
|
||
;LOCATION, THEN READING IN THE REST OF THE APPROPRIATE OVERFLOW FILE AROUND THE
|
||
;WINDOW.
|
||
|
||
JBLOAD: DMOVE P1,LC.LB ;SAVE THE CURRENT LOCATIONS
|
||
DMOVE P3,LC.AB ; SO WE CAN MOVE DATA
|
||
MOVE T1,DY.AB ;TOP OF FIXED AREA
|
||
MOVEM T1,DY.UB ;[1147] MAKE SURE UB IS UP TO DATE
|
||
ADDI T1,1 ;NEXT FREE
|
||
MOVEM T1,LC.LB ;MAKE LOWEST FOR LOW CODE
|
||
ADD T1,HC.S1 ;HOW MUCH WE NEED
|
||
SUBI T1,1 ;[1146] LB + LENGTH - 1 FOR LAST NEEDED
|
||
IORI T1,.IPM ;BLOCK BOUND
|
||
MOVEM T1,LC.AB
|
||
IOR. T1,.PGSIZ ;TO NEXT PAGE FOR REMAP
|
||
MOVEM T1,LC.UB ;ACCOUNT FOR ALL SPACE
|
||
JUMPE P2,JBGCL ;[1170] GO MOVE IF NO HI SEG
|
||
ADDI T1,1 ;LOWER BOUND FOR HISEG
|
||
MOVEM T1,HC.LB ;RESET IT
|
||
ADD T1,HC.S2 ;[1170] HIGHEST LOC WE NEED
|
||
SUBI T1,1 ;[1146] LB + LENGTH - 1 FOR LAST NEEDED
|
||
IORI T1,.IPM ;BLOCK BOUND
|
||
MOVEM T1,HC.AB
|
||
IOR. T1,.PGSIZ ;UPTO PAGE (OR K) BOUND
|
||
MOVEM T1,HC.UB ;FOR VERY TOP
|
||
;FALL IN FROM ABOVE IFF WE HAVE A HIGH SEGMENT (HC AREA)
|
||
;NOW DO THE FOLLOWING:
|
||
;
|
||
; 1. IF THE LC AREA IS SO HIGH THAT IT MIGHT GET OVERWRITTEN WHEN WE MOVE THE
|
||
; HC AREA TO WHERE IT BELONGS, THEN MOVE THE LC AREA DOWN OUT OF THE WAY.
|
||
; 2. MOVE THE HC AREA TO WHERE IT BELONGS, AND READ IN ANY DATA STILL OUT IN
|
||
; OVERFLOW FILES.
|
||
; 3. MOVE THE LC AREA TO WHERE IT BELONGS, AND READ IN ANY DATA STILL OUT IN
|
||
; OVERFLOW FILES.
|
||
; 4. DO A CORE UUO TO GET RID OF CORE FOR TABLES NO LONGER NEEDED.
|
||
; 5. MAKE SURE THE CORE BETWEEN AREAS IS STILL ZERO AFTER ALL THIS MOVING.
|
||
;
|
||
;ENTER FROM ABOVE AT JBGCL (STEP 3) IF WE DON'T HAVE A HIGH SEG.
|
||
|
||
MOVEI R,LC.IX ;[1170] POINT TO LOW SEG FOR JBCGM
|
||
CAMLE P3,LC.AB ;[1170] MIGHT LC AREA BE WIPED BY MOVING HC?
|
||
PUSHJ P,JBGCM ;[1170] YES, MOVE LC AREA FIRST
|
||
MOVEI R,HC.IX ;INDEX TO HIGH
|
||
PUSHJ P,JBGCMV ;MOVE HIGH AREA
|
||
|
||
JBGCL: ;NOW FOR LOW SEG
|
||
MOVEI R,LC.IX ;INDEX TO LOW
|
||
PUSHJ P,JBGCMV ;MOVE CODE AND READ IN REST OF DATA
|
||
SKIPN T1,HC.UB ;[1170] GET LAST LOCATION USED
|
||
MOVE T1,LC.UB ;[1170] NO HI SEG, END OF LOW IS LAST USED
|
||
IOR. T1,.PGSIZ ;[1170] UP TO PAGE BOUND IF NEEDED
|
||
CAME T1,.JBREL ;[1170] ALREADY THE RIGHT SIZE?
|
||
CORE T1, ;[1170] NO, SHRINK DOWN (OR GROW???)
|
||
JFCL ;[1170] ALREADY WAS THE RIGHT SIZE
|
||
;NOW TO ZERO ALL SPACE NOT USED
|
||
MOVEI R,HC.IX ;START WITH HIGH SEGMENT
|
||
SKIPN TAB.LB(R) ;IS THERE ONE?
|
||
SUBI R,1 ;NO
|
||
JBGCZ: MOVE T1,TAB.AB(R) ;LAST LOCATION IN USE
|
||
CAML T1,TAB.UB(R) ;CHECK FOR ANY CORE TO ZERO
|
||
JRST JBGCZ1 ;NONE - SO CHECK FOR FINISH
|
||
ADDI T1,2
|
||
HRLI T1,-1(T1) ;FORM BLT PTR TO CLEAR UNUSED CORE
|
||
SETZM -1(T1) ;[1170] CLEAR FIRST WORD
|
||
BLT T1,@TAB.UB(R) ;AND REST
|
||
JBGCZ1: SOJG R,JBGCZ ;NOW FOR LOW SEG
|
||
JRST JBEXIT ;[1146] PROGRAM NOW ALL IN MEMORY
|
||
;HERE TO MOVE CODE FOR EITHER SEG AND READ IN DATA
|
||
|
||
P0==P1-1 ;[1146] USED FOR REFERENCING P1 OR P2 VIA R
|
||
|
||
JBGCMV: MOVE T1,TAB.LB(R) ;BASE
|
||
ADD T1,LW.S0(R) ;PLUS WINDOW OFFSET
|
||
CAME T1,P0(R) ;IF WHERE WE SHOULD BE DO NOTHING
|
||
PUSHJ P,JBGCM ;[1170] MOVE THE AREA, UP OR DOWN
|
||
;NOW FOR REST OF CODE
|
||
SKIPN PAG.S0(R) ;HOWEVER IF THIS SEGMENT NOT PAGED
|
||
POPJ P, ;WE MUST BE IN RIGHT PLACE ALREADY
|
||
HRRZ T2,LW.S0(R) ;[2202] GET LOWER WINDOW
|
||
SOJL T2,JBGMV4 ;[2202] DONE IF WAS ZERO
|
||
SETZB T1,LW.S0(R) ;[2202] NOW POINT TO BASE
|
||
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
|
||
JBGMV4: MOVE T1,HC.S0(R) ;[2202] HIGHEST DATA WE NEED
|
||
IORI T1,.IPM ;UP TO BOUND
|
||
CAMG T1,UW.S0(R) ;IF WE'VE ALREADY GOT IT IN
|
||
POPJ P, ;[1170] ALL DONE
|
||
EXCH T1,UW.S0(R) ;GET BASE
|
||
ADDI T1,1 ;[2202] NEW BASE = OLD UPPER + 1
|
||
MOVE T2,UW.S0(R) ;[2202] LAST
|
||
PJRST @[EXP LC.IN##,HC.IN##]-1(R) ;[1170] READ IT IN AND RETURN
|
||
|
||
;SUBROUTINE TO MOVE AN AREA TO ITS FINAL RESTING PLACE.
|
||
;CALL WITH:
|
||
; R/ INDEX TO SEGMENT, ??.IX
|
||
; P1-P4/ OLD LB/AB OF AREAS
|
||
; ??.LB&AB/ NEW LB/AB OF AREAS
|
||
;
|
||
;UPDATES P1-P4 TO INDICATE THE AREA HAS BEEN MOVED.
|
||
;THIS SUBROUTINE USES BLTS, A PIECE AT A TIME IF OVERLAPPING UPWARDS.
|
||
|
||
JBGCM:
|
||
MOVE W1,HC.S0(R) ;[1170] FIRST, CALCULATE LAST DEST+1
|
||
SUBI W1,1 ;[1170] DEPENDS ON IF PAGING, AND
|
||
IORI W1,.IPM ;[1170] WHERE WINDOW IS IF SO
|
||
SKIPE PAG.S0(R) ;[1170] PAGING?
|
||
CAMG W1,UW.S0(R) ;[1170] YES, DOES WINDOW POINT TO END OF AREA?
|
||
CAIA ;[1170] NOT PAGING OR WINDOW AT END
|
||
MOVE W1,UW.S0(R) ;[1170] WINDOW IN MIDDLE, STOP BLT AT UW
|
||
ADDI W1,1 ;[1170] CONVERT LAST DEST TO FIRST NOT TOUCHED
|
||
ADD W1,TAB.LB(R) ;[1170] FORM ABSOLUTE ADDRESS
|
||
MOVE T1,TAB.LB(R) ;[1170] NOW CALCULATE FIRST DESTINATION ADDR
|
||
ADD T1,LW.S0(R) ;[1170] WHERE CURRENT WINDOW GOES IN NEW LC AREA
|
||
MOVE T3,W1 ;[1170] T1 GETS TOTAL LENGTH TO MOVE
|
||
SUB T3,T1 ;[1170] LAST+1-FIRST IS LENGTH
|
||
MOVE T4,T1 ;[1170] T4 GETS OFFSET (HOW FAR TO MOVE)
|
||
SUB T4,P0(R) ;[1170] THIS IS ALSO CHUNK SIZE IF OVERLAPS UP
|
||
SKIPG T4 ;[1170] MOVE DOWN OR IN PLACE?
|
||
MOVE T4,T3 ;[1170] YES, MOVE ENTIRE THING IN ONE PIECE
|
||
HRLS T4 ;[1170] FORM CHUNK SIZE,,CHUNK SIZE (FOR BLT AC)
|
||
MOVEI W3,-1(W1) ;[1170] W1 GETS LAST DEST
|
||
MOVE T2,P0(R) ;[1170] T2 GETS LAST SOURCE + 1
|
||
ADD T2,T3 ;[1170] FOR LH OF W1 AS PROTOTYPE BLT POINTER
|
||
HRLM T2,W1 ;[1170] W1/ LAST SRC+1,,LAST DST+1
|
||
MOVEM T1,P0(R) ;[1170] UPDATE P1/P2 SO WE KNOW WE DID THIS
|
||
|
||
; ..
|
||
; ..
|
||
|
||
;LOOP BACK HERE TO DO EACH NEW PIECE OF THE BLT. THIS CODE USES ACS AS FOLLOWS:
|
||
;
|
||
; T3/ TOTAL # WORDS LEFT TO MOVE
|
||
; T4/ CHUNK SIZE,,CHUNK SIZE (.GT. T3 IF LAST OR ONLY TIME)
|
||
; W1/ LAST SRC+1,,LAST DEST+1 FOR NEXT BLT
|
||
; W2/ SCRATCH AC FOR BLT
|
||
; W3/ LAST DEST FOR NEXT BLT
|
||
;
|
||
;W1 AND W3 ARE DECREMENTED BY CHUNK SIZE WITH EACH BLT UNTIL DONE.
|
||
|
||
JBGCM6: CAIGE T3,(T4) ;[1170] LAST (OR ONLY) TIME?
|
||
JRST JBGCM8 ;[1170] YES, GO ADJUST CHUNK SIZE ETC.
|
||
SUB W1,T4 ;[1170] DECREMENT PROTOTYPE BLT POINTER
|
||
MOVE W2,W1 ;[1170] SCRATCH COPY FOR BLT
|
||
BLT W2,(W3) ;[1170] BLT NEXT PIECE
|
||
SUBI W3,(T4) ;[1170] DECREMENT LAST BLT ADDRESS
|
||
SUBI T3,(T4) ;[1170] DECREMENT TOTAL LEFT TO DO
|
||
JRST JBGCM6 ;[1170] LOOP BACK
|
||
|
||
|
||
;HERE THE LAST TIME
|
||
|
||
JBGCM8: JUMPE T3,CPOPJ ;[1170] ALL DONE?
|
||
MOVE T4,T3 ;[1170] DO WHAT'S LEFT
|
||
HRLS T4 ;[1170] SET NEW CHUNK SIZE
|
||
JRST JBGCM6 ;[1170] BACK THROUGH THE LOOP, ONE MORE TIME
|
||
SUBTTL HERE TO BLT DOWN AREA AND EITHER GO TO EXECUTION OR EXIT
|
||
|
||
|
||
JBEXIT: SKIPE IO.PTR+%XC ;[1146] DO WE WANT .XPN FILE
|
||
SKIPE IO.PTR+LC ;AND DON'T ALRADY HAVE AN OVERFLOW FILE
|
||
CAIA ;NOT BOTH TRUE
|
||
PUSHJ P,WRTXPN ;WRITE OUT CURRENT CORE IMAGE
|
||
SKIPE STADDR ;WARN USER IF NO STARTING ADDRESS
|
||
JRST JBEX10 ;IS A STARTING ADDRESS, KEEP GOING
|
||
MOVE T2,VERLVL ;[1301] GET THE VERBOSITY
|
||
E01NSA::HRROI T1,[ASCIZ \[LNKNSA No start address]
|
||
\] ;[1301] GET DEFAULT
|
||
TXNN T2,M%F ;[1301] WANT FIRST LINE?
|
||
HRROI T1,[ASCIZ \[LNKNSA]
|
||
\] ;[1301] NO, GET PREFIX ONLY
|
||
TXNN T2,M%P ;[1301] WANT PREFIX?
|
||
HRROI T1,[ASCIZ \[ No start address ]
|
||
\] ;[1301] GET FIRST LINE
|
||
.XERR. ;[1301] FINISH OFF MESSAGE
|
||
JBEX10: SKIPE JOBPTR ;[2366] NEED TO RESTORE .JBDA?
|
||
PUSHJ P,BLTJDA ;YES
|
||
SKIPE JBHPTR ;SAME FOR HIGH
|
||
PUSHJ P,BLTJHA ;RESTORE FIRST 10 WORDS
|
||
SKIPE IO.PTR+%XC ;[2366] NEED TO RENAME .XPN FILE?
|
||
PUSHJ P,XPNREN ;YES
|
||
SKIPE IO.PTR+HC ;HIGH SEG OVERFLOW FILE STILL THERE?
|
||
PUSHJ P,HC.DLT ;YES, REMOVE IT
|
||
SKIPE IO.PTR+LC ;SAME FOR LOW SEG
|
||
PUSHJ P,LC.DLT
|
||
PUSHJ P,TERMES ;PRINT FINAL MESSAGES
|
||
MOVE T1,LC.LB ;LOAD UP OFFSET
|
||
MOVE T2,.JBDDT(T1) ;[1145] GET DEBUGGER ADDRESS
|
||
;NOW PUT PHASED CODE INTO LOW SEG
|
||
|
||
MOVEM T2,%T4 ;SAVE FOR LATER
|
||
MOVE T1,[%HIGH,,%LOW] ;MOVE PHASED CODE
|
||
BLT T1,%END ;INTO LOWSEG
|
||
HRLZ T1,LC.LB ;WHERE WE ARE NOW
|
||
ADD T1,[20,,20] ;BLT POINTER TO WHERE WE WILL BE
|
||
MOVEM T1,%0 ;STORE BLT POINTER FOR LATER
|
||
MOVE T1,LC.AB ;WHERE WE WILL END
|
||
SUB T1,LC.LB ;AFTER BLT
|
||
HRRM T1,%4 ;STORE FOR LATER
|
||
SKIPN T1,EXECSW ;GET STARTING ADDRESS
|
||
JRST JBEX0 ;DON'T WANT TO START
|
||
HRLI T1,(JRST) ;COMPLETE INST IF EXECUTING
|
||
TRNN T1,-1 ;WANT TO START, BUT DO WE HAVE A VALID ADDRESS
|
||
SKIPGE DEBUGSW ;IF /DEB WILL CHECK AT JBEX3
|
||
JRST JBEX01 ;OK
|
||
JRST JBNEX ;NO, ABORT
|
||
JBEX0: MOVE T1,[EXIT] ;STOP JOB
|
||
JBEX01: MOVEM T1,%16 ;STORE EXEC OR EXIT
|
||
MOVSI T1,(JFCL) ;NO-OP
|
||
SKIPE EXECSW ;IF EXECUTION
|
||
HLLM T1,%DMES ;EXTRA MESSAGE
|
||
SKIPGE DEBUGSW ;IF DEBUGGING
|
||
JRST JBEX3 ;CHANGE MESSAGE
|
||
MOVE T1,LC.LB ;GET BASE OF LOW CODE
|
||
HRRZ T1,.JBERR(T1) ;ANY ERRORS?
|
||
SKIPE T1
|
||
SKIPN EXECSW ;AND USER WANTS EXECUTION?
|
||
JRST JBEX2 ;NO
|
||
JBNEX: MOVE T1,[EXIT] ;PUT A STOP TO THAT
|
||
MOVEM T1,%16
|
||
MOVE T1,%HIGH+%DMES-%LOW
|
||
MOVEM T1,%DDMES ;SKIP REST OF MESSAGES
|
||
MOVE T3,VERLVL ;[1301] GET THE VERBOSITY BITS
|
||
E01DLT::HRLI T1,[ASCIZ /%LNKDLT Execution deleted/] ;[1301]
|
||
TXNN T3,M%F ;[1301] FIRST WANTED?
|
||
HRLI T1,[ASCIZ /%LNKDLT/
|
||
EXP 0,0,0,0] ;[1301] NO, GET PREFIX ONLY
|
||
TXNN T3,M%P ;[1301] PREFIX WANTED?
|
||
HRLI T1,[ASCIZ /% Execution deleted/
|
||
EXP 0,0] ;[1301] NO, FIRST
|
||
HRRI T1,%TMES
|
||
BLT T1,%TMES+5
|
||
JBEX2: MOVE T1,LC.LB ;GET BASE OF LOW CODE
|
||
MOVE T1,.JBVER(T1) ;PICKUP VERSION NUMBER
|
||
MOVEM T1,%VER ;STORE IT FOR VERSION WATCHING
|
||
SKIPN T1,HC.AB ;GET REAL TOP OF HIGH SEG
|
||
MOVE T1,LC.AB ;USE LOWSEG IF NO HIGH
|
||
TLO T1,1 ;ALSO REMOVE CURRENT HIGH SEG
|
||
MOVEM T1,%T1 ;SAVE CORE UUO ARG
|
||
SKIPE T1,HC.LB ;GET BOTTOM OF HIGH SEG
|
||
SUBI T1,1 ;TOP OF LOW SEG
|
||
HRRZM T1,%T2 ;STORE FOR REMAP
|
||
MOVSI T2,(CAIA) ;INCASE NO HIGH SEG
|
||
SKIPN T1
|
||
MOVEM T2,%REMAP ;OVERWRITE REMAP UUO
|
||
SKIPN T1,RUNAME ;GET NAME TO CALL CORE IMAGE
|
||
MOVE T1,LODNAM ;USE DEFAULT IF NOT SET
|
||
TLNN T1,770000 ;[2402] IS IT A LONG NAME
|
||
MOVE T1,(T1) ;[2402] YES - GET FIRST 6 CHARS
|
||
LDB T3,[POINT 7,%TMES,6] ;[1301] GET THE FIRST CHARACTER
|
||
CAIN T3,"%" ;[1301] IS THE WARNING MESSAGE THERE
|
||
JRST JBEX20 ;[1301] YES, DON'T TOUCH
|
||
MOVE T2,VERLVL ;[1301] GET THE VERBOSITY BITS
|
||
MOVE T3,<[ASCIZ \[ \]> ;[1301]
|
||
TXNN T2,M%P ;[1301] PREFIX WANTED?
|
||
MOVEM T3,%TMES ;[1301] NO
|
||
MOVE T3,2+<[ASCIZ \ execution ]
|
||
\]> ;[1301]
|
||
TXNN T2,M%P ;[1301] PREFIX WANTED?
|
||
MOVEM T3,%RTXT+2 ;[1301] NO
|
||
TXNN T2,M%F ;[1301] FIRST LINE WANTED
|
||
JRST [SETZM %DTXT ;[1301] NO, ZERO THE PROGRAM NAME
|
||
SETZM %RTXT ;[1301] AND THE 'EXECUTION'
|
||
MOVE T2,%TMES+1;[1301] GET THE PREFIX
|
||
IORX T2,<BYTE(7) 0,0,"]",15,12> ;[1301] TACK A ']' ON THE END
|
||
MOVEM T2,%TMES+1 ;[1301]
|
||
JRST JBEX20 ] ;[1301]
|
||
SKIPE %DTXT ;IF NOT ALREADY SET
|
||
JRST JBEX20 ;EITHER DDT OR NO NESSAGE
|
||
MOVE T3,T1 ;GET A COPY
|
||
MOVE T4,[POINT 7,%DTXT]
|
||
SETZ T2, ;CLEAR RECEIVING AC
|
||
LSHC T2,6 ;GET NEXT CHAR
|
||
ADDI T2," " ;INTO ASCII
|
||
IDPB T2,T4
|
||
JUMPN T3,.-4 ;MORE TO DO
|
||
IDPB T3,T4 ;MAKE SURE A 0 THERE
|
||
JBEX20: MOVEM T1,%T3 ;FOR SETNAM UUO
|
||
;HERE TO SETUP ARGS FOR CORE AND REMAP UUO'S
|
||
|
||
SKIPE T1,HL.S1 ;GET HIGHEST LOC LOADED +1
|
||
SUBI T1,1
|
||
IOR. T1,.PGSIZ ;ROUND UP
|
||
CAMGE T1,RUNCOR ;MORE THAN USER REQUESTED?
|
||
MOVE T1,RUNCOR ;NO, USE SUPPLIED VALUE
|
||
MOVEM T1,%1 ;FOR 2ND CORE UUO
|
||
MOVE T2,HL.S2 ;SAME FOR HIGH SEG
|
||
SOJL T2,JBEX2A ;AS LONG AS THERE IS ONE
|
||
IOR. T2,.PGSIZ
|
||
CAMGE T2,RUNCOR+1 ;USER SUPPLIED 2ND ARG
|
||
MOVE T2,RUNCOR+1 ;AND MORE THAN WE NEED
|
||
ADDI T1,1 ;TOP OF LOW SEG +1
|
||
CAMGE T1,LL.S2 ;LARGER THAN HI-ORG?
|
||
MOVE T1,LL.S2 ;NO, SO ASSUME HI-ORG
|
||
CAIE T1,400000 ;CONVENTIONAL HI-ORG?
|
||
HRLM T1,%T2 ;NO, FANCY REMAP UUO FOR V/M
|
||
ADDI T2,(T1) ;CORE UUO WILL KEEP HISEG
|
||
HRLM T2,%1 ;MAKE SURE CORE UOO CORRECT
|
||
JBEX2A: MOVE T1,HC.S1 ;GET HIGHEST DATA WORD+1
|
||
CAIGE T1,.JBDA ;BUT DON'T ZERO JOBDAT
|
||
MOVEI T1,.JBDA
|
||
HRRZ T2,%1 ;GET CORE UUO ADDRESS FOR LOW SEG TOP
|
||
CAML T1,T2 ;IS FIRST FREE LOC IN BOUNDS?
|
||
JRST [MOVSI T3,(JFCL) ;NO, ASSUME EQUAL
|
||
CAMG T1,T2 ;IS IT?
|
||
JRST [MOVEM T3,%11 ;IN WHICH CASE DON'T DO BLT
|
||
JRST .+1] ;BUT DO ZERO LAST WORD
|
||
MOVSI T3,(TDZA) ;NO, FIRST FREE LOC IS OUT OF BOUNDS
|
||
MOVEM T3,%10 ;JUST ZERO AC 0
|
||
JRST JBEX2B] ;AND FORGET FIRST FREE AND BLT
|
||
HRRM T1,%10 ;SET FOR ZEROING
|
||
HRL T1,T1
|
||
ADDI T1,1 ;FORM BLT PTR
|
||
MOVEM T1,%ZCBP ;[1244] TO CLEAR LOW SEG
|
||
JBEX2B: ;[1272] PREPARE TO GO TO PHASED CODE
|
||
MOVE T4,[%T1,,T1] ;LOAD ACCS
|
||
BLT T4,T4
|
||
JRST %LOW ;GO TO LOW SEG
|
||
JBEX3: MOVE T1,DEBUGSW ;GET INDEX TO DEBUG NAME
|
||
DMOVE T1,@DEBNAM(T1) ;GET BOTH WORDS (IF THERE ARE 2)
|
||
DMOVEM T1,%DTXT ;STORE
|
||
SKIPE EXECSW ;IF NO EXECUTION
|
||
CAME T1,[ASCII \COBDD\] ;OR NOT COBDDT
|
||
JRST JBEX4 ;START @.JBDDT
|
||
SKIPN T1,STADDR ;START COBDDT VIA MAIN PROG
|
||
JRST JBNEX ;OR GIVE EXECUTION DELETED MESSAGE
|
||
HRLI T1,(JRST) ;FORM INST
|
||
MOVEM T1,%16 ;SAVE GOTO ADDRESS
|
||
JBEX4:
|
||
MOVE T1,VERLVL ;[1301] GET THE VERBOSITY BITS
|
||
TXNN T1,M%P ;[1301] PREFIX WANTED?
|
||
JRST JBEX5 ;[1301] NO, GET "[ "
|
||
IFE FTKIONLY,<
|
||
MOVE T1,[ASCIZ \[LNKDEB \]
|
||
MOVE T1+1,1+[ASCIZ \[LNKDEB \]
|
||
> ;END IFE FTKIONLY
|
||
IFN FTKIONLY,<
|
||
DMOVE T1,[ASCIZ \[LNKDEB \]
|
||
> ;END IFN FTKIONLY
|
||
DMOVEM T1,%TMES
|
||
JRST JBEX2
|
||
JBEX5: MOVE T1,[ASCIZ \[ \] ;[1301] REPLACE THE PREFIX
|
||
MOVEM T1,%TMES ;[1301] WITH A BRACKET AND SPACE
|
||
JRST JBEX2 ;[1301]
|
||
|
||
|
||
;HERE FOR PHASED LOWSEG CODE
|
||
;ENTER WITH :-
|
||
;T1 = ARG FOR CORE UUO
|
||
;T2 = ARG FOR REMAP UUO
|
||
;T3 = ARG FOR SETNAM UUO
|
||
;T4 = ARG FOR SETDDT UUO
|
||
;[1326] P1 = POINTER FOR PA1050 SUICIDE FUNCTION [TOPS-20 ONLY]
|
||
;[1326] P2 = ARG BLOCK FOR PA1050 SUICIDE COMPT. [TOPS-20 ONLY]
|
||
|
||
%HIGH:
|
||
PHASE %LOW
|
||
%LOW: CORE T1, ;REMOVE HIGH SEG AND EXCESS LOWSEG
|
||
JFCL ;TOO BAD
|
||
%REMAP: REMAP T2, ;CHANGED TO SKIPA IF NO HIGH SEG
|
||
JRST REMERR ;FAILED
|
||
SKIPA T1,%VER ;PICK UP VERSION NUMBER
|
||
%VER: .-. ;FROM HERE
|
||
MOVEM T1,.JBVER ;SO CORRECT VERSION COMES OUT IF WATCHING
|
||
HLRZ T2,%0 ;GET REL 20
|
||
MOVE T1,.JBREL ;REMEMBER THIS
|
||
%REL: MOVEM T1,.JBREL-20(T2) ;[2232] IN CASE CORE UUO NOT DONE
|
||
IFE TOPS20,<
|
||
MOVE T1,.JBPFH## ;GET CURRENT PAGE FAULT HANDLER
|
||
EXCH T1,.JBPFH-20(T2) ;GET USER ONE
|
||
MOVEM T1,%3 ;SO WE CAN SET IT
|
||
>
|
||
SETNAM T3, ;FOR ARG WATCHING
|
||
SETDDT T4, ;CHANGE TO NEW ADDRESS
|
||
%DMES: JRST %RMES ;PATCH IF NEED MESSAGE
|
||
E01XCT:: ;[1174]
|
||
E01DEB::.OERR. %TMES ;[1174] LNKDEB OR LNKXCT
|
||
%DDMES: OUTSTR %DTXT ;NAME OF DEBUGGER
|
||
OUTSTR %RTXT ;TELL USER
|
||
%RMES: MOVSI 17,%0 ;BLT PTR
|
||
RESET ;MAKE SURE NO I/O STILL OPEN
|
||
BLT 17,17 ;[644] LOAD ACCS
|
||
JRST 4 ;[644] GO THERE
|
||
%TMES: ASCIZ \[LNKXCT \
|
||
%DTXT: EXP 0,0 ;ENOUGH FOR 6 CHARS PLUS NULL
|
||
%RTXT: ASCIZ \ execution]
|
||
\
|
||
|
||
REMERR: TLZN T2,-1 ;REMAP FOR V/M?
|
||
JRST E01RME ;[1174] NO, OR FAILED TWICE
|
||
HRRZS %1 ;MAKE SURE CORE UUO IN BOUNDS
|
||
SKIPA T1,.+1 ;STOP EXECUTION
|
||
EXIT ;WITH AN EXIT
|
||
MOVEM T1,%16 ;IF IT WAS ON
|
||
E$$RME::.OERR. %VMRERR ;[1174] LNKRME
|
||
JRST %REMAP ;NOW TRY AGAIN
|
||
E01RME::.OERR. %RMPE ;[1174] LNKRME
|
||
EXIT
|
||
%RMPE: ASCIZ \?LNKRME REMAP error\
|
||
%VMRER: ASCIZ \%LNKRME REMAP error, high segment origin incorrect
|
||
\
|
||
IFE TOPS20,< ;[1244]
|
||
%0: .-. ;BLT POINTER
|
||
%1: .-. ;CORE UUO
|
||
%2: .-. ;ZERO CORE BLT PTR
|
||
%3: .-. ;PFH
|
||
%4: BLT 0,.-. ;BLT LOWSEG DOWN
|
||
%5: CORE 1, ;ADJUST CORE
|
||
%6: JFCL ;SHOULD NOT FAIL
|
||
%7: MOVEM 3,.JBPFH## ;SET PAGE FAULT HANDLER
|
||
%10: SETZB 0,.-. ;CLEAR FIRST WORD
|
||
%11: BLT 2,@.JBREL ;AND REST
|
||
%12: MOVEM 15,.JBBLT ;LOAD .JBBLT AT LAST MINUTE
|
||
%13: MOVEM 16,.JBBLT+1
|
||
%14: JRST .JBBLT ;JUMP INTO EXEC PDL
|
||
%15: BLT 17,17 ;CLEAR ALL ACCS
|
||
%16: .-. ;START OR EXIT
|
||
%17: 0,,1 ;FINAL BLT PTR TO CLEAR ACCS
|
||
%ZCBP==%2 ;[1244] PUT POINTER IN ACC 2
|
||
> ;[1244]
|
||
%END:
|
||
DEPHASE
|
||
|
||
%T1==%END+0
|
||
%T2==%T1+1
|
||
%T3==%T2+1
|
||
%T4==%T3+1
|
||
>;[2247] IFE TOPS20
|
||
|
||
SUBTTL DATA AREAS
|
||
|
||
|
||
.ZZ==.TEMP
|
||
IFE TOPS20,<
|
||
U (LOW,LOWLEN) ;[1144] LOW CODE FOR RUN UUO--MUST BE FIRST
|
||
>
|
||
IFN TOPS20,<
|
||
U (ACS,20) ;[1144] PLACE TO WORK ON SUICIDE CODE
|
||
U (RUNSPC,4) ;[1144] ASCIZ FILE SPEC FOR EXE FILE
|
||
> ;END IFN TOPS20
|
||
U (TTLPTR) ;BACK POINTER TO LAST SUBPROGRAM
|
||
U (JOBPTR) ;POINTER TO COPY OF JOBDAT AREA
|
||
U (JBHPTR) ;DITTO FOR HIGH SEG
|
||
IFE FTEXE,<
|
||
U (LSTPAG) ;-1 WHEN LAST PAGE IS IN CORE
|
||
> ;END IFE FTEXE
|
||
U (ERRNO) ;.JBERR COUNT
|
||
U (JOB116) ;.JBSYM FOR .SYM FILE
|
||
U (JOB117) ;.JBUSY FOR .SYM FILE
|
||
U (SYMDEW) ;[1172] RESERVE SPACE IN SYMBOL TABLE
|
||
U (SYMFUL) ;[1172] SYMOUT HAS NON-SKIPPED ONCE
|
||
IFN TOPS20,<
|
||
U (ARGBLK,6) ;[2247] ARGUMENT BLOCK FOR SPLFK%
|
||
U (NOLOW) ;[2247] -1 IF .LOW. DOESN'T GO IN PDV MAP
|
||
U (GETBLK,.GBASE+1) ;[2277] GET% ARG BLOCK
|
||
U (DDTJFN) ;[2277] DDT'S JFN DURING /DEBUG LOADING OF IT
|
||
U (EVLEN,2) ;[2277] ENTRY VECTOR LENGTH & ADDR. TEMP
|
||
U (UDDFLG) ;[2277] -1=UDDT LOADED, 0=XDDT LOADED
|
||
U (XJFLG) ;[2277] -1=EXTENDED JSYSES OK, 0=NOT OK
|
||
U (PDMPLN) ;[2304] PRELIMINARY PDV MEMORY MAP LENGTH
|
||
U (DDTASC) ;[2314] X/UDDT'S ASCIZ FILESPEC PTR.
|
||
U (UDPTRS,2) ;[2314] FLAG/PTRs FOR UDDT LINK
|
||
> ;[2202] IFN TOPS20
|
||
IFE TOPS20,< ;[2366]
|
||
U (SYMVEC) ;[2366] SYMBOL VECTOR ADDRESS
|
||
>;[2366] IFE TOPS20
|
||
U (DSTADR) ;[2366] DEFINED SYMBOL TABLE ADDR.
|
||
U (USTADR) ;[2366] SAME AGAIN FOR UNDEFINED TABLE
|
||
U (DSYCNT) ;[2306] COUNT OR SIZE OF DEFINED SYMBOLS
|
||
U (USYCNT) ;[2306] COUNT OR SIZE OF UNDEFINED SYMBOLS
|
||
|
||
XITLIT: END LNKXIT
|