Trailing-Edge
-
PDP-10 Archives
-
bb-d868c-bm_tops20_v4_2020_distr
-
language-sources/lnkmap.mac
There are 38 other files named lnkmap.mac in the archive. Click here to see a list.
TITLE LNKMAP - MAP MODULE FOR LINK
SUBTTL D.M.NIXON/DMN/SRM/JBC/RKH/JNG/DZN 24-Aug-79
;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
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL
ENTRY LNKMAP
EXTERN LNKFIO,LNKXIT,LNKLOD,LNKLOG,LNKCOR,.TYOCH
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==1 ;DEC MINOR VERSION
DECEVR==1220 ;DEC EDIT VERSION
VERSION
SEGMENT
SUBTTL REVISION HISTORY
;START OF VERSION 1A
;47 INTEGRATE WITH SCAN %4, ADD DATE75 HACK
;54 ADD KIONLY D.P. INST.
;55 PUT VERSION# IN .RBVER OF MAP FILE
;63 PUT MULTIPLY-DEFINED SYMBOLS IN MAP
;104 PUT FAIL BLOCKS OUT ON MAP
;START OF VERSION 2
;135 ADD OVERLAY FACILITY
;144 (12772) FIX LOOP IF MORE THAN 1 SFD
;160 (12736) ADD WORDS FREE IN EACH SEGMENT TO MAP OUTPUT
;205 ADD NO. OF GLOBALS AND MIN. HASH SIZE TO MAP OUTPUT
;START OF VERSION 2A
;225 ADD SUPPORT FOR PSECT (MACRO VERSION 51 ONLY)
;START OF VERSION 2B
;304 FIX LOOP IN MAP OUTPUT
;344 INCLUDE EDIT 304 IN MAINTENANCE SOURCES
;353 REMOVE EDIT 225
;363 UPDATE MINOR VERSION #
;372 Don't print an overlay path on /MAP:NOW
;START OF VERSION 2C
;452 Don't print the module name as the only line on a new page
;453 Don't repeat module names if map index is longer than one page.
;463 Fix ?ILL UUO and lost symbols on /MAP:NOW
;475 Replace calls to .TYVER with calls to .TVERW
;503 Make pages LN.LPP lines long, not LN.LPP+1.
;507 Avoid informational messages in map when using /ERR:0.
;530 Get triplet flag bit definitions right.
;532 Fix problems with title when paging heavily.
;540 Detect all cases of zero length modules correctly.
;557 Clean up the listing for release.
;START OF VERSION 3A
;560 Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)
;START OF VERSION 4
;601 Print the correct version if from /VERSION
;604 Support device NUL: correctly
;611 Support COBOL-74
;640 Avoid additional disk overflow if possible.
;711 Fix bug in MAP when only 1 psect in a module.
;731 SEARCH MACTEN,UUOSYM instead of C.
;765 Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
;START OF VERSION 4A
;1100 Don't free up a different size title buffer than we allocated.
;1112 Get words free and segment lengths in K/P right in the map.
;1120 Pring correct CPU specifications in the map for module and program.
;1161 Clean up printout of PSECT lengths.
;1164 Don't overwrite FX area in SHFSYM if no extra room.
;1174 Label and clean up all error messages.
;1203 Add support for extended FORTRAN.
;1217 Clean up the listings for release.
;1220 Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL HEADER LINES
LNKMAP: JFCL .+1 ;INCASE CCL
E$$MPS::.ERR. (MS,0,V%L,L%I,S%I,MPS,<MAP segment>) ;[1174]
ZAPTMP ;CLEAR DATA AREA
SETOM LS.PP ;PROHIBIT DEFAULT PAGING OF SYMBOL TABLE
AOS SYMPTR ;SKIP INITIAL ZERO
PUSHJ P,RDVER ;SET UP VERSION # IN MAPVER
MOVEI T1,MC ;SET IO.CHN
MOVEM T1,IO.CHN ;TO MAP CHAN#
MOVE T1,IO.PTR+MC ;GET DATA BLOCK
SKIPN T2,VERNUM ;GET VERSION FROM SWITCH
SKIPA T2,MAPVER ;[601] NO SWITCH, GET VERSION FROM CORE
MOVEM T2,MAPVER ;[601] STORE /VERSION FOR MAP TITLE
SKIPN I.VER(T1) ;BUT NOT IF SET IN FILE
MOVEM T2,I.VER(T1) ;PUT IN .RBVER
SKIPN T2,I.NAM(T1) ;GET USER OR DEFAULT NAME
PUSHJ P,DVNAM.## ;SET DEFAULT
MOVEM T2,MAPNAM ;FOR HEADER INFO
PUSHJ P,DVCHK.## ;GET DEVCHR AGAIN
MOVE T2,IO.CHR ;GET DEVCHR WORD
TLC T2,-1-<(DV.TTA)> ;[604] NUL: ISN'T A TTY
TLCE T2,-1-<(DV.TTA)> ;[604]
TXNN T2,DV.TTY ;[604] IF TTY
CAIA ;[604] IT ISN'T
JRST .+3 ;IGNORE INIT & ENTER
PUSHJ P,DVOPN.## ;OPEN MAP DEVICE
PUSHJ P,DVENT.## ;AND ENTER FILE NAME
HRRZ T1,LOWSUB ;[604] ASSUME TTY IS MAP DEVICE
MOVE T2,IO.PTR+MC ;[604] GET POINTER BACK
SKIPE I.RNG(T2) ;[604] ARE THERE SOME BUFFERS
MOVEI T1,MAPIT ;[604] YES, POINT TO SOSGE ROUTINE
PUSHJ P,.TYOCH## ;INIT OUTPUT
MOVEM T1,OLDDEV ;SAVE OLD .TYOCH RETURN INCASE ERROR
MOVEI T1,LN.LPP ;NO OF LINES PER PAGE
MOVEM T1,CNTLPP
;HERE WITH MAP FILE OPEN. PRINT HEADER LINES.
LNKMP1: MOVEI T1,HEAD1 ;NORMAL HEADER
MOVEM T1,PAGHDR ;FOR PAGES
PUSHJ P,.TYHDR ;TYPE HEADER LINE
MOVEI T1,HEAD2
PUSHJ P,.TSTRG##
MOVE T2,HIORGN ;[650] GET HISEG ORIGIN
MOVSI T1,. ;FIND OUT WHERE WE ARE
SKIPL T1 ;SHOULD BE IN HIGH SEG
SKIPA T1,.JBVER ;NO, GET LOW VERSION
MOVE T1,.JBHVR(T2) ;[650] HIGH SEG VER
PUSHJ P,.TVERW## ;TYPED IN VERSION FORMAT
MOVEI T1,[ASCIZ \ on \]
PUSHJ P,.TSTRG##
PUSHJ P,.TDATN## ;DAY
MOVEI T1,[ASCIZ \ at \]
PUSHJ P,.TSTRG##
PUSHJ P,.TTIMN## ;TIME
PUSHJ P,.TYLPP ;END LINE
PUSHJ P,.TYLPP ;BLANK LINE
SETZ R1, ;NOW FOR PER-SEGMENT STUFF
IFN FTOVERLAY,<
AOS FSTPGN ;INCASE NO OVERLAYS, START ON PAGE 1
SKIPGE T2,LNKMAX ;ANY OVERLAYS?
JRST SEGSTF ;NO
LSH T2,-1
ADDI T2,1 ;TAKE CARE OF ODD#
PUSHJ P,LOGBCK ;PUT MOVING LOWSEG MSGS IN LOG
PUSHJ P,DY.GET## ;GET SPACE FOR NO. INDEX
HRLI T1,T1 ;PUT T1 IN INDEX FIELD
MOVEM T1,OVMIDX
PUSHJ P,LOGBCK ;REST OF INFO IN MAP
SETZM LNKNO. ;START AT LINK# 0
JRST OVMAP1
OVMAP0: SETZM CNTLPP ;START ON NEW PAGE
MOVEI T1,HEAD1 ;RESET HEADER LINE
MOVEM T1,PAGHDR
PUSHJ P,.TYLPP ;NEW PAGE & HEADER LINE
MOVEI T1,1
MOVEM T1,SYMPTR ;RESET SYMBOL PTR
OVMAP1: MOVE P1,LNKNO.
PUSHJ P,LOGBCK ;MAKE SURE ERRORS GET TO TTY
PUSHJ P,RDCST## ;READ THE PREAMBLE & CS FOR THIS LINK
JFCL ;NEITHER EXTTAB NOR INTTAB
PUSHJ P,LOGBCK ;PUT LOG INFO OUT TO LOG
MOVE T1,OV.S1 ;LENGTH
HRRM T1,HL.S1 ;SO BOUNDS COME OUT RIGHT
MOVEI T1,[ASCIZ \ Overlay no. \]
PUSHJ P,.TSTRG##
MOVE T1,LNKNO. ;GET THIS ONE
PUSHJ P,.TDECW## ;LIST IN DECIMAL
SKIPN PH.NAM ;SEE IF NAME
JRST OVMAP2 ;NO
MOVEI T1,[ASCIZ \ name \]
PUSHJ P,.TSTRG##
MOVE T1,PH.NAM ;GET NAME
PUSHJ P,.TSIXN## ;IN SIXBIT
OVMAP2: PUSHJ P,.TYLPP
;SEGMENT LENGTHS
SETZ R1, ;MAKE SURE R IS CORRECT
SGSTF0: PUSHJ P,.TTABC##
MOVEI T1,SEG0(R1)
PUSHJ P,.TSTRG##
MOVEI T1,SEG1
PUSHJ P,.TSTRG##
HRRZ T1,PV.S1(R1) ;STARTS AT
PUSHJ P,.T6OCT##
MOVEI T1,SEG2
PUSHJ P,.TSTRG##
HRRZ T1,OV.S1(R1) ;ENDS AT
SKIPE T1
SUBI T1,1 ;ONE LESS THAN PROG BREAK
; ADD T1,LL.S1(R1) ;DON'T FORGET OFFSET
PUSHJ P,.T6OCT##
MOVEI T1,SEG3
PUSHJ P,.TSTRG##
HRRZ T1,OV.S1(R1)
HRRZ T2,PV.S1(R1) ;PREVIOUS
SUB T1,T2 ;DIFFERENCE
PUSH P,T1 ;SAVE IT
PUSHJ P,.T6OCT## ;LENGTH IN OCTAL
MOVEI T1,[ASCIZ \ = \]
PUSHJ P,.TSTRG##
POP P,T1 ;LENGTH BACK
ADD. T1,.PGSIZ ;[1112] ROUND UP TO NEXT PAGE BOUND
ANDCM. T1,.PGSIZ ;[1112] ..
IFE TOPS20,<
MOVE T2,.PGSIZ ;[1112] GET THIS SYSTEM'S PAGE SIZE
CAIE T2,777 ;PAGES?
JRST [LSH T1,-^D10 ;K
PUSHJ P,.TDEC3 ;IN DECIMAL
MOVEI T1,"K"
JRST SGSTF1]
>;END OF IFE TOPS20
LSH T1,-^D9 ;P
PUSHJ P,.TDEC3 ;IN DECIMAL
MOVEI T1,"P"
SGSTF1: PUSHJ P,.TCHAR##
PUSHJ P,.TYLPP
JUMPN R1,OVMP2A ;DONE HIGH SEG ALREADY?
HRRZ T1,OV.S2 ;NO, BUT IS THERE ANY HIGH SEGMENT?
HRRZ T2,PV.S2
SUB T1,T2
SKIPE T1 ;NO
AOJA R1,SGSTF0 ;NOW FOR HIGH SEG
OVMP2A: MOVEI T1,[ASCIZ \ Control Block address is \]
PUSHJ P,.TSTRG##
HRRZ T1,PH.CST
PUSHJ P,.T6OCT##
MOVEI T1,[ASCIZ \, length \]
PUSHJ P,.TSTRG##
HLRE T1,CS.INT ;LENGTH OF INTTAB
JUMPE T1,[HLRE T1,CS.EXT
JUMPE T1,OVMAP4 ;NEITHER
IMUL T1,[-ET.ZZ] ;GET LENGTH
ADD T1,CS.EXT ;PLUS START
JRST OVMAP3]
IMUL T1,[-2] ;2 WORDS PER INTTAB
ADD T1,CS.INT
OVMAP3: SUB T1,PH.CST ;- START
TLZA T1,-1 ;RIGHT HALF ONLY
OVMAP4: MOVEI T1,CS.ZZ ;USE LENGTH OF CS ONLY
PUSH P,T1 ;SAVE IT
PUSHJ P,.T6OCT## ;LIST IN OCTAL
MOVEI T1,[ASCIZ \ (octal), \]
PUSHJ P,.TSTRG##
POP P,T1
PUSHJ P,.TDECW## ;AND IN DECIMAL
MOVEI T1,[ASCIZ \. (decimal)\]
PUSHJ P,.TSTRG##
PUSHJ P,.TYLPP
HLRE P2,PH.SYM ;LENGTH WE NEED
MOVM P2,P2
SUB P2,LS.AB ;SEE IF ENOUGH
ADD P2,LS.LB
JUMPLE P2,OVMAP5 ;YES
PUSHJ P,LOGBCK ;PUT INFO MESSAGES TO LOG FILE
MOVEI P1,LS.IX
PUSHJ P,LNKCOR##
PUSHJ P,E$$MEF## ;[1174]
PUSHJ P,LOGBCK ;BUT ALL OTHERS IN MAP
OVMAP5: MOVEI T1,$MAPNOW ;GET /MAP:NOW
CAME T1,MAPSW ;SKIP PATH IF SO (NOT SET UP)
SKIPN LNKNO. ;LIST PATH FOR ALL BUT ROOT
JRST OVMAP6
MOVEI T1,[ASCIZ \ Path is \]
PUSHJ P,.TSTRG##
MOVE T1,PH.FPT ;GET PATH POINTER
USETI OC,(T1) ;SET ON BLOCK
HLRZ P1,T1 ;GET WORD NUMBER
ADD P1,LS.LB ;WHERE IN CORE
HRLI P1,(POINT 18) ;1/2 WORDS
;FORM IOWD AND READ IN PATH INFO FOR PRINTING
MOVE T1,LS.LB
SUBI T1,1
HRLI T1,-.DBS ;[650] FORM IOWD
SETZ T2,
IN OC,T1
CAIA
PUSHJ P,[PUSHJ P,LOGBCK ;ERRORS TO TTY
PJRST E$$IOV##] ;[1174] GO REPORT INPUT ERROR
ILDB T1,P1 ;GET FIRST #
PUSHJ P,.TDECW## ;AUGHT TO BE 0 BUTB MUST PRINT IT
OVMP5A: ILDB T1,P1 ;GET NEXT
JUMPE T1,OVMP5B ;DONE
MOVEI T1,[ASCIZ \, \]
PUSHJ P,.TSTRG## ;SEPARATOR
LDB T1,P1 ;GET # BACK
PUSHJ P,.TDECW##
JRST OVMP5A ;GET NEXT
OVMP5B: PUSHJ P,.TYLPP ;END LINE
OVMAP6: MOVE T1,PH.SYM ;GET BLOCK# OF SYMBOLS
USETI OC,(T1) ;SET ON IT
MOVE T1,LS.LB ;FORM IOWD TO READ IN SYMBOLS
SUBI T1,1
HLL T1,PH.SYM ;EVENTUALLY
SETZB T2,USYM
IN OC,T1
SKIPA T1,LNKNO. ;OK
PUSHJ P,[PUSHJ P,LOGBCK ;ERRORS TO TTY
PJRST E$$IOV##] ;[1174] INPUT ERROR
ROT T1,-1 ;USUAL WAY TO ADDRESS 1/2 WORD
MOVE T2,PAGENO ;PAGE # OF FIRST MODULE INCASE NO INDEX
MOVEM T2,FSTPGN ;SO WE CAN SEE IF INDEX REQUIRED
JUMPL T1,[HRRM T2,@OVMIDX
JRST .+2]
HRLM T2,@OVMIDX
MOVE T1,LS.LB
ADD T1,LSYM ;NEXT FREE LOCATION
SETZM (T1) ;CLEAR UP TO END OF LS.AB WITH A BLT
HRLZI T2,0(T1)
HRRI T2,1(T1)
BLT T2,@LS.AB
IORI T1,.IPM
MOVEM T1,LS.AB ;GIVE BACK EXCESS SPACE
JRST SEGDN
>;END OF IFN FTOVERLAY
;SEGMENT LENGTHS
SEGSTF: PUSHJ P,.TTABC##
MOVEI T1,SEG0(R1)
PUSHJ P,.TSTRG##
MOVEI T1,SEG1
PUSHJ P,.TSTRG##
MOVE T1,LL.S1(R1) ;STARTS AT
PUSHJ P,.T6OCT##
MOVEI T1,SEG2
PUSHJ P,.TSTRG##
SKIPE T1,HL.S1(R1) ;ENDS AT
SUBI T1,1 ;ONE LESS THAN PROG BREAK
ADD T1,LL.S1(R1) ;DON'T FORGET OFFSET
PUSHJ P,.T6OCT##
MOVEI T1,SEG3
PUSHJ P,.TSTRG##
MOVE T1,HL.S1(R1)
PUSH P,T1
PUSHJ P,.T6OCT## ;LENGTH IN OCTAL
MOVEI T1,[ASCIZ \ = \]
PUSHJ P,.TSTRG##
POP P,T1 ;GET BACK LENGTH
ADD. T1,.PGSIZ ;[1112] ROUND UP TO NEXT PAGE BOUND
ANDCM. T1,.PGSIZ ;[1112] ..
IFE TOPS20,<
MOVE T2,.PGSIZ ;[1112] GET THIS SYSTEM'S PAGE SIZE
CAIE T2,777 ;PAGES?
JRST [LSH T1,-^D10 ;K
PUSHJ P,.TDECW## ;IN DECIMAL
MOVEI T1,"K"
JRST SGSTF2]
>;END OF IFE TOPS20
LSH T1,-^D9 ;P
PUSHJ P,.TDECW## ;IN DECIMAL
MOVEI T1,"P"
SGSTF2: PUSHJ P,.TCHAR##
PUSHJ P,.TYLPP
SKIPN R1 ;DONE HIGH SEG ALREADY?
SKIPN HL.S2 ;NO, BUT IS THERE ANY HIGH SEGMENT?
JRST SEGDN ;NO
AOJA R1,SEGSTF ;NOW FOR HIGH SEG
;HERE TO READ THE VERSION NUMBER IN USER LOC .JBVER
RDVER:
IFN FTOVERLAY,<
SKIPGE LNKMAX ;ANY OVERLAYS?
JRST RDVER1 ;NO
PUSHJ P,LOGBCK ;I/O ERRORS TO TTY
SETZB P1,LNKNO. ;NEED LINK# 0 IN CORE
PUSHJ P,INPH## ;GET PREAMBLE
MOVE T1,PH.OVL ;BLOCK# OF JOBDAT
USETI OC,(T1) ;SET ON IT
MOVE T1,LC.LB
SUBI T1,1
HRLI T1,-.DBS ;[650] READ FIRST BLOCK
SETZ T2,
IN OC,T1
SKIPA T1,.JBVER+1(T1) ;GET VERSION#
PUSHJ P,E$$IOV## ;[1174] INPUT ERROR
MOVEM T1,MAPVER
PJRST LOGBCK ;PUT ALL MAP INFO IN MAP
RDVER1:
>;END OF IFN FTOVERLAY
SKIPE PAG.S1 ;IF PAGING LOW SEG
SKIPN LW.S1 ;AND JOBDAT NOT IN CORE
JRST [MOVE T1,LC.LB ;GET START OF LOW AREA
MOVE T1,.JBVER(T1) ;GET VERSION#
MOVEM T1,MAPVER ;SAVE FOR HEADER LINE
POPJ P,] ;RETURN
PUSHJ P,LOGBCK ;[LNKEXP] MESSAGES TO TTY
MOVEI T2,.JBDA ;NEED 140 WORDS
PUSHJ P,DY.GET## ;TO HOLD JOBDAT
SUBI T1,1 ;IOWD STARTS 1 BACK
HRLI T1,-140 ;NO OF WORDS
SETZ T2, ;TERMINATE LIST
USETI LC,1 ;TO READ BLOCK 1
IN LC,T1 ;FOR FIRST 140 WORDS
JRST [MOVEI T1,1(T1) ;INCR T1
MOVE T2,.JBVER(T1) ;GET VERSION #
MOVEM T2,MAPVER ;SAVED
MOVEI T2,.JBDA ;NOW TO RESTORE BLOCK
PUSHJ P,DY.RET## ;RETURN THE CORE
PJRST LOGBCK] ;AND .TYOCH AND RETURN
PUSHJ P,LOGBCK ;MAKE SURE USER GETS MESSAGE
E01ILC::PUSH P,[LC] ;[1174] CHAN #
.ERR. (ST,,V%L,L%F,S%F,ILC)
SEGDN: PUSHJ P,.TTABC##
MOVE T1,HL.S1 ;GET LOW SEG BREAK
ADD. T1,.PGSIZ ;[1112] ROUND UP TO NEXT P OR K
ANDCM. T1,.PGSIZ ;[1112] ..
SUB T1,HL.S1 ;FIND WHATS LEFT
PUSHJ P,.TDECW## ;PRINT IN DECIMAL
MOVEI T1,[ASCIZ \ words free in Low segment\]
PUSHJ P,.TSTRG##
SKIPN HL.S2 ;ANY HIGH SEGMENT
JRST SEGDN1 ;NO, CLOSE OUT LINE
MOVEI T1,[ASCIZ \, \]
PUSHJ P,.TSTRG## ;SEPARATE
MOVE T1,HL.S2 ;SAME FOR HIGH SEG
ADD. T1,.PGSIZ ;[1112] ROUND UP TO NEXT P OR K
ANDCM. T1,.PGSIZ ;[1112] ..
SUB T1,HL.S2
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ \ words free in high segment\]
PUSHJ P,.TSTRG##
SEGDN1: PUSHJ P,.TYLPP
PUSHJ P,.TTABC## ;TAB OUT
MOVE T1,GSYM ;NO. OF GLOBALS
IFN FTOVERLAY,<
ADD T1,BSYM ;PLUS BOUND SYMBOLS
>
PUSHJ P,.TDECW## ;PRINT NO.
MOVEI T1,[ASCIZ \ Global symbols loaded, therefore min. hash size is \]
PUSHJ P,.TSTRG##
MOVE T1,GSYM ;NO. OF SYMBOLS
IFN FTOVERLAY,<
ADD T1,BSYM ;PLUS BOUND SYMBOLS
>
IMULI T1,^D100
IDIVI T1,.HS% ;HOW MUCH SPACE WE WILL NEED TO AVOID REHASH
ADDI T1,1 ;JUST INCASE A PRIME NO.
PUSHJ P,.TDECW##
PUSHJ P,.TYLPP ;CLOSE LINE
SKIPN STADDR ;IS THERE A STARTING ADDRESS
JRST NOSTAD ;NO
MOVEI T1,[ASCIZ \ Start address is \]
PUSHJ P,.TSTRG##
HRRZ T1,STADDR ;GET IT
PUSHJ P,.T6OCT##
SKIPN STANAM ;NAME OF PROG CONTAINING ST ADDR.
JRST TTLDN ;NONE, OR SET BY SWITCH
MOVEI T1,[ASCIZ \, located in program \]
PUSHJ P,.TSTRG##
MOVE T1,STANAM ;PROGRAM NAME
PUSHJ P,.TSIXN##
PUSHJ P,.TYLPP
JRST TTLDN
NOSTAD:
IFN FTOVERLAY,<
SKIPL LNKMAX ;ANY OVERLAYS
SKIPN LNKNO. ;YES, BUT NOT ROOT
CAIA
JRST TTLDN ;DON'T GIVE MESSAGE TO OTHER LINKS
>
MOVEI T1,[ASCIZ \ No start address\]
PUSHJ P,.TSTRG##
PUSHJ P,.TYLPP
TTLDN: SKIPL NOSYMS ;USER SET FOR NO SYMBOLS
SKIPN LS.LB ;OR NOTHING YET STORED?
JRST NOMAP ;EITHER WAY
PUSHJ P,SYMINI ;GET SYMBOL TABLE RE-INITIALIZED
SKIPN T2,PRGNO ;GET NUMBER OF MODULE NAMES
JRST TTLSRT ;NO MODULES LOADED YET
MOVEM T2,MDLCNT ;HELPS TO TRAP ERRORS
LSH T2,1 ;2 WORDS PER ENTRY
PUSHJ P,LOGBCK ;LNKMOV MESSAGES TO LOG FILE
PUSHJ P,DY.GET## ;GET SPACE TO HOLD INDEX
MOVEM T1,MDLIDX ;START OF IT
HRLI T1,(POINT 36) ;FORM BYTE PTR
MOVEM T1,MDLPTR ;TO DEPOSIT NAMES
;AND ADDRESSES
PUSHJ P,LOGBCK ;RESET OUTPUT TO MAP FILE
TTLSRT: SETZB R2,R1 ;INCASE UNSORTED
JRST NXTSYM ;GET NEXT SYMBOL
SKIPN T1,NXTTTL ;REL POSITION ON NEXT TITLE
MOVE T1,LSYM ;USE END IF LAST
SUB T1,SYMPTR ;REMOVE CURRENT POSITION
SUB T1,LW.LS ;INCASE ON DSK
LSH T1,1 ;NEED 2 WORDS
IDIVI T1,.L ;FROM TRIPLET ORIGINALLY
ADD T2,T1 ;ACCOUNT FOR REMAINDER?
PUSHJ P,LOGBCK ;ANY MESSAGES TO LOG FILE
PUSHJ P,DY.GET## ;GET SPACE
HRL T1,T2
MOVEM T1,SRTPTR ;STORE START AND SIZE
PUSHJ P,LOGBCK ;BACK TO MAP FILE
HRLZI T2,(POINT 36)
HRR R2,T2 ;BYTE POINTER TO STORE NAMES ETC
MOVE R1,MAPSRT ;INDEX TO SORT TYPE
; JRST NXTSYM ;JUMP TO SYMBOL LOOP
SUBTTL SYMBOL LOOP
NXTSYM: PUSHJ P,GETSYM ;GET FIRST SYMBOL
JRST SYMDN ;ALL OVER
JRST TTLBLK ;A TITLE BLOCK
PUSHJ P,SYMCHK ;SEE IF WE WANT THIS SYMBOL?
JRST NXTSYM ;NO
JUMPN R2,STRSYM ;JUMP IF SORTING
PNTSYM: PUSHJ P,.TTABC## ;TAB
MOVEM W1,SYFLAG ;SAVE PRIMARY FLAGS
MOVE T1,W2 ;FIRST 6 CHARS OF NAME
MOVEM W3,VALUE ;VALUE OF SYMBOL
PUSHJ P,.TSIXN##
SYMLNG: MOVX T1,S.SYM ;SEE IF LONG SYMBOL
PUSHJ P,FNDAST
JRST SYMVAL ;NO
MOVE T1,W2
PUSHJ P,.TSIXN##
SKIPE T1,W3
PUSHJ P,.TSIXN##
JRST SYMLNG ;SEE IF MORE
SYMVAL: PUSHJ P,.TTABC##
MOVE T1,VALUE
PUSHJ P,.TFOCT## ;FULL WORD OCTAL WITH LEADING BLANKS
PUSHJ P,.TTABC##
MOVE T1,SYFLAG
TXNE W1,PS.ENT ;TEST FOR ENTRY POINT
JRST ENTSYM ;FOUND ONE
TXNE W1,PS.COM ;OR COMMON
JRST COMSYM ;BOTH ARE SPECIAL CASES OF GLOBALS
TXNE W1,PS.UDF ;UNDEFINED?
JRST UDFSYM ;YES
TXNE W1,PS.GLB
JRST GLBSYM ;NORMAL GLOBAL
TXNE W1,PS.LCL ;SHOULD BE LOCAL
JRST LCLSYM ;IT WAS
RELTST: TXNE W1,PS.MDF ;MULTIPLY-DEFINED?
JRST [MOVEI T1,[ASCIZ \Multiply-defined\]
JRST TSTFIN]
MOVEI T1,[ASCIZ \Relocatable \]
TXNN W1,PS.REL ;ASSUME IT WAS RELOCATABLE
MOVEI T1,[ASCIZ \Absolute \]
PUSHJ P,.TSTRG## ;OUTPUT ONE OR OTHER
MOVEI T1,[ASCIZ \Suppressed\]
TXNN W1,PS.DDT ;SUPPRESSED?
COMRET: MOVEI T1,[ASCIZ \ \]
TSTFIN: PUSHJ P,.TSTRG## ;YES
SETCMB T1,ODDNESS ;AT END OF LINE?
JUMPN T1,ENDSYM ;NOT THIS TIME
PUSHJ P,.TYLPP ;END LINE
ENDSYM: JUMPE R2,NXTSYM ;IF NOT SORTING, NOW FOR NEXT
POPJ P, ;SORTING
;HERE FOR ENTRY
ENTSYM: MOVEI T1,[ASCIZ \Entry \]
PUSHJ P,.TSTRG##
JRST RELTST
;HERE FOR GLOBAL
GLBSYM: MOVEI T1,[ASCIZ \Global \]
PUSHJ P,.TSTRG##
JRST RELTST
;HERE FOR LOCAL
LCLSYM: MOVEI T1,[ASCIZ \Local \]
PUSHJ P,.TSTRG##
JRST RELTST
;HERE FOR UNDEFINED SYMBOL (LOCAL OR GLOBAL)
UDFSYM: MOVEI T1,[ASCIZ \Undefined \]
PUSHJ P,.TSTRG##
JRST RELTST
;HERE FOR COMMON
COMSYM: MOVEI T1,[ASCIZ \Common length \]
PUSHJ P,.TSTRG##
MOVX T1,S.COM ;FIND SECONDARY
PUSHJ P,FNDAST
JRST COMRET ;FAILED!
MOVE T1,W3 ;GET LENGTH
PUSHJ P,.TDSPC ;ALLIGN IT
MOVE T1,W3 ;NO. AGAIN
PUSHJ P,.TDECW## ;IN DECIMAL
MOVEI T1,"." ;SIGNIFY DECIMAL
PUSHJ P,.TCHAR##
JRST COMRET ;END LINE
;HERE TO STORE SYMBOL IN SORT BUFFER
STRSYM: JRST @STRTBL(R1) ;GO TO RIGHT FUNCTION
DEFINE KEYMAC (A,B)<
IFIDN <A><MPS>,<
IRP B,<
STR'B
>>>
XALL
STRTBL: KEYWORDS
SALL
STRALPHA:
MOVS W3,SYMPTR ;RELATIVE ADDRESS NOW
LSHC W2,-2 ;MAKE SPACE SO SIGNED TEST WILL WORK
LSH W3,-1 ;SAME FOR 2ND WORD
TXNN W2,3B3 ;IF NOT ALPHANUMERIC
TXO W2,1B1 ;MAKE .,%,$ LARGER
IDPB W2,R2
IDPB W3,R2
JRST NXTSYM ;GET NEXT SYMBOL
STRNUMERIC:
STRUNSORTED:
HALT
SUBTTL SYMBOL REQUIRED TEST
;HERE TO SEE IF SYMBOL SHOULD BE LISTED
;CALLED BY
; MOVE W1,FLAGS
; PUSHJ P,SYMCHK
;RETURNS
;+1 IGNORE THIS SYMBOL
;+2 PRINT THIS SYMBOL
;USES T1, T2, T3
SYMCHK: SKIPGE T1,MAPCON ;GET CONTENTS SWITCH
JRST CPOPJ1 ;ALL WAS SET
MOVE T2,W1 ;GET FLAGS
ANDX T2,PS.GLB!PS.ENT!PS.UDF!PS.LCL!PS.COM!PS.REL
TXZN T2,PS.REL ;MUST BE ABS IF NOT REL
JRST %%.ABS ;SEE IF ALLOWED
%%.REL: TXNN T1,C%RELOC ;IS IT ALLOWED?
POPJ P, ;NO
; JRST SYMTST ;YES, TRY OTHER BITS
SYMTST: JFFO T2,.+2 ;GET LEADING BIT
AOSA (P) ;NO TESTS LEFT
JRST @TSTTAB-%%F(T3) ;MUST WAIT TIL T3 SETUP
POPJ P,
DEFINE MAKSYM (A)<
%%L==0
%%F==^D36
IRP A,<
%%==^L<PS.'A>
IFG %%F-%%,<%%F==%%>
IFL %%L-%%,<%%L==%%>
STRSYM \%%,A
>>
DEFINE STRSYM (%%,A)<
%%.'%%==%%.'A
>
DEFINE SYMGEN <
IF1,<BLOCK 1>
IF2,<
SYMDMP \%%
%%==%%+1
>>
DEFINE SYMDMP (%%)<
IFDEF %%.'%%,<%%.'%%>
IFNDEF %%.'%%,<0>
PURGE %%.'%%
>
MAKSYM <GLB,ENT,UDL,UDR,LCL,COM,REL>
%%==%%F
TSTTAB:REPEAT %%L-%%F+1,<SYMGEN>
IF2,<PURGE %%,%%F,%%L>
;HERE FOR ABSOLUTE
%%.ABS: TXNE T2,PS.COM ;HOWEVER COMMON IS NOT REALLY ABS
JRST SYMTST ;SO PASS THIS TEST
TXNN T1,C%ABSOLUTE
POPJ P,
JRST SYMTST
;HERE FOR GLOBAL
%%.GLB: TXZ T2,PS.GLB ;CLEAR IT
TXNN T1,C%GLOBAL
POPJ P,
JRST SYMTST
;HERE FOR LOCAL
%%.LCL: TXZ T2,PS.LCL
TXNN T1,C%LOCAL
POPJ P,
JRST SYMTST
;HERE FOR ENTRY
%%.ENT: TXZ T2,PS.ENT!PS.GLB
TXNN T1,C%ENTRY
POPJ P,
JRST SYMTST
;HERE FOR COMMON
%%.COM: TXZ T2,PS.COM!PS.GLB
TXNN T1,C%COMMON
POPJ P,
JRST SYMTST
;HERE FOR UNDEFINED (RH OR LH)
%%.UDL:!%%.UDR:!
%%.UDF: TXZ T2,PS.UDF
TXNN T1,C%UNDEFINED
POPJ P,
JRST SYMTST
;HERE TO SORT AND PRINT SYMBOL TABLE
SRTSYM: HRRZ W2,SRTPTR ;INITIAL VALUE
SUBI W2,(R2) ;- NO. OF PAIRS OF WORDS
LSH W2,^D17 ;CUT IN HALF AND PUT IN LHS
HRR W2,SRTPTR ;-N,,ADDRESS
PUSHJ P,IDXLP0 ;SORT IT
HRRZ R2,SRTPTR ;POINT TO TOP OF BUFFER
SRTSY1: SKIPN T1,1(R2) ;GET POINTER
JRST SRTFIN ;ALL DONE
LSH T1,3-^D18 ;PUT IN RHS
ADD T1,LS.LB ;FIX INCORE
TMOVE W1,(T1) ;GET TRIPLET AGAIN
PUSHJ P,PNTSYM ;PRINT IT NOW
JRST SRTSY1
SRTFIN: HRRZ T1,SRTPTR
HLRZ T2,SRTPTR
PUSHJ P,DY.RET## ;GIVE BACK BUFFER
SKIPE ODDNESS ;NEED TO END LINE
PUSHJ P,[SETCMM ODDNESS
PJRST .TYLPP] ;YES
MOVE T1,SYMPTR
ADD T1,LS.LB
TMOVE W1,(T1) ;GET BACK ORIGINAL TRIPLET
POPJ P,
SUBTTL TITLE ROUTINES
;HERE IF TRIPLET FOUND IS A TITLE
TTLBLK:
TXNE W1,PT.PSC ;IS THIS JUST THE PSECTS?
JRST NXTSYM ;YES, ALREADY READ THEM
IFN .NWBLK,<
TXNE W1,PT.MSF ;JUST A MULT. SRC. FILE BLOCK?
JRST NXTSYM ;YES, IGNORE IT (ALREADY PRINTED)
> ;END IFN .NWBLK
SKIPE ODDNESS ;NEED TO END LINE?
PUSHJ P,[SETCMM ODDNESS
PJRST .TYLPP] ;YES
TXNE W1,PT.BLK ;FAIL BLOCK HEADER?
JRST BTITLE ;YES
MOVEM W3,NXTTTL ;SAVE POINTER TO NEXT TITLE
SETZM CURPRG ;FINISHED WITH THIS PROGRAM
PUSHJ P,.TYLPP ;BLANK LINE
PUSHJ P,TYSTAR ;PRINT SEPARATORS
PUSHJ P,.TSTP5 ;SEE IF ENOUGH SPACE ON THIS PAGE
JFCL
PUSHJ P,.TYLPP ;BLANK LINE
MOVE T1,W2 ;FIRST 6 CHARS OF NAME
MOVEM W2,CURPRG ;SAVE INCASE GOES OVER PAGE
PUSHJ P,.TSIXN##
TXNE W1,PT.FAK ;ONLY A FAKE TITLE?
JRST TTLFAK ;YES, NO ROOM IN INDEX
MOVE T1,W2 ;NAME
MOVS T2,PAGENO ;GET PAGE NUMBER
LSHC T1,-2 ;SO SIGNED TEST CAN WORK
LSH T2,-1 ;SAME FOR 2ND WORD OF PAIR
TXNN T1,3B3 ;IF NOT ALPHANUMERIC
TXO T1,1B1 ;MAKE .,%,$ LARGER
IDPB T1,MDLPTR ;STORE MODIFIED NAME
IDPB T2,MDLPTR ;AND PAGE NO
SOSGE MDLCNT ;STILL ROOM LEFT?
JRST E$$TTF ;[1174] NO, MUST BE ERROR
;CONTINUED ON NEXT PAGE
TTLFAK: MOVX T1,S.TTL ;SEE IF ANY MORE TO NAME
MOVX T4,S.CMT!S.RLD!S.RLN!S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDAST
JRST TTLCMT ;NO, TRY COMMENT
TTLLNM: MOVE T1,W2 ;GET NEXT SIX CHARS
PUSHJ P,.TSIXN##
SKIPE T1,W3 ;AND NEXT SIX
PUSHJ P,.TSIXN##
MOVX T1,S.TTL
MOVX T4,S.CMT!S.RLD!S.RLN!S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEE IF ANY MORE (NOT INCLUDING THIS ONE)
JRST TTLCMT ;NO
JRST TTLLNM ;YES
TTLCMT:
IFN .NWBLK,<
MOVX T1,S.TTL!S.CMT ;LOOK FOR THE ASCII COMMENT
MOVX T4,S.RLD!S.RLN!S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;LOOK FOR COMMENTS
JRST TTLRL1 ;NONE, GO AFTER NEXT
PUSHJ P,.TTABC## ;TYPE A TAB
JRST TTLCM2 ;AND JUMP INTO MAIN LOOP
TTLCM1: MOVX T1,S.TTL!S.CMT ;LOOK FOR NEXT BLOCK OF COMMENT
MOVX T4,S.RLD!S.RLN!S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;GO LOOK
JRST TTLRLD ;DONE, GIVE UP
TTLCM2: DMOVE W1,W2 ;MOVE ASCII STRING UP
SETZ W3, ;MAKE ASCIZ
MOVEI T1,W1 ;POINT TO THE ASCIZ STRING
PUSHJ P,.TSTRG## ;TYPE IT
JRST TTLCM1 ;LOOK FOR MORE
TTLRLD: PUSHJ P,.TYLPP ;END LINE IF COMMENT PRINTED
> ;END IFN .NWBLK
;FALL THROUGH TO PRINT .REL FILE SPEC
TTLRL1: MOVX T1,S.TTL!S.RLD ;GET REL FILE DEVICE & FILENAME
MOVX T4,S.RLN!S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS
JRST TTLPRC ;SKIP REST OF THIS ALSO
MOVEI T1,[ASCIZ \ from \]
PUSHJ P,.TSTRG##
MOVE T1,W2 ;DEVICE
PUSHJ P,.TSIXN##
PUSHJ P,.TCOLN##
PUSH P,W3 ;SAVE UFD
MOVX T1,S.TTL!S.RLN ;FILE NAME & EXT
MOVX T4,S.RLS!S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS
JRST TTLRLU
MOVE T1,W2 ;FILE NAME
PUSHJ P,.TSIXN##
MOVEI T1,"."
PUSHJ P,.TCHAR##
SKIPE T1,W3 ;EXT
PUSHJ P,.TSIXN##
TTLRLU: POP P,W3 ;RECOVER UFD
JUMPE W3,TTLPRC ;NO UFD
MOVEI T1,"["
PUSHJ P,.TCHAR##
MOVE T1,W3 ;GET PPN
PUSHJ P,.TXWDW## ;PROG,PROJ
MOVX T1,S.TTL!S.RLS ;NOW FOR POSSIBLE SFD
MOVX T4,S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS
JRST TTLRLR ;CLOSE [DIRECTORY]
TTLRLS: PUSHJ P,.TCOMA##
MOVE T1,W2
PUSHJ P,.TSIXN##
JUMPE W3,TTLRLR
PUSHJ P,.TCOMA##
MOVE T1,W3
PUSHJ P,.TSIXN##
MOVX T1,S.TTL!S.RLS ;NOW FOR NEXT SFD
MOVX T4,S.PRC!S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS
JRST TTLRLR ;CLOSE [DIRECTORY]
JRST TTLRLS
TTLRLR: MOVEI T1,"]"
PUSHJ P,.TCHAR##
TTLPRC: MOVX T1,S.TTL!S.PRC ;FIND PROCESSOR NAME
MOVX T4,S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS
JRST TTLCRU ;NO LUCK, GO PRINT CREATION STUFF
PUSH P,W3 ;SAVE CPU BITS ETC
JUMPE W2,TTLPRX ;IF NO NAME GIVEN, USE DEFAULT
MOVEI T1,[ASCIZ \ created by \]
PUSHJ P,.TSTRG##
MOVE T1,W2 ;SET UP PROC NAME
TTLPR1: PUSHJ P,.TSIXN## ;TYPE 1ST SIX CHARS OF PROCESSOR NAME
MOVX T1,S.TTL!S.PRC ;LOOK FOR MORE OF PROCESSOR NAME
MOVX T4,S.CRE!S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;GET NEXT TRIPLET
JRST TTLCPU ;NO MORE, GO PRINT RUNNABLE CPU'S
MOVE T1,W2 ;NEXT CHARACTERS OF PROCESSOR NAME
PUSHJ P,.TSIXN## ;TYPE THEM
SKIPE T1,W3 ;MORE?
JRST TTLPR1 ;YES
TTLCPU: POP P,T1 ;[1120] RESTORE CPU BITS
TTLCP1: TLZ T1,-1 ;[1120] ZAP PROCESSOR TYPE BITS
PUSHJ P,TYPCPU ;[1120] TYPE CPUS FOR THIS MODULE
JRST TTLCRE ;GO PRINT CRE STUFF
TTLPRX: POP P,W3 ;RESTORE CPU BITS
JUMPE W3,TTLCRU ;UNKNOWN PROCESSOR SO SKIP
MOVEI T1,[ASCIZ \ created by \]
PUSHJ P,.TSTRG##
HLRE T1,W3 ;GET PROCESSOR TYPE (-1 IS LINK)
CAML T1,[-1] ;TOO LOW?
CAILE T1,CT.LEN ;MAKE SURE IN RANGE
SETZ T1, ;USE UNKNOWN
TTLCRL: MOVE T1,PRCTAB(T1) ;PICKUP NAME
PUSHJ P,.TSTRG##
HRRZI T1,(W3) ;[1120] GET CPU BITS
JRST TTLCP1 ;PRINT CPU BITS
TTLCRE: MOVX T1,S.TTL!S.CRE ;LOOK FOR CREATION INFO
MOVX T4,S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;FIND THE TRIPLET
JRST TTLSRC ;WHAT CAN YOU DO?
JUMPE W3,TTLDAT ;DON'T PRINT A VERSION IF NONE
MOVEI T1,[ASCIZ/ version /]
PUSHJ P,.TSTRG## ;PROCLAIM THE DATA
MOVE T1,W3 ;SET IT UP
PUSHJ P,.TVERW## ;THEN LET SCAN DO ALL THE WORK
TTLDAT: JUMPE W2,TTLSRC ;FORGET IT IF NOT GIVEN
MOVEI T1,[ASCIZ/ on /]
PUSHJ P,.TSTRG##
HLRZ T1,W2 ;GET DATE
PUSHJ P,.TDATE## ;TYPE IT
MOVEI T1,[ASCIZ/ at /]
PUSHJ P,.TSTRG##
HRRZ T1,W2 ;GET TIME (SECS)
IMULI T1,^D1000 ;SCAN WANTS MILLISECS
PUSHJ P,.TTIME## ;TYPE AWAY
JRST TTLSRC ;DONE, NOW PRINT SEGMENT STUFF
TTLCRU: MOVX T1,S.TTL!S.CRE
MOVX T4,S.DEV!S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEE IF CREATION TRIPLET THERE
JRST TTLSRC ;NO, FORGET THE WHOLE IDEA
JUMPE W2,TTLSRC ;MUST BE SPECIFIED
MOVEI T1,[ASCIZ \ created\]
PUSHJ P,.TSTRG##
JRST TTLDAT
TTLSRC:
IFN .NWBLK,<
MOVX T1,S.TTL!S.DEV ;LOOK FOR SOURCE FILE INFO
MOVX T4,S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEARCH SYMBOL TABLE
JRST TTLSG1 ;NOT THERE
PUSH P,W3 ;SAVE SOURCE UFD
PUSHJ P,.TYLPP ;END LINE
MOVEI T1,[ASCIZ/ Source file was /]
TTLSR1: PUSHJ P,.TSTRG## ;TYPE HEADER
MOVE T1,W2 ;DEVICE
PUSHJ P,.TSIXN## ;TYPE IT
PUSHJ P,.TCOLN## ;A COLON
MOVX T1,S.TTL!S.NAM ;FILE NAME AND EXTENSION NEXT
MOVX T4,S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEARCH SYMBOL TABLE
JRST TTLUFD ;NON-DIRECTORY DEVICE??
MOVE T1,W2 ;FILE NAME
PUSHJ P,.TSIXN## ;TYPE IT
MOVEI T1,"." ;A DOT
PUSHJ P,.TCHAR## ;OUT IT GOES
SKIPE T1,W3 ;IF AN EXTENSION EXISTS
PUSHJ P,.TSIXN## ;TYPE IT TOO
TTLUFD: POP P,W3 ;RESTORE UFD
JUMPE W3,TTLVER ;NONE, DON'T TYPE [0,0]
MOVEI T1,"[" ;OPEN BRACKET
PUSHJ P,.TCHAR## ;ZAP
MOVE T1,W3 ;POSITION PPN
PUSHJ P,.TXWDW## ;LET SCAN DO ALL THE WORK
TTLSFD: MOVX T1,S.TTL!S.SFD ;SEARCH FOR SFD'S
MOVX T4,S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEE IF SPECIFIED
JRST TTLRBK ;NO, GO CLOSE OFF [P,PN]
PUSHJ P,.TCOMA## ;A COMMA TO SEPERATE
MOVE T1,W2 ;SET UP FIRST ONE
PUSHJ P,.TSIXN## ;TYPE IT
JUMPE W3,TTLRBK ;FINISH UP IF NO MORE
PUSHJ P,.TCOMA## ;A SEPARATING COMMA
MOVE T1,W3 ;THERE IS, SET IT UP
PUSHJ P,.TSIXN## ;TYPE IT
JRST TTLSFD ;AND CONTINUE
TTLRBK: PUSHJ P,.TRBRK## ;CLOSE [PATH]
TTLVER: MOVX T1,S.TTL!S.VER ;SOURCE VERSION INFO NEXT
MOVX T4,S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;LOOK FOR IT
JRST TTLNXT ;CAN'T HAVE EVERYTHING
JUMPE W2,TTLCRS ;IF NO VERSION, PRINT CREATION INFO
MOVEI T1,[ASCIZ/ version /]
PUSHJ P,.TSTRG## ;TYPE INTRODUCTION
MOVE T1,W2 ;SET UP VERSION
PUSHJ P,.TVERW## ;AND LET SCAN WORRY ABOUT IT
TTLCRS: JUMPE W3,TTLNXT ;FORGET IT IF NOT SPECIFIED
MOVEI T1,[ASCIZ/ created on /]
PUSHJ P,.TSTRG## ;USE UP DISK SPACE
HLRZ T1,W3 ;PICKUP DATE
PUSHJ P,.TDATE## ;TYPE IT
MOVEI T1,[ASCIZ/ at /]
PUSHJ P,.TSTRG## ;TYPE "AT"
HRRZ T1,W3 ;GET TIME (SECONDS)
IMULI T1,^D1000 ;SCAN WANTS MILLISECONDS
PUSHJ P,.TTIME## ;TYPE THE TIME AS HH:MM:SS
TTLNXT: SKIPL T1,NXTTTL ;IS NEXT TITLE BLOCK A MULT. SRC. FILE?
JRST TTLSEG ;NO, PRINT IT NEXT TIME
HRRZ T1,T1 ;YES, CLEAR FLAG IN LH
SUB T1,LW.LS ;CONVERT TO PHYSICAL ADDRESS
ADD T1,LS.LB ; ...
ADDI T1,.L-1 ;WANT TO ACCESS LAST WORD OF TRIPLET
SKIPE PAG.LS ;IF PAGING
CAMGE T1,LS.AB ;AND THIS ADDRESS NOT YET IN CORE
SKIPA ;NOT TRUE
HALT ;GIVE UP (FOR NOW)
SUBI T1,.L-1 ;BACK TO FIRST WORD OF TRIPLET
MOVE T2,ASTPTR ;IN CASE FIRST TIME THROUGH, GET ASTPTR
SKIPN SAVAST ;ANYTHING SAVED YET?
MOVEM T2,SAVAST ;NO, JUST SAVE THE FIRST ONE
MOVE T2,2(T1) ;SAVE POINTER TO TITLE AFTER THIS ONE
MOVEM T2,NXTTTL ;SAVE FOR LATER
ADDI T1,.L ;POINT TO 1ST 2NDARY 3RPLET OF NEW BLK
MOVEM T1,ASTPTR ;SETUP TO SCAN NEW PT.MSF BLOCK
MOVX T1,S.TTL!S.DEV ;LOOK FOR SOURCE DEVICE & UFD
MOVX T4,S.NAM!S.SFD!S.VER!S.SEG ;STOPPERS
PUSHJ P,FNDNAS ;SEARCH THE SYMBOL TABLE
JRST TTLNXT ;NOT THERE, LOOK FOR MORE
PUSH P,W3 ;SAVE SOURCE UFD
PUSHJ P,.TYLPP ;END OLD LINE
MOVEI T1,[ASCIZ/ concatenated with /]
JRST TTLSR1 ;DUMP THIS BLOCK
> ;END IFN .NWBLK
TTLSEG:
IFN .NWBLK,<
SKIPN T1,SAVAST ;IS THERE AN ASTPTR SAVED?
JRST TTLSG1 ;NO
MOVEM T1,ASTPTR ;YES, RESTORE IT
SETZM SAVAST ;NOTHING THERE NOW
TTLSG1:> ;END IFN .NWBLK
PUSHJ P,.TYLPP ;END LINE
SETZB R1,ZERLEN ;ASSUME NOT ZERO LENGTH
MOVX T1,S.TTL!S.SEG
SETZ T4, ;NO STOPPERS
PUSHJ P,FNDNAS ;GET SEGMENT INFO
JRST TTLEND
HLRZ T1,W2 ;GET LOW SEG ORIGIN
HLRZ T2,W3 ;AND HIGH SEG
CAIN T1,(W2) ;LOW SEG EMPTY?
CAIE T2,(W3) ;YES, AND HIGH SEG TOO?
CAIA ;SOMETHING LOADED SOMEWHERE
SETOM ZERLEN ;NOTHING IN EITHER SEGMENT
TTLHSG: HLRZ T1,W2(R1) ;GET LOW SEG INIT REL
HRRZ T2,W2(R1) ;AND FINAL
CAMN T2,T1 ;SAME?
JRST [JUMPN R1,TTLEND ;THIS IS HIGH SEG
SKIPN W3
SETOM ZERLEN ;BOTH SEGMENTS ZERO
AOJA R1,TTLSG1] ;TRY AGAIN
PUSHJ P,.TTABC##
MOVEI T1,SEG0(R1)
PUSHJ P,.TSTRG##
MOVEI T1,SEG1
PUSHJ P,.TSTRG##
HLRZ T1,W2(R1)
PUSHJ P,.T6OCT## ;STARTING
MOVEI T1,SEG2
PUSHJ P,.TSTRG##
HRRZ T1,W2(R1)
SKIPE T1 ;MIGHT NOT BE SETUP (IF 0)
SUBI T1,1 ;ONE LESS THAN PROG BREAK
PUSHJ P,.T6OCT## ;ENDS
MOVEI T1,SEG3
PUSHJ P,.TSTRG##
HRRZ T1,W2(R1)
HLRZ T2,W2(R1)
SUB T1,T2
MOVEM T1,W2(R1) ;SAFE PLACE TO STORE IT
PUSHJ P,.T6OCT## ;LENGTH
MOVEI T1,[ASCIZ \ (octal),\]
PUSHJ P,.TSTRG##
MOVE T1,W2(R1)
PUSHJ P,.TDSPC ;ALLIGN WORD
MOVE T1,W2(R1) ;GET LENGTH BACK
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ \. (decimal)\]
PUSHJ P,.TSTRG##
PUSHJ P,.TYLPP ;END LINE
JUMPN R1,TTLEND ;DONE
ADDI R1,1 ;GET NEXT WORD
TTLSG1: SKIPN T1,W2(R1) ;SEE WHAT IT IS
JRST TTLEND ;NOTHING
TLNE T1,-1 ;LHS 0?
JRST TTLHSG ;NO TRY HIGH
;HERE TO HANDLE PSECTS
TTLPSC: MOVE R,W3 ;GET OFFSET TO BLOCK
ADD R,LS.LB ;PLUS BASE
SUB R,LW.LS ;MINUS WINDOW
CAMLE R,LS.AB ;IN CORE
HALT ;NO
MOVEI T1,[ASCIZ / Psect /] ;[1161]
PUSHJ P,.TSTRG##
MOVE T1,1(R) ;NAME
PUSHJ P,.TSIXB## ;[1161] TYPE WITH TRAILING BLANKS
MOVEI T1,[ASCIZ / starts at /]
PUSHJ P,.TSTRG##
HLRZ T1,2(R) ;RC.CV
PUSHJ P,.T6OCT##
MOVEI T1,SEG2
PUSHJ P,.TSTRG##
HRRZ T1,2(R) ;PROG BREAK
SUBI T1,1
PUSHJ P,.T6OCT##
MOVEI T1,SEG3 ;LENGTH
PUSHJ P,.TSTRG##
HLRZ T2,2(R) ;RC.CV
HRRZ T1,2(R) ;RC.HL
SUBI T1,(T2)
PUSH P,T1 ;SAVE LENGTH
PUSHJ P,.T6OCT##
MOVEI T1,[ASCIZ / (octal),/] ;[1161]
PUSHJ P,.TSTRG##
MOVE T1,0(P) ;[1161] GET LENGTH AGAIN
PUSHJ P,.TDSPC ;[1161] ALIGN WORD TO COME
POP P,T1 ;LENGTH
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ /. (decimal)/] ;[1161]
PUSHJ P,.TSTRG##
PUSHJ P,.TYLPP
ADDI W3,.L ;POINT TO NEXT
MOVE W1,(R)
JUMPL W1,[ TXNE W1,PT.EXT ;[711] IT'S PRIMARY
JRST TTLPSC ;[711] MORE TO COME
JRST TTLEND] ;[711] NO MORE
TXNN W1,S.LST ;[711] NOT PRIMARY, ALL DONE?
JRST TTLPSC ;NOT YET
;YES
TTLEND: PUSHJ P,.TYLPP ;BLANK LINE
MOVE T1,MAPCON ;GET MASK FOR MAP CONT
SKIPGE ZERLEN ;MAKE ZERO LENGTH TEST NOW
TXNE T1,C%ZERO ;SKIP IF NOT ALLOWED
JRST TTLSRT ;OK, ALLOWED
MOVEI T1,[ASCIZ \ Zero length module\]
PUSHJ P,.TSTRG##
PUSHJ P,.TYLPP
PUSHJ P,GETSYM ;GET FIRST SYMBOL
JRST SYMDN ;ALL OVER
JRST TTLBLK ;A TITLE BLOCK
JRST .-3 ;LOOP TIL NEXT TITLE OR ELSE END
E$$TTF::.ERR. (MS,,V%L,L%W,S%W,TTF,<Too many titles found>) ;[1174]
JRST NXTSYM ;IGNORE, BUT TRY TO COMPLETE MAP
SUBTTL FAIL BLOCK HEADER
BTITLE: MOVX W1,PS.LCL ;FAKE A LOCAL SYMBOL
PUSHJ P,SYMCHK ;SEE IF WE WANT THIS SYMBOL?
JRST NXTSYM ;NO
PUSHJ P,.TYLPP ;BLANK LINE
PUSHJ P,.TTABC## ;TAB
MOVEM W1,SYFLAG ;SAVE PRIMARY FLAGS
MOVE T1,W2 ;FIRST 6 CHARS OF NAME
HRRZM W3,VALUE ;VALUE OF SYMBOL
PUSHJ P,.TSIXN##
MOVEI T1,[ASCIZ \ block level \]
PUSHJ P,.TSTRG##
MOVE T1,VALUE
PUSHJ P,.TDECW## ;LEVEL IN DECIMAL
PUSHJ P,.TYLPP ;END LINE
JRST NXTSYM
SUBTTL SYMBOL TABLE ROUTINES
;HERE TO READ BACK SYMBOL TABLE IF ON DSK
;CALLED BY
; PUSHJ P,SYMINI
SYMINI: SKIPN T1,PAG.LS ;PAGING SYMBOLS?
POPJ P, ;NO
MOVS T1,LW.LS ;LOWEST INCORE
HRR T1,LSYM ;HIGHEST
IORI T1,.DBM ;PUT ON DSK BLOCK BOUND (NOT NECESSARY)
PUSHJ P,LS.OUT## ;DUMP THEM
SETZM LW.LS ;START AGAIN AT 0
PUSH P,FRECOR ;SAVE INCASE NOT 0
SETZM FRECOR ;DON'T NEED EXTRA SPACE IN MAPS
PUSHJ P,FR.CNT## ;COUNT ALL OF FREE CORE
CAILE T1,1000 ;[640] UNLESS THAT WOULD USE IT ALL
SUBI T1,1000 ;[640] LEAVE SOME FOR OTHERS (TTLDN ETC)
MOVEI P1,LS.IX ;WILL WANT TO EXPAND LS AREA MOST LIKELY
MOVE P2,LSYM ;WE WANT THIS MUCH MOST LIKELY
ADD P2,LS.LB ;FIND EXTRA WE NEED
SUB P2,LS.AB ;REMOVING WHAT WE HAVE
CAMLE P2,T1 ;MORE THAN WHATS FREE?
MOVE P2,T1 ;YES, SO JUST GET WHAT WE CAN
JUMPE P2,[MOVE T1,LS.AB ;MAKE SURE WE HAVE AT LEAST 2 BLOCKS
SUB T1,LS.LB ;IF WE ARE NOT INCREASING
CAIL T1,.IPS ;MORE THAN ONE BLOCK
JRST SYMIN1 ;[640] ENOUGH ALREADY, LEAVE
MOVEI P2,.IPS ;NOT ENOUGH, GET ONE MORE
JRST .+1]
PUSHJ P,LOGBCK ;INCASE LOG FILE OPEN
PUSHJ P,LNKCOR ;GET IT ALL
PUSHJ P,E$$MEF## ;[1174] CANNOT HAPPEN
PUSHJ P,LOGBCK ;RESTORE MAP DEVICE
SYMIN1: POP P,FRECOR ;[640] RESTORE
MOVE T1,LS.AB ;RECALCULATE UW.LS
SUB T1,LS.LB ;SEE HOW BIG
MOVEM T1,UW.LS ;BIGGEST IN CORE
PJRST LS.IN## ;INPUT AND RETURN
;HERE TO GET NEXT PRIMARY SYMBOL
;CALLED BY
; PUSHJ P,GETSYM
;RETURNS
;+1 END OF SYMBOL TABLE
;+2 TRIPLET IS A TITLE OR OTHER NON-SYMBOL
;+3 NORMAL SYMBOL RETURN
;USES T1
;SETS UP W1, W2, W3 & SYMPTR
GETSYM: MOVE T1,SYMPTR ;GET POINTER TO LAST PRIMARY
ADD T1,LS.LB ;ADD IN OFFSET
NOTPRM: ADDI T1,.L ;GET TO END OF NEXT TRIPLET
CAMLE T1,LS.AB ;STILL IN CORE
JRST SHFSYM ;NO, GET NEXT BLOCK OR GIVE UP
SKIPL W1,-.L(T1) ;GET FLAGS
JRST NOTPRM ;NOT A PRIMARY
DMOVE W2,-.L+1(T1) ;LOAD REST OF TRIPLET
SUB T1,LS.LB ;REMOVE OFFSET
MOVEM T1,SYMPTR ;STORE POINTER
AOS (P) ;AT LEAST SKIP RET
TXNE W1,PT.SYM ;SEE IF SYMBOL TYPE
AOS (P) ;YES, RET +3
POPJ P,
;HERE TO SHIFT NEW SYMBOL WINDOW INTO CORE
;ALL EXCEPT THE LAST 128 WORDS ARE THROWN AWAY (KEPT INCASE SYMBOL ACROSS A BOUND)
;READ IN NEW PART AND ADJUST POINTERS
;IF THERE IS MORE SPACE THAN WE NEED GIVE BACK THE EXCESS
SHFSYM: SKIPN UW.LS ;PAGING?
POPJ P, ;NO, ALL DONE
MOVE T1,UW.LS ;LAST HIGHEST
ADDI T1,1 ;NEW LOWEST
CAMLE T1,LSYM ;STILL SOME SYMBOLS LEFT?
POPJ P, ;NO, ALL DONE
;KEEP LAST BLOCK IN CORE AGAIN
HRLI T1,-.IPS(T1) ;[650] IN BOTH HALVES
HLRZ T2,T1
SUB T2,LW.LS ;DIFFERENCE = WINDOW SIZE
ADDM T2,LW.LS ;FIXUP WINDOW PTRS
ADDM T2,UW.LS
MOVN T2,T2
ADDM T2,SYMPTR ;BACKUP SYMBOL PTR
MOVM T2,T2 ;BACK POSITIVE
MOVE T3,UW.LS ;GET NEXT UPPER BOUND
ANDCMI T3,.IPM ;[1164] FORM FIRST FREE IN ALL BUT LAST PAGE
CAMG T3,LSYM ;HAVE WE TOO MUCH ROOM NOW?
SOJA T2,SHFSY1 ;NO, READ ALL WE CAN GET
MOVE T2,LSYM ;GET UPPER WE NEED
SUB T2,LW.LS ;LENGTH WE REALLY NEED
IORI T2,.IPM ;[650] BLOCK BOUND
MOVE T3,LSYM ;HIGHEST SYMBOL SEEN
IORI T3,.IPM ;PUT ON BOUND
MOVEM T3,UW.LS ;STORE AS HIGHEST WINDOW
MOVE T3,LS.LB ;ACTUAL LOWER
ADD T3,T2 ;NEW UPPER
MOVEM T3,LS.AB ;ACTUAL BOUND IN USE
SETZM 1(T3) ;CLEAR IT
HRLI T3,1(T3)
ADDI T3,2 ;FORM BLT PTR
BLT T3,@LS.UB ;CLEAR IT ALL
SUBI T2,.IPS ;[1164] LAST PAGE HAS ALREADY BEEN COUNTED
SHFSY1: ADDI T1,(T2) ;INPUT PTR
PUSHJ P,LS.IN## ;READ IN NEW BLOCKS
JRST GETSYM ;AND CONTINUE
;HERE TO FIND ASSOCIATED SECONDARY TRIPLET
;CALLED BY
; MOVE T1,FLAGS
; MOVE T4,"STOPPER" FLAGS (WILL NOT SCAN BEYOND THESE)
; PUSHJ P,FNDAST (FIRST TIME)
; -OR-
; PUSHJ P,FNDNAS
;RETURNS
;+1 FAILED
;+2 SUCCESS
;USES T1, T2, T3, T4
;SETS UP W1, W2, W3
FNDAST: SKIPA T2,SYMPTR ;GET POINTER
FNDNAS: SKIPA T2,ASTPTR ;ALREADY RELOCATED
ADD T2,LS.LB ;FIX
FNDNAT: ADDI T2,.L ;GET NEXT TRIPLET
CAMLE T2,LS.AB ;STILL IN CORE?
PUSHJ P,FNDNIC ;NOT IN CORE, OR FINISHED
MOVEI T3,-.L(T2) ;KEEP ASTPTR UP TO DATE
MOVEM T3,ASTPTR ;IN CASE FNDNIC OR ENTERED AT FNDAST
SKIPGE T3,-.L(T2) ;GET FLAGS
POPJ P, ;FOUND A PRIMARY (FAILED)
XOR T3,T1 ;IFF ALL BITS MATCH
TXZ T3,S.LST ;IGNORE THIS BIT HOWEVER
TDZ T4,T1 ;GUARD AGAINST REQUESTING A STOPPER
JUMPN T3,[TDNE T3,T4 ;FOUND A STOPPER?
POPJ P, ;YES, QUIT
JRST FNDNAT] ;NO, KEEP TRYING
TMOVE W1,-.L(T2) ;LOAD TRIPLET
MOVEM T2,ASTPTR ;SAVE INCASE CALLED AGAIN
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
;HERE TO READ IN MORE OF SYMBOL TABLE IF PAGING
;LEAVES THE LAST PAGE IN CORE (IN CASE TRIPLET SPLIT ACROSS BOUND)
;BUT ADJUSTS SYMPTR ETC
;CALLED BY
; PUSHJ P,FNDNIC
;
FNDNIC: SKIPN PAG.LS
JRST TPOPJ ;REMOVE RETURN AND EXIT
MOVE T1,UW.LS ;GET CURRENT HIGHEST
ADDI T1,1
CAMLE T1,LSYM ;ANY MORE TO READ IN?
JRST TPOPJ ;NO, GIVE UP
SUB T2,LS.LB ;REMOVE OFFSET
MOVE T1,SYMPTR ;GET PTR TO CURRENT PRIMARY
ANDCMI T1,.IPM ;KEEP THAT BLOCK
SUB T2,T1 ;ADJUST T2 FOR NEW VALUE
PUSH P,T2 ;SAVE IT FOR RETURN
MOVEI T2,.IPM
ANDM T2,SYMPTR ;BACKUP PRIMARY PTR
ADDM T1,LW.LS ;GET NEW
ADDB T1,UW.LS ;AFTER NEXT INPUT
CAML T1,LSYM ;DO WE NEED ALL OF IT?
PUSHJ P,REDUSM ;NO, REDUCE SIZE
HRLZ T1,LW.LS ;LOWEST ADDRESS
HRR T1,UW.LS ;HIGHEST
PUSHJ P,LS.IN## ;READ IN AGAIN
POP P,T2 ;RESTORE T2
ADD T2,LS.LB ;RESTORE OFFSET
POPJ P, ;RETURN
;HERE TO REDUCE SIZE SO WE DON'T WASTE TIME LOOKING AT ZEROS
;AND SAVES READIN TIME
REDUSM: SUB T1,LSYM ;GET EXCESS
ANDCMI T1,.IPM ;IN THIS BLOCK
MOVN T1,T1 ;AS - OFFSET
ADDM T1,UW.LS ;BACKUP WINDOW
ADD T1,LS.AB ;WILL BE NEW TOP LATER
;FIRST WE MUST CLEAR JUNK FROM THIS SPACE
MOVEI T2,1(T1) ;FIRST FREE LOC
SETZM (T2) ;CLEAR IT
HRL T2,T2
ADDI T2,1 ;BLT PTR
BLT T2,@LS.AB ;UP TO OLD LIMIT
MOVEM T1,LS.AB ;NOW SET TOP
POPJ P,
TPOPJ: POP P,T1 ;REMOVE RETURN
POPJ P,
SUBTTL OUTPUT ROUTINES
MAPIT: SOSGE MCBUF+2 ;ANY SPACE EFT
JRST MAPDMP ;NO
IDPB T1,MCBUF+1 ;YES
POPJ P,
MAPDMP: OUT MC,
JRST MAPIT
PUSHJ P,LOGBCK ;RESTORE LOG CHAN
E$$OEM::PUSH P,[MC] ;ERROR, SAVE CHAN
.ERR. (ST,,V%L,L%W,S%W,OEM,<Output error on map file, file closed, load continuing>) ;[1174]
CLOSE MC,
JRST MAPRET ;AND RETURN
;HERE TO SWAP CURRENT OUTPUT SUBROUTINE WITH PREVIOUS
;CALLEDD BY
; PUSHJ P,LOGBCK
LOGBCK: MOVE T1,OLDDEV ;RESTORE
PUSHJ P,.TYOCH##
MOVEM T1,OLDDEV
POPJ P,
;HERE TO OUTPUT CR-LF OR CR-FF & HEADER
;CALLED BY
; PUSHJ P,.TYLPP
.TYLPP: SOSLE CNTLPP ;STILL SPACE ON THIS PAGE?
PJRST .TCRLF## ;YES, JUST CRLF
MOVEI T1,LN.LPP ;NO, RESET PAGE COUNT
MOVEM T1,CNTLPP
PUSHJ P,.TCRLF## ;CR-LF
MOVEI T1,.CHFFD ;FF
PUSHJ P,.TCHAR##
.TYHDR: MOVE T1,PAGHDR ;HEADER AGAIN
PUSHJ P,.TSTRG##
MOVE T1,MAPNAM ;GET MAP FILE NAME
PUSHJ P,.TSIXN## ;IN SIXBIT
MOVE T1,OKCPUS ;[1120] PRINT CPUS FOR PROGRAM
PUSHJ P,TYPCPU ;[1120] ..
SKIPN MAPVER ;ONLY PRINT IF NOT ZERO
JRST TYPAGE ;JUST PAGE NUMBER
MOVEI T1,[ASCIZ \ version \]
PUSHJ P,.TSTRG##
MOVE T1,MAPVER ;VERSION
PUSHJ P,.TVERW##
TYPAGE:
IFN FTOVERLAY,<
SKIPL LNKMAX ;ANY OVERLAYS?
SKIPG LNKNO. ;EXCEPT #0
JRST TYPAG1 ;NO
MOVEI T1,[ASCIZ \ #\]
PUSHJ P,.TSTRG##
MOVE T1,LNKNO.
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ \ page \]
CAIA
TYPAG1:
>;END OF IFN FTOVERLAY
MOVEI T1,[ASCIZ \ page \]
PUSHJ P,.TSTRG##
AOS T1,PAGENO ;GET PAGE NUMBER
PUSHJ P,.TDECW##
PUSHJ P,.TYLPP
MOVE T1,PAGENO ;GET PAGE NUMBER
CAIN T1,1 ;BLANK LINE UNLESS PAGE 1
POPJ P,
SKIPE T1,CURPRG ;GET CURRENT PROG NAME
PUSHJ P,.TSIXN## ;OUTPUT IT SO WE KNOW WHERE WE ARE
PJRST .TYLPP
;HERE TO TEST FOR 5 FREE LINE ON PAGE
;CALLED BY
; PUSHJ P,.TSTP5
.TSTP5: MOVEI T1,5
;FALL INTO .TSTPG
;HERE TO SEE IF WITHIN SO MANY LINES FROM END OF PAGE
;IF SO END PAGE AND RETURN +1
;IF NOT JUST RETURN +2
;CALLED BY
; MOVEI T1,NO. OF LINES TO TEST FOR
; PUSHJ P,.TSTPG
;RETURNS
;+1 ON A NEW PAGE
;+2 ENOUGH SPACE ON CURRENT PAGE
.TSTPG: CAMG T1,CNTLPP ;ENOUGH FREE LINES?
JRST CPOPJ1 ;YES
SETZM CNTLPP ;NO, FORCE END
PJRST .TYLPP ;AND WRITE IT OUT
;HERE TO PRINT LINE OF STARS
;CALLED BY
; PUSHJ P,TYSTAR
TYSTAR: MOVEI T1,STARS ;GET LINE
PUSHJ P,.TSTRG## ;OUTPUT
PJRST .TYLPP ;AND CLOSE LINE
;.TDSPC - SUBROUTINE TO PRINT ALLIGNMENT SPACES FOR DECIMAL NO.
;CALLED BY
; MOVE T1,NUMBER
; PUSHJ P,.TDSPC
;OUTPUTS ONE SPACE FOR EVERY DIGIT NOT PRINTED
.TDSPC: MOVSI T2,-SPCLEN ;AOBJN WORD
CAMGE T1,SPCTBL(T2) ;SEE HOW BIG
AOBJN T2,.-1 ;NOT YET
MOVEI T1," " ;SPACE
HRRZ T2,T2 ;COUNT OF HOW MANY
JUMPE T2,CPOPJ ;NONE
PUSHJ P,.TCHAR##
SOJG T2,.-1 ;LOOP
POPJ P,
SPCTBL: ^D100000
^D10000
^D1000
^D100
^D10
SPCLEN==.-SPCTBL
;.TDEC3 -- TYPE DECIMAL AT LEAST THREE DIGITS
;CALL: SAME AS .TDECW WITH T2=FILLER CHAR (" " OR "0")
.TDEC3: CAILE T1,^D99 ;SEE IF TWO DIGITS OR LESS
PJRST .TDECW## ;NO--JUST OUTPUT
MOVEI T2," " ;SET FILLER
EXCH T1,T2 ;SWAP
PUSHJ P,.TCHAR## ;OUTPUT FILLER
EXCH T1,T2 ;PUT BACK
PJRST .TDEC2## ;OUTPUT OTHER TWO DIGITS
SUBTTL HEADER MESSAGES ETC
HEAD1: ASCIZ \ LINK symbol map of \
HEAD2: ASCIZ \ Produced by LINK version \
SEG0: ASCIZ \Low \
ASCIZ \High\
SEG1: ASCIZ \ segment starts at \
SEG2: ASCIZ \ ends at \
SEG3: ASCIZ \ length \
STARS: ASCIZ \ *************\
END1: ASCIZ \ [End of LINK map of \
DEFINE X (A,B,C)<
[ASCIZ \C\]
>
[ASCIZ \LINK\]
XALL
PRCTAB: PROCESSORS
SALL
;ROUTINE TO PRINT CPUS ON WHICH A MODULE OR PROGRAM WILL RUN. IF ALL CPUS
;KNOWN TO LINK ARE ALLOWED, PRINT NOTHING.
;ON CALL:
; T1/ CP.??? BITS
TYPCPU: CAIN T1,CP.MSK ;[1120] RUNNABLE ON ALL CPUS?
POPJ P, ;[1120] YES--DON'T BOTHER PRINTING
PUSH P,P1 ;[1120] SAVE SOME VARS
PUSH P,P2 ;[1120] ..
MOVE P1,T1 ;[1120] SAVE CPU BITS IN SAFE AC
PUSHJ P,.TSPAC## ;[1120] SEPARATE BY A SPACE
SETZ P2, ;[1120] START CHECK AT KA
TYPCPL: JUMPE P1,TYPCPE ;[1120] ANY CPUS LEFT TO PRINT?
MOVE T1,CPUTAB(P2) ;[1120] YES--GET ADDR OF CPU NAME
TXNE P1,1B35 ;[1120] PRINT THIS CPU?
PUSHJ P,.TSTRG## ;[1120] YES--PRINT IT
LSH P1,-1 ;[1120] ADVANCE TO NEXT CPU
AOJA P2,TYPCPL ;[1120] AND LOOP UNTIL DONE
TYPCPE: POP P,P2 ;[1120] RESTORE VARS
POP P,P1 ;[1120] ..
POPJ P,
DEFINE X(A,B)<
[ASCIZ \/A\]
>
XALL
CPUTAB: CPUS
SALL
SUBTTL END OF MAP
SYMDN: SETZM CURPRG ;DON'T WANT LAST PROG ON UNDEF PAGES
SKIPE ODDNESS ;NEED TO END LINE?
PUSHJ P,[SETCMM ODDNESS
PJRST .TYLPP] ;YES
PUSHJ P,.TYLPP ;BLANK
PUSHJ P,TYSTAR ;SEPARATE THIS AREA
PUSHJ P,.TYLPP ;AND BLANK LINE
SKIPN USYM ;ANY UNDEFINED SYMBOLS?
JRST MULDF0 ;NO, TRY FOR MULTIPLY DEFINED
UNRES0: MOVE T1,CNTLPP ;GET NUMBER OF LINES ON PAGE
CAIGE T1,LN.LPP-3 ;UNLESS JUST OUTPUT HEADER
SETZM CNTLPP ;START NEW PAGE
PUSHJ P,.TYLPP ;START ON A NEW LINE
MOVE P1,USYM ;GET NUMBER OF UNDEFS IN A PRESERVED AC
MOVE T1,P1 ;WHERE SCAN EXPECTS NUMBER
PUSHJ P,.TDECW## ;TYPE NO.
MOVE T1,P1 ;GET UNDEFS AGAIN
CAILE T1,2 ;LEAVE 0 OR 1 ALONE
MOVEI T1,2 ;SET INDEX TO 0,1, OR 2
MOVE T1,UNRTAB-1(T1) ;GET ADDRESS
PUSHJ P,.TSTRG## ;OUTPUT MESSAGE
PUSHJ P,.TYLPP ;AND CR-LF
PUSHJ P,.TYLPP
MOVE P2,HT.PRM ;GET INDEX INTO HASH TABLE
UNRES1: SKIPN P3,@HT.PTR ;GET POINTER TO SYMBOL
JRST UNRES2 ;NO POINTER, NO SYMBOL
ADD P3,GS.LB ;ADD IN BASE
MOVE T1,0(P3) ;GET FLAGS
TXNE T1,PT.SYM ;WE ONLY WANT SYMBOLS
TXNN T1,PS.UDF!PS.REQ ;SEE IF UNDEFINED STILL
JRST UNRES2 ;NO
MOVE T1,1(P3) ;GET SYMBOL
PUSHJ P,.TSIXN## ;SIXBIT WORD
PUSHJ P,.TTABC## ;TAB
MOVE T1,2(P3) ;VALUE
PUSHJ P,.TOCTW## ;IN OCTAL
PUSHJ P,.TYLPP ;NEW LINE
IFE DEBSW,< ;IF DEBUGGING SCAN ALL OF TABLE
SOJLE P1,UNRES3 ;DONE IF NO MORE UNDFS
;INCASE COUNT OFF>
UNRES2: SOJGE P2,UNRES1 ;LOOP IF MORE SYMBOLS TO LOOK AT
UNRES3: PUSHJ P,.TYLPP ;BLANK
PUSHJ P,TYSTAR ;OUTPUT STARS
;NOW FOR MULTIPLY DEFINED SYMBOLS
MULDF0: SKIPN MSYM ;ANY TO OUTPUT?
JRST MAPIDX ;NO
PUSHJ P,.TSTP5 ;SEE IF ENOUGH ROOM
JFCL
MOVE P1,MSYM ;GET NUMBER OF MULT-DEFS IN A PRESERVED AC
MOVE T1,P1 ;WHERE SCAN EXPECTS NUMBER
PUSHJ P,.TDECW## ;TYPE NO.
MOVE T1,P1 ;GET MULT-DEFS AGAIN
CAILE T1,2 ;LEAVE 0 OR 1 ALONE
MOVEI T1,2 ;SET INDEX TO 0,1, OR 2
MOVE T1,MDFTAB-1(T1) ;GET ADDRESS
PUSHJ P,.TSTRG## ;OUTPUT MESSAGE
PUSHJ P,.TYLPP ;AND CR-LF
PUSHJ P,.TYLPP
MOVE P2,HT.PRM ;GET INDEX INTO HASH TABLE
MULDF1: SKIPN P3,@HT.PTR ;GET POINTER TO SYMBOL
JRST MULDF2 ;NO POINTER, NO SYMBOL
ADD P3,GS.LB ;ADD IN BASE
MOVE T1,0(P3) ;GET FLAGS
TXNE T1,PT.SYM ;WE ONLY WANT SYMBOLS
TXNN T1,PS.MDF ;SEE IF MULT-DEFINED
JRST MULDF2 ;NO
MOVE T1,1(P3) ;GET SYMBOL
PUSHJ P,.TSIXN## ;SIXBIT WORD
PUSHJ P,.TTABC## ;TAB
MOVE T1,2(P3) ;VALUE
PUSHJ P,.TOCTW## ;IN OCTAL
PUSHJ P,.TYLPP ;NEW LINE
IFE DEBSW,< ;IF DEBUGGING SCAN ALL OF TABLE
SOJLE P1,MULDF3 ;DONE IF NO MORE UNDFS
;INCASE COUNT OFF>
MULDF2: SOJGE P2,MULDF1 ;LOOP IF MORE SYMBOLS TO LOOK AT
MULDF3: PUSHJ P,.TYLPP
PUSHJ P,TYSTAR
JRST MAPIDX
UNRTAB: [ASCIZ / undefined global symbol/]
[ASCIZ / undefined global symbols/]
MDFTAB: [ASCIZ / multiply-defined global symbol/]
[ASCIZ / multiply-defined global symbols/]
SUBTTL MAP INDEX
IDXHDR: ASCIZ \ Index to LINK symbol map of \
MAPIDX: MOVE T1,PRGNO
SOJLE T1,MAPEND ;IGNORE INDEX IF ONLY ONE PROGRAM
MOVE T1,PAGENO
IFE FTOVERLAY,<
SOJLE T1,MAPEND ;OR ONLY ONE PAGE
>
IFN FTOVERLAY,<
SUB T1,FSTPGN ;- START OF THIS OVERLAY
JUMPLE T1,MAPEND ;OR ONLY ONE PAGE
>
SETZM CNTLPP ;WANT NEW PAGE
MOVEI T1,IDXHDR ;CHANGE HEADER
MOVEM T1,PAGHDR
PUSHJ P,.TYLPP ;AND FORCE IT OUT
IFN FTOVERLAY,<
MOVE T1,LNKNO.
ROT T1,-1 ;USUAL WAY TO ADDRESS 1/2 WORD
MOVE T2,PAGENO ;PAGE # OF INDEX
JUMPL T1,[HRRM T2,@OVMIDX
JRST .+2]
HRLM T2,@OVMIDX
>;END OF IFN FTOVERLAY
PUSHJ P,IDXSRT ;SORT AND LIST
JRST MAPEND ;ALL DONE
;NOW TO SORT INDEX
;USES W1, W2, W3 TO HOLD AOBJN POINTERS
;R1, R2 TO HOLD COUNT AND POSITION
;T1 T2 TO HOLD CURRENT NAME AND PAGE
;T3 T4 FOR EXCHANGE
IDXLP0: MOVE W1,W2 ;GET RUNNING COPY
DMOVE T1,0(W1) ;NAME & PAGE
IDXLP1: CAMLE T1,2(W1) ;BIGGER THAN ONE FOLLOWING?
JRST IDXSWP ;YES, MUST EXCH
CAML T1,2(W1) ;HOWEVER IF JUST EQUAL
JRST [CAMLE T2,3(W1) ;TEST 2ND WORD
JRST IDXSWP ;SMALLER, SO SWAP
JRST .+1] ;REALLY IS BIGGER
DMOVE T1,2(W1) ;NO GET BIGGER
ADDI W1,1 ;ACCOUNT FOR 2ND ENTRY
IDXLP2: AOBJN W1,IDXLP1 ;AND FOR ALL NAMES IN TABLE
AOBJP W2,CPOPJ ;ALL SORTED NOW
SOJA W2,IDXLP0 ;TRY AGAIN
IDXSWP: DMOVE T3,2(W1) ;GET NAME & PAGE
DMOVEM T3,0(W1) ;AND STORE
DMOVEM T1,2(W1)
AOJA W1,IDXLP2 ;TRY NEXT
IDXSRT: MOVN W2,PRGNO ;NO. OF NAMES
AOJE W2,IDXFIN ;DON'T SORT IF SINGLE ITEM
HRLZ W2,W2
HRR W2,MDLIDX ;-N+1,,INDEX
PUSHJ P,IDXLP0 ;SORT BUFFER
; JRST IDXFIN ;PRINT RESULTS
IDXFIN: MOVE R1,PRGNO ;INITIAL NO OF NAMES
MOVE R2,MDLIDX ;INITIAL POSSITION
IDXHDI: MOVE T1,R1 ;NO. OF MODULE NAMES LEFT
CAILE T1,4*<LN.LPP-4> ;WILL IT FIT ON PAGE
MOVEI T1,4*<LN.LPP-4> ;NO, JUST USE MAX
SUBI R1,(T1) ;REDUCE COUNT NOW LEFT
MOVE T3,T1 ;GET A COPY
IDIVI T1,4 ;4 ACCROSS
MOVSI W1,-4 ;AOBJN POINTER
MOVEM T1,LCOUNT(W1) ;STORE COUNT
SOSL T2 ;IF REMAINDER
AOS LCOUNT(W1) ;COUNT ONE MORE
AOBJN W1,.-3 ;LOOP FOR ALL 4
MOVSI W1,-4+1 ;RESET POINTER
MOVE T1,R2 ;GET ADDRESS OF FIRST ITEM FOR THIS PAGE
ADDI R2,(T3) ;INCREMENT FOR NEXT TIME
ADDI R2,(T3) ;REMEMBER 2 WORDS PER ENTRY
HRLI T1,(POINT 36) ;FORM BASIC BYTE PTR
MOVEM T1,BYTEPT(W1) ;STORE IT
ADD T1,LCOUNT(W1) ;GET TO NEXT
ADD T1,LCOUNT(W1) ;2 WORDS PER ITEM
MOVEM T1,BYTEPT+1(W1)
AOBJN W1,.-3 ;FOR ALL
IDXHD0: MOVSI W1,-4 ;BASIC LOOP
MOVEI T1,[ASCIZ \ Name Page\]
SKIPE LCOUNT(W1) ;ANYTHING TO OUTPUT FOR THIS COLUMN
PUSHJ P,.TSTRG##
AOBJN W1,.-3
PUSHJ P,.TYLPP ;END LINE
PUSHJ P,.TYLPP ;AND BLANK LINE
MOVSI W1,-4 ;NOW FOR OUTPUT
IDXHD1: SOSGE LCOUNT(W1) ;ANYTHING TO DO
JRST IDXHD2 ;NOT FOR THIS COLUMN
PUSHJ P,.TTABC## ;SPACE ACROSS
ILDB T1,BYTEPT(W1) ;GET NAME
ILDB T2,BYTEPT(W1) ;AND PAGE
LSH T2,1 ;NOW PUT BACK
LSHC T1,2 ;AS SIXBIT AND PAGE NO
PUSH P,T2 ;SAVE PAGE
PUSHJ P,.TSIXN##
PUSHJ P,.TTABC##
POP P,T1 ;PAGE
MOVS T1,T1 ;RIGHT JUSTIFIED
MOVEI T2," " ;FILLER CHAR
PUSHJ P,.TDEC2## ;DECIMAL
IDXHD2: AOBJN W1,IDXHD1 ;LOOP ACCROSS PAGE
PUSHJ P,.TYLPP ;END LINE
MOVSI W1,-4 ;REINIT COUNTER
SKIPLE LCOUNT(W1) ;DONE IF NOTHING LEFT ON THIS PAGE
JRST IDXHD1 ;NO, OUTPUT NEXT LINE
JUMPG R1,IDXHDI ;MORE TO COME
POPJ P, ;ALL DONE
MAPEND: SKIPN T2,PRGNO ;[1100] NOW DELETE INDEX BLOCK
JRST MAPND0 ;[1100] BUT NOT IF ZERO
LSH T2,1 ;[1100] TWO ENTRIES PER MODULE
HRRZ T1,MDLIDX ;[1100] GET ADDRESS OF BLOCK
JUMPE T1,MAPND0 ;[1100] UNLESS NO SYMBOLS
PUSHJ P,DY.RET## ;[1100] AND FREE IT
MAPND0:
IFN FTOVERLAY,<
SKIPGE LNKMAX ;ANY OVERLAYS?
JRST MAPND1 ;NO
AOS T1,LNKNO.
CAMG T1,LNKMAX ;ALL DONE?
JRST OVMAP0 ;NO
SETZM CNTLPP ;WANT NEW PAGE
MOVEI T1,OVXHDR ;CHANGE HEADER
MOVEM T1,PAGHDR
SETOB R2,LNKNO. ;START WITH LINK# 0
PUSHJ P,.TYLPP ;AND FORCE IT OUT
MOVE R1,LNKMAX ;HIGHEST LINK NO.
ADDI R1,1 ;INITIAL NO. OF LINKS
OVXHDI: MOVE T1,R1 ;NO. OF MODULE NAMES LEFT
CAILE T1,4*<LN.LPP-4> ;WILL IT FIT ON PAGE
MOVEI T1,4*<LN.LPP-4> ;NO, JUST USE MAX
SUBI R1,(T1) ;REDUCE COUNT NOW LEFT
MOVE T3,T1 ;GET A COPY
IDIVI T1,4 ;4 ACROSS
MOVSI W1,-4 ;AOBJN POINTER
MOVEM T1,LCOUNT(W1) ;STORE COUNT
SOSL T2 ;IF REMAINDER
AOS LCOUNT(W1) ;COUNT ONE MORE
AOBJN W1,.-3 ;LOOP FOR ALL 4
MOVSI W1,-4+1 ;RESET POINTER
MOVE T1,R2 ;GET ADDRESS OF FIRST ITEM FOR THIS PAGE
ADDI R2,(T3) ;INCREMENT FOR NEXT TIME
MOVEM T1,BYTEPT(W1) ;STORE IT
ADD T1,LCOUNT(W1) ;GET TO NEXT
MOVEM T1,BYTEPT+1(W1)
AOBJN W1,.-2 ;FOR ALL
OVXHD0: MOVSI W1,-4 ;BASIC LOOP
MOVEI T1,[ASCIZ \ Overlay Page\]
SKIPE LCOUNT(W1) ;ANYTHING TO OUTPUT FOR THIS COLUMN
PUSHJ P,.TSTRG##
AOBJN W1,.-3
PUSHJ P,.TYLPP ;END LINE
PUSHJ P,.TYLPP ;AND BLANK LINE
MOVSI W1,-4 ;NOW FOR OUTPUT
OVXHD1: SOSGE LCOUNT(W1) ;ANYTHING TO DO
JRST OVXHD2 ;NOT FOR THIS COLUMN
PUSHJ P,.TTABC## ;SPACE ACROSS
;PRINT LINK NUMBER, WITH LEADING "#" TO DISTINGUISH FROM NUMERIC NAMES
MOVEI T1,"#" ;SAVE CONFUSION, MARK LINKS WITH #
PUSHJ P,.TCHAR##
AOS T1,BYTEPT(W1) ;GET LINK# OF NEXT LINK
PUSHJ P,.TDECW##
PUSHJ P,.TTABC##
MOVE T1,BYTEPT(W1) ;LINK#
ROT T1,-1 ;1/2 WORD PICKUP
JUMPL T1,[HRRZ T1,@OVMIDX ;GET PAGE #
JRST .+2]
HLRZ T1,@OVMIDX
MOVEI T2," " ;FILLER CHAR
PUSHJ P,.TDEC2## ;DECIMAL
OVXHD2: AOBJN W1,OVXHD1 ;LOOP ACCROSS PAGE
PUSHJ P,.TYLPP ;END LINE
MOVSI W1,-4 ;REINIT COUNTER
SKIPLE LCOUNT(W1) ;DONE IF NOTHING LEFT ON THIS PAGE
JRST OVXHD1 ;NO, OUTPUT NEXT LINE
JUMPG R1,OVXHDI ;MORE TO COME
HRRZ T2,LNMPTR ;GET NUMBER OF NAMES
JUMPE T2,MAPND1 ;NONE
LSH T2,1 ;2 WORDS PER NAME
PUSHJ P,LOGBCK ;PUT INFO MESSAGES ON TTY
PUSHJ P,DY.GET## ;GET SPACE TO HOLD LIST SO WE CAN SORT
MOVEM T1,MDLIDX
HRLI T1,(POINT 36)
MOVEM T1,MDLPTR
PUSHJ P,LOGBCK ;PUT INDEX IN MAP FILE
PUSHJ P,.TYLPP ;BLANK LINE
MOVEI T1,OVNHDR ;NEW HEADER LINE
MOVEM T1,PAGHDR ;INCASE NEEDED
PUSHJ P,.TSTRG## ;OUTPUT IT ANYWAY
MOVE T1,MAPNAM
PUSHJ P,.TSIXN##
SKIPE MAPVER ;ANY VERSION
PUSHJ P,[MOVEI T1,[ASCIZ \ version \]
PUSHJ P,.TSTRG##
MOVE T1,MAPVER
PJRST .TVERW##]
PUSHJ P,.TYLPP ;END LINE
PUSHJ P,.TYLPP ;BLANK LINE SEPARATOR
;NOW SORT INDEX OF LINK NAMES, USING IDXSRT.
HLRZ T2,LNMPTR ;GET INITIAL PTR
OVXHD4: MOVE T3,0(T2) ;GET NAME
MOVE T2,1(T2) ;NUMBER ,, PTR
HLRZ T1,T2 ;NUMBER
ROT T1,-1 ;1/2 WORD PICKUP
JUMPL T1,[HRLZ T4,@OVMIDX
JRST .+2]
HLLZ T4,@OVMIDX ;PAGE CORRESPONDING TO LINK#
LSHC T3,-2 ;SO SIGNED TEST CAN WORK
LSH T4,-1 ;SAME FOR 2ND WORD OF PAIR
TXNN T3,3B3 ;IF NOT ALPHANUMERIC
TXO T3,1B1 ;MAKE .,%,$ LARGER
IDPB T3,MDLPTR ;STORE MODIFIED NAME
IDPB T4,MDLPTR ;AND PAGE NO
TRNE T2,-1 ;DONE?
JRST OVXHD4 ;NOT YET
PUSH P,PRGNO ;EASIEST WAY TO FAKE OUT IDXSRT
HRRZ T1,LNMPTR
MOVEM T1,PRGNO
PUSHJ P,IDXSRT ;SORT AND LIST
POP P,PRGNO
HRRZ T1,MDLIDX ;[1100] FREE INDEX BLOCK FOR LINK NAMES
HRRZ T2,LNMPTR ;[1100] LENGTH OF BLOCK
LSH T2,1 ;[1100] WITH TWO WORDS PER LINK NAME
PUSHJ P,DY.RET## ;[1100] DO THE WORK
JRST MAPND1
OVXHDR: ASCIZ \ Index to overlay numbers of \
OVNHDR: ASCIZ \ Index to overlay names of \
>;END OF IFN FTOVERLAY
MAPND1: PUSHJ P,.TYLPP ;BLANK LINE
MOVEI T1,END1 ;AND FINAL MESSAGE
PUSHJ P,.TSTRG##
MOVE T1,MAPNAM
PUSHJ P,.TSIXN##
MOVEI T1,"]"
PUSHJ P,.TCHAR##
PUSHJ P,.TCRLF##
MAPRET: PUSHJ P,LOGBCK ;RESTORE LOG DEVICE
E$$EMS::.ERR. (MS,0,V%L,L%I,S%I,EMS,<End of MAP segment>) ;[1174]
MOVE T1,LS.LB ;NOW TO MAKE SURE LS.PT IS CORRECT
ADD T1,LSYM ;BASE + LENGTH
SUB T1,LW.LS ; - OFFSET
MOVEM T1,LS.PT ;POINTS TO NEXT FREE SYMBOL SLOT
SUB T1,LS.AB ;GET NO. OF FREE WORDS
MOVMM T1,LS.FR ; IN LAST BLOCK
SETZM LS.PP ;OK TO DEFAULT PAGE SYMBOLS AGAIN
MOVE T1,MAPSW ;SEE WHAT SORT OF MAP IT WAS
CAMN T1,[$MAPEND] ;@ END?
JRST MAPXIT ;YES, FINISH OFF
SKIPN UW.LS ;PAGING SYMBOLS?
JRST MAPRT1 ;NO
MOVE T1,LS.AB ;TOP
SUB T1,LS.LB ;LENGTH
SUBI T1,.IPM ;MINUS LAST BLOCK
ADDM T1,LW.LS ;ONLY KEEP LAST BLOCK IN CORE
MOVE T1,LS.AB
SUBI T1,.IPS ;LAST ADDRESS TO KEEP
PUSHJ P,GBCK.L## ;GIVE IT AWAY
SETOM UW.LS ;INDICATE LS AREA AT END AGAIN
MAPRT1: MOVE T1,MAPSW ;RESTORE T1 FROM GBCK.L
CAMN T1,[$MAPNOW] ;@ NOW
JRST MAPRT2 ;YES, CLOSE MAP AND DELETE BUFFERS
CAME T1,[$MAPERROR] ;ON ERROR
POPJ P,
PUSHJ P,DVRLS.## ;CLOSE OUT MAP FILE
RELEASE RC, ;AND LOG FILE
EXIT ;GIVE UP
MAPRT2: SETZM MAPSW ;DONE WITH MAP SPEC
PUSHJ P,DVRLS.## ;CLOSE FILE
MOVEI T1,MC ;NOW DELETE BUFFERS
MOVEM T1,IO.CHN
PUSHJ P,DVZAP.## ;AND DATA BLOCK
JRST LNKLOD ;GET NEXT F/S
;HERE IF SYMBOL AREA EMPTY
NOMAP: MOVEI T1,[ASCIZ \ No symbols to output
\]
PUSHJ P,.TSTRG##
JRST MAPRET ;AND GIVE UP
IFE FTOVERLAY,<
MAPXIT=LNKXIT
>
IFN FTOVERLAY,<
MAPXIT: SKIPL LNKMAX ;ANY OVERLAYS?
POPJ P, ;YES, RETURN TO LNKOV2
JRST LNKXIT ;NO
>
SUBTTL DATA STORAGE
.ZZ==.TEMP
U (OLDDEV) ;LOG DEVICE WHILE MAP IN USE
U (CNTLPP) ;LINE PER PAGE
U (PAGENO) ;PAGE NUMBER (STARTS AT 1)
U (MAPNAM) ;SIXBIT NAME OF MAP FILE
U (SYMPTR) ;POINTER TO CURRENT SYMBOL (REL TO LS.LB)
U (ASTPTR) ;POINTER TO CURRENT ASSOCIATED TRIPLET (ABS)
U (SAVAST) ;SAVE ASTPTR WHILE DOING MSF
U (SYFLAG) ;TEMP W1
U (VALUE) ;TEMP W3
U (ZERLEN) ;-1 IF ZERO LENGTH PROG
U (MAPVER) ;VERSION IN LOC 137 (REL TO LC.LB)
U (CURPRG) ;CURRENT OUTPUT PROG NAME
U (PAGHDR) ;POINTER TO PAGE HEADER
U (MDLIDX) ;INDEX TO PROG NAMES
U (MDLPTR) ;BYTE POINTER TO NAMES
U (MDLCNT) ;RUNNING COUNT OF PROGRAM NAMES
U (BYTEPT,4) ;BYTE POINTERS FOR OUTPUT
U (LCOUNT,4) ;LINE COUNTS FOR OUTPUT
U (OVMIDX) ;INDEX TO LINK NUMBERS
U (ODDNESS) ;COLUMN COUNTER (ON/OFF)
U (NXTTTL) ;REL POSITION OF NEXT TITLE
U (SRTPTR,2) ;START AND SIZE OF SORT BUFFER
U (FSTPGN) ;FIRST PAGE# OF THIS LINK
SUBTTL THE END
MAPLIT: END LNKMAP