Trailing-Edge
-
PDP-10 Archives
-
BB-H138A-BM
-
3a-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-10
SUBTTL D.M.NIXON/DMN/SRM/JBC/RKH/JNG 27-FEG-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 LNKMAP
SEARCH LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
EXTERN LNKFIO,LNKXIT,LNKLOD,LNKLOG,LNKCOR,.TYOCH
CUSTVR==0 ;CUSTOMER VERSION
DECVER==4 ;DEC VERSION
DECMVR==0 ;DEC MINOR VERSION
DECEVR==765 ;DEC EDIT VERSION
VERSION
SALL
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)
SUBTTL HEADER LINES
LNKMAP: JFCL .+1 ;INCASE CCL
.ERR. (MS,0,V%L,L%I,S%I,MPS,<MAP segment>)
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
SKIPN T2,PRGNO ;NO. OF PROGRAMS
JRST OVMAP1 ;NONE
LSH T2,1 ;2 WORDS EACH
HRRZ T1,MDLIDX ;GIVE BACK TITLE BUFFER
PUSHJ P,DY.RET##
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
IFN TOPS20,<
JUMPE T1,.+3 ;LEAVE 0 ALONE
IORI T1,.PGSIZ ;ALWAYS PAGES
ADDI T1,1
>
IFE TOPS20,<
MOVE T2,.PGSIZ ;P OR K BOUND
JUMPE T1,.+3 ;LEAVE 0 ALONE
IOR T1,T2
ADDI T1,1
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,NO.COR##
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 ER.IOV##] ;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 ER.IOV##] ;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
IFN TOPS20,<
JUMPE T1,.+3 ;LEAVE 0 ALONE
IORI T1,.PGSIZ ;ALWAYS PAGES
ADDI T1,1
>
IFE TOPS20,<
MOVE T2,.PGSIZ ;P OR K BOUND
JUMPE T1,.+3 ;LEAVE 0 ALONE
IOR T1,T2
ADDI T1,1
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,ER.IOV## ;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
PUSH P,[LC] ;CHAN #
.ERR. (ST,,V%L,L%F,S%F,ILC)
SEGDN: PUSHJ P,.TTABC##
MOVE T1,HL.S1 ;GET LOW SEG BREAK
IOR. T1,.PGSIZ ;ROUND UP TO NEXT P OR K
SUB T1,HL.S1 ;FIND WHATS LEFT
ADDI T1,1
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
IOR. T1,.PGSIZ
SUB T1,HL.S2
ADDI T1,1
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 TTLTTF ;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,W3 ;RESTORE CPU BITS
TTLCP1: TLZ W3,-1 ;ZAP PROCESSOR TYPE BITS
JUMPE W3,TTLCRE ;IF NOT SPECIFIED, GO PRINT CRE STUFF
CAILE W3,CP.LEN ;IN RANGE?
SETZ W3, ;NO, MAKE UNKNOWN
IFE TOPS20,<
MOVE T1,CPUTAB(W3) ;GET ASCII FOR CPU TYPE
PUSHJ P,.TSTRG## ;OUT IT GOES
> ;END IFE TOPS20
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##
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
;FALL INTO PSECT CODE
;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 /]
PUSHJ P,.TSTRG##
MOVE T1,1(R) ;NAME
PUSHJ P,.TSIXN##
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), /]
PUSHJ P,.TSTRG##
POP P,T1 ;LENGTH
PUSHJ P,.TDECW##
MOVEI T1,[ASCIZ /, (decimal)/]
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
TTLTTF: .ERR. (MS,,V%L,L%W,S%W,TTF,<Too many titles found>)
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,NO.COR## ;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 I