Trailing-Edge
-
PDP-10 Archives
-
bb-d868b-bm_tops20_v3a_2020_dist
-
3a-sources/lnkxit.mac
There are 38 other files named lnkxit.mac in the archive. Click here to see a list.
TITLE LNKXIT - EXIT MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC 27-Feb-78
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
ENTRY LNKXIT
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM
EXTERN LNKCOR,LNKLOG,LNKFIO
EXTERN .JB41
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==0 ;DEC MINOR VERSION
DECEVR==765 ;DEC EDIT VERSION
VERSION
SEGMENT
;LOCAL ACC DEFINITION
R==R1
SALL
SUBTTL REVISION HISTORY
;START OF VERSION 1A
;50 H ANDLE 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)
SUBTTL ENTER HERE
LNKXIT: JFCL .+1 ;IN CASE CCL ENTRY
.ERR. (MS,0,V%L,L%I,S%I,EXS,<EXIT segment>)
ZAPTMP ;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
IFN FTOVERLAY,<
SKIPGE LNKMAX ;DID WE LOAD ANY OVERLAYS?
JRST LNKX1 ;NO
MOVE T1,PH.OVL ;GET START OF CODE FOR ROOT
USETI OC,(T1) ;POSITION ON THE BLOCK
MOVE P2,PH.LEN ;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: MOVE T1,LC.LB
SUBI T1,1
HLL T1,PH.OVL ;SETUP IOWD
SETZ T2,
IN OC,T1 ;READ BACK CORE
LNKX0B: SKIPA T1,OV.S1 ;CORE BOUNDS
PUSHJ P,ER.IOV## ;INPUT ERROR
HRRZM T1,HL.S1 ;
HLRZM T1,HC.S1
JRST LNKX1 ;
;NOW TO READ BACK FIRST FEW BLOCK
LNKX0F: SETZM LW.S1 ;STARTS AT ZERO
MOVE T1,LC.UB
MOVEM T1,LC.AB ;USE IT ALL AGAIN
SUB T1,LC.LB
MOVEM T1,UW.S1 ;UPPER BOUND
PUSHJ P,LC.IN## ;READ IT BACK
JRST LNKX0B ;FIXUP VARIOUS POINTERS
LNKX0C: SETZM LW.S1 ;SET BACK TO START
MOVE T1,PH.OVL
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: MOVN T1,T1
HRLZ T1,T1
HRR T1,LC.LB ;IOWD
SUBI T1,1 ;AT LAST
SETZ T2,
IN OC,T1
SKIPA T1,LC.AB
PUSHJ P,ER.IOV##
SUB T1,LC.LB
ADD T1,LW.S1 ;ADD BASE
CAMG T1,PH.LEN ;REACHED END YET?
JRST LNKX0E ;NO
MOVE T1,PH.LEN ;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
LNKX0E: HRL T1,LW.S1 ;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.LEN ;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.LEN ;DO WE NEED TO READ IT ALL IN?
JRST LNKX0D ;YES
MOVE T1,PH.LEN ;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
>;END OF IFN FTOVERLAY
LNKX1: MOVEI R,1 ;SETUP TO POINT TO LOW SEG
MOVE R,@SG.TB
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
;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
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: SKIPE PAG.S2 ;HIGH SEG PAGING?
PUSHJ P,RDJBH ;YES, READ IN .JBHDA
SKIPE PAG.S1 ;LOW SEG PAGING?
PUSHJ P,RDJBL ;YES
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 UDF0 ;NOW FOR UNDEFINED SYMBOLS
;HERE TO READ IN FIRST 10 WORDS OF HIGH SEGMENT
RDJBH: 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
PUSH P,[HC]
.ERR. (ST,,V%L,L%F,S%F,IHC)
;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
RDJBL: 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
PUSH P,[LC]
.ERR. (ST,,V%L,L%F,S%F,ILC)
;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 UNDEFINED SYMBOLS
;HERE TO PUT UNDEFINED GLOBALS INTO UNDEF TABLE IN CORE
;THIS IS OLD FORMAT (2 WORD SYMBOLS)
UDF0: SKIPN R,SYMSEG ;LOAD OFFSET TO EITHER LC OR HC
MOVEI R,LC.IX ;ASSUME LOWSEG FOR SYMBOLS
SKIPN NOSYMS ;DON'T WANT UNDEFS IF /NOSYM
SKIPN P2,USYM ;ANY UNDEFINED SYMBOLS?
JRST NOUNDF ;NO, GET RID OF AREA
;BUT DO WE REALLY NEED UNDEFS?
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT POINTER
MOVE T1,LC.LB ;NO
SKIPN .JBDDT(T1) ;JOBDDT NON-ZERO
SKIPE SYMSEG ;OR SYMBOLS REQUESTED
JRST UDF0A ;YES
SKIPE IO.PTR+%SC ;BUT DO WE WANT SYMBOL FILE
SKIPL SYMFRM ; OLD STYLE?
JRST NOUNDF ;NO, GET RID OF THEM
UDF0A: LSH P2,1 ;2 WORDS PER SYMBOL
MOVE P4,PATSPC ;NEED TO LEAVE A HOLE FOR PATCHING
PUSHJ P,GETSST ;[715] GET FINAL SYMBOL START ADDR
SKIPE PAG.S0(R) ;PAGING?
PUSHJ P,LSYP ;YES, GET RIGHT PAGE IN CORE
ADDB P4,P2 ;SPACE WE NEED
ADD P2,TAB.LB(R) ;IN CORE
SUB P2,LW.S0(R) ;REMOVE WINDOW OFFSET
CAMG P2,TAB.AB(R) ;ENOUGH CORE?
JRST UDF1 ;YES,
SUB P2,TAB.AB(R) ;GET EXTRA WE NEED
MOVEI P1,(R) ;FROM WHERE
PUSHJ P,LNKCOR## ;GET IT
PUSHJ P,NO.COR## ;TOTAL FAILURE
SKIPN TAB.PG(R) ;[570] PAGING?
JRST UDF0B ;[570] NO, SKIP THIS
MOVE T1,P4 ;[570] YES, UPDATE UW
IORI T1,.IPM ;[570] SINCE PAGING ROUTINES DON'T
MOVEM T1,TAB.UW(R) ;[570] WHEN MAKING WINDOW BIGGER
UDF0B: PUSHJ P,CHKPAG ;[570] JUST INCASE WE STARTED PAGING
MOVE P2,P4 ;RELATIVE
ADD P2,TAB.LB(R) ;FIX IN CORE
SUB P2,LW.S0(R) ;REMOVE WINDOW OFFSET
UDF1: SKIPGE SYMSEG ;[715] PSECT NAME USED?
JRST .+3 ;[715] YES, JUMP
MOVEM P4,HC.S0(R) ;FOR .JBCOR
;NOW LOOP THROUGH GS AREA LOOKING FOR UNDEFINED SYMBOLS
EXCH P4,HL.S0(R) ;GET BASE OF UNDFS
MOVN T2,USYM ;NUMBER OF UNDEF SYMBOLS
MOVMM T2,JOB117 ;WILL FIX IT LATER, JUST NO. NOW
HRL P4,T2 ;AOBJN POINTER TO UNDEFS
LSH T2,^D18+1 ;PUT 2*COUNT IN LEFT HALF
HRR T2,P4 ;ADDRESS
ADD T2,LL.S0(R) ;+OFFSET
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
MOVEM T2,.JBUSY(T1) ;FIXUP POINTER
ADD P4,TAB.LB(R) ;FIX IN CORE
SUB P4,LW.S0(R) ;REMOVE WINDOW OFFSET
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)
PUSHJ P,SXBR50 ;CONVERT TO SIXBIT
TXO W2,R5.GLB ;MAKE GLOBAL DEFINITION
ADDI P4,1 ;WILL BUMP LOCATION BY 2 (LATER)
HRRZ T1,P4 ;ADDRESS ONLY
CAMLE T1,TAB.AB(R) ;WILL IT FIT IN WHAT WE HAVE?
PUSHJ P,UDFEXP ;NO, EXPAND AREA
DMOVEM W2,-1(P4) ;STORE NAME & VALUE
TXNE W1,PS.FXP ;ANY ADDITIVE GLOBAL FIXUPS
JRST UDFGB ;YES, RECREATE THE REQUESTS
UDFLUP: AOBJN P4,UDFNXT ;AND COUNT BY 1
UDFDN: ;UNLESS FINISHED
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
MOVE T2,JOB117 ;GET NUMBER OF UNDEFS
LSH T2,1 ;2 WORDS PER SYMBOL
MOVN T2,T2
HRLM T2,.JBUSY(T1) ;FIXUP POINTER
MOVE T2,.JBUSY(T1) ;GET A COPY
MOVEM T2,JOB117 ;FOR LATER
JRST GSDLT ;DELETE GLOBAL SYMBOL TABLE
UDFGB0: TXNE W1,S.LST ;IS THIS THE LAST BLOCK
JRST UDFLUP ;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 W3,.L+2(T1) ;GET VALUE
MOVE T1,W3
UDFGB1: ADD T1,FX.LB ;RELOCATE IN FIXUP TABLE
SKIPL W1,0(T1) ;GET FLAGS
JRST UDFERR ;JUST INCASE
TXNN W1,FP.SYM ;ADDITIVE GLOBAL FIXUP?
JRST UDFGB2 ;NO
DMOVE W2,1(T1) ;GET DATA WORDS
TXNE W1,FS.FXS ;SYMBOL FIXUP?
JRST UDFGB2 ;*** DON'T KNOW HOW TO DO IT YET ***
PUSHJ P,SXBR50 ;CONVERT TO RADIX-50
TXO W2,R5.GLB ;MAKE INTO A GLOBAL DEFINITION
TXO W3,R5.FXA ;AND TURN ON ADDITIVE BIT
TXNE W1,FS.FXL ;LEFT HALF?
TXO W3,R5.FXL ;YES
ADDI P4,2 ;USES 2 WORDS
HRRZ T1,P4 ;ADDRESS ONLY
CAMLE T1,TAB.AB(R) ;WILL IT FIT
PUSHJ P,UDFEXP ;NO
DMOVEM W2,-1(P4) ;STORE
AOS JOB117 ;COUNT 1 MORE WORD PAIR
SKIPGE SYMSEG ;[715]
JRST UDFGB2 ;[715] JUMP IF PSECT SPCIFIED
MOVEI T1,2 ;AND INCLUDE IN SPACE ASSIGNED
ADDM T1,HL.S0(R) ;SINCE WE DIDN'T ACCOUNT FOR IT EARLIER
;FALL THROUGH TO NEXT PAGE
; JRST UDFGB2
;FALL IN FROM PREVIOUS PAGE
UDFGB2: HRRZ T1,W1 ;GET POINTER
JUMPE T1,UDFLUP ;ALL DONE IF ZERO
JRST UDFGB1 ;GET NEXT BLOCK
UDFEXP: PUSH P,P2 ;SAVE P2 BEFORE EXPANDING CORE
MOVEI P1,(R)
MOVEI P2,2 ;AT LEAST 2 WORDS EXTRA
SUB P4,TAB.LB(R) ;REMOVE BASE INCASE WE MOVE
ADD P4,LW.S0(R) ;INCASE PAGES CHANGE
PUSHJ P,LNKCOR##
PUSHJ P,NO.COR## ;FAILED
SKIPN TAB.PG(R) ;[570] PAGING THIS AREA?
JRST UDFEX1 ;[570] NO, FORGET IT
MOVE T1,P4 ;[570] YES, MUST UPDATE UW OURSELVES
IORI T1,.IPM ;[570] ONLY EXPANDED TO THIS PAGE
MOVEM T1,TAB.UW(R) ;[570] UPDATE THE WORD
UDFEX1: PUSHJ P,CHKPAG ;[570] INCASE WE STARTED PAGING
SUB P4,LW.S0(R) ;BACK AS IT WAS
ADD P4,TAB.LB(R)
POP P,P2 ;RESTORE P2 TO BEFORE UDFEXP
POPJ P,
UDFERR: JRST UDFLUP ;SYMBOL TABLE FOULED UP
;HERE TO GET RID OF GLOBAL TABLE AND IF POSSIBLE CUT BACK CORE
NOUNDF: SETZM USYM ;MAKE SURE ITS CLEAR
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;BASE OF LOW SEG
SETZM .JBUSY(T1) ;CLEAR UNDF POINTER
GSDLT: 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
MOVEM T2,GS.AB ;RESET TABLE
MOVEM T2,GS.UB
CAMLE T2,GS.LB ;INCASE WE REDUCED IT ALL
JRST GSRED ;NO, ALL IS WELL
MOVEM T2,TAB.UB(T1) ;RESET HIGHEST FREE LOC AGAIN
SETZM GS.LB ;SO XX.ZAP CAN WORK
GSRED: .ERR. (MS,.EC,V%L,L%I,S%I,RED,<Reducing low segment to >)
.ETC. (COR,.EP,,,,.JBREL)
GSNRED: PUSHJ P,GS.ZAP ;GET RID OF GS
JRST LSY0 ;[715] GO DO LOCAL SYMBOLS
;HERE TO SETUP THE SPECIFIED PSECT FOR SYMBOL TABLE
GETSST: PUSH P,T1 ;[727]
SKIPL SYMSEG ;[715] A PSECT WAS SPECIFIED?
JRST [SKIPGE T1,SYMLIM ;[727] HAVE A DEFAULT LIMIT?
HRRZM T1,SYMLIM ;[727] YES, MAKE IT THE LIMIT
SKIPN HL.S0(R) ;[715] NO, NULL SEGMENT?
ADD P4,[EXP .JBDA,.JBHDA]-1(R) ;[715] SAVE JOBDAT
ADDB P4,HL.S0(R) ;[715] HIGHEST LOADED FOR SEG
POP P,T1 ;[727] RESTORE T1
POPJ P,] ;[715] RETURN FROM HERE IF HIGH/LOW
SETZ R, ;[727] YES, HAVE PSECT NAME
GETS1: MOVE T1,@RC.TB ;[715]
MOVE T2,RC.NM(T1) ;[715] GET PSECT NAME
CAMN T2,SSGNAM ;[715] IS THIS THE ONE?
JRST GETS2 ;[715] YES,
ADDI R,1 ;[715] NEXT ONE
CAMG R,RC.NO ;[715] ANY MORE?
JRST GETS1 ;[715] YES, LOOP
.ERR. (MS,,V%M,L%W,S%W,NPS,<NON-EXISTENT PSECT SPECIFIED>)
SETZM SSGNAM ;[715]
MOVEI R,1 ;[715] SET TO LOW
MOVEM SYMSEG ;[715]
POP P,T1 ;[715] RESTORE AC'S
JRST GETSST+1 ;[715] AND LOOP BACK
GETS2: MOVE T2,RC.CV(T1) ;[715] GET HIGHEST LOCATION
ADDB P4,T2 ;[715] GET SYMBOL START ADDR
CAMLE P4,HL.S1 ;[715] GREATER THAN HIGHT LOCATION?
MOVEM P4,HL.S1 ;[715] UPDATE IT IN THAT CASE
SKIPLE SYMLIM ;[727] DO WE HAVE A LIMIT
JRST GETS3 ;[715] FROM THE LAST CALL TO HERE
GETS4: ADDI R,1 ;[715] NEXT PSECT
CAMG R,RC.NO ;[715] SKIP IF NO MORE
JRST [MOVE T1,@RC.TB ;[715] THERE IS ONE
MOVE T2,RC.IV(T1) ;[715] GET ITS ORIGIN
SUBI T2,1 ;[727] ONE LESS
MOVEM T2,SYMLIM ;[715] MAKE IT THE SYMBOL LIMIT
JRST GETS3] ;[715]
SETOM SYMLIM ;[715] NO LIMIT AND BEEN HERE BEFORE
GETS3: MOVE T1,P4 ;[764] GET START OF THE SYMBOL TABLE
TRZ T1,777 ;[764] ROUND DOWN TO PAGE BOUND
CAMGE T1,LOWLOC ;[764] LOWER THAN ANY CODE?
MOVEM T1,LOWLOC ;[764] YES, UPDATE LOWEST LOCATION
MOVEI R,1 ;[715] UPDATE SEGMENT#
POP P,T1 ;[715] RESTORE AC'S
POPJ P, ;[715]
SUBTTL LOCAL SYMBOLS
;IF LOCAL SYMBOLS AREA REQUIRED IN CORE STORE THEM ON TOP
; OF LOW SEG OR HIGH SEG CODE
;IF LOWSEG LEAVE A GAP (PATSPC) FOR MORE SYMBOLS OR PATCHING
; IF HIGH PUT AGAINST PAGE BOUND (0.5K)
;
;IF LOCAL SYMBOLS NOT REQUIRED JUST FLUSH SPACE
;IF SYMBOLS ON DSK READ BACK IN FIRST
LSY0: SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;LOAD UP OFFSET
SKIPN T2,VERNUM ;GET VERSION# SET BY SWITCH
SKIPA T2,.JBVER(T1) ;GET VERSION FROM LOC .JBVER
MOVEM T2,.JBVER(T1) ;STORE BACK IN CORE IMAGE
MOVEM T2,VERNUM ;SAVE FOR .RBVER OF FILES
SKIPE NOSYMS ;NOT IF /NOSYMS
JRST LSY00
SKIPN .JBDDT(T1) ;IF DDT WE NEED LOCALS
SKIPE SYMSEG ;OR IF USER SPECIFIED WHERE TO PUT THEM
JRST LSREQ ;YES,
LSY00: SETZM .JBSYM(T1) ;CLEAR POINTER
SKIPE IO.PTR+%SC ;HOWEVER IF WE WANT OLD SYMBOL FILE
SKIPL SYMFRM ;WE STILL NEED TO CONVERT SYMBOLS
JRST NOLOCS ;NO, DONT BOTHER
;HERE IF /SYMSEG, /SYFILE:RADIX50, OR C(.JBDDT) <> 0.
;CONVERT THE SYMBOLS IN THE LS AREA TO RADIX50 AND PUT THEM IN CORE.
LSREQ:
IFN FTOVERLAY,<
SKIPL LNKMAX ;DID WE SEE ANY OVERLAYS?
JRST LSOVS ;YES, SPECIAL
>
.ERR. (MS,0,V%L,L%I,S%I,SST,<Sorting symbol table>)
PUSHJ P,SYMINI ;DO THE MAGIC TO MOVE SYMBOLS UP IN CORE
LSREQ1: PUSHJ P,CHKPAG ;[645] INCASE PAGE FOR THE FIRST TIME
SKIPE USYM ;IF NO UNDEFINED SYMBOLS
TDZA P4,P4 ;YES, DONE ALREADY
MOVE P4,PATSPC ;NEED TO LEAVE A HOLE FOR PATCHING
PUSHJ P,GETSST ;[715] GET FINAL SYMBOL START ADDR
MOVE P2,P4 ;COPY INCASE NOT ENOUGH
SKIPE PAG.S0(R) ;PAGING THIS AREA?
SKIPE USYM ;YES, BUT ALREADY SETUP IF UNDEFS
CAIA ;DON'T HAVE TO WORRY
PUSHJ P,LSYP ;YES, GET RIGHT PAGES IN CORE
SUB P2,LW.S0(R) ;REMOVE PAGED BASE
ADD P2,TAB.LB(R) ;IN CORE
CAMG P2,TAB.AB(R) ;ENOUGH CORE?
JRST LSY1 ;YES,
SUB P2,TAB.AB(R) ;GET EXTRA WE NEED
MOVEI P1,(R) ;FROM WHERE
SETOM LS.PP ;[754] PROHIBIT PAGING OF SYMBOLS
PUSHJ P,LNKCOR## ;GET IT
JRST LSREQ1 ;[645] NO CORE, LOOP BACK AND PAGE
SKIPN TAB.PG(R) ;[570] PAGING?
JRST LSREQ0 ;[570] NO, FORGET IT
MOVE T1,P4 ;[570] YES, UPDATE UW
IORI T1,.IPM ;[570] FROM MAX VIRT ADDR, IN P4
MOVEM T1,TAB.UW(R) ;[570]
LSREQ0: MOVE P2,P4 ;[570] RELATIVE
SUB P2,LW.S0(R) ;REMOVE PAGED BASE
ADD P2,TAB.LB(R) ;FIX IN CORE
LSY1: SETZM LS.PP ;[754]
SKIPGE SYMSEG ;[715]
JRST .+3 ;[715] JUMP IF PSECT SPCIFIED
MOVEM P4,HC.S0(R) ;FOR .JBCOR
EXCH P4,HL.S0(R) ;GET BASE OF UNDFS
SKIPE PAG.S1 ;PAGING?
SKIPA T1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE T1,LC.LB ;CODE OFFSET
ADD P4,LL.S0(R) ;PLUS STARTING OFFSET
HRRZM P4,.JBSYM(T1) ;FIXUP POINTER (ADDRESS ONLY)
HRRZM P4,JOB116 ;AND FOR .SYM FILE
MOVEI T1,.IPS ;SIZE WE CARE ABOUT
SUB T1,LS.FR ;MINUS FREE
MOVEM T1,LSCNT ;LEFT IN THIS BLOCK
SKIPGE SYMSEG ;[715] PSECT NAME USED?
SKIPA T1,P4 ;[715] YES, USED P4 INSTEAD
MOVE T1,HL.S0(R) ;SETUP CORE POINTER
MOVEI T2,2(T1) ;REL ADDRESS OF "TITLE" FOR PAT..
MOVEM T2,TTLPTR
SUB T1,LW.S0(R) ;REMOVED PAGED BASE
ADD T1,TAB.LB(R) ;ADD FIXED BASE
MOVEM T1,TAB.PT(R) ;ABS POINTER TO NEXT FREE LOC
;NOW OUTPUT THE SYMBOL PAT.. IN MODULE PAT.. AS THE LAST SYMBOL
MOVE W2,[RADIX50 04,PAT..] ;BE COMPATIBLE (ALMOST)
SKIPGE SYMSEG ;[715] PSECT NAME USED?
SKIPA W3,P4 ;[715] YES, USE P4 INSTEAD
HRRZ W3,HL.S0(R) ;VALUE
SUB W3,PATSPC ;POINT TO BOTTOM OF AREA
HLRE T1,JOB117 ;BUT TAKE INTO ACCOUNT UNDEFINED SYMBOLS
ADD W3,T1 ;WHICH ARE BETWEEN PAT.. AND .JBSYM
ADD W3,LL.S0(R) ;ADD IN OFFSET TO SEGMENT
PUSHJ P,SYMOUT ;LAST SYMBOL
JRST SYDONE ;[715] EXCEEDED SPACE, ALL DONE
TLZ W2,740000 ;MAKE RADIX50 0,PAT.. BE THE TITLE
PUSHJ P,SYMOUT
SKIPA ;[715] EXCEEDED SPACE, ALL DONE
PUSHJ P,LSLOOP ;READ ALL OF SYMBOLS
JRST SYDONE ;ALL DONE
IFN FTOVERLAY,<
LSOVX:: MOVEM T1,LSCNT ;STORE WORDS LEFT IN THIS BLOCK
SETZM TTLPTR ;START AFRESH
POPJ P,
LSOVS: HLRE T2,PH.RDX ;GET - NO. OF SYMBOLS
MOVM T3,T2 ;+
ADD T3,HL.S1 ;HIGHEST LOCATION
ADD T3,SPACE ;PLUS BUFFER SPACE
ADD T3,PATSPC ;AND PATCHING SPACE
IOR. T3,.PGSIZ ;UP TO PAGE BOUND
ADDI T3,1 ;NEXT FREE
ADD T3,T2 ;START OF SYMBOLS
HLL T3,PH.RDX ;- COUNT
MOVEM T3,JOB116
MOVEM T3,.JBSYM(T1) ;STORE SYMBOL TABLE PTR
JRST NOLOCS ;BUT DON'T READ IN
>
;HERE TO SETUP CORRECT LC/HC PAGES
;WRITE OUT ALL OF CURRENT (UPTO START OF LAST LOC IN USE)
;ALLOCATE INITIALLY 1 BLOCK (IT WILL EXPAND AS REQUIRED)
LSYP: HRLZ T1,LW.S0(R) ;BASE
HRR T1,UW.S0(R) ;UPPER LIMIT
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;GO TO CORRECT ROUTINE
SKIPGE SYMSEG ;[715] PSECT SPECIFIED?
SKIPA T2,P4 ;[715] YES,
HRRZ T2,HL.S0(R) ;THIS IS THE LOCATION WE REQUIRE
ANDCMI T2,.IPM ;WILL BE LOWER PAGE BOUND
MOVEM T2,LW.S0(R) ;STORE IT NOW
IORI T2,.IPM ;THENCE UPPER BOUND
EXCH T2,UW.S0(R) ;SWAP WITH CURRENT
CAME T2,UW.S0(R) ;IF IDENTICAL
JRST [MOVE T1,UW.S0(R) ;GET UPPER LIMIT
HRLI T1,-.IPM(T1) ;GET LOWER LIMIT FOR THIS BLOCK
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R) ;READ IN TOP BLOCK
JRST LSYP1] ;AND CONTINUE
HRLZ T2,TAB.AB(R) ;WE MUST BLT DOWN THE LAST BLOCK
TLZ T2,.IPM ;AS IT MAY CONTAIN DATA
HRR T2,TAB.LB(R)
MOVEI T1,.IPS(T2) ;BASE OF FREE
BLT T2,-1(T1) ;MOVE IT
LSYP1: HRRZ T1,TAB.LB(R) ;LOWEST LOC IN CORE
ADDI T1,.IPS ;FIRST BLOCK NOW CONTAINS DATA
CAML T1,TAB.AB(R) ;AREA ONLY ONE PAGE LONG?
JRST LSYP2 ;YES, DON'T ZERO NEXT AREA
HRL T1,T1
SETZM (T1) ;ZERO IT
ADDI T1,1 ;FORM BLT PTR
BLT T1,@TAB.AB(R) ;CLEAR ALL OF THIS CORE
;NOW GIVE REST TO NEXT LOWER AREA
LSYP2: MOVE T1,TAB.LB(R) ;GET BASE
IORI T1,.IPM ;MAKE IT ONE BLOCK LONG
MOVEM T1,TAB.AB(R) ;SO WE CAN CORRECTLY COUNT
MOVEI T1,-1(R) ;GET INDEX TO NEXT AREA
SKIPN TAB.LB(T1) ;FIND ONE SETUP (MUST BE)
SOJA T1,.-1 ;SHOULD NEVER GET HERE ANYWAY
MOVE T2,TAB.AB(T1) ;GET HIGHEST IN USE
ADDI T2,1 ;POINT TO NEXT FREE
CAML T2,TAB.LB(R) ;ALREADY HERE?
POPJ P, ;YES, NOTHING WE CAN DO ABOUT IT
SUBI T2,1 ;UPPER LIMIT AGAIN
MOVEM T2,TAB.UB(T1) ;RESET IT FOR LOWER AREA
HRRZI T1,1(T2) ;NEXT FREE WHERE BLOCK WILL GOTO
HRL T1,TAB.LB(R) ;FROM WHERE IN LEFT
HRRZM T1,TAB.LB(R) ;NOW RESET IT
MOVE T2,T1 ;GET A COPY
BLT T1,.IPM(T2) ;THIS BLOCK DOWN
MOVS T2,T2 ;PUT FROM ADDR. IN RIGHT
HRLI T1,(T2) ;NOW FOR ZERO BLT
HRRI T1,1(T2)
SETZM (T2)
TLO T2,.IPM ;STILL HAVE TO SET TOP INUSE
HLRZM T2,TAB.AB(R) ;FOR 1 BLOCK
BLT T1,.IPM(T2) ;THROUGH THIS BLOCK
POPJ P,
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
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
POPJ P, ;[715] EXCEEDED SPACE, RETURN
SKIPGE LSCNT ;DO WE HAVE SOMETHING TO GIVE BACK?
PUSHJ P,RDUSYM ;YES, SAFE TO DO SO NOW
JRST LSLOOP ;AND BACK FOR MORE
LSLUPC: PUSHJ P,SYMOUT ;OUTPUT IT
POPJ P, ;[715] EXCEEDED SPACE, RETURN
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 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
MOVNI T1,3
ADDB T1,LSCNT ;REDUCE COUNT IN THIS BLOCK
JRST CPOPJ1 ;SKIP RETURN
;HERE TO GIVE BACK TOP BLOCK OF SYMBOLS
;CAN ONLY BE DONE IF WE HAVE FINISHED WITH CURRENT SYMBOL
;AND ITS SECONDARY TRIPLETS
;SPECIFICALLY TITLE SECONDARIES MUST NOT BE DELETED UNTIL
;TITLE IS OUTPUT
RDUSYM: MOVE T1,LS.PT ;GET LOWEST ADDRESS WE STILL NEED
IORI T1,.IPM ;FORM BLOCK BOUND
MOVE T2,LS.AB ;PREV TOP
SUBI T2,(T1) ;LENGTH
JUMPE T2,CPOPJ ;JUST IN CASE
HRLZ T3,T1 ;FORM BLT PTP
HRRI T3,1(T1)
SETZM (T1) ;CLEAR FIRST WORD
EXCH T1,LS.AB ;SET IT SO
BLT T3,(T1)
MOVEI T1,.IPS ;RESET COUNT
ADDM T2,LSCNT ;RESET WORD COUNT
MOVN T2,T2 ;NEGATE IT
SKIPE UW.LS ;LEAVE ALONE IF NOT PAGING
ADDM T2,UW.LS ;ADJUST UPPER WINDOW
POPJ P,
;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
SKIPE T1,FX.LB ;ANY FIXUPS LEFT
SOJA T1,.+2 ;YES, BETTER LEAVE AREA WHERE IT IS
MOVE T1,.JBREL ;MOVE LAST BLOCK TO A SAFE PLACE
MOVE T2,T1 ;GET A COPY FOR END OF BLT
ANDCMI T1,.IPM ;AT TOP OF CORE
CAMG T1,LS.LB ;SAME AREA BLT FROM/TO?
JRST PAGSY2 ;YES, DON'T CLEAR IT!
MOVEI T3,-1(T1) ;END OF VACATED AREA
CAMLE T3,LS.AB ;CLEAR ALL OF IT?
MOVE T3,LS.AB ;NO, JUST PART NOT DONE
HRL T1,LS.LB ;SO WE HAVE THE HOLE IN THE MIDDLE
BLT T1,(T2) ;GO
HRRZ T1,LS.LB ;NOW TO ZERO THE JUNK WE LEFT BEHIND
SETZM (T1) ;FIRST WORD
HRL T1,T1
ADDI T1,1 ;BLT PTR
BLT T1,(T3) ;CLEAR 200 WORDS (USUALLY)
PAGSY2: MOVE T1,T2 ;
MOVEM T1,LS.UB ;ABSOLUTE NEW TOP
MOVEM T1,LS.AB ;NO FREE SPACE (AB SAME)
SUB T1,LS.LB ;+DIFF (TOTAL AREA - 1)
ANDCMI T1,.IPM ;DON'T COUNT PART IN USE
ADDM T1,LS.LB ;FIXUP PTRS
ADDM T1,LS.PT
MOVEI T1,LS.IX ;ACCOUNT FOR NEW FREE SPACE
PUSHJ P,ADJ.L ;BY GIVING IT TO NEXT LOWER AREA
;NOW CHECK TO SEE IF AREA IS BIG ENOUGH
PAGSY1: PUSHJ P,FR.CNT## ;SEE WHATS FREE
LSH T1,-1 ;CUT IN HALF
ANDCMI T1,.IPM ;BUT KEEP ON A BLOCK BOUND
JUMPE T1,[MOVEI T1,(R) ;AREA
MOVEI T2,2*.IPS ;SIZE
PUSHJ P,EXPSYM ;INCREASE SYMBOL SIZE
MOVNI T1,2*.IPS ;NOW GIVE BACK SPACE
ADDM T1,TAB.AB(R)
JRST PAGSY1] ;AND TRY AGAIN
CAMLE T1,LW.LS ;DO WE NEED ALL OF THIS SPACE
MOVE T1,LW.LS ;NO, JUST USE ENOUGH
MOVN T1,T1 ;-INCREASE IN SIZE
ADDM T1,LS.LB ;ADJUST LOWER BOUND
MOVEI T2,LS.IX-1 ;NOW TO FIND NEXT LOWER BOUND
SKIPN TAB.LB(T2) ;IN USE
SOJA T2,.-1
MOVE T3,TAB.AB(T2) ;GET UPPER BOUND OF NEXT LOWER
CAML T3,LS.LB ;IS THERE ENOUGH ROOM?
AOJA T3,[SPUSH <P1,P2> ;SAVE
MOVEI P1,LS.IX ;AREA TO EXPAND
MOVM P2,T1 ; AND SIZE
ADDM P2,LS.LB ;ADD BACK
PUSHJ P,LNKCOR## ;GET THE SPACE
PJRST NO.COR## ;SHOULD NEVER OCCUR
SPOP <P2,P1> ;RESTORE
PJRST PAGSYM] ;GO GET SYMBOLS
MOVE T3,LS.LB ;BOTTOM OF THIS AREA
SUBI T3,1 ;-1 IS TOP OF NEXT
MOVEM T3,TAB.UB(T2) ;TAKE IT ALL (SHUFFLER WILL GET US OUT OF TROUBLE)
ADDM T1,LW.LS ;BACKUP WINDOW
HRLZ T1,LW.LS ;FORM INPUT PTR
HRR T1,UW.LS ;LOWER ,, UPPER
PUSHJ P,LS.IN## ;INPUT AREA
JRST CPOPJ1 ;SKIP RETURN
;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
.ERR. (MS,.EC,V%L,L%F,S%F,CNW)
.ETC. (STR,,,,,,<FNDNIC>)
SYMOUT: AOS T1,TAB.PT(R) ;SEE IF ENOUGH TO STORE 2 WORDS
SKIPG T2,SYMLIM ;[715] IS IT LIMITED BY NEXT PSECT?
JRST SYMO4 ;[715] NO,
PUSH P,T1 ;[715] YES, SAV T1
SUB T1,LC.LB ;[715] MINUS WINDOW
ADD T1,LW.LC ;[715] CONVERT TO VIRTUAL ADDR
CAMGE T1,SYMLIM ;[715] EXCEEDED THE LIMIT
JRST [POP P,T1 ;[715] RESTURE T1
JRST SYMO4] ;[715] AND RETURN
SKIPN SSGNAM ;[727] HAVE A NAME TO OUTPUT?
JRST SYMOE1 ;[727] NO, JUMP OVER OUTPUTTING NAME
.ERR. (MS,.EC,V%L,L%W,S%W,ISS,<Insufficient space for symbol table>)
.ETC. (STR,.EC,,,,,< after PSECT >)
.ETC. (SBX,.EP!.EC,,,,SSGNAM)
.ETC. (STR,,,,,,<--Table truncated>)
JRST SYMOE2 ;[727]
SYMOE1: .ERR. (MS,.EC,V%L,L%W,S%W,ISS)
.ETC. (STR,,,,,,<--table truncated>)
SYMOE2: SOS TAB.PT(R) ;[727] DECREMENT ONE
POP P,T1 ;[715]
POPJ P, ;[715] ERROR RETURN
SYMO4: CAMG T1,TAB.AB(R)
JRST SYMO1 ;YES
;SEE IF WE CAN JUST EXPAND
CAML T1,TAB.UB(R) ;INTO FREE SPACE?
JRST SYMO2 ;NO, EXPAND OR WRITE PAGE OUT
MOVEI T2,.IPS ;PAGE SIZE
ADDM T2,TAB.AB(R) ;ACCOUNT FOR IT
SKIPE UW.S0(R) ;IF PAGING THIS SEGMENT
ADDM T2,UW.S0(R) ;INCREASE WINDOW
;FALL INTO SYMO1
SYMO1: AOS T1,TAB.PT(R) ;POINT TO NEXT FREE
DMOVEM W2,-2(T1) ;STORE SYMBOL & VALUE
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
POPJ P,
;HERE WHEN NOT ENOUGH ROOM
SYMO2: SKIPE PAG.S0(R) ;PAGING?
JRST SYMO3 ;YES, NOT WORTH EXPANDING, JUST OUTPUT IT
MOVE T1,R ;EITHER LC.IX OR HC.IX
MOVEI T2,.IPS ;EXPAND THIS MUCH
PUSHJ P,EXPSYM ;GET SPACE
JRST SYMO1 ;AND STORE
;SUBROUTINE TO EXPAND CORE, BUT NOT TO PAGE SYMBOLS
;USUALLY CALLED TO CAUSE OTHER AREA TO START PAGING
;CALLED BY
; MOVEI T1,AREA
; MOVEI T2,SIZE
; PUSHJ P,EXPSYM
EXPSYM: PUSHJ P,.SAVE2## ;USES P1, P2
SETOM LS.PP ;PROHIBIT PAGING OF SYMBOLS
DMOVE P1,T1 ;GET ARGS
PUSHJ P,LNKCOR## ;MUST BE ABLE TO GET IT
JRST NO.COR## ;SHOULD NEVER HAPPEN
;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: 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
CAIA
PUSHJ P,RDJBH ;SET UP JOBDAT IN HIGH
SETZM LS.PP ;BACK AS BEFORE
POPJ P,
;HERE WHEN WE HAVE TO OUTPUT CORE
;THERE IS NO NEED TO KEEP ANY OF IT SO OUTPUT IT ALL
SYMO3: AOS T1,TAB.PT(R) ;POINT TO NEXT FREE
TRNE T1,1 ;SEE IF 1 FREE LOC
MOVEM W2,-2(T1) ;YES, OUTPUT HALF OF SYMBOL
HRLZ T1,LW.S0(R) ;OUTPUT ALL OF WINDOW
HRR T1,UW.S0(R)
PUSHJ P,@[EXP LC.OUT##,HC.OUT##]-1(R) ;GO TO CORRECT ROUTINE
SKIPGE SYMFRM ;NEED OLD SYMBOLS (RADIX50)
PUSHJ P,OLDSYM ;YES
HRRZ T1,TAB.LB(R) ;NOW TO CLEAR JUNK
HRLI T1,(T1)
ADDI T1,1 ;LOW,,LOW+1
SETZM -1(T1)
BLT T1,@TAB.AB(R) ;TO HIGH
MOVE T1,UW.S0(R) ;PREVIOUS HIGH WINDOW
ADDI T1,1 ;NEW LOW
MOVEM T1,LW.S0(R)
IORI T1,.IPM ;NEW HIGH IS END OF PAGE
MOVEM T1,UW.S0(R)
MOVE T1,TAB.PT(R) ;GET POINTER (JUST BEYOND END OF CORE)
ANDI T1,.IPM ;SO JUST KEEP OFFSET IN THIS PAGE
IOR T1,TAB.LB(R) ;ADD IN BASE
MOVEM T1,TAB.PT(R) ;AND STORE
TRNN T1,1 ;DID WE STORE 1 WORD BEFORE?
MOVEM W2,-2(T1) ;NO, DO SO NOW
MOVEM W3,-1(T1)
IORI T1,.IPM ;LAST ADDRESS IN BLOCK
MOVEM T1,TAB.AB(R) ;NOW WINDOWS MATCH
JRST CPOPJ1 ;[715] SKIP RETURN
;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## ;
;HERE TO MOVE SYMBOLS TO TOP OF CORE
;IF SORTING PUT SORT BUFFER IN AREA GS
SYMINI: SKIPE FX.LB ;ANY FIXUPS LEFT?
PUSHJ P,MOVFX ;YES, MUST MOVE THEM UP
SKIPN UW.LS ;IF LOCAL SYMBOLS ON DSK?
PJRST MOVSYM ;NO, JUST MOVE UP
; PJRST LKPSYM ;READ BACK INTO CORE
;HERE TO WRITE OUT END OF SYMBOL TABLE AND SET IT UP FOR SORTING
LKPSYM: SKIPL UW.LS ;IF -1 THEN SYMBOL TABLE NOT OUTPUT YET
JRST RDSYM ;JUST READ IT BACK IN
MOVE T1,LSYM ;ADRESS OF LAST SYMBOL STORED +1
SUBI T1,1
IORI T1,.IPM ;BLOCK BOUND
HRL T1,LW.LS ;FORM BLT WORD
HRRZM T1,UW.LS ;SIGNAL ALL OF SYMBOLS ON DSK
PUSHJ P,LS.OUT## ;AND OUTPUT IT
;FALL INTO RDSYM TO READ IT BACK
RDSYM: PUSHJ P,MOVSYM ;MOVE WHAT WE HAVE UP IN CORE
;AT THIS POINT THERE IS NO NEED TO READ
;MORE SYMBOLS, THAT WILL HAPPEN NEXT TIME ANYWAY
;UNLESS WE ONLY HAVE ONE BLOCK IN CORE
;THIS CASES PROBLEMS SO READ IN MORE
MOVE T1,UW.LS ;UPPER LIMIT
ANDCMI T1,.IPM ;START OF THIS PAGE
CAME T1,LW.LS ;IS IT THE LOWER PAGE BOUND?
POPJ P, ;NO, JUST RETURN
MOVEI T1,LS.IX-1 ;YES, SEE HOW MUCH SPACE WE HAVE WITHOUT SHUFFLING
SKIPN TAB.LB(T1) ;USUAL LOOK FOR LOWER AREA
SOJA T1,.-1
MOVE T2,LS.LB ;WHERE WE START AT
SUB T2,TAB.AB(T1) ;MINUS WHATS IN USE
SUBI T2,1 ;COUNT OF WHATS FREE
LSH T2,-1 ;CUT IN HALF
ANDCMI T2,.IPM ;ON BLOCK BOUND
CAMLE T2,LW.LS ;BUT DON'T GET TOO MUCH
MOVE T2,LW.LS ;IF WE DON'T HAVE ENOUGH SYMBOLS
MOVN T2,T2 ;GET NEG SO WE CAN BACKUP
ADDM T2,LS.LB ;MOVE DOWN IN CORE
ADDM T2,TAB.UB(T1) ;AND TAKE THIS SPACE
ADDM T2,LW.LS ;OPEN WINDOW WIDER
MOVE T1,UW.LS ;GET TOP OF WINDOW
SUBI T1,.IPS ;BUT WE ALREADY HAVE THIS PAGE
HRL T1,LW.LS ;FORM TRANS WORD
PJRST LS.IN## ;READ IT IN
;HERE IF TOP OF SYMBOL TABLE IS ALREADY IN CORE
;HOWEVER IT IS NOT AT TOP OF CORE WHERE WE WOULD LIKE IT
;THEREFOR MOVE ALL LS UP TO .JBREL
;USE REVERSE BLT IN ACCS
MOVSYM:
IFN FTOVERLAY,<
SKIPLE LNKMAX ;ANY OVERLAYS
SKIPN LNKNO. ;BUT NOT ROOT
JRST .+3 ;NO
MOVE T1,LS.UB ;CAN NOT USE TOP OF CORE
JRST .+4
>
SKIPE T1,FX.LB ;STILL FIXUPS TO DO?
SOJA T1,.+2 ;YES, MAKE T1 POINT TO HIGHEST FREE
MOVE T1,.JBREL ;NO, GET TOP OF CORE
CAMN T1,LS.AB ;AT ACTUAL TOP OF LS?
POPJ P, ;YES, JUST RETURN
MOVEM T1,LS.UB ;MAKE IT TOP
SUB T1,LS.AB ;GET DIFFERENCE = OFFSET
PUSH P,T1 ;SAVE OFFSET
MOVE T4,LS.AB ;TOP
SUB T4,LS.LB ;-BOTTOM
ADDI T4,400001 ;400000+LENGTH
MOVS T4,T4
HRR T4,LS.AB ;TOP OF OLD DATA
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVSI T3,(POPJ P,) ;REVERSE BLT NOW SET UP
PUSHJ P,T1 ;DO IT
MOVE T2,LS.AB ;[647]
MOVE T1,LS.UB
MOVEM T1,LS.AB ;SET BOUNDS THE SAME
POP P,T1 ;OFFSET
ADD T1,LS.LB ;NEW BASE
SUBI T1,1 ;HIGHEST TO GIVE BACK
HRL T1,T2 ;[647] HIGHEST ADDR TO ZERO
PUSHJ P,GBCK.L##
MOVE T1,LSYM ;NOW RESET LS.PT TO POINT TO LAST SYMBOL
SUB T1,LW.LS ;MINUS WINDOW BASE
ADD T1,LS.LB ;PLUS OFFSET IN CORE
MOVEM T1,LS.PT ;OK NOW
POPJ P,
;HERE TO ADD FREE SPACE TO NEXT LOWEST AREA IN USE
;CALLED BY
; MOVEI T1,THIS AREA
; PUSHJ P,ADJ.L
;USES T1, T2
ADJ.L: MOVE T2,TAB.LB(T1) ;GET CURRENT LOWEST SIZE
SUBI T2,1 ;THIS IS NOW UPPER OF NEXT LOWER
SKIPN TAB.LB-1(T1) ;FIND ONE
SOJA T1,.-1 ;EVENTUALLY
MOVEM T2,TAB.UB-1(T1)
POPJ P, ;RETURN
;HERE IF WE HAVE TO MOVE FIXUP AREA (IT MAY CONTAIN SYMBOL FIXUPS)
;MOVE UP TO VERY TOP OF CORE, OUT OF WAY OF SYMBOLS
;USE REVERSE BLT IN ACCS
MOVFX: MOVE T1,.JBREL ;GET TOP OF CORE
CAMN T1,FX.AB ;AT ACTUAL TOP OF FIXUPS?
POPJ P, ;YES, JUST RETURN
MOVEM T1,FX.UB ;MAKE IT TOP
SUB T1,FX.AB ;GET DIFFERENCE = OFFSET
PUSH P,T1 ;SAVE OFFSET
MOVE T4,FX.AB ;TOP
SUB T4,FX.LB ;-BOTTOM
ADDI T4,400001 ;400000+LENGTH
MOVS T4,T4
HRR T4,FX.AB ;TOP OF OLD DATA
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVSI T3,(POPJ P,) ;REVERSE BLT NOW SET UP
PUSHJ P,T1 ;DO IT
MOVE T1,FX.UB
MOVEM T1,FX.AB ;SET BOUNDS THE SAME
POP P,T1 ;OFFSET
ADDM T1,FX.PT
ADD T1,FX.LB ;NEW BASE
SUBI T1,1 ;HIGHEST LOC TO GIVE AWAY
PJRST GBCK.L## ;TO NEXT LOWER
SYDONE: SKIPE PAG.S1 ;PAGING LOW SEG?
SKIPA P1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE P1,LC.LB ;LOAD UP OFFSET
SKIPE PAG.S2 ;PAGING HIGH SEG?
SKIPA P2,JBHPTR ;YES, LOAD CORRECT OFFSET
MOVE P2,HC.LB ;LOAD UP OFFSET
MOVE T2,.JBSYM(P1) ;GET ADDRESS OF BASE OF SYMBOLS
HRRZ T3,TAB.PT(R) ;AND CURRENT TOP
SUB T3,TAB.LB(R) ;REMOVE OFFSET
ADD T3,LW.S0(R) ;BUT ADD IN BASE OF INCORE WINDOW
CAMG T3,HC.S0(R) ;[715] PSECT NAME USED?
JRST .+3 ;[715] YES, DON'T UPDATE
MOVEM T3,HC.S0(R) ;RESET HIGHEST LOC IN USE COUNTERS
MOVEM T3,HL.S0(R) ;SO WE WILL PRESERVE THE SYMBOLS
ADD T3,LL.S0(R) ;ADD IN SEGMENT OFFSET
SUBI T2,0(T3) ;FIND - LENGTH
HRLM T2,.JBSYM(P1) ;FIXUP SYMBOL TABLE POINTER
HRLM T2,JOB116 ;AND FOR .SYM FILE
SKIPGE SYMFRM ;OLD STYLE SYMBOL FILE REQUIRED?
PUSHJ P,OLDSYM ;YES, WRITE OR COMPLETE IT
.ERR. (MS,0,V%L,L%I,S%I,STC,<Symbol table completed>)
JRST REMVLS ;SETUP REST AND DELETE LS AREA
NOLOCS: SKIPE PAG.S1 ;PAGING LOW SEG?
SKIPA P1,JOBPTR ;YES, LOAD CORRECT OFFSET
MOVE P1,LC.LB ;LOAD UP OFFSET
SKIPE PAG.S2 ;PAGING HIGH SEG?
SKIPA P2,JBHPTR ;YES, LOAD CORRECT OFFSET
MOVE P2,HC.LB ;LOAD UP OFFSET
REMVLS:
SKIPLE T1,SYMFRM ;NEW STYLE SYMBOL FILE NEEDED?
PUSHJ P,SAVSYM ;YES, OUTPUT THEM NOW
PUSHJ P,AS.ZAP ;DONE WITH ALGOL SYMBOLS
PUSHJ P,FX.ZAP ;ALSO DONE WITH FIXUP BY NOW
IFN FTOVERLAY,<
SKIPL LNKMAX ;OVERLAYS?
JRST SAVTST ;KEEP UNTIL SAV FILE MADE
>
PUSHJ P,LS.ZAP ;GET RID OF LS
SKIPN PAG.LS ;IF NOT PAGING
JRST SAVTST ;DON'T DELETE LS FILE
MOVEI T1,SC ;CAN DELETE CHAN# NOW
PUSHJ P,DVDEL.##
JFCL
SAVTST: SKIPE IO.PTR+%VC ;SAVE FILE REQUIRED?
JRST JBSAVE ;YES
JRST JBEXIT ;NO, EXECUTE OR FORM CORE IMAGE
SUBTTL ROUTINES FOR SYMBOLS
LTITLE: 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
JUMPE T2,.+2 ;IGNORE IF FIRST TIME
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
SETZB W2,W3 ;ONLY HERE IF DEFINED BY /SWITCH
SKIPE W3 ;IF ANY HIGH SEG STUFF
MOVE W2,W3 ;USE IT
POP P,W3 ;GET W3 BACK
HLR W3,W2 ;FIX IT UP
POP P,W2
PUSHJ P,SYMOUT ;OUTPUT PSEUDO SYMBOL
POPJ P, ;[715] EXCEEDED SPACE, RETURN
JRST LSLOOP ;RETURN
BTITLE: TXO W2,R5.LCL!R5.GLB ;MAKE RADIX50 14,SYM
HRRZ W3,W3 ;BLOCK LEVEL ONLY
JRST LSLUP1 ;AND TREAT AS LOCAL SYMBOL
;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 )
SALL
;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)
PUSH P,[MC]
.ERR. (ST,,V%L,L%W,S%W,OES,<Output error on symbol file, file closed, job 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 T1,TAB.LB(P1) ;ALSO MAKE SURE DISK FILE IS OK
ADD T1,TAB.PT(P1) ;IN CASE NEVER OUTPUT BEFORE
JUMPE T1,.+4 ;FORGET IT IF NOTHING TO OUTPUT
ADD T1,TAB.LW(P1) ;NOTE WE'RE GETTING EXACT WORD CNT
HRL T1,TAB.LW(P1) ;ALGOL 7 NEEDS .RBSIZ EXACT
PUSHJ P,@TB.OUT##(P1) ;SO USE XX.PT INSTEAD OF XX.AB
MOVE T1,TAB.AB(P1) ;NOW READ IN FRONT OF FILE
SUB T1,TAB.LB(P1) ;SO CAN SET UP 10??,,COUNT
SETZM TAB.LW(P1) ;?W.?S MUST BE UP TO DATE
MOVEM T1,TAB.UW(P1) ;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 T2,ASYM ;YES, GET SYMBOL COUNT
HRLI T2,1044 ;AND BLOCK TYPE
JRST SAVSY1 ;AND CONTINUE
SAVSY0: MOVE T2,LSYM ;COUNT FOR LS AREA
HRLI T2,1700 ;AND BLOCK TYPE
SAVSY1: SUBI T2,1 ;WORDS FOLLOWING IS 1 LESS
MOVEM T2,@TAB.LB(P1) ;STORE COUNT WORD
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,DC ;USE THIS CHAN
MOVEM T1,IO.CHN
MOVE T1,IO.PTR+%SC ;HIDE DATA BLOCK HERE
MOVEM T1,IO.PTR+DC ;NOW BRING IT FORTH
PUSHJ P,DVCHN.## ;PUT ADDRESS OF BLOCK IN T1
MOVSI T2,(Z DC,) ;RESET CHAN # IN AC 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 DC,T1 ;OUTPUT IT
PJRST DVRLS.## ;PAGING NO LONGER HANDLED HERE
PUSH P,[DC]
.ERR. (ST,,V%L,L%W,S%W,OES)
POPJ P,
SUBTTL GENERATE .EXE (OR .XPN/.SHR/.HGH/.LOW) FILE
;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
;HERE TO SETUP SAVED LOCATIONS
JBSAVE: .ERR. (MS,0,V%L,L%I,S%I,CSF,<Creating saved file>)
SKIPE PAG.S1 ;PAGING?
SKIPA P1,JOBPTR ;YES
MOVE P1,LC.LB ;NO, USE INCORE ADDRESS
SKIPE PAG.S2 ;PAGING HIGH SEG?
SKIPA P2,JBHPTR ;YES, LOAD CORRECT OFFSET
MOVE P2,HC.LB ;LOAD UP OFFSET
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)
>
PUSHJ P,JOBSET ;SETUP REST OF JOBDAT
HLRZ T1,.JBSA(P1) ;ALSO SETUP RIGHT HALF OF .JBCOR
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
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
PUSHJ P,HJBSET ;SETUP VESTIGIAL JOB DATA AREA (HIGH)
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
HRLZ T1,LW.S2 ;LOWER WINDOW
HRR T1,UW.S2 ;UPPER WINDOW
PUSHJ P,HC.OUT## ;OUTPUT LAST BLOCKS
SETZM LW.S2 ;START BACK AT ZERO
MOVEI T1,.IPM ;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
PUSH P,[DC]
.ERR. (ST,,V%L,L%F,S%F,SOE,<SAVE file output error>)
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
IFE TOPS20,<
MOVSI T1,'SAV' ;EXT IS NOW SAV NOT LOW
>
IFN TOPS20,<
MOVSI T1,'EXE' ;EXT IS NOW EXE 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
HRLZ T1,LW.S1 ;GET LOWER WINDOW
HRR T1,UW.S1 ;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
SETZM LW.S1 ;START AT LOWEST LOCATION
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 T1,LS.LB ;CAN ONLY USE TO BOTTOM OF LS
;AREA IF IT'S STILL THERE
SKIPA T1,.JBREL ;IF IT'S NOT, CAN USE ALL OF CORE
SUBI T1,1 ;LAST TO USE IS START OF LS - 1
MOVEM T1,LC.UB ;RESET POINTERS
MOVEM T1,LC.AB ;FOR CONSISTENCY
SUB T1,LC.LB ;MINUS WHAT WE ALREADY HAVE
MOVEM T1,UW.S1 ;ASSUME IT WON'T FIT
CAMGE T1,HC.S1 ;ENOUGH EXTRA FOR ALL OF FILE?
JRST JBSAV1 ;NO, DO IT THE HARD WAY
MOVE T1,HC.S1 ;WE NEED ONLY THIS MUCH
IORI T1,.IPM ;ROUNDED UP
MOVE T2,T1 ;CAN ALSO CUT BACK LC.AB
ADD T2,LC.LB ;TO WHAT WE ACTUALLY NEED
MOVEM T2,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 ;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 SETUP REST OF JOBDAT AREA
;ENTER WITH P1 POINTING TO JOBDAT AREA
;AND P2 TO HIGH DATA AREA (0 IF NO HIGH SEG)
JOBSET: SKIPE T2,HC.S1 ;GET HIGHEST DATA LOCATION LOADED
SUBI T2,1 ;MAKE IT HIGHEST LOC LOADED
IFN FTOVERLAY,<
SKIPL LNKMAX ;LOADED ANY OVERLAYS?
SKIPN T1,JOB116 ;AND SAVED SYMBOLS?
JRST .+4 ;NO
HLRE T2,T1 ;-LENGTH
MOVM T2,T2
ADDI T2,-1(T1) ;HIGHEST LOCATION
>
HRLZM T2,.JBCOR(P1) ;PUT HIGHEST LOC IN LEFT HALF
HRRZ T2,HL.S1 ;GET HIGHEST LOC REQUIRED
HRL T2,STADDR ;GET STARTING ADDRESS
MOVSM T2,.JBSA(P1) ;SET .JBSA AND .JBFF
HRRZM T2,.JBFF(P1) ;INCASE RESET NOT DONE FIRST
IOR. T2,.PGSIZ ;INCLUDE ALL OF THIS PAGE
HRRZM T2,.JBREL(P1) ;SET .JBREL
MOVSI T2,(HALT) ;PUT A HALT IN .JB41
SKIPN .JB41(P1) ;UNLESS ALREADY SETUP
MOVEM T2,.JB41(P1)
MOVE T2,.JBSYM(P1) ;GET SYMBOL TABLE POINTER
HRRZ T1,T2 ;GET POINTER
JUMPE P2,JOBST0 ;NO HIGH SEG POSSIBLE
CAML T1,LL.S2 ;SEE IF IN HIGH SEG
MOVEM T2,.JBHSM(P2) ;STORE IN HIGH SEG DATA AREA
SKIPE T1,HL.S2 ;GET HIGHEST LOC +1
SUBI T1,1 ;HIGHEST LEGAL ADDRESS
ADD T1,LL.S2 ;PLUS ORIGIN
IOR. T1,.PGSIZ ;PUT ON PAGE BOUND
SKIPN T2,HL.S2 ;[650] LENGTH TO SAVE
JRST JOBST1 ;[650] NONE?
SKIPN .JBDDT##(P1) ;[650] DDT LOADED?
JRST JOBST1 ;[650] NO, NUMBER IS OK
SUBI T2,1 ;[650] YES, BE LIKE MONITOR
IOR. T2,.PGSIZ ;[650] ROUND UP TO TOP OF PAGE
ADDI T2,1 ;[650] THENCE TO BOTTOM OF NEXT
JOBST1: HRL T1,T2 ;[650] LENGTH TO SAVE,,HIGHEST ADDR
MOVEM T1,.JBHRL(P1) ;LENGTH,,HIGHEST ADDRESS
JOBST0: MOVE T1,.JBERR ;GET NO OF PREVIOUS ERRORS
MOVEM T1,.JBERR(P1) ;COUNT AS EXECUTION ERRORS
MOVEM T1,ERRNO ;PROHIBIT EXECUTION IF NON-ZERO
;NOW SETUP STARTING ADDRESS FOR EXECUTION
SETZ T1, ;INITIALLY ZERO
SKIPE EXECSW ;GO INTO EXECUTION?
MOVE T1,STADDR ;YES, ASSUME .JBSA
SKIPGE DEBUGSW ;UNLESS DEBUG
MOVE T1,.JBDDT(P1) ;INWHICH CASE ASSUME DDT SETUP
HRRM T1,EXECSW ;IN ANY CASE STORE BACK IN EXECSW
POPJ P,
;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 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,
IFN FTOVERLAY,<
;HERE TO DELETE LS FILE
LS.DLT: SETZM PAG.LS
MOVEI T1,SC
PUSHJ P,DVDEL.##
JFCL
POPJ P,
>
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
MOVEI T1,.DBM ;YES
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
MOVEI T1,.DBM ;NOW WRITE IT BACK
PJRST HC.OUT## ;WRITE IT BACK
;BUT IS IT THE RIGHT F/S
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,XPNERR
PUSHJ P,DVRLS.## ;RELEASE DEV
PJRST DVZAP.## ;FORGET ABOUT .XPN FILE NOW
XPNERR: PUSH P,[LC]
.ERR. (ST,,V%L,L%W,S%W,OEX,<Output error on XPN file, file closed, job continuing>)
POPJ P,
IFN FTEXE,<
;HERE FOR EXECUTABLE FILE
;THE ACTIONS IS
;RESERVE SPACE FOR DIRECTORY (1 PAGE)
;WRITE OUT LOW SEGMENT REMOVING ALL ZERO BUT ALLOCATED PAGES
;THEN WRITE OUT THE HIGH SEGMENT THE SAME WAY
;NOW GO BACK AND WRITE THE DIRECTORY
;NOTE, PAGE 0 AND FIRST PAGE OF HIGH SEGMENT ARE ALWAYS WRITTEN
JBEXE: SKIPN HC.LB ;ANY HIGH SEGMENT?
JRST JBEXEN ;NO,
SKIPN T1,UW.S2 ;IS IT PAGED?
JRST JBEXEH ;NO,
HRL T1,LW.S2 ;OUTPUT WORD
PUSHJ P,HC.OUT ;MAKE SURE IT GET OUT
MOVE T1,UW.S2
SUB T1,LW.S2 ;GET LENGTH
MOVEM T1,UW.S2 ;RESET IT
SETZM LW.S2 ;BACK TO FRONT OF FILE
PUSHJ P,HC.IN ;READ IT BACK
JBEXEH: PUSHJ P,HJBSET ;YES, SETUP VESTIGIAL JOBDAT
SKIPE JBHPTR ;WAT 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
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
MOVEM T1,LW.S1 ;[732] NO, START AT LOWEST LOC
JRST JBEXE1] ;[732]
HRLZ T1,LW.S1 ;GET LOWER WINDOW
HRR T1,UW.S1 ;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 T1,HC.LB ;YES, HIGH SEG STILL EXISTS
SUBI T1,1 ;TOP OF LOW
MOVEM T1,LC.UB ;RESTORE POINTERS
JRST JBEXER ;GO MAKE PAGE BOUND AND CHECK ROOM
JBEXEA: SKIPN T1,LS.LB ;TO BOTTOM OF LS, IF IT'S THERE
SKIPA T1,.JBREL ;IF NOT, ALL OF CORE
SUBI T1,1
MOVEM T1,LC.UB ;RESER
JBEXER: SUB T1,LC.LB ;MAKE SURE
SUBI T1,777 ;WE ARE ON A PAGE BOUND
IORI T1,777 ;...
ADD T1,LC.LB ;ADD IN BASE
MOVEM T1,LC.AB ;FOR CONSISTANCY
SUB T1,LC.LB ;MINUS WHAT WE ALREADY HAVE
MOVE T3,HC.S1 ;[762]
SUB T3,LOWLOC ;[762] GET ACTUALLY NEEDED LENGTH
IORI T3,777 ;[762]
CAMGE T1,T3 ;[762] COMPARE WHAT WE HAVE AND WHAT WE NEED
JRST [ADD T1,LW.S1 ;[762] WE HAVE LESS THAN WE NEED
MOVEM T1,UW.S1 ;[762] UPDATE UPPER WINDOW VALUE
HRL T1,LW.S1 ;[762]
PUSHJ P,LC.IN ;READ IN AS MUCH AS WE CAN
JRST JBEXE1]
MOVE T1,T3 ;[762] WE HAVE MORE THAN WE NEED
ADD T1,LW.S1 ;[762] UPDATE UPPER WINDOW VALUE
MOVEM T1,UW.S1 ;[762]
HRL T1,LW.S1 ;[762]
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?
PUSHJ P,BLTJDA ;BLT .JBDA TO LOW SEG
; JRST EXEINI
;HERE TO OPEN EXE FILE
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
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,4 ;[744] 1 FOR REMAINDER, 1 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
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 [PUSH P,[DC] ;FATAL CHAN
.ERR. (LRE,0,V%L,L%F,S%F,ECE,<Error creating EXE file - >)]
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 compress out pages containing all zeros
;uses acc as follows
;t1 iowd -1000,address
;t2 0 (terminator)
;p1 flags,,file page
;p2 repeat count,,process page
;p3 process address
;P4 FLAGS TO DETERMINE WHAT TO DO WITH THE DIRECTORY ENTRY:
; ZEROF==400000
; DATAF==200000
; GAPF==100000
;
; 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
;w1 store ptr
ZEROF==400000 ;[704]
DATAF==200000 ;[704]
GAPF==100000 ;[704]
XCMPRS: SETZM RC.CUR ;[704] INITIALIZE CURRENT PSECT INDEX
MOVEI R,1 ;MAKE SURE LOW SEGMENT
MOVEM R,EXEBLK ;CONVENIENT 1
USETO DC,5 ;BYPASS DIRECTORY
MOVE P1,[SV%WRT+1] ;FLAGS AND FILE PAGE FOR PAGE 0
SETZB P2,P3 ;CLEAR PROCESS PAGE #
SETZB P4,T2 ;
MOVSI W1,-1000 ;- LENGTH
HRR W1,EXEDIR ;AOBJN PTR
MOVE T3,LOWLOC ;[742] GET LOWEST LOCATION
CAIL T3,2000 ;[742] LOWEST LOCATION IN PAGE0 OR PAGE 1?
JRST XCMPRJ ;[742] NO,
MOVE T1,LC.LB ;[742] YES,
SUBI T1,1 ;[742]
JRST XCMPRL ;[742]
;HERE IF THE LOWEST LOCATION IS IN PAGE 2 OR HIGHER.
;MUST OUTPUT JOBDAT FIRST, THEN CHECK TO SEE IF PAGE0 AND PAGE 1
;IS PART OF .LOW. IF THAT IS THE CASE, OUTPUT A DIRECTORY ENTRY
;TO MAKE THOSE PAGES ALLOCATED.
XCMPRJ: HRR T1,JOBPTR ;[732] OUTPUT JOBDAT DIRECTLY
SUBI T1,1 ;[732]
HRLI T1,-.JBDA+1 ;[732]
OUT DC,T1 ;OUTPUT PAGE 0
TLOA P4,GAPF ;[732] FLAG IT GAP, OUTPUT DIR HERE
JRST XCMPER ;ERROR
USETO DC,9 ;WRITE REST OF PAGE AS 0
DMOVEM P1,1(W1) ;STORE ENTRIES
HRRI P1,2 ;NEXT FREE FILE PAGE
AOBJN W1,.+1 ;
AOBJN W1,.+1 ;[732] ADJUST DIR PTR BY 2 ALSO
MOVE T3,HC.S1 ;[732] NO CODE IN PAGE0, BUT ANY CODE AT ALL?
CAIG T3,.JBDA ;[732]
JRST XCMPR8 ;[732] NO, NOW FOR HIGH SEG
MOVE T2,@RC.TB ;[742] YES,
MOVE T2,RC.CV(T2) ;[742] PAGE 0 AND PAGE 1 IN .LOW.?
CAILE T2,.JBDA ;[742]
JRST [PUSHJ P,XCMPXD ;[742] YES, NEED TO MAKE AN ENTRY
HLLZM P1,(W1) ;[742] IN EXE DIRECTORY
PUSHJ P,XCMPXD ;[742]
HRLZ T2,LOWLOC ;[742] ALLOCATE ALL PAGES UP TO
TLZ T2,2777 ;[742] THAT PAGE THAT CONATAINS LOWLOC
ADDI T2,1 ;[742] BUMP PROCESS PAGE
MOVEM T2,(W1) ;[742]
JRST .+1] ;[742]
MOVE P3,LOWLOC ;[732] YES, GET LOWEST LOCATION
MOVE P2,P3 ;[732] ALSO UPDATE PROCESS PAGE
LSH P2,-^D9 ;[732]
HRR T1,LC.LB ;[742] NOW, READY TO DUMP THE ACTUAL CORE
SUBI T1,1 ;[742]
HRLI T1,-1000 ;[732] ASSUME AT LEAST A PAGE
JRST XCMPR4 ;[732] AND THAT CORE IS ALREADY SETUP
XCMPRL: HRLI T1,-1000 ;SET UP IOWD WORD
XCMPR7: SETZ T2, ;MAKE SURE TERMINATOR IS 0
OUT DC,T1 ;ALWAYS OUTPUT PAGES 0 & 400
TLOA P4,DATAF ;[704] JUST OUTPUT A DATA PAGE
JRST XCMPER ;ERROR
XCMPR0: ADDI T1,1000 ;NEXT PAGE
ADDI P3,1000 ;INCREMENT PROCESS ADDRES
CAILE P3,777777 ;[732] OVERFLOWED INTO LH?
JRST [PUSHJ P,XCMPRD ;[732] YES, WRITE DIR ENTRY OUT
JRST XCMPRH] ;[732] TRY HIGH SEG
XCMPR4: PUSHJ P,INGAP ;[732] CHECK TO SEE IF IN PSECT GAP
JRST XCMPR0 ;[704] YES, SKIP OVER THIS PAGE
MOVEI T3,1(T1) ;ADDRESS ONLY
CAMG T3,TAB.AB(R) ;NEXT PAGE IN CORE
JRST XCMPR1 ;YES
CAMLE P3,HC.S0(R) ;FINISHED?
JRST [PUSHJ P,XCMPRD ;NO, WRITE IT OUT
JRST XCMPRH] ;TRY HIGH SEG
MOVE T3,TAB.AB(R) ;
SUB T3,TAB.LB(R) ;GET SIZE
ADDI T3,1 ;
MOVEM P3,LW.S0(R) ;[713] RESET BASE TO PROCESS PAGE
ADD T3,LW.S0(R) ;[764] GET NEW UPPER WINDOW
CAILE T3,-1 ;[764] MAKE SURE IT DOESN'T OVERFLOW
MOVEI T3,-1 ;[764] JUST IN CASE
MOVEM T3,UW.S0(R) ;[763]
CAMLE T3,HC.S0(R) ;STILL IN RANGE?
JRST [MOVE T3,HC.S0(R) ;NO
IORI T3,.IPM ;GET PAGE LIMIT
MOVEM T3,UW.S0(R) ;SET NEW
SUB T3,LW.S0(R) ;GET LENGTH
ADD T3,TAB.LB(R) ;
MOVEM T3,TAB.AB(R) ;RESET TOP
JRST .+1] ;
HRLZ T1,LW.S0(R) ;LOWER BOUND
HRR T1,UW.S0(R) ;TO UPPER BOUND
PUSHJ P,@[EXP LC.IN##,HC.IN]-1(R) ;READ IN NEW PAGE
MOVE T3,TAB.LB(R) ;RESET INCORE PROCESS ADDRESS
MOVEI T1,-1(T3) ;RESET IOWD ADDRESS
HRLI T1,-1000 ;AND COUNT
XCMPR1: MOVEI T4,(P3) ;[732] MUST USED 2 INSTRS TO DO THIS
ADDI T4,1000 ;[732] INCASE OVERFLOW INTO LH
CAMLE T4,HC.S0(R) ;WHOLE PAGE EXITS?
JRST [MOVE T4,HC.S0(R)
SUBI T4,(P3)
MOVN T4,T4
HRL T3,T4
HRL T1,T4
JRST .+2]
HRLI T3,-1000 ;NORMAL AOBJN WORD
SKIPE (T3) ;LOOK FOR A NON-ZERO
JRST XCMPR3 ;FOUND ONE
AOBJN T3,.-2 ;LOOP FOR ALL OF PAGE
TLNE P4,ZEROF ;[704] GOT A ZERO PAGE, WAS LAST ONE ALSO ZERO?
JRST XCMPR2 ;[704] LAST ONE WAS ALSO ZERO
TLNN P4,DATAF ;[704] NO, WAS LAST ONE DATA?
TLNA P4,GAPF ;[704] NO, MUST HAVE BEEN GAP, SO SKIP
PUSHJ P,XCMPRD ;[704] YES,IT WAS DATA, GO OUTPUT CURRET DIR
TLO P4,ZEROF ;[704] SET ZEROF
TLZ P4,DATAF+GAPF ;[704] AND OFF WITH OTHERS
JRST XCMPR0 ;LOOP AGAIN
;[704] HERE TO SEE OF NEXT PAGE(CORE ADDR IN P3) FALLS IN
;A PSECT GAP. RETURN IF IN GAP. SKIP RETURN IF NOT IN A GAP.
INGAP: CAILE R,1 ;[713] DOING LOW SEG OR ABS?
JRST CPOPJ1 ;[704] NO, DON'T BOTHER, SKIP RETURN
CAMLE P3,HC.S1 ;[724] EXCEEDED ADDR SPACE?
JRST CPOPJ1 ;[724] YES,
PUSH P,R ;[704] USES ACS R, T1, AND T2
PUSH P,T1 ;[704]
MOVE R,RC.CUR ;[704] GET CURRENT PSECT
INGAP1: MOVE T1,@RC.TB ;[704] GET RELOC TABLE ADDR FOR CURRENT PSECT
MOVE T2,RC.SG(T1) ;[704] SET SEGMENT NO.
CAILE T2,1 ;[713] LOW SEG?
JRST INGAP5 ;[724] NO, FORGET IT
MOVE T2,RC.CV(T1) ;[704] GET CURRENT PSECT BREAK
TRO T2,777 ;[704] ROUND UP PSECT BREAK
CAIG P3,(T2) ;[704] ADDR LARGER THAN THE PSECT BREAK?
JRST [MOVE T2,RC.IV(T1) ;[704] MAKE SURE IT IN PSECT RANGE
TRZ T2,777 ;[704] ROUND DOWN
CAIGE P3,(T2) ;[704] IN RANGE?
JRST INGAP3 ;[704] NO, IN GAP
JRST INGAP5] ;[724] YES, DO SKIP RETURN
ADDI R,1 ;[704] ADDR IS GT CURRENT PSECT
CAMLE R,RC.NO ;[704] IS THERE A NEXT PSECT?
JRST INGAP5 ;[724] NO, SKIP RETURN
MOVE T1,@RC.TB ;[704] GET ADDR OF RELOC TABLE
MOVE T2,RC.IV(T1) ;[704] GET ORIGIN
TRZ T2,777 ;[704] ROUND IT DOWN TO PAGE BOUND
CAIL P3,(T2) ;[704] ADDR IS LESS THAN THE ORIGIN?
JRST [MOVEM R,RC.CUR ;[704] UPDATE TO NEXT PSECT
JRST INGAP1] ;[704] AND LOOP FOR ANOTHER CHECK
INGAP3:
IFN FTOVERLAY,< ;[724]
SKIPL LNKMAX ;[724] ANY OVERLAYS (SKIP IF NO)
JRST INGAP4> ;[724] YES,
HRRZ T1,JOB116 ;[724] CHECK TO SEE IF IT'S IN SYMBOL
HLRE T2,JOB116 ;[724] TABLE RANGE
SUBM T1,T2 ;[724] GET TOP
TRZ T1,777 ;[726] ROUND DOWN LOWER BOUND
TRO T2,777 ;[726] ROUND UP UB OF SYMBOL TABLE
CAML P3,T1 ;[724]
CAMLE P3,T2 ;[724] IN RANGE?
JRST INGAP4 ;[724] NO,
INGAP5: POP P,T1 ;[724] YES, RESTORE ACS
POP P,R ;[724]
JRST CPOPJ1 ;[724] SKIP RETURN
INGAP4: POP P,T1 ;[704] YES, IN A GAP, DO NON-SKIP RET
POP P,R ;[704]
TLOE P4,GAPF ;[704] WE HAVE A GAP, WAS LAST PAGE ALSO GAP?
JRST INGAP2 ;[704] BUMP PROCESS PAGE AND RETURN
PUSHJ P,XCMPRD ;[704] NO, WRITE OUT LAST DIR,
TLZ P4,ZEROF+DATAF ;[704] OFF WITH OTHER FLAGS
INGAP2: ADDI P2,1 ;[704] BUMP PROCESS PAGE
POPJ P, ;[704]
;HERE TO WRITE OUT A DIRECTORY ENTRY
XCMPRD: PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
MOVEM P1,(W1) ;STORE DIRECTORY PTRS
TLNE P4,ZEROF ;[704] ZEFO PAGE?
HLLZS (W1) ;YES, SO NO FILE PAGES
PUSHJ P,XCMPXD ;SECOND WORD
MOVEM P2,(W1) ;
LDB T3,[POINT 9,P2,8] ;GET REPEAT COUNT
TLNE P4,DATAF ;[704] DATA PAGE?
ADDI P1,1(T3) ;INCREMENT FILE PTR
ADDI P2,1(T3) ;AND PROCESS PTR
TXZ P2,777B8 ;CLEAR REPEAT COUNT
POPJ P,
;HERE IF WE HAVE A PAGE OF ALLOCATED ZEROES
XCMPR2: ADD P2,[1B8] ;INCREMENT REPEAT COUNT
TLO P4,ZEROF ;[704] WE GOT A ZERO PAGE
TLZ P4,DATAF+GAPF ;[704] OFF OTHER FLAGS
JRST XCMPR0 ;GET NEXT PAGE
;HERE IF NON-ZERO FOUND
;IF WE WERE OUTPUTTING DATA LAST, JUST INCREMENT REPEAT COUNT
;IF NOT, UPDATE DIRECTORY
XCMPR3: SETZ T2, ;MAKE SURE
OUT DC,T1 ;OUTPUT THIS PAGE
CAIA ;OK
JRST XCMPER
TLNE P4,DATAF ;[704] LAST PAGE WAS ALSO DATA?
JRST [ADD P2,[1B8] ;[704] BUMP REPEAT COUNT
JRST XCMPR0] ;[704]
TLNN P4,GAPF ;[704] NO, LAST PAGE GAP THEN SKIP
PUSHJ P,XCMPRD ;[704] NO, MUST BE ZERO, OUTPUT DIR
TLO P4,DATAF ;[704] SET DATAF
TLZ P4,GAPF+ZEROF ;[704] OFF WITH OTHERS
JRST XCMPR0 ;[704] GET NEXT PAGE
XCMPRH: TLNN T1,777 ;A PARTIAL WORD?
JRST XCMPR8 ;NO
MOVE T1,P1 ;GET FILE PTR
LSH T1,2 ;IN BLOCKS
USETO DC,1(T1) ;ALLOCATE REMAINDER
XCMPR8: MOVE T1,HC.S0(R) ;GET HIGHEST DATA LOCATION
MOVE T3,HL.S0(R) ;AND HIGHEST ALLOCATEDLOCATION
IORI T1,777 ;PUT ON PAGE BOUNDARY
IORI T3,777 ;...
SUB T3,T1 ;SEE IF SAME PAGE
JUMPE T3,XCMPR9 ;YES
HRL P2,T3 ;[733] P2 HAS RIGHT PROCESS PAGE
SUB P2,[1B8] ;[733] REPEAT COUNT IS ONE LESS IN LH
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
HLLZM P1,(W1) ;STORE FLAGS
PUSHJ P,XCMPXD ;
MOVEM P2,(W1) ;[733] STORE ALLOCATED BUT ZERO PAGES
XCMPR9: SKIPE PAG.S0(R) ;A TEMP FILE STILL?
PUSHJ P,@[EXP LC.DLT,HC.DLT]-1(R) ;YES, GET RID OF IT
CAIE R,1 ;JUST DUMPED LOW CORE?
JRST [CAIE R,2 ;JUST DUMPED HIGH CORE?
JRST XCMPHG ;NO, GO CHECK HIGH
JRST XCMPRX] ;YES, FINISH UP
IFN FTOVERLAY,<
SKIPL LNKMAX ;YES, SEE IF ANY OVERLAY?
SKIPN JOB116 ;ANY SYMBOLS TO DUMP?
JRST XCMPHG ;NO, GO CHECK HIGH
JRST XCMPOV ;YES, GO DUMP OVERLAY SYMBOL
>
IFN FTOVERLAY,<
;HERE IF OVERLAY AND LOCAL SYMBOLS OF ROOT MODULES ARE TO BE DUMPED
;FIRST SET UP EXE FILE DIRECTORY ENTRIES FOR THE
;ZERO PAGES BETWEEN LOW CORE AND THE SYMBOL TABLE
;AND THE SYMBOLS.
;ALSO, ZEROS GET PADDED IN FRONT IS LOCAL SYMBOLS DON'T
;START AT A VIRTUAL PAGE BOUND
;
XCMPOV: PUSHJ P,XCMPXD ;INCREMENT W1 AND SEE IF ENOUGH ROOM?
HLLZM P1,(W1) ;FLAGS+0 FILE PAGE
PUSHJ P,XCMPXD ;ENOUGH ROOM?
MOVEM P2,0(W1) ;CORE-PAGE
HRRZ T1,JOB116 ;START ADDR. FOR LOCAL SYMBOLS
MOVE T3,T1
IDIVI T1,1000 ;T1/PAGE # T2/ZERO WORDS
SUBM T1,P2 ;GET THE NUMBER OF ZERO PAGES
SUBI P2,1
DPB P2,[POINT 9,0(W1),8] ;DEPOSIT AS THE REPEAT COUNT
PUSHJ P,XCMPXD ;ENOUGH ROOM?
MOVEM P1,(W1) ;FLAGS+FILE PAGE#
PUSHJ P,XCMPXD ;ENOUGH ROOM?
MOVEM T1,0(W1) ;CORE PAGE #
ADD T3,LSYM ;GET REPEAT COUNT FROM START+LENGTH
LSH T3,-9 ;CONVERT TO PAGE
SUB T3,T1 ;TAKE AWAY STARTING PAGE COUNT
ADD P1,T3 ;[725] INCREMENT PROCESS PAGE
SUBI T3,1
DPB T3,[POINT 9,0(W1),8] ;REPEAT COUNT
MOVE P2,T2 ;# OF ZEROS IN FRONT
MOVEI T2,200 ;GET A 200 WORD
PUSHJ P,DY.GET## ;SCRATCH BLOCK
MOVEM T1,SCRTCH ;SAVE IT, SO WE CAN GIVE BACK
SUBI T1,1 ;MAKE IT IOWD
HRLI T1,-200 ;
SETZ T2,
XCMPO1: CAIGE P2,200 ;MORE THAN 200 ZEROS?
JRST XCMPO2 ;NO,
OUT DC,T1 ;YES, OUTPUT A BLOCK OF ZEROES
JRST [SUBI P2,200
JRST XCMPO1]
JRST XCMPER
;HERE IF LOCAL SYMBOLS ARE PAGED
;
XCMPO2: PUSH P,T1 ;SAVE IOWD TO SCRATCH FOR A WHILE
SKIPN PAG.LS ;PAGED?
JRST XCMPLS ;NO
HRLZ T1,LW.LS ;YES, GO OUTPUT CURRENT WINDOW
HRR T1,LSYM
PUSHJ P,LS.OUT##
SETZM LW.LS ;START AT LOWEST LOCATION
SKIPN HC.S2 ;GET MORE CORE AREA--ANY HIGH?
JRST XCMPP1 ;NO
MOVE T1,HC.AB ;YES,
MOVEM T1,HC.UB
JRST XCMPP2
XCMPP1: MOVE T1,LC.AB
MOVEM T1,LC.UB
XCMPP2: ADDI T1,1
MOVEM T1,LS.LB ;NEW LOWER BOUND
MOVE T2,.JBREL ;NEW UPPER BOUND
MOVEM T2,LS.UB
SUBM T2,T1 ;GET LEGTH OF CORE AVAILABLE
SETZ R,
MOVEM T1,UW.LS ;WE HAVE UPPER WINDOW
CAMGE T1,LSYM ;WINDOW BIG ENOUGH FOR ALL?
JRST [PUSHJ P,LS.IN## ;NO, READ IN AS MUCH AS WE CAN
JRST XCMPO3]
MOVE T1,LSYM ;YES, JUST READIN WHAT WE HAVE
IORI T1,.IPM
MOVE T2,T1
ADD T2,LS.LB ;
MOVEM T2,LS.AB ;AND UPDATE
PUSHJ P,LS.IN##
PUSHJ P,LS.DLT ;GO DELETE THE TMP FILE
JRST XCMPO3 ;GO FIX UP FIRST BLOCK
;DUMP LOCAL SYMBOLS--HERE ONLY IF NOT PAGED
XCMPLS: MOVEI R,LS.IX-1 ;SEE WHO HAS CORE RIGHT BELOW IT
SKIPN T2,TAB.UB(R) ;LOOK FOR NON-ZERO
SOJGE R,.-1 ;IT'S ZERO, DECREMENT INDEX
SUB T2,TAB.AB(R) ;GET LENTH OF GAP
SETZ R, ;KEEP COUNT OF LEGTH OF LS ALREADY OUT
CAMGE T2,P2 ;IS THE GAP BIT ENOUGH?
JRST XCMPO3 ;NO, GO FIXUP FIRST BLOCK
HRLS P2,P2 ;YES, BORROW WHAT WE NEED
MOVE R,LSYM ;UPDATE R SO WE KNOW ITS END
MOVE T1,LS.LB ;SET UP IOWD
HLL T1,JOB116 ;IN T1
SUB T1,P2 ;ADJUST BY NUMBER OF ZEROS
SUBI T1,1
SETZ T2, ;MAKE SURE ENDS WITH ZERO
JRST XCMPO4 ;GO DO OUTPUT
XCMPO3: POP P,T1 ;GET IOWD TO SCRATCH BACK FROM STACK
MOVEI T2,201(T1) ;USE SCRATCH SPACE
MOVEI P1,1(T1) ;GET START OF THE AREA
ADD P1,P2 ;GET WHERE DATA SHOULD GO
HRL P1,LS.LB
BLT P1,(T2)
MOVE T4,LS.AB ;
SUB T4,LS.LB ;LENTH IN CORE
ADDI T4,1 ;NUMBER OF WORDS TO BE READ IN
CAMGE T4,LSYM ;WOULD WE HAVE READ ALL?
JRST [MOVNI T3,-200(T4) ;NO, NUMBER OF WORDS TO DUMP
MOVE R,T4
SUBI R,(P2)
JRST XCMPO5]
MOVN T3,LSYM ;YES, NUMBER OF WORDS TO DUMP
SUBI T3,-200(P2) ;LESS BY DATA BLT TO SCRATCH BLOCK
MOVE R,LSYM
XCMPO5: MOVE T2,LS.LB ;GET BEGINNING OF DATA
SUBI T2,-200(P2) ;ADJUST IT TO EXCLUDE DATA TO SCRATCH
SUBI T2,1 ;1 LESS FOR IOWD
HRL T2,T3 ;MINUS LENGTH IN LH OF IOWD
PUSH P,T2 ;SAVE IOWD, NEED IT LATER IF PAGED
SETZ T3, ;MAKE SURE LIST END WITH ZERO
XCMPO4: OUT DC,T1
CAIA
JRST XCMPER
CAML R,LSYM ;FINISHED?
JRST [POP P,0(P) ;YES, RESTORE STACK
MOVEI R,1 ;INDICATE WE JUST DID LOW SEG
MOVE T1,SCRTCH ;GIVE BACK THE SCRATCH SPACE
MOVEI T2,200 ;OF 200 WORDS
PUSHJ P,DY.RET##
SKIPE PAG.LS ;STILL A TEMP FILE?
PUSHJ P,LS.DLT ;YES, DELETE IT
JRST XCMPHG] ;GO CHECK HIGH CORE
;FALL THROUGH TO NEXT PAGE
;HERE TO DUMP THE NEXT BLOCK OF SYMBOLS, IF NEEDED
MOVE T1,LW.LS ;GET LOWER WINDOW
ADDI T1,-200(T4) ;INCRREMENT IT
MOVEM T1,LW.LS ;NEW LOWER WINDOW
ADD T1,T4 ;ADD THE NUMBER OF WORDS TO BE READ
CAML T1,LSYM ;EXCEEDED THE END?
MOVE T1,LSYM ;YES, READ ONLY WHAT WE NEED
MOVE R,T1 ;UPDATE R
MOVEM T1,UW.LS ;UPDATE UPPER WINDOW
HRL T1,LW.LS ;LOW WINDOW IN LH FOR LS.IN
PUSHJ P,LS.IN## ;GO READ IT
HRRZ T1,T1 ;GET NEW OUTPUT LENGTH
SUB T1,LW.LS
ADDI T1,-200(P2) ;ADJUST IT BY PREVIOUS OUT
MOVN T3,T1 ;NEGATE IT AND SAVE IN CASE AT END
MOVE T1,LW.LS ;GET LOWER WINDOW
MOVE T1,0(P) ;GET IOWD FROM STACK
CAML R,LSYM ;AT END, NEED TO FISUP THE LH
HRL T1,T3 ;YES,
SETZ T2, ;END LIST WITH ZERO
JRST XCMPO4 ;GO OUTPUT
>
XCMPHG: SKIPN HC.LB ;ANY HIGH SEGMENT?
JRST XCMPRX ;NO, FINISH UP
SKIPN PAG.S2 ;PAGING?
JRST XCMPRN ;NO,
MOVE T1,HC.AB ;GET TOP
SUB T1,HC.LB ;LENTH
ADDI T1,1 ;ROUND UP
ANDCMI T1,777 ;MAKE SURE ON PAGE BOUNDARY
SUBI T1,1 ;GET CORRESPONDING UPPER BOUND
MOVEM T1,PAG.S2 ;RESET WINDOW
ADD T1,HC.LB ;
MOVEM T1,HC.AB ;AND CORE BOUND
XCMPRN: MOVE T1,SSEXT ;GET TYPE BITS
HRRZ P1,P1 ;CLEAR FLAGS
IFE TOPS20,<
TXO P1,SV%HIS ;HIGH ALWAYS FOR -10
TXNE T1,SS.SHR ;SHAREABLE?
> ;END OF IFE TOPS20
TXO P1,SV%SHR ;YES,
MOVE T1,HC.LB ;START OF HI SEG
SUBI T1,1 ;IOWD IS 1 LESS
MOVE P2,LL.S2 ;GET ORIGIN
LSH P2,-9 ;IN PAGES
SETZB P3,P4 ;RESET FLAGS
MOVE T3,HC.S2 ;GET LENGTH OF HI SEG
CAIL T3,1000 ;LESS THAN 1 PAGE
AOJA R,XCMPRL ;NOW SAVE HIGH SEGMENT
MOVN T3,T3 ;YES, GET ACTUAL WORD COUNT
HRL T1,T3 ;JUST OUTPUT THAT MUCH
AOJA R,XCMPR7 ;OF HIGH SEGMENT
XCMPRX:
IFN TOPS20,<
MOVE T1,STADDR ;GET ENTRY VECTOR
TLNN T1,-1 ;JUST AN ADDRESS
HRLI T1,(JRST) ;YES, MAKE COMPATIBLE WITH OLD
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
MOVE T2,[.SVEVC,,3] ;STORE 2 WORD EVEC
MOVEM T2,(W1) ;STORE HEADER
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
HLRZM T1,(W1) ;STORE COUNT
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
HRRZM T1,(W1) ;STORE ADDRESS
XCMPRV:>
MOVE T1,[.SVEND,,1] ;END MARKER
PUSHJ P,XCMPXD ;SEE IF ENOUGH ROOM
MOVEM T1,(W1) ;STORE IT
MOVEI W1,(W1) ;
SUB W1,EXEDIR ;GET LENGTH
IFN TOPS20,<
SUBI W1,3 ;DON'T COUNT ENTRY VECTOR BLOCK
>
HRLI W1,.SVDIR ;HEADER
MOVE T3,EXEBLK ;SEE WHICH DIRECTORY BLOCK
CAIG T3,1 ;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 XCMPER ;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 XCMPER] ;ERROR
MOVE T1,EXEDIR ;GET BASE AGAIN
MOVEI T2,1000 ;LENGTH
PUSHJ P,DY.RET## ;GIVE SPACE BACK
JRST ENDCMP ;CLOSE FILE
XCMPXD: AOBJN W1,CPOPJ ;ALLOCATE IF ENOUGH ROOM
PUSH P,T1 ;SAVES SPACE TO SAVE IT HERE
USETO DC,@EXEBLK ;SET ON IT
MOVE W1,EXEDIR ;PTR TO START
HRLI W1,-400 ;NO. TO TRY
MOVEI T1,1 ;INCREMENT
XCMPXE: MOVE T3,1(W1) ;GET FILE PAGE
TRNE T3,-1 ;TEST FOR ALLOCATED BUT ZERO
ADDM T1,1(W1) ;INCREMENT REAL PAGE
ADDI W1,1 ;
AOBJN W1,XCMPXE ;LOOP
HRRZ T1,EXEDIR ;
SUBI T1,1 ;
HRLI T1,-1000 ; FORM IOWD
SETZ T2, ;MAKE SURE
OUT DC,T1 ;WRITE OUT DIRECTORY
CAIA ;OK
JRST XCMPER ;ERROR
MOVEI T3,4 ;NO. OF BLOCKS WE WILL MOVE BY
ADDB T3,EXEBLK ;WHERE REST OF DIRECTORY WILL GO
LSH T3,-2 ;NO. OF PAGES
SUBI T3,1(P1) ;- NO. OF PAGES TO COPY
MOVEI T4,(P1) ;PAGE NO.
LSH T4,2 ;BLOCK NO.
HRL T4,T3 ;AOBJN PTR
XCMPXL: USETI DC,1(T4) ;SET ON INPUT BLOCK
IN DC,T1 ;READ FILE BACKWARDS
CAIA ;OK
JRST XCMPER ;ERROR
OUT DC,T1 ;WRITE IT BACK OUT 1 PAGE HIGHER
CAIA ;OK
JRST XCMPER ;
HRRI T4,-5(T4) ;SUBTRACT BUT WORRY ABOUT CARRY
AOBJN T4,XCMPXL ;LOOP
HRRZ W1,EXEDIR ;RESET DEPOSIT PTR
HRLI W1,-1000 ;
HRLZ T1,W1 ;
HRRI T1,1(W1) ;FORM BLT PTR
SETZM (W1) ;
BLT T1,777(W1) ;CLEAR DIRECTORY BLOCK
AOS T1,P1 ;NEW FILE PAGE
LSH T1,2 ;BLOCKS
USETO DC,5(T1) ;RESET OUTPUT PTR
POP P,T1 ;RESTORE
POPJ P, ;
XCMPER: PUSH P,[DC]
.ERR. (ST,,V%L,L%F,S%F,EOE,<EXE FILE OUTPUT ERROR>)
>;END OF IFN FTEXE
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,NO.COR## ;CANNOT HAPPEN
POP P,P2 ;RESTORE RELATIVE ADDRESS
ADD P2,LC.LB ;MAKE ABSOLUTE
MOVE T1,LS.UB ;SETUP T1 FOR LS.IN
SUB T1,LS.LB
MOVEM T1,UW.LS ;UPPER WINDOW
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 ZCMP7E ;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
HRLZ T1,LW.LS
HRR T1,UW.LS ;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
ZCMP7E: PUSH P,[DC]
.ERR. (ST,,V%L,L%F,S%F,SOE)
;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
HRRZ T1,LW.S1 ;THIS IS WINDOW BASE
HRLZI T1,.IPS(T1) ;BUT WE ALREADY HAVE THIS MUCH
HRR T1,UW.S1 ;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 RUN UUO
;HERE WHEN THROUGH
ENDCMP: 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
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 OVRENE ;[616] REPORT RENAME ERROR
SKIPE PLOTSW ;WANT PLOT PACKAGE?
JRST LNKPLT## ;YES
JRST ENDSAV ;[616] NO, DO RUN UUO OR EXIT
;HERE ON A RENAME ERROR FOR THE OVERLAY FILE
OVRENE: PUSH P,[%OC] ;[616] 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
SKIPE EXECSW ;GO INTO EXECUTION?
JRST RUNUUO ;YES, DO RUN UUO ON 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
DEFINE KEYMAC (A,B)<
IFIDN <A><DEB>,<
%%==-1
IRP B,<
IFGE %%,<
IFN %%&1,<
[ASCIZ \B\]
>>
%%==%%+1
>>
PURGE %%
>
DEBNAM: KEYWORDS
;HERE FOR RUN UUO
RUNUUO: SKIPN STADDR ;WARN USER IF NO STARTING ADDRESS
OUTSTR [ASCIZ \[LNKNSA No start address]
\]
SKIPN STADDR
AOSA T2,ERRNO ;PREVENT EXECUTION IF NO START ADDRESS
MOVE T2,ERRNO ;SAVE ERROR COUNT, GETS WIPED OUT
SKIPL DEBUGSW ;IF DDT
SKIPA P1,STADDR ;NO
MOVE P1,EXECSW ;NEED TO START AT IT
SUB P1,STADDR ;OFFSET OR 0
MOVE T1,[%RHIGH,,%RLOW]
BLT T1,%RUN ;MOVE DOWN RUN UUO
SKIPGE DEBUGSW ;IF DEBUGGING
JRST RUNUUD ;YES
JUMPN T2,RUNUU2 ;ERRORS, TOO BAD U LOSE
SKIPN T2,RUNAME ;GET NAME TO CALL CORE IMAGE
MOVE T2,LODNAM ;USE DEFAULT IF NOT SET
MOVE T4,[POINT 7,%DEXM]
SETZ T1, ;CLEAR RECEIVING AC
LSHC T1,6 ;GET NEXT CHAR
ADDI T1," " ;INTO ASCII
IDPB T1,T4
JUMPN T2,.-4 ;MORE TO DO
IDPB T2,T4 ;MAKE SURE A 0 THERE
RUNUU1: SKIPN T1,IO.PTR+HC ;GET HIGH SEG POINTER
MOVE T1,IO.PTR+LC ;SETTLE FOR LOW SEG IF NO HIGH
MOVE T2,I.DEV(T1) ;GET DEVICE
MOVEM T2,%RUN+0 ;RUN DEVICE
MOVE T2,I.NAM(T1) ;FILE NAME
MOVEM T2,%RUN+1
SKIPN T1,IO.PTR+LC ;[575] MAKE SURE POINTING AT LOW SEG
JRST RUNUU3 ;[575] HISEG ONLY, USE .LOW
MOVE T2,I.EXT(T1) ;[575] MAY AS WELL USE KNOWN EXT
TLNN T2,-1 ;[575] EXTENSION KNOWN?
RUNUU3: MOVSI T2,'LOW' ;[575] NO, USE .LOW
HLLZM T2,%RUN+2 ;[575] STORE EXTENSION & ZERO DATE
SETZM %RUN+3 ;CLEAR DATE TIME
SETZM %RUN+4 ;PPN
MOVE T1,RUNCOR ;CORE FOR RUN UUO IF SET
ADD T1,RUNCOR+1 ;IN CASE LK+HK
MOVEM T1,%RUN+5
CAIGE T1,%RUN+7 ;USE LARGER OF WHAT WE WANT AND WHAT WE NEED
MOVEI T1,%RUN+7
HRLI T1,1 ;REMOVE HIGH SEG IN EITHER CASE
MOVEI T2,%RUN ;ADDRESS OF RUN BLOCK
HRL T2,P1 ;GET OFFSET
JRST %RLOW ;GO TO LOW SEG
RUNUUD: MOVE T1,DEBUGSW ;GET DEB INDEX
DMOVE T1,@DEBNAM(T1) ;GET NAME (POSSIBLE 6 CHARS PLUS NULL)
DMOVEM T1,%DEXM ;STORE IT
CAMN T1,[ASCII \COBDD\]
SETZ P1, ;START AT MAIN PROG IF COBOL
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,%DEXH
JRST RUNUU1 ;RETURN
RUNUU2: OUTSTR DLTTXT
JRST ENDZAP ;AND DELETE USER
DLTTXT: ASCIZ \?LNKDLT Execution Deleted\
;ENTER WITH :-
;T1 = ARG FOR CORE UUO
;T2 = ARG FOR RUN UUO
%RHIGH:
PHASE .TEMP
%RLOW: CORE T1,
JFCL
OUTSTR %DEXH
OUTSTR %DEXM ;NAME OF DEBUGGER
OUTSTR %REXM ;TELL USER
RUN T2,
HALT
EXIT
%DEXH: ASCIZ \[LNKXCT \
%DEXM: EXP 0,0
%REXM: ASCIZ \ Execution]
\
%RUN:
DEPHASE
TERMES: .ERR. (MS,0,V%L,L%I,S%I,FIN,<LINK finished>)
MOVEI T1,FINMES ;TELL USER WE'VE CLOSE LOG FILE
SKIPE LOGSUB ;BUT ONLY IF A REAL LOG FILE
PUSHJ P,.TSTRG##
SKIPN IO.PTR+RC ;SEE IF A LOG FILE?
POPJ P, ;NO
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
PUSH P,[%RC] ;[616] CHANNEL FOR ERROR
.ERR. (LRE,,V%L,L%F,S%F,FRE) ;[616] SEND THE MESSAGE
FINMES: ASCIZ \[LNKELF End of log file]
\
;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
PUSH P,IO.CHN ;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 LKPERR## ;???
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 INERR ;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 DVMOV4 ;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
DVMOV4: PUSH P,[TC] ;TELL WHICH CHANNEL HAD THE ERROR
.ERR. (ST,,V%L,L%F,S%F,EOO,<Error on output>) ;
INERR: .ERR. (ST,,V%L,L%F,S%F,EOI,<Error on input>) ;
;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,
;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 HERE WHEN NOT ENOUGH CORE TO LOAD OR EXECUTE JOB
;WHEN THERE IS NOT ENOUGH CORE TO LOAD OR EXECUTE JOB
;BUT USER DID NOT SPECIFY A SAV FILE
;GIVE WARNING AND CREATE A SAV FILE
;AND IF /EXECUTE , RUN IT
JBNC: MOVEI T2,F.LEN ;SETUP FAKE FILE SPEC
PUSHJ P,DY.GET## ;AS THOUGH WE HAD SEEN /SAVE
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
SKIPN EXECSW ;WANT TO EXECUTE?
TDZA T1,T1 ;NO
MOVEI T1,1 ;YES
PUSHJ P,@[EXP JBNCM1,JBNCM2](T1) ;PRINT MESSAGE
JRST JBSAVE ;AND TREAT AS IF /SAVE SEEN
JBNCM1: .ERR. (MS,.EC,V%L,L%W,S%W,NCL,<Not enough core to load job, saved as >)
.ETC. (FSP,,,,,%VC)
POPJ P,
JBNCM2: .ERR. (MS,.EC,V%L,L%W,S%I,NCX,<Not enough core to load and execute job, will run from >)
.ETC. (FSP,,,,,%VC)
POPJ P,
SUBTTL HERE TO BLT DOWN AREA AND EITHER GO TO EXECUTION OR EXIT
;HERE TO CHECK FOR HIGH SEG AND MAKE SURE IT'S ON A K BOUNDARY
JBEXIT: PUSHJ P,JOBSET ;SETUP REST OF JOBDAT
PUSHJ P,HJBSET ;AND VESTIGIAL JOB DATA AREA
SKIPN PAG.S1 ;SEE IF PAGING LOW
SKIPE PAG.S2 ;OR HIGH
PUSHJ P,JBCC ;YES, SEE IF ENOUGH CORE
SKIPE IO.PTR+%XC ;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 T1,HC.LB ;ANY HIGH SEG CODE
IFN TOPS20,<
TRNN T1,.PGSIZ ;[650] ON A PAGE BOUND ALREADY?
JRST JBEX1 ;[650] YES, EXPECTED
SUBI T1,1001 ;[650] NO, FIND NEXT LOWER PAGE
> ;END IFN TOPS20
IFE TOPS20,<
TDNN T1,.PGSIZ ;[650] ON A (K/P) BOUND?
JRST JBEX1 ;[650] YES, WHAT LUCK
SUB T1,.PGSIZ ;[650] NO, NEXT LOWER PAGE
SUBI T1,2 ;[650] 1 FOR EVEN PAGE, 1 FOR LOW END
> ;END OF IFE TOPS20
IOR. T1,.PGSIZ ;[650] UP TO CORE BLOCK BOUND
CAMGE T1,LC.AB ;ENOUGH SPARE TO BLT DOWN?
JRST JBEXUP ;NO MOVE UPWARDS
ADDI T1,1 ;PUT THE 1 BACK
HRL T1,HC.LB ;FROM,,TO BLT POINTER
MOVE T2,HC.AB
SUB T2,HC.LB ;GET LENGTH
ADDI T2,(T1) ;LAST ADD TO BLT
HRRZM T1,HC.LB ;NEW LOW BASE
MOVEM T2,HC.AB ;NEW HIGH BASE
BLT T1,-1(T2) ;MOVE DATA
;NOW TO ZERO REST OF AREA UP TO K BOUND
HRRZI T1,-1(T2) ;GET TOP DATA WORD
IOR. T1,.PGSIZ ;[650] UP TO CORE BLOCK BOUND
SETZM (T2) ;ZERO FIRST WORD
HRLI T2,1(T2) ;FORM BLT POINTER
MOVS T2,T2 ;RIGHT WAY ROUND
BLT T2,(T1) ;ZERO JUNK
JRST JBEX1 ;NOW FOR REMAP
;HERE TO SEE IF WE CAN GET ENOUGH CORE TO FINISH THIS LOAD
;IF WE CAN DO SO (UNLESS ALREADY ENOUGH)
;IF NOT CREATE A SAVE FILE AND TRY TO RUN IT
P0==P1-1 ;TO MAKE CODE EASIER TO READ
JBCC: MOVE T1,HL.S2 ;GET HIGH SEG STUFF
IFE TOPS20,<
TDZE T1,.PGSIZ ;BUT MUST BE IN K OR P
>
IFN TOPS20,<
TRZE T1,.PGSIZ
>
IOR. T1,.PGSIZ ;SO ROUND UP
ADD T1,HC.S1 ;ADD HIGHEST DATA LOCATION REQUIRED
ADD T1,DY.AB ;TOP OF SPACE WE STILL NEED
IFE TOPS20,<
TDZE T1,.PGSIZ ;ROUND UP
>
IFN TOPS20,<
TRZE T1,.PGSIZ
>
IOR. T1,.PGSIZ ;TO NEXT K OR P
ADDI T1,1 ;UP TO NEXT BLOCK
TLNE T1,-1 ;[732] OVERFLOWED INTO THE LH?
JRST JBNC ;[732] DO IT THE HARD WAY.
CAMG T1,.JBREL ;DO WE HAVE ENOUGH ALREADY?
JRST JBGC ;YES, READ IN REST OF TEMP FILE
CORE T1, ;NO TRY FOR IT
JRST JBNC ;NO LUCK, DO IT THE HARD WAY
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)
;FALL INTO JBGC TO READ IN READ IN REST OF TEMP FILE
;HERE TO READ IN HIGH/LOW TEMP FILES
;IN ORDER TO MINIMIZE DSK TRANSFERES CURRENT CODE WILL NOT
;BE OUTPUT AND REREAD, RATHER WE WILL BLT CODE TO CORRECT PLACE
;AND READ IN REST ARROUND IT
;AT THE END THE TEMP FILES WILL BE DELETED
JBGC: 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
ADDI T1,1 ;NEXT FREE
MOVEM T1,LC.LB ;MAKE LOWEST FOR LOW CODE
ADD T1,HC.S1 ;HOW MUCH WE NEED
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,[HRRZ T1,.JBREL
MOVEM T1,LC.UB ;IGNORE IF NO HIGH SEG
JRST JBGCL] ;BUT RESET UPPER LIMIT
ADDI T1,1 ;LOWER BOUND FOR HISEG
MOVEM T1,HC.LB ;RESET IT
ADD T1,HL.S2 ;HIGHEST LOC WE NEED
IORI T1,.IPM ;BLOCK BOUND
MOVEM T1,HC.AB
IOR. T1,.PGSIZ ;UPTO PAGE (OR K) BOUND
MOVEM T1,HC.UB ;FOR VERY TOP
JBGC1: ;NOW FOR MOVES
;MAKE TWO SIMPLE TESTS FIRST
;THEN MOVE IN HIGH AND LOW CODE
JUMPE P2,JBGCL ;ONLY LOW CODE TO WORRY ABOUT
CAMGE P2,HC.LB ;IF BOTTOM OF CODE IS UNDER WHERE IT SHOULD BE
JRST JBGCHU ;MOVE IT UP (TO CORRECT PLACE)
CAMLE P3,LC.AB ;IF TOP OF LOW IS ABOVE WHERE IT SHOULD BE
JRST JBGCLD ;MOVE LOWER
JBGCH: ;NOW FOR HIGH SEG
SKIPN T1,HC.UB ;FIRST GET RID OF EXCESS CORE IF ANY
MOVE T1,LC.UB ;NO HIGH USE LOW
CAMLE T1,.JBREL ;BUT DON'T WASTE TIME IF ALREADY THERE
CORE T1,
JFCL ;TOO BAD
JUMPE P2,JBGCL ;NO HIGH
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
;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 T1,-1(T1) ;CLEAR FIRST WORD
BLT T1,@TAB.UB(R) ;AND REST
JBGCZ1: SOJG R,JBGCZ ;NOW FOR LOW SEG
POPJ P, ;RETURN
;HERE TO MOVE CODE FOR EITHER SEG AND READ IN DATA
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,[CAMG T1,P0(R) ;OTHERWISE MOVE UP OR DOWN
JRST JBGCD ;DOWN
JRST JBGCU] ;UP
;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 T1,LW.S0(R) ;GET LOWER WINDOW
SOJL T1,.+3 ;DONE IF WAS ZERO
SETZM LW.S0(R) ;NOW POINT TO BASE
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
MOVE T1,HC.S0(R) ;HIGHEST DATA WE NEED
IORI T1,.IPM ;UP TO BOUND
CAMG T1,UW.S0(R) ;IF WE'VE ALREADY GOT IT IN
JRST .+5 ;JUST IGNORE
EXCH T1,UW.S0(R) ;GET BASE
HRLZI T1,1(T1) ;FIRST LOC TO READ
HRR T1,UW.S0(R) ;LAST
PUSHJ P,@[EXP LC.IN##,HC.IN##]-1(R)
;NOW TO ZERO JUNK AT TOP
HRRZ T1,TAB.AB(R) ;TOP IN USE OR KNOWN TO BE ZERO
CAMN T1,TAB.UB(R) ;ALL TAKEN?
POPJ P, ;YES
HRLI T1,1(T1) ;FIRST TO ZERO
SETZM 1(T1) ;CLEAR IT
ADDI T1,2 ;FORM BLT PTR
BLT T1,@TAB.UB(R) ;ALL THE WAY
POPJ P, ;ALL DONE
JBGCHU: ;HERE TO MOVE HIGH UP
;USUAL REVERSE BLT IN T1-T4
MOVE T1,HC.LB ;WHERE BOTTOM SHOULD BE
SUBI T1,(P2) ;WHERE IT NOW IS (GIVES DIFF)
ADD T1,LW.S2 ;ADD IN WINDOW ADDRESS
MOVE T4,P4 ;FIND LENGTH TO MOVE
SUBI T4,-1(P2)
MOVS T4,T4 ;LENGTH IN LEFT
HRR T4,P4 ;TOP OF OLD DATA
TLO T4,(1B0) ;PREVENT PDLOV
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVE T3,[JRST JBGCH]
MOVE P2,HC.LB ;NOW FIXUP P2
ADD P2,LW.S2 ;SO WE DON'T MOVE THIS STUFF AGAIN
JRST T1 ;JUMP INTO FAST LOOP
JBGCLD: ;HERE TO MOVE LOW DOWN
MOVE T1,LC.LB ;START OF WHERE LOW CODE GOES
ADD T1,LW.S1 ;WHERE THIS WINDOW GOES
MOVE T2,T1 ;COPY SO WE CAN END
HRL T1,P1 ;BLT WORD
SKIPN UW.S1 ;MAY NOT BE PAGING
SKIPA T2,LC.AB ;SO USE ALL OF AVAILABLE CORE
ADD T2,UW.S1 ;WHERE IT SHOULD END
BLT T1,0(T2) ;MOVE ALL DATA
MOVE P1,LC.LB ;FIXUP P1 TO REFLECT CHANGE
ADD P1,LW.S1 ;SO WE DON'T MOVE AGAIN
JRST JBGCH ;NOW DO INTERNAL MOVES
;HERE TO MOVE WINDOW UP IN EITHER AREA
;ENTER WITH R=1 FOR LOW
;R=2 FOR HIGH
JBGCU: ;HERE TO MOVE UP
;USUAL REVERSE BLT IN T1-T4
MOVE T1,TAB.LB(R) ;WHERE BOTTOM SHOULD BE
SUB T1,P0(R) ;WHERE IT NOW IS (GIVES DIFF)
ADD T1,LW.S0(R) ;ADD IN WINDOW ADDRESS
MOVE T4,P2(R) ;FIND LENGTH TO MOVE
SUB T4,P0(R)
ADDI T4,400001 ;PREVENT PDLOV, INCREMENT LENGTH CORRECTLY
MOVS T4,T4 ;LENGTH IN LEFT
HRR T4,P2(R) ;TOP OF OLD DATA
HRLI T1,(POP T4,0(T4))
MOVE T2,[JUMPL T4,T1]
MOVSI T3,(POPJ P,)
PJRST T1 ;JUMP INTO FAST LOOP
JBGCD: ;HERE TO MOVE DOWN
SKIPN PAG.S0(R) ;IF NOT PAGED
JRST JBGCN ;USE DIFFERENT ROUTINE
MOVE T1,TAB.LB(R) ;START OF WHERE LOW CODE GOES
ADD T1,LW.S0(R) ;WHERE THIS WINDOW GOES
MOVE T2,T1 ;COPY SO WE CAN END
HRL T1,P0(R) ;BLT WORD
ADD T2,UW.S0(R) ;WHERE IT SHOULD END
BLT T1,0(T2) ;MOVE ALL DATA
POPJ P,
JBGCN: ;MOVE DOWN WHEN NOT PAGED
MOVE T1,TAB.LB(R) ;START OF WHERE LOW CODE GOES
HRL T1,P0(R) ;WHERE IT IS NOW
BLT T1,@TAB.AB(R) ;MOVE IT ALL
POPJ P,
;HERE TO MOVE CODE UP TO A K BOUND SO REMAP WILL WORK
JBEXUP: MOVE T4,HC.AB ;TOP
SUB T4,HC.LB ;MINUS BOTTOM GIVES LENGTH
MOVE T1,LC.AB ;GET TO OF CURRENT AREA
IOR. T1,.PGSIZ ;[650] PUT ON BLOCK BOUND
ADD T1,T4 ;GET NEW TOP
CAMG T1,HC.UB ;WILL IT FIT?
JRST JXUP1 ;YES
CORE T1, ;EXPAND
PUSHJ P,NO.COR## ;SHOULD NEVER GET HERE
MOVE T1,.JBREL ;GET NEW TOP
MOVEM T1,HC.UB ;SET IT
JRST JBEXUP ;RESET T4
JXUP1: MOVE T3,T4 ;GET A COPY
HRL T4,T4 ;IN BOTH HALVES
ADD T4,HC.LB ;TOP OF DATA
TLO T4,(1B0) ;PREVENT PDLOV
MOVE T1,HC.LB ;GET CURRENT BOTTOM
IOR. T1,.PGSIZ ;[650] UP TO BLOCK BOUND
ADDI T1,1 ;STARTS ON NEXT WORD
MOVE T2,T1 ;GET COPY
SUB T1,HC.LB ;GET OFFSET
HRLI T1,(POP T4,0(T4))
PUSH P,HC.LB ;SAVE OLD BASE
MOVEM T2,HC.LB ;RESET BASE
ADDI T3,(T2) ;START + LENGTH
MOVEM T3,HC.AB ;AND TOP
MOVE T2,[JUMPL T4,T1] ;LOAD INST
MOVSI T3,(POPJ P,) ;RETURN
PUSHJ P,T1 ;JUMP INTO CODE IN ACCS
POP P,T1 ;GET OLD HC.LB
SETZM (T1) ;ZERO FIRST WORD
HRL T1,T1
ADDI T1,1 ;BLT PTR
MOVE T2,HC.LB ;NEW LOWER BOUND
BLT T1,-1(T2) ;CLEAR JUNK WE LEFT BEHIND
;FALL INTO JBEX1
JBEX1: SKIPE STADDR ;WARN USER IF NO STARTING ADDRESS
JRST JBEX10 ;IS A STARTING ADDRESS, KEEP GOING
OUTSTR [ASCIZ \[LNKNSA No start address]
\]
JBEX10: SKIPE JOBPTR ;NEED TO RESTORE .JBDA?
PUSHJ P,BLTJDA ;YES
SKIPE JBHPTR ;SAME FOR HIGH
PUSHJ P,BLTJHA ;RESTORE FIRST 10 WORDS
SKIPE IO.PTR+%XC ;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) ;GET DDT ADDRESS
IFN TOPS20,<
HRRZ T1,T2 ;GET ADDRESS
CAIE T1,770000 ;IDDT?
JRST JBEX1A ;NO
MOVE T2,LC.LB ;GET BASE
MOVE T1,.JBSYM(T2) ;
MOVEM T1,@770001 ;GIVE SYMBOLS TO DDT
MOVE T1,.JBUSY(T2) ;
MOVEM T1,@770002 ;AND UNDEFS
SETZ T2, ;AND DON'T STORE IN .JBDDT
JBEX1A:>
;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
IFN TOPS20,< ;IF TENEX, SETUP START VECTOR
MOVEI T1,400000 ;THIS FORK
MOVE T2,STADDR ;ADDRESS
TLNN T2,-1 ;IF LHS NOT SET, PUT JRST
HRLI T2,(JRST) ;IN LEFT
SEVEC ;SET ENTRY VECTOR
>
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 T1,[DLTTXT,,%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
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,%2 ;TO CLEAR LOW SEG
JBEX2B: 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:
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
;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
%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
MOVEM T1,.JBREL-20(T2);INCASE 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
OUTSTR %TMES ;INFO INDICATOR
%DDMES: OUTSTR %DTXT ;NAME OF DEBUGGER
OUTSTR %RTXT ;TELL USER
%RMES: MOVSI 17,%0 ;BLT PTR
IFE TOPS20,< ;
RESET ;MAKE SURE NO I/O STILL OPEN
> ;
IFN TOPS20,< ;SPECIAL IF TENEX DDT
MOVEI T1,400000 ;THIS FORK
DIR ;
CIS ;
MOVSI T1,(JFCL) ;[644] REPLACE WITH JFCL IF DESIRED
MOVE T2,%16 ;[644] GET IT
CAMN T2,%EXIT ;[644] EXIT? RATHER THAN START ADDR
MOVEM T1,%7 ;[644] YES, REPLACE RESET WITH JFCL
>
BLT 17,17 ;[644] LOAD ACCS
JRST 4 ;[644] GO THERE
%EXIT: EXIT ;[644] THIS IS COMPARED WITH CONTENT OF %16
%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 REMER1 ;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
OUTSTR %VMRERR ;WARN USER
JRST %REMAP ;NOW TRY AGAIN
REMER1: OUTSTR %RMPE ;ERROR MESSAGE
EXIT
%RMPE: ASCIZ \?LNKRME REMAP error\
%VMRER: ASCIZ \%LNKRME REMAP error, high segment origin incorrect
\
%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
IFE TOPS20,< ;
%7: MOVEM 3,.JBPFH## ;SET PAGE FAULT HANDLER
> ;
IFN TOPS20,< ;
%7: JSYS 147 ;TENEX RESET, FLUSH PA1050
> ;
%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
%END:
DEPHASE
%T1==%END+0
%T2==%T1+1
%T3==%T2+1
%T4==%T3+1
SUBTTL DATA AREAS
.ZZ==.TEMP
U (LSCNT) ;COUNT OF WORDS LEFT IN THIS 128 WORD BLOCK
U (TTLPTR) ;BACK POINTER TO LAST SUBPROGRAM
U (LCSIZE) ;SIZE OF LOCAL SYMBOL FILE
U (JOBPTR) ;POINTER TO COPY OF JOBDAT AREA
U (JBHPTR) ;DITTO FOR HIGH SEG
U (LSTPAG) ;-1 WHEN LAST PAGE IS IN CORE
U (ERRNO) ;.JBERR COUNT
U (JOB116) ;.JBSYM FOR .SYM FILE
U (JOB117) ;.JBUSY FOR .SYM FILE
U (SCRTCH) ;POINTER TO A SCRATCH PAGE
XITLIT:
END LNKXIT