Google
 

Trailing-Edge - PDP-10 Archives - BB-H138A-BM - 3a-sources/filcom.mac
There are 45 other files named filcom.mac in the archive. Click here to see a list.
;<1B-UTILITIES>FILCOM.MAC.5, 30-Jul-76 15:55:51, EDIT BY HURLEY
;<1B-UTILITIES>FILCOM.MAC.4,  9-Jul-76 09:42:31, EDIT BY HURLEY
;INCREASED VERSION NUMBER FOR RELEASE 1B
;<1B-UTILITIES>FILCOM.MAC.3, 23-Jun-76 15:47:21, EDIT BY HURLEY
;<1B-UTILITIES>FILCOM.MAC.2, 23-Jun-76 15:32:31, EDIT BY HURLEY
TITLE	FILCOM   %20A	18-JULY-73
SUBTTL FILE COMPARE - BOWERING/DMN/TWE/DMN
;*****(C)COPYRIGHT 1970,1971,1972,1973,1974,1975,1976 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.,USA*****

	VFILCM==20		;VERSION NUMBER
	VUPDATE==2		;DEC UPDATE
	VEDIT==40		;EDIT LEVEL
	VCUSTOM==0

INTERNAL .JBVER
LOC <.JBVER==137>
<VCUSTOM>B2+<VFILCM>B11+<VUPDATE>B17+VEDIT
RELOC	0

EXTERNAL	.JBFF,	.JBREL,	.HELPR

TWOSEG
RELOC 400000

ACDEV==1	;COMMAND SCANNER ACCUMULATORS
ACFILE==2
ACEXT==3
ACDEL==4
ACPNTR==5
ACPPN==6	;COMMAND SCANNER AC FOR PROJ,PROG #

CTL==0		;I/O CHANNEL ASSIGNMENTS
IN1==1
IN2==2
AL==1		;ASCII LINE MODE
BIN==14		;BINARY MODE

W1=1
W2=2
W3=3
FIL=4		;FILE # (0 IS FILE 1; 1 IS FILE 2)
F1=5		;LINE POINTER FILE 1 (CONTAINS INTEGER)
F2=F1+1		;DITTO FILE 2
FR=7		;FLAG REGISTER (LH) AND FILE #(0 OR 1)(RH)
C=10		;CONTAINS 1 CHAR FOR PROCESSING
T=11		;TEMPORARY AC
TT=12		;TEMP AC
LOWER=13	;LOWER BOUND OF COMPARE
UPPER=14	;UPPER BOUND OF COMPARE
CNT=15		;WORD OR LOCATION COUNT (BINARY)
PP=17		;PUSH DOWN POINTER
S1==F1
S2==F2
LPDL==20	;LENGTH OF PUSH DOWN LIST

TAB==11
LF==12
FF==14
CR==15
VT==13		;VERTICAL TAB

NOFORM==1		;DON'T OUTPUT FORM FEED
PAGSW==2
ENDSW==4		;END SWITCH (SUPPRESS FORM-FEED  IF FILES IDENTICAL)
EOF1SW==10		;EOF SEEN ON FILE 1
EOF2SW==20		;EOF SEEN ON FILE 2
IOTTY==40		;OUTPUT TO TTY
SSWBIT==100		;/S SWITCH - IGNORE SPACING
CSWBIT==200		;/C SWITCH - IGNORE COMMENTS
ALLSW==400		;/B SWITCH (ALLOWS COMPARING BLANK LINES)
ASWBIT==1000		;/A SWITCH - LINE BY LINE COMPARE (ASCII)
WSWBIT==2000		;/W SWITCH - WORD BY WORD COMPARE (BINARY)
XSWBIT==4000		;/X SWITCH - EXPAND SAV FILES (BINARY)
CTYPF==10000		;1 IF ANY CHARS TYPED FOR A COMMAND
WDFBIT==20000		;DEFAULT /W (EXTENSION OF REL,XPN,CHN,DMP ETC)
XDFBIT==40000		;DEFAULT /X (EXTENSION OF SAV,LOW,SVE)
HSGBIT==100000		;DEFAULT HIGH SEGMENT FILE (EXT OF SHR OR HGH)
USWBIT==200000		;LIST ENTIRE 2ND FILE, SHOWING CHANGES

ASCSW==ASWBIT!SSWBIT!CSWBIT!ALLSW!USWBIT	;ASCII SWITCHES
BINSW==WSWBIT!XSWBIT!WDFBIT!XDFBIT!HSGBIT	;BINARY SWITCHES

MATCH==3		;# LINES TO BE MATCHED
WPL==^D100/5+1		;MEMORY WORDS/LINE
LPP==^D56		;LINES/PAGE
SUBTTL	REVISION HISTORY

;FILCOM V20B(40) - CHANGED COPYRIGHT STATEMENT

;START OF VERSION 20A
;17	ADD DATE75 HACK
SUBTTL	FILE COMPARE

COMP:	CLOSE	CTL,
	RELEAS	CTL,
	RELEAS	IN1,
	RELEAS	IN2,
COMPGO:	CALLI
	MOVE	PP,[IOWD LPDL,PPSET]	;SET UP PUSH DOWN LIST
	MOVEI	0,ENDP+500	;GUARANTEE ROOM FOR BUFFERS (2 DSK +TTY IN AND OUT)
	CAMG	0,.JBREL	;BUT NEVER REDUCE SIZE
	JRST	.+3		;INCASE LOADED WITH DDT
	CORE	0,
	 JRST	ERRCOR		;NOT AVAILABLE
	SETZB	LOWER,PPSET	;THIS IS THE ZERO WHICH WILL
			;BE "BLT"ED TO CLEAR CORE
	MOVE	[XWD PPSET,PPSET+1]	;ZERO STORAGE AREA
	BLT	ENDP-1		;ZEROED
	HRLOI	UPPER,377777	;LARGE NUMBER BY DEFAULT

	MOVEI	0,MATCH
	MOVEM	0,NUMLIN	;MATCH IS NORMALLY 3 LINES

	AOS	PAGNUM+0	;ZEROED BY BLT ABOVE-1ST PAGE IS 1
	AOS	PAGNUM+1	;DITTO FOR SECOND FILE


	MOVSI	FR,PAGSW+NOFORM	;INIT FR FOR NEW PAGE HEADING
	PUSHJ	PP,INITTY	;INITIALIZE TTY
	PUSHJ	PP,CRLF		;OUTPUT CARRIAGE RETURN - LINE FEED
	MOVEI	C,"*"		;TELL USER WE ARE READY FOR COMMAND
	PUSHJ	PP,TYO		;OUTPUT THE *
	PUSHJ	PP,DMPOUT	;OUT GOES THE *

	PUSHJ	PP,NAME1	;ANALYIZE OUTPUT DEVICE AND NAME
	CAIN	C,"_"		;ERROR IF NO ARROW
	JRST	CTLSE1		;ITS THERE--PROCEED
	TLNN	FR,CTYPF	;ANY COMMAND TYPED?
	JRST	COMPGO		;NO
CTLSER:	JSP	T,ERROUT
	ASCIZ	/?Command error/

CTLSE1:	JUMPN	ACDEV,CTLSE2	;NO DEFAULT IF DEVICE NOT 0
	SKIPN	ACFILE
	MOVSI	ACDEV,'TTY'	;IF FILENAME 0, ASSUME TTY
	SKIPE	ACFILE
	MOVSI	ACDEV,'DSK'	;IF FILENAME NOT 0, ASSUME DSK
CTLSE2:	MOVEM	ACDEV,OUTDEV	;SAVE OUTPUT DEVICE IN DIRECTORY BLOCK
	MOVEM	ACFILE,OUTDIR	;PUT SIXBIT FILE NAME IN
	HLLZM	ACEXT,OUTDIR+1	;AND SAVE EXTENSION
	MOVEM	ACPPN,OUTDIR+3	;  AND PROJ, PROG NUMBER
;PROCESS INPUT PART OF COMMAND STRING

	PUSHJ	PP,NAME1	;GET INPUT COMMAND STRING
	TLNN	FR,CTYPF	;ANY FILE DESCRIPTOR TYPED?
	JRST	CTLSER		;NO, ERROR
	SETZ	T,		;GET A ZERO
	EXCH	T,EXTFL2	;INCASE NO 2ND FILE
	MOVEM	T,EXTFL1	;FLAGS IN RIGHT PLACE
	CAIN	C,","		;COMMA TO TERMINATE 1ST INPUT FILE?
	JRST	CTLSE3		;YES, NORMAL CASE
	TLNE	FR,ASCSW	;ASCII SWITCH?
	JRST	CTLSER		;YES, ERROR
	TLNN	FR,BINSW	;BINARY SWITCH?
	TLNE	T,BINSW		;OR EXT?
	TLOA	FR,EOF2SW	;YES, SET EOF FOR 2'ND INPUT FILE
	JRST	CTLSER		;ASCII, ERROR
CTLSE3:	SKIPN	ACDEV		;ASSUME DSK IF NO SPECIFIED DEVICE
	MOVSI	ACDEV,'DSK'
	MOVEM	ACDEV,INDEV1
	MOVEM	ACFILE,INDIR1	;FIRST INPUT FILE
	MOVEM	ACEXT,INDIR1+1	;AND SAVE EXTENSION
	MOVEM	ACPPN,INDIR1+3	;  AND PROJ,PROG NUMBER
	MOVEM	ACPPN,INDPPN	;SAVE P,P AGAIN

	MOVEI	0,AL		;SET UP INPUT DATA MODE
				;1 (WHICH IS ACDEV) ALREADY IS SET UP
	MOVEI	2,INBUF1	;SET UP INPUT BUFFER HEADER
	OPEN	IN1,0		;INIT DEVICE
	 JRST	ERRI		;DEVICE CAN'T BE INITIALIZED

	INBUF	IN1,2		;DO LOOKUP ON FIRST FILE NAME
	LOOKUP	IN1,INDIR1
	JRST	ERRIA		;ERROR RETURN
	MOVEI	T,HBUF1
	PUSHJ	PP,HEADER	;CREATE HEADER LINE- FILE #1
	MOVE	T,EXTFL1	;RESET T INCASE NO 2ND FILE
	TLNE	FR,EOF2SW	;PREMATURE EOF SET
	JRST	NOINP2		;YES, NO SECOND FILE

	PUSHJ	PP,NAME1
	TLNN	FR,CTYPF	;ANY FILE DESCRIPTOR TYPED?
	JRST	CTLSER		;NO, ERROR
	SKIPN	ACDEV
	MOVSI	ACDEV,'DSK'	;"DSK" IS DEFAULT
	MOVEM	ACDEV,INDEV1
	SKIPE	ACFILE
	MOVEM	ACFILE,INDIR1	;INSERT FILE NAME AND EXTENSION
	CAIN	ACDEL,"."	;PERIOD MEANS EXPLICIT EXTENSION
	MOVEM	ACEXT,INDIR1+1
	MOVEM	ACPPN,INDIR1+3	;SAVE PROG,PROG NUMBER IN DIRECT BLOCK
	MOVEM	ACPPN,INDPPN	;SAVE P,P AGAIN

	MOVEI	0,AL		;INIT DEVICE IN ASCII LINE MODE
	MOVEI	2,INBUF2	;BUFFER HEADER FOR 2ND INPUT FILE
	OPEN	IN2,0		;INIT 2ND DEVICE
	 JRST	ERRI		;INIT FAILED

	INBUF	IN2,2		;LOOKUP ON SECOND FILE NAME
	LOOKUP	IN2,INDIR1
	JRST	ERRIA
	MOVEI	T,HBUF2
	PUSHJ	PP,HEADER	;CREATE HEADER LINE- FILE #2

	TLNE	FR,ASCSW	;ASCII SWITCHES SEEN
	JRST	INICTL		;YES, LEAVE WELL ALONE
	TLNE	FR,BINSW	;BINARY SWITCHES SEEN?
	JRST	SETBIN		;YES, CHANGE MODE TO BINARY
	MOVE	T,EXTFL1	;GET DEFAULT EXT MODE
	IOR	T,EXTFL2	;FOR BOTH FILES
	TLNN	T,BINSW		;BINARY WIN OVER ASCII
	JRST	INICTL		;ASCII
SETBIN:	SETSTS	2,BIN		;CHANGE TO BINARY MODE
NOINP2:	MOVEI	0,(POINT 36,,35)
	IOR	FR,T		;SET MODE BINARY
	SETSTS	1,BIN
	HRLM	0,INBUF1+1	;CHANGE FROM ASCII
	HRLM	0,INBUF2+1
INICTL:	MOVEI	0,0		;INIT OUTPUT DEVICE
	MOVE	1,OUTDEV
	MOVSI	2,CTOBUF
	OPEN	CTL,0
	 JRST	ERRA		;INIT FOR OUTPUT FAILED

	MOVE	TT,OUTDEV	;CAN OUTPUT DEVICE DO OUTPUT
	DEVCHR	TT,
	TLNN	TT,1
	JRST	ERRO		;NO
	TLNE	TT,10		;IS OUTPUT DEVICE  TTY?
	TLO	FR,IOTTY	;YES, DO 1 OUTPUT PER LINE

	SKIPN	ACFILE,INDIR1	;IF LAST INPUT FILE NAME WAS NULL,
	MOVE	ACFILE,[SIXBIT /FILCOM/]	; MAKE OUTPUT "FILCOM", BUT
	SKIPN	OUTDIR		;  ONLY IF NO OUTPUT FILENAME SPECIFIED
	MOVEM	ACFILE,OUTDIR
	MOVSI	ACEXT,'SCM'	;ASSUME ASCII
	TLNE	FR,BINSW	;BINARY?
	MOVSI	ACEXT,'BCM'	;BCM IF BINARY
	SKIPN	OUTDIR+1	;BUT NOT IF ONE ALREADY
	MOVEM	ACEXT,OUTDIR+1	;USE DEFAULT
	ENTER	CTL,OUTDIR	;AND TRY TO ENTER OUTPUT FILE NAME
	JRST	ERRO
	OUTPUT	CTL,
;FIND OUT HOW MUCH CORE IS AVAILABLE AND SET POINTERS AND LIMITS

	HRRZ	W1,.JBFF
	ADDI	W1,20		;GUARANTEE AN INITIAL 20 WORDS
	CORE	W1,		;  FOR TEXT BUFFERS
	  JRST	NORERR		;DIDN'T GET IT, ERROR

	AOS	W1,.JBFF
	HRRZM	W1,LBUFP1	;SET 1ST ADDRESS FILE 0
	SETZM	1(W1)		;FORCE NULLS INTO BUFFER
	HRRZM	W1,LBUFP2	;DITTO FILE 2
	MOVE	W1,.JBREL
	SUB	W1,.JBFF	;COMPUTE SPACE AVAILABLE
	HRRZS	W1
	LSH	W1,-1		;AVAILABLE SPACE/2
	ADDB	W1,LBUFP2	;INPUT POINTER FILE 2 STARTS HALF WAY THROUGH BUFFER
	SETZM	1(W1)		;FORCE NULLS INTO BUFFER

	HRLOI	0,377777
	MOVEM	0,OLDNUM+0	;ANY LINE # IS SMALLER THAN
	MOVEM	0,OLDNUM+1	;  THIS ONE

	SETOB	F1,TOP1		;INITIALIZE TOP OF EACH FILE
	SETOB	F2,TOP2		;THE TOP IS THE HIGHEST LINE THAT WE HAVE EXAMINED
	TLNE	FR,BINSW	;BINARY COMPARE?
	JRST	BINCOM		;USE WORD BY WORD IF BINARY
	SOS	NUMLIN		;INIT SRCCOM MATCH COND TO "MATCH-1"
	JRST	MAINST		;START SRCCOM WITH 1ST LINES
;THE FOLLOWING CODE IS THE GUTS OF THE PROGRAM.
;WHEN THE LOOP AROUND MAIN DETECTS THAT TWO LINES ARE NOT A MATCH
;CONTROL GOES OFF TO DETERMINE THE EXTENT OF THESE DIFFERENCES.
;THE TOTAL DIFFERENCES ARE DETERMINED AS FOLLOWS.  FIRST GET TWO 
;MORE LINES. DOES THE ORGINAL LINE IN FILE 1 WHICH DID NOT MATCH
;MATCH THE NEW LINE FROM FILE TWO. IF SO THEN THE ORGINAL LINE
;IN FILE 2 WAS AN INSERTION. (OR A DELETION).  IF NO MATCH THIS 
;WAY TRY IT THE OTHER WAY. IF STILL NO MATCH GET TWO MORE LINES
;TAKE THE NEW LINE FROM FILE 1 AND TRY TO MATCH IT AGAINST ALL THE
;LINES WE HAVE BEEN EXAMINING IN FILE TWO; THEN DO IT THE OTHER
;WAY AROUND. EOF'S ARE DETECTED BY "GETTWO"  WITH NO RETURN SKIP

MAIN:	TRZ	FR,-1		;THIS FOR FILE ONE
	PUSHJ	PP,MOVEUP	;MOVE UP THE BOTTOM, BECAUSE WE ARE FINISHED
				;WITH TWO LINES
	HRRI	FR,1		;NOW FOR FILE TWO
	PUSHJ	PP,MOVEUP	;UP GOES THE BOTTOM POINTER
MAINST:	SETOB	F1,F2		;INITIALIZE LINE POINTERS
	PUSHJ	PP,GETTWO	;GET TWO LINES
	  JRST	MAIN15		;ONE FILE SHORT
	PUSHJ	PP,COMPL	;COMPARE THESE TWO LINES
	JRST	MAIN		;THEY MATCH--LOOK AT NEXT TWO

;WHEN WE GET HERE WE HAVE DETECTD A DIFFERENCE
;NOW THE PROGRAM WILL LOOK AHEAD TO TRY AND FIND THE NEXT TWO
;MATCHING LINES

	AOS	DIFFLG		;SET "DIFFERENCE IN PROGRESS" FLAG
	AOS	ERRCNT		;SET FLAG SHOWING DIFFERENCES FOUND

MAIN10:	PUSHJ	PP,GETTWO	;GET THE NEXT TWO LINES
	  JRST	MAIN15		;ONE FILE SHORT
	SETZ	F1,		;RESET POINTER FOR FIRST FILE TO
				;THE LINE IN WHICH THE DIFFERENCE WAS FOUND


MAIN12:	PUSHJ	PP,COMPL	;NOW SEE IF WE CAN MATCH THAT LINE
	JSP	W1,MULTI	;FOUND 1 LINE MATCH- LOOK FOR MULTIPLE
	CAME	F1,F2		;HAVE WE LOOKED FROM THE MISMATCHED LINE
				;TO THE CURRENT LINE?
	AOJA	F1,MAIN12	;NO--UP LINE POINTER AND TRY AGAIN
	SETZ	F2,		;HAVEN'T FOUND A MATCH THIS TIME
				;NOW TRY IT THE OTHER WAY

MAIN14:	CAML	F2,F1		;LOOKED FAR ENOUGH? (THIS VERSION HAS
				;THE INEFFICIENCY MENTIONED IN THE LIBRARY
				;WRITE UP REMOVED- TWE)
	JRST	MAIN10		;YES
	PUSHJ	PP,COMPL
	JSP	W1,MULTI	;LOOK FOR MULTI LINE MATCH
	AOJA	F2,MAIN14	;INDEX AND LOOK SOME MORE
;THE MAIN15 CODE HANDLES THE CASE OF EITHER (OR BOTH) FILES
;HAVING NO LINES TO COMPARE. IF BOTH FILES HAVE NO LINES, "FINISH"
;PRINTS OUT ALL LINES IN BOTH FILES (IF ANY) AS DIFFERENCES.
;IF EITHER FILE HAS A NEW LINE, THE SHORTER FILE IS
;SEARCHED FOR A MATCH FOR THAT LINE. THIS CONTINUES (READING A NEW LINE
;FROM THE LONGER FILE) UNTIL NEITHER FILE HAS ANY LINES OR UNTIL A
;MATCH IS FOUND.

MAIN15:	SKIPGE	W1,GETFIL	;DOES EITHER FILE HAVE A LINE?
	JRST	FINISH		;NO
	AOS	DIFFLG		;SET "DIFFERENCE IN PROGRESS" FLAG
	AOS	ERRCNT		;SET "DIFFERENCES FOUND" FLAG
	HRRZM	W1,FIL		;SAVE FILE # THAT HAS LINES
	HRR	FR,W1		;SETUP FR FOR MAIN18
	JUMPL	F1,MAIN18	;TRA IF FILE 1 HAS NO LINES
	JUMPL	F2,MAIN18	;DITTO FILE 2
	TRC	FIL,1		;CHANGE 1 TO 0 (OR VICE VERSA)
	SETOM	F1(FIL)		;LOOK THRU SHORT FILE FOR MATCH
MAIN17:	MOVE	W1,F1(FIL)
	CAML	W1,TOP1(FIL)	;SEARCHED THRU SHORT FILE?
	JRST	MAIN10		;YES, AND NO MATCH
	AOS	F1(FIL)		;INDEX LINE
	PUSHJ	PP,COMPL	;LOOK FOR A MATCHING LINE
	JSP	W1,MULTI	;FOUND A MATCH, NOW LOOK FOR MULTIPLE MATCH
	JRST	MAIN17		;NO MULTI LINE MATCH

MAIN18:	TLNN	FR,USWBIT	;FOR UPDATING, NO LISTING HERE
	PUSHJ	PP,PNTTXT	;ALL LINES ARE GONE FROM 1 FILE,
				;OUTPUT THE OTHER WITHOUT USING CORE
	JRST	MAIN

;AT THIS POINT NEITHER FILE HAS ANY MORE LINES TO BE READ.
;PRINT AS DIFFERENCES ANY LINES REMAINING FOR EITHER FILE.

FINISH:	JUMPGE	F1,MULT8	;PRINT DIFFERENCES IF EITHER BUFFER
	JUMPGE	F2,MULT8	;  HAS ANY LINES IN IT
				;NO LINES ANYWHERE
	MOVE	W1,[POINT 7,[ASCIZ /|
/]]
	TLNE	FR,USWBIT	;"UPDATE" MODE?
	SKIPN	DIFFLG		;YES
	JRST	FIN2		;NO
	PUSHJ	PP,PRINT	;PRINT MESS. IF 2ND FILE IS TRUNCATED 1ST FILE
FIN2:	MOVEI	T,[ASCIZ /No differences encountered/]
	SKIPN	ERRCNT		;ANY DIFFERENCES?
	JRST	FIN3		;NO
	MOVEI	T,[ASCIZ /%files are different/]
	SKIPE	QSW		;/Q MODE?
	MOVEI	T,[ASCIZ /?files are different/]
FIN3:	PUSHJ	PP,TYPMSG	;PRINT MESSAGE
	PUSHJ	PP,CRLF
	JRST	COMP		;END OF SOURCE COMPARE
;THIS SECTION LOOKS FOR MULTI LINE MATCH

MULTI:	SKIPG	NUMLIN		;MULTIPLE LINE TEST?
	JRST	MULT7		;NO
	HRRZM	W1,RTNTMP	;YES, SAVE RETURN ADDRESS
	SETZM	NUMTMP		;INIT MULTI-LINE COUNTER
	MOVEM	F1,TEMPF1	;SAVE CURRENT POINTERS
	MOVEM	F2,TEMPF2
MULT2:	PUSHJ	PP,GETTWO	;GET NEXT TWO LINES
	  JRST	MULT4		;ONE FILE DOESN'T HAVE A LINE
	PUSHJ	PP,COMPL	;COMPARE THEM
	JRST	MULT6		;MATCH, TEST MULTI COUNTER
MULT4:	MOVE	F1,TEMPF1	;NO MATCH, RESET REGS
	MOVE	F2,TEMPF2
	JRST	@RTNTMP		;RETURN TO WHERE WE GOT TO MULTI FROM

MULT6:	AOS	W1,NUMTMP	;INDEX MULTI-LINE COUNTER
	CAMGE	W1,NUMLIN	;TEST FOR END
	JRST	MULT2		;TEST NEXT TWO
	SUB	F1,W1		;RESET TO 1ST COMPARISON
	SUB	F2,W1
MULT7:	TLNE	FR,USWBIT	;MANUAL UPDATE MODE?
	JRST	MULT9		;YES
MULT8:	TLNE	FR,USWBIT	;CHECK UPDATE MODE
	JRST	MAIN		;FOR UPDATE MODE, GET 2ND FILE PRINTED
	PUSHJ	PP,PNTBTH	;PRINT DIFFERENCES

;GO BACK AND START COMPARING.
;WHEN WE START COMPARING AGAIN THE LINE POINTERA WILL
;BE POINTING TO THE FIRST TWO LINES AFTER THE MATCHING LINES

	ADD	F1,NUMLIN	;CAUSE MOVEUP TO FLUSH ALL THE
	ADD	F2,NUMLIN	;  LINES THAT WERE JUST MATCHED
	JRST	MAIN		;DIFFERENCES PRINTED- LOOK FOR MORE

MULT9:	SUBI	F1,1		;LEAVE POINTERS POINTING TO
	SOJA	F2,MAIN		;  LAST DIFFERENCE
;THIS ROUTINE SETS UP THE POINTERS TO THE TEXT

;MEMORY STORAGE AREA LOOKS LIKE THIS:
;1) BUFFER SPACE FOR FILE # 0 (POINTED TO BY LBUFP1)
;	A) XWD (PAGE #),(WORD COUNT FOR LINE (INCLUDING THIS WORD))
;	   TEXT FOR LINE 0
;	    MORE TEXT FOR LINE 0
;	     & MORE, ENDED WITH A NULL
;	B) MORE LINES (EACH WITH PAGE #,WORD COUNT, AND TEXT
;2) BUFFER SPACE FOR FILE 1 (POINTED TO BY LBUFP2)
;	A) AS ABOVE

SETP:	HRRI	FR,1		;SET UP POINTER FILE 1
	PUSHJ	PP,SETONE
	HRRI	FR,0		;DITTO FILE 0

SETONE:	MOVE	W3,F1(FR)	;GET LINE #
SETON1:	MOVE	TT,OLDNUM(FR)	;GET LAST # COMPUTED FOR
	MOVEM	W3,OLDNUM(FR)	;SAVE NEW # AS OLD
	CAML	W3,TT		;IS NEW LARGER THAN OLD?
	SKIPA	T,OLDPNT(FR)	;YES, START FROM OLD BYTE POINTER
	SKIPA	T,LBUFP1(FR)	;NO, START FROM BEGINNING
	SUB	W3,TT		;LOOP ONLY FROM OLD POINTER
	MOVSI	TT,(ADD T,(T))	;(SET UP IN AC)
	MOVE	TT+2,[JRST SETON2]	;SET UP AC
	MOVE	TT+1,.+1	;SET UP AC
	SOJGE	W3,TT
			;TT/	ADD T,(T)	;ADD IN WORD COUNT FOR LINE
			;TT+1/	SOJGE W3,.-1	;MORE LINES LEFT?
			;TT+2/	JRST SETON2	;NO

SETON2:	HRRZM	T,OLDPNT(FR)	;SAVE POINTER TO THIS LINE
	HRLI	T,(POINT 7,0,35)	;NO, CHANGE TO BYTE POINTER
	MOVEM	T,W1(FR)
	POPJ	PP,

;MOVE UP THE POINTERS WHICH POINT TO THE LINES FROM WHICH WE
;ARE EXAMINING.  THIS IS DONE EVERYTIME A MATCH IS FOUND

MOVEUP:	TLNE	FR,USWBIT	;MANUAL "UPDATE" MODE?
	PUSHJ	PP,UPDATE	;YES
	MOVE	W3,F1(FR)	;GET LINE # FOR THIS FILE
	CAML	W3,TOP(FR)	;GETTING RID OF ALL LINES?
	JRST	MOVEX		;YES, DON'T MOVE MEMORY
	AOS	W3,F1(FR)	;GET LINE # OF LINE TO SAVE
	PUSHJ	PP,SETON1	;GET ADR OF 1ST LINE TO SAVE
	HRL	T,LBUFP1(FR)	;SET UP BLT AC (REVERSED)
	PUSH	PP,T		;SAVE
	AOS	W3,TOP(FR)	;GET 1ST NON-EXISTANT LINE #
	PUSHJ	PP,SETON1	;GET CORRESPONDING 1ST ADR
	POP	PP,W1
	SUB	T,W1		;CALCULATE WORD COUNT OF TRANSFER
	ADD	T,LBUFP1(FR)	;CALCULATE "E" OF BLT AC,E
	MOVSS	W1		;SWITCH AC TO XWD FROM,TO
	BLT	W1,(T)		;AND AWAY WE GO

MOVEX:	SETCM	W2,F1(FR)	;W2_-<(F1)+1>
	ADDM	W2,TOP(FR)	;CHANGE TOP TO ACCOUNT FOR DEAR DEPARTED LINES
	HRLOI	0,377777
	MOVEM	0,OLDNUM(FR)	;FORCE SETON1 TO RECALCULATE
	POPJ	PP,
;LIST ALL OF SECOND FILE, EACH LINE PRECEDED BY VERTICAL BAR-TAB
;  IF IT IS PART OF A MISMATCH (MISMATCH MEANS (F2) .GE. 1)

UPDATE:	TRNN	FR,-1		;SECOND FILE?
	POPJ	PP,		;NO, RETURN
	SETOM	TEMP		;YES, INIT LINE COUNTER
UPDAT1:	AOS	W1,TEMP		;GET NUMBER OF NEXT LINE
	CAMLE	W1,F2		;DONE?
	POPJ	PP,		;YES
	MOVEI	C,174		;PRINT VERTICAL BAR IF
	SKIPN	DIFFLG		;  "DIFFERENCE FLAG" IS SET, OR IF
	SKIPE	F2		;  MORE THAN 1 LINE HAS BEEN LOOKED AT
	PUSHJ	PP,PCHAR
	SETZM	DIFFLG		;CLEAR "DIFFERENCE FLAG"
	MOVEI	C,TAB		;PRINT A TAB
	PUSHJ	PP,PCHAR
	PUSH	PP,F2		;SAVE F2
	MOVE	F2,W1		;GET LINE NUMBER TO PRINT
	PUSHJ	PP,SETONE	;GET BYTE POINTER TO LINE
	MOVE	W1,W2		;GET BYTE POINTER INTO W1
	PUSHJ	PP,PRINT	;GO PRINT LINE
	MOVEI	C,15
	PUSHJ	PP,PCHAR	;PRINT CARRIAGE RETURN
	ILDB	C,W1		;GET LINE TERMINATING CHARACTER
	PUSHJ	PP,PCHAR	;AND PRINT IT
	POP	PP,F2		;RESTORE F2
	JRST	UPDAT1		;GO PRINT MORE LINES, IF ANY
;CODE FOR GETTING TWO LINES
;CALLING SEQUENCE IS:
;	PUSHJ PP,GETTWO
;	   RETURN 1 IF EITHER FILE HAS NO MORE LINES
;	   RETURN 2 IF ONE LINE READ FROM EACH FILE
; C(GETFIL)=THE # OF FILE FOR WHICH A LINE WAS READ (OR -1 IF NONE)

GETTWO:	SETOM	GETCNT		;INIT # LINESOBTAINED
	SETOM	GETFIL		;INIT FILE # LINE CAME FROM
	TRZ	FR,-1		;ZERO RIGHT HALF OF "FR"--SET FOR FIRST FILE
	PUSHJ	PP,GLINE	;GET A LINE FROM FIRST FILE
	HRRI	FR,1		;NOW DO FOR SECOND FILE
	PUSHJ	PP,GLINE
	SKIPLE	GETCNT		;GETCNT .G. 0 IF TWO LINES WERE GOT
	AOS	(PP)		;SKIP IF 2 LINES WERE AVAILABLE
	POPJ	PP,

GLINE:	AOS	W1,F1(FR)	;BUMP THE LINE POINTERS
	CAMG	W1,TOP(FR)	;HAVE WE GONE OVER THE TOP
	JRST	GLEXIT		;NO, LINE WAS AVAILABLE
	SOS	F1(FR)		;NOT CLEAR YET THAT A NEW LINE EXISTS
GLINE1:	HRLS	PAGNUM(FR)	;SAVE PAGE # AT BEGINNING OF LINE
	PUSHJ	PP,GCHAR	;GET A CHARACTER
	TLNE	FR,@EOFTBL(FR)	;END OF FILE?
	POPJ	PP,		;YES, NO LINE
	TLNN	FR,ALLSW	;SKIP IF COMPARING BLANK LINES
	JUMPL	C,GLINE1	;MINUS CHARS INDICATE BLANK LINES
	AOS	W1,F1(FR)	;THERE ARE CHARS FOR A NEW LINE
	MOVEM	W1,TOP(FR)	;THIS LINE IS THE TOP LINE
	PUSHJ	PP,SETONE	;CALCULATE BYTE POINTER
	MOVE	W1,W1(FR)	;GET BYTE POINTER IN W1
	MOVEM	W1,WCADR	;SAVE ADR OF LINE WORD COUNT
	MOVE	W2,PAGNUM(FR)	;PICKUP PAGE # AT BEGINNING OF LINE
	HLLZM	W2,(W1)		;SAVE WITH THIS LINE
	JRST	GLINE3
			
GLINE2:	PUSHJ	PP,GCHAR	;GET NEXT CHAR FOR LINE
GLINE3:	TLNN	W1,760000	;WILL NEXT IDPB GO INTO NEXT WORD?
	PUSHJ	PP,GLCHEK	;CHECK ADDRESS
	IDPB	C,W1		;STORE CHARS IN LINE BUFFER
	JUMPG	C,GLINE2	;NEG CHARACTER IS END OF LINE
	MOVEI	W3,0		;REPLACE LAST CHAR WITH NULL
	DPB	W3,W1
	TLNN	W1,760000	;WILL TERM CHAR GO INTO NEXT WORD?
	PUSHJ	PP,GLCHEK	;YES, CHECK ADDRESS
	IDPB	C,W1		;STORE TERM CHAR AFTER NULL
	MOVE	W3,WCADR	;GET BACK ADR OF WORD COUNT
	SUBI	W1,-1(W3)	;CALCULATE WORD COUNT
	HRRM	W1,(W3)		;SAVE WORD COUNT IN BUFFER
GLEXIT:	AOS	GETCNT		;INDEX # LINES FOUND
	HRRZM	FR,GETFIL	;SAVE # OF THIS FILE
	POPJ	PP,

GLTBL:	LBUFP2		;POINTS TO TOP ADR FILE 0
	.JBREL		;POINTS TO TOP ADR FILE 1

GLCHEK:	HRRZ	W3,@GLTBL(FR)	;YES,GET HIGHEST ADR FOR THIS BUFFER
	CAIG	W3,3(W1)	;CHECK ADR. (LEAVE 1 WORD FOR WORD
				;COUNT FOR NEXT LINE PLUS 1 WORD
				;SLOP TO BE SAFE
	JRST	NOROOM		;NO ROOM IN THE INN
	HLRZM	C,1(W1)		;PUT BIT17 INTO BIT35 (FOR SEQUENCE  #)
	POPJ	PP,
;IF A "CORE" UUO IS INSTALLED HERE, IT MUST ADJUST THE FOLLOWING
;LIST OF LOCATIONS (ALL BY THE AMOUNT THE SECOND BUFFER AREA
;IS MOVED, IF ANY):
;1) BYTE POINTER ADDRESS IN: W1
;2) BUFFER POINTER IN: LBUFP2
;3) 1ST ADDRESS FOR LINE IN: 0(PP) ON PUSH DOWN LIST
;THEN RETURN TO THE IDPB NEAR GLINE2+6


NOROOM:	PUSH	PP,W1		;SAVE BYTE POINTER
	TRC	FR,1		;CHANGE 1 TO 0 (OR VICE VERSA)
	MOVE	W3,TOP(FR)	;GET TOP LINE # FOR "OTHER" FILE
	ADDI	W3,1		;FIND 1ST ADR OF THE NEXT LINE ABOVE TOP
	PUSHJ	PP,SETON1	;GET ADR
	HRRZM	T,HIGH		;SAVE 1ST FREE ADR OF NON-FULL FILE
	HRRZ	T,@GLTBL(FR);GET HIGHEST ADR AVAILABLE TO NON-FULL FILE
	SUB	T,HIGH		;GET SPACE AVAILABLE
	SUBI	T,2		;LEAVE 1 WRD FOR NEXT LINE WORD COUNT
				;PLUS 1 WORD SLOP TO BE SAFE
	TRC	FR,1		;CHANGE FILE # BACK TO THE WAY IT WAS
	MOVEM	T,ROOM		;SAVE ROOM AVAILABLE
	CAIL	T,^D400		;COMPARE WITH 400. (NO MAGIC SIGNIFICANCE)
	JRST	NOR2		;PLENTY ROOM AVAILABLE- DON'T GET MORE CORE

	HRRZ	T,.JBREL
	MOVEM	T,W1		;SAVE THIS .JBREL AS "OLD" .JBREL
	ADDI	T,1		;REQUEST CORE SIZE CONTAINING THIS ADDRESS
NOR1:	CORE	T,		;CORE UUO
	SKIPA	T,ROOM		;FAIL
	JRST	NOR3		;SUCCESS
NOR11:	JUMPG	T,NOR4		;ANY CORE LEFT AT ALL?
NORERR:	JSP	T,ERROUT	;NO, PRINT MESSAGE
	ASCIZ	/?Buffer capacity exceeded and no core available/
NOR3:	HRRZ	T,.JBREL	;CORE UUO SUCCESFUL- GET "NEW" .JBREL
	SUB	T,W1		;FIND OUT HOW MUCH WAS ADDED
	ADDB	T,ROOM		;UPDATE TOTAL ROOM AVAILABLE
NOR33:	TRNE	FR,1		;WHICH FILE NEEDED ROOM?
	JRST	NOR98		;FILE #1, IT JUST GOT IT
			;FILE #0, SHUFFLE CORE
NOR2:	ASH	T,-1		;DIVIDE AVAILABLE SPACE BETWEEN FILES
NOR4:	MOVEM	T,ROOM		;FILE #1 GETS MOVED THIS AMOUNT
	TRNN	FR,1		;WHICH FILE NEEDED ROOOM?
	JRST	NOR5		;FILE #0. MOVE #1 TOWARD 777777
			;FILE #1. MOVE #1 TOWARD 0
NOR6:	MOVNS	T,ROOM		;FILE IS MOVING IN NEGATIVE DIRECTION
	ADDM	T,WCADR		;WORD COUNT ADR FOR FILE# 1 IS MOVED DOWN
	ADDM	T,(PP)		;SAME WITH BYTE POINTER
	MOVE	W1,(PP)		;GET LAST ADR TO MOVE FROM BYTE POINTER
	ADD	T,LBUFP2	;GET "TO" ADR. [(LBUFP2)-D OF M]
	HRL	T,LBUFP2	;GET "FROM" ADR
	BLT	T,(W1)		;BLT T,"E" (T/  XWD "FROM","TO")
	JRST	NOR90

NOR5:	MOVE	W1,T		;GET D OF M
	HRLI	W1,(POP T,(T))	;SETUP- POP T,<D OF M>(T) INTO W1
	MOVE	W2,HIGH		;GET HIGH(+1) ADR OF FILE #1
	SUB	W2,LBUFP2	;GET LENGTH OF FILE #1
	SOS	T,HIGH		;GET LAST ADR IN FILE #1
	HRLI	T,400000(W2)	;PUT WORD COUNT(+400000) IN LEFT HALF
				;400000 AVOIDS PDL OVERFLOW PROBLEM IN AC LOOP
	MOVE	W3,[JRST NOR90]
	MOVE	W2,.+1
	JUMPL	T,W1		;W1/	POP T,<DISTANCE OF MOVE>(T)
			;W2/	JUMPL T,W1
			;W3/	JRST NOR90
;THE ABOVE INSTRUCTIONS ARE A REVERSE BLT AND ARE IN THE AC'S FOR SPEED

NOR90:	MOVE	T,ROOM		;GET DISTANCE FILE #1 WAS MOVED
	ADDM	T,LBUFP2	;MODIFY STARTING ADR OF FILE #1
	HRLOI	0,377777
	MOVEM	0,OLDNUM+1	;FORCE "SETONE" TO RECALCULATE BYTE POINTER
NOR98:	POP	PP,W1
NOR99:	POPJ	PP,
;THIS PAGE CONTAINS ROUTINE FOR COMPARING TWO LINES
;IT HAS TWO RETURNS--CALLING ADR.+1 IF LINES MATCH OR
;CALLING ADR+2 IF NO MATCH

COMPL:	PUSHJ	PP,SETP		;CALCULATE POINTERS TO TEXT
	MOVEM	W1,P1		;P1=TEMP POINTER TO TEXT FOR FIRST FILE
	MOVEM	W2,P2		;P2 FOR SECOND FILE

	MOVEI	W3,1
	TDNN	W3,1(W1)	;TEST SEQUENCE # BIT
	JRST	.+3		;NOT SEQ. #
	AOS	P1		;SKIP OVER SEQ. # AND
	IBP	P1		;THE TAB
	TDNN	W3,1(W2)	;SAME THING FOR FILE #2
	JRST	.+3
	AOS	P2
	IBP	P2

COMPL1:	ILDB	W1,P1		;GET A CHARACTER FROM LINE FROM FIRST FILE
COMPL2:	ILDB	W2,P2		;AND ONE FROM SECOND FILE
COMPL0:	CAME	W1,W2		;THIS IS THE BIG TEST--ARE THEY EQUAL
	JRST	COMPL4		;NO
COMPL7:	CAIN	W1,";"		;YES, COMMENT?
	TLNN	FR,CSWBIT	;YES, SUPPRESS COMMENTS?
	JUMPN	W1,COMPL1	;NO,NO. TEST FOR END OF LINE
	POPJ	PP,		;LINES MATCH, RETURN

COMPL3:	ILDB	W1,P1		;GET NEW CHAR FOR FILE 1
COMPL4:	CAIE	W1,40		;SPACE?
	CAIN	W1,TAB		;OR TAB?
	TLNN	FR,SSWBIT	;AND IS SPACING BEING IGNORED?
	SKIPA			;NO
	JRST	COMPL3		;FLUSH SPACE OR TAB FOR FILE 1

	CAIE	W2,40		;SPACE?
	CAIN	W2,TAB		;OR TAB?
	TLNN	FR,SSWBIT	;AND IS SPACING BEING IGNORED?
	SKIPA			;NO
	JRST	COMPL2		;YES, FLUSH A SPACE OR TAB FOR FILE 2

	CAMN	W1,W2		;ARE THE CHARACTERS NOW THE SAME?
	JRST	COMPL7		;YES, TEST FOR END OF LINES

	CAIE	W1,";"		;COMMENT IN FILE 1?
	CAIN	W2,";"		;OR IN FILE 2?
	TLNN	FR,CSWBIT	;AND ARE COMMENTS BEING IGNORED?
	JRST	CPOPJ1		;NO, FILES DON'T MATCH, SKIP RETURN
	JUMPE	W1,CPOPJ	;YES, OTHER CHAR MUST BE NULL OR ELSE ONE
	JUMPE	W2,CPOPJ	;  LINE IS LONGER THAN OTHER AND FILES DIFFER
CPOPJ1:	AOS	(PP)
CPOPJ:	POPJ	PP,
;WHEN WE GET TO THIS POINT WE HAVE FOUND 
;THE EXTENT OF THE DIFFERENCES AND WE ARE READY TO PRINT
;THESE DIFFERENCES OUT

PNTBTH:	TRZ	FR,-1		;OUTPUT FILE 1
	PUSHJ	PP,PNTTXT	;PRINT FILE 1 DIFFERENCES
	MOVE	W1,[POINT 7,[ASCIZ /****/]]
	PUSHJ	PP,PRINT
	PUSHJ	PP,PCRLF
	HRRI	FR,1		;THEN PRINT FILE 2 DIFFERENCES
	PUSHJ	PP,PNTTXT
	MOVE	W1,[POINT 7,[ASCIZ /**************/]]
	PUSHJ	PP,PRINT
	JRST	PCRLF		;PRINT CARRIAGE RETURN-LINE FEED

;THIS SUBROUTINE PRINTS ALL THE TEXT IN THE
;BUFFER SPECIFIED BY C(FR)R. I. E. FILE 1 OR FILE 2

PNTTXT:	SETOM	TEMP		;START POINTER AT -1
	SETOM	PAGEN		;GUARANTEE PAGE # MISMATCH- THEREFORE PRINT IT
PNTTX1:	AOS	W1,TEMP		;INDEX LINE COUNTER
	CAMLE	W1,F1(FR)	;PRINTED ALL LINES?
	POPJ	PP,		;YES, RETURN
	PUSH	PP,F1		;NO, SAVE LINE POINTERS
	PUSH	PP,F2
	SETZB	F1,F2		;F1=F2=0
	MOVEM	W1,F1(FR)	;SET UP EITHER FOR F1 OR F2
	PUSHJ	PP,SETONE	;CALCULATE BYTE POINTERS TO TEXT
	MOVE	W1,W1(FR)	;UNNECESSARY FOR FILE 1- MOVES BYTE PNT FILE 2
	PUSHJ	PP,PLINEN	;PRINT: 1)	TEXT
	PUSHJ	PP,PCRLF
	POP	PP,F2
	POP	PP,F1		;RESTORE REGS
	JRST	PNTTX1		;FINISH OUT ALL LINES
;THE FOLLOWING CODE IS USED TO OUTPUT A LINE OF TEXT
PLINEN:	MOVEI	C,"1"(FR)
	PUSHJ	PP,PCHART	;PRINT 1 OR 2
	MOVEI	C,")"
	PUSHJ	PP,PCHART	;PRINT )
	HLRZ	C,(W1)		;GET PAGE NUMBER FOR THIS LINE
	CAME	C,PAGEN		;IS IT THE SAME AS PREVIOUS LINE?
	PUSHJ	PP,PGNUM	;PRINT NEW PAGE NUMBER
	MOVEI	C,TAB		;PRINT TAB
	PUSHJ	PP,PCHART

PRINT:	ILDB	C,W1		;GET CHARACTER
	JUMPN	C,.-2		;LOOP UNTIL A NULL SHOWS UP
	POPJ	PP,


TCRLF:			;THIS TEST IS FOR BINARY COMPARE ON TTY
			;ONLY PRINT HEADER ONCE, SINCE TAKES UP SPACE
			;ON VT05'S ETC
	TLNN	FR,IOTTY	;IS OUTPUT TO TTY?
	JRST	PCRLF		;NO, GIVE EACH PAGE A HEADER
	SKIPE	ERRCNT		;COUNT IS ZERO FIRST TIME IN
	JRST	CRLF		;NOT FIRST TIME

PCRLF:			;THIS CODE OUTPUTS A CARRAIGE RETURN-LINE
			;FEED AND DECREMENTS THE LINE COUNT

	PUSHJ	PP,CRLF
	SOSN	LINCNT		;DECREMENT THE LINES/PAGE COUNT
	TLO	FR,PAGSW	;THIS MEANS WE GET A NEW HEADING
	POPJ	PP,

PGNUM:	MOVEM	C,PAGEN		;SAVE NEW PAGE # AS OLD
PGNUM1:	IDIVI	C,12		;STANDARD DECIMAL PRINT ROUTINE
	HRLM	C+1,(PP)
	SKIPE	C
	PUSHJ	PP,PGNUM1
	HLRZ	C,(PP)
	ADDI	C,"0"
	JRST	PCHART
;THIS PAGE CONTAINS ROUTINES FOR CHARACTER OUTPUT

;CHARACTERS OUTPUTED AS A STRING OF TEXT COME THROUGH HERE

PCHART:	JUMPE	C,CPOPJ		;ZERO MEANS A CARRIAGE RETURN
				;IF SO WE ARE THROUGH WITH LINE
	CAIL	C,11		;IS CHAR BETWEEN 11 (TAB) AND
	CAILE	C,15		;  15 (CARRIAGE RETURN), OR
	CAIL	C," "		;  .GE. THAN 40 (SPACE)?
	JRST	PCHAR		;YES, PRINT AS IS
	MOVSI	C,100(C)	;NO, CONTROL CHAR --SAVE
	HRRI	C,"^"		;THIS IS CONTROL SYMBOL
	PUSHJ	PP,PCHAR	;OUTPUT THE "^"
	MOVSS	C		;AND NOW FOR THE LETTER

PCHAR:	TLNN	FR,USWBIT	;NO HEADERS FOR UPDATE MODE
	TLZN	FR,PAGSW	;DO WE NEED A NEW HEADING
	JRST	TYO		;NO--SIMPLE CHARACTER OUTPUT
	SETOM	LINCNT		;YES
;THIS CODE OUTPUTS A HEADING COMPRISES OF THE TITLE OF
;EACH FILE AFTER "FILE 1)" AND "FILE 2)"

	MOVEM	16,SAVEXS+16	;SAVE ACCUMULATORS WHILE OUTPUTING HEADING
	MOVEI	16,SAVEXS
	BLT	16,SAVEXS+15	;ACCUMULATORS ARE NOW SAVED
	TLNE	FR,ENDSW	;DON'T BOTHER IF NO ERRORS DETECTED
	JRST	PCHAR1
	MOVEI	C,FF		;FOR NEW PAGE, ISSUE FORM FEED
	TLNN	FR,NOFORM	;IF 1, SUPPRESS FORM FEED
	PUSHJ	PP,TYO
	MOVE	W1,[POINT 7,[ASCIZ /File 1)	/]]
	PUSHJ	PP,PRINT
	MOVE	W1,[POINT 7,HBUF1]
	PUSHJ	PP,PRINT	;PRINT FILE 1 NAME
	PUSHJ	PP,PCRLF
	MOVE	W1,[POINT 7,[ASCIZ /File 2)	/]]
	PUSHJ	PP,PRINT
	MOVE	W1,[POINT 7,HBUF2]
	PUSHJ	PP,PRINT	;PRINT FILE 2 NAME
PCHAR1:	PUSHJ	PP,CRLF		;FOLLOWED BY TWO CARRIAGE RETURN FINE FEEDS
	PUSHJ	PP,CRLF
	MOVEI	LPP		;RESET LINES/PAGE COUNT
	MOVEM	LINCNT
	MOVSI	16,SAVEXS	;AND RESTORE ACS
	BLT	16,15
	MOVE	16,SAVEXS+16
	TLZ	FR,NOFORM	;CLEAR SUPPRESS FF FLAG AFTER RESTORING AC'S
	SKIPE	QSW		;Q LISTING ONLY?
	JRST	QFIN		;YES, GIVE UP ON FIRST ERROR
	JRST	TYO		;DON'T FORGET ABOUT THAT ORGINAL CHARACTER
;THE CODE ON THIS PAGE IS FOR HANDLING INPUT ERRORS
;THERE ARE TWO TYPES OF ERRORS--EITHER THE FILE IS NOT FOUND
;OR THE DEVICE IS NOT AVAILABLE--THE FORMAT FOR THESE MESSAGES
;IS THE SAME FORMAT USED FOR THE "TECO" MESSAGES.



ERRIA:	MOVEI	T,[ASCIZ /?Input error- /]
	PUSHJ	PP,TYPMSG	;TYPE FIRST PART OF MESSAGE
	MOVE	T,INDIR1	;GET FILE NAME
	PUSHJ	PP,PNTSIX	;PRINT
	HLLZS	T,INDIR1+1	;GET EXTENSION FREED FROM GARBAGE
	JUMPE	T,NOEXT		;ANY EXTENSION?
	MOVEI	C,"."		;YES, TYPE DOT
	PUSHJ	PP,TYO
	MOVE	T,INDIR1+1	;GET EXTENSION
	PUSHJ	PP,PNTSIX	;PRINT
NOEXT:	MOVEI	T,[ASCIZ / file not found/]	;FINISH MESSAGE
	PUSHJ	PP,TYPMS0
	JRST	CARR		;THIS WILL OUTPUT TWO C.R. AND EXIT


ERRA:	MOVE	T,OUTDEV	;OUTPUT INIT FAIL
	MOVEM	T,INDEV1

ERRI:	MOVEI	T,[ASCIZ /?Device /]
	PUSHJ	PP,TYPMSG	;TYPE BEGINING OF MESSAGE
	MOVE	T,INDEV1
	PUSHJ	PP,PNTSIX
	MOVEI	T,[ASCIZ /: NOT AVAILABLE/]
	PUSHJ	PP,TYPMS0	;TYPE REST OF MESSAGE
	JRST	CARR		;INSERT CARRIAGE RETURNS AND EXIT

PNTSIX:	MOVE	TT,[POINT 6,T]	;INIT SIXBIT BYTE POINTER
PNTS1:	TLNN	TT,770000	;FINISHED WITH WORD?
	POPJ	PP,		;YES
	ILDB	C,TT		;NO, GET CHARACTER
	JUMPE	C,PNTS1		;FLUSH SPACES
	ADDI	C,40		;CHANGE TO ASCII
	PUSHJ	PP,TYO
	JRST	PNTS1
CRLF:	MOVEI	C,15		;OUTPUT A CARRIAGE RETURN-LINE FEED
	PUSHJ	PP,TYO
	MOVEI	C,12		;NOW THE LINE FEED

TYO:	SOSG	CTOBUF+2	;DECREMENT BUFFER COUNT
	PUSHJ	PP,DMPOUT	;BUFFER WAS FULL
	IDPB	C,CTOBUF+1	;DEPOSIT CHAR.
	CAIN	C,12		;LINE FEED?
	TLNN	FR,IOTTY	;WHILE DOING 1 OUTPUT PER LINE?
	POPJ	PP,		;NO
DMPOUT:	OUT	CTL,		;YES, OUTPUT BUFFER
	POPJ	PP,		;OK
	JSP	T,ERROUT
	ASCIZ	/?Output device error/

ERRO:	JSP	T,ERROUT
	ASCIZ	/?Output initialization error/
ERRCOR:	MOVEI	T,[ASCIZ /?2K core needed and not available/]
	PUSHJ	PP,TYPMSG
	EXIT			;PRINT MESSAGE AND EXIT

ERROUT:	PUSHJ	PP,TYPMSG	;OUTPUT ERROR
	JRST	CARR		;THROW IN TWO CR AND TRY AGAIN
TYPB:	PUSHJ	PP,TYPTAB
	PUSHJ	PP,TYCELL
	PUSHJ	PP,TYPSP
TYCELL:	MOVEI	TT,6		;CALCULATER CONTENTS A A MEMORY WORD
			;WHICH IS STORED IN AC T
			;SHIFT A CHAR. INTO ACC AND ADD 60
			;DO IT TO MAKE IT ASCII; DO THIS 6 TIMES

	MOVEI	C,0
	LSHC	C,3
	ADDI	C,"0"
	PUSHJ	PP,PCHAR
	SOJG	12,TYCELL+1
	POPJ	PP,

TYPSP:	MOVEI	C," "
	JRST	TYO

TYPTB2:	PUSHJ	PP,TYPTAB
TYPTAB:	MOVEI	C,TAB
	JRST	TYO

TYCNT:	AOS	ERRCNT
	HRLZ	T,CNT
	JRST	TYCELL
;ROUTINES FOR OUTPUTING ERROR MESSAGES

TYPMSG:	PUSHJ	PP,INITTY	;INTIALIZE TTY
	PUSHJ	PP,CRLF		;OUTPUT A CARRIAGE RETURN
TYPMS0:	HRLI	T,(POINT 7,,)	;THIS IS POINTER FOR ERROR MESSAGE
	SKIPA
	PUSHJ	PP,TYO
TYPMS1:	ILDB	C,T		;LOAD A CHAR. FROM ERROR MESSAGE
	JUMPN	C,.-2		;ALL ERROR MESSAGES END WITH A ZERO
	POPJ	PP,		;THROUGH WITH ERROR MESSAGE

CARR:	PUSHJ	PP,CRLF		;COMMON EXIT FOR ERROR MESSAGES
	PUSHJ	PP,CRLF
	JRST	COMP		;GO TO VERY BEGINNING

;INITIALIZE TTY FOR ERROR MESSAGES
INITTY:	CLOSE	CTL,
	RELEAS	CTL,
	INIT	CTL,1
	SIXBIT	/TTY/
	XWD	CTOBUF,CTIBUF
	HALT
	INBUF	CTL,1
	OUTBUF	CTL,1
	POPJ	PP,

;HELP MESSAGE TEXT

HELP:	MOVE	1,['FILCOM']	;NAME OF HELP FILE
	PUSHJ	PP,.HELPR	;READ IT
	JRST	COMPGO		;PRINT * AGAIN
;ROUTINE TO GET A LEGITIMATE CHARACTER

GCHAR:	TLNE	FR,@EOFTBL(FR)	;EOF SEEN?
	JRST	NULL		;YES, RETURN NULL
	SOSG	@CNTTBL(FR)	;DECREMENT BUFFER COUNT
	JSP	C,@[EXP GCHAR1,GCHAR2](FR)	;BUFFER EMPTY- DO "INPUT"
	SKIPN	@CNTTBL(FR)	;DID WE GET ANY DATA
	JRST	GCHAR		;NO
	ILDB	C,@BYTTBL(FR)	;YES, GET A CHARACTER
	JUMPE	C,GCHAR		;GET RID OF NULLS
	CAIE	C,LF		;LINE FEED?
	CAIN	C,VT		;NO-VERTICAL TAB?
	JRST	EOL		;YES, RETURN WITH LINE-END FLAG SET
	CAIN	C,CR		;CARRIAGE RETURN?
	JRST	GCHAR		;YES, FLUSH
	CAIN	C,FF		;IS IT A FORM FEED?
	JRST	FORM		;YES
	HRL	C,@SEQTBL(FR)	;GET SEQUENCE # BIT (IF IT EXISTS)
	TLZ	C,777776	;TURN OFF ALL BUT SEQ. # BIT
	POPJ	PP,		;NO, RETURN WITH CHAR

GCHAR1:	INPUT	IN1,		;INPUT FOR FILE 1
	STATO	IN1,762000	;ERRORS OR END OF FILE?
	JRST	(C)		;NO
	STATO	IN1,742000	;YES, EOF?
	JRST	EOF		;YES END OF FILE
	JSP	T,ERROUT
	ASCIZ	/?File 1 read error/

GCHAR2:	INPUT	IN2,
	STATO	IN2,762000
	JRST	(C)
	STATO	IN2,742000
	JRST	EOF
	JSP	T,ERROUT
	ASCIZ	/?File 2 read error/
SEQTBL:	Z	@INBUF1+1	;POINTS TO ADR OF LAST CHAR FILE #0
	Z	@INBUF2+1	;DITTO FILE #1

BYTTBL:	INBUF1+1		;ADR OF BYTE POINTER FILE #0
	INBUF2+1		;DITTO FILE #1

EOFTBL:	EOF1SW		;EOF FLAG FOR FILE 1
	EOF2SW		;EOF FLAG FOR FILE 2

CNTTBL:	INBUF1+2		;POINTS TO FILE 1 CHAR COUNT
	INBUF2+2		;DITTO FILE 2

EOF:	TLO	FR,@EOFTBL(FR)	;SET EOF FLAG
NULL:	TDZA	C,C		;THEN RETURN NULL CHAR
FORM:	AOS	PAGNUM(FR)	;INDEX PAGE NUMBER
EOL:	TLO	C,(1B0)		;SET BIT 0 TO SHOW END-OF-LINE
	POPJ	PP,

;HERE TO SKIP REST OF FILES, BUT MUST READ THEM INCASE OF ERRORS

QFIN:	AOS	ERRCNT		;ENSURE AT LEAST ONE ERROR SEEN
	MOVE	W1,[POINT 7,[ASCIZ /?files are different/]]
	TLNN	FR,IOTTY	;WILL GET DONE AT FIN2 IF TTY
	PUSHJ	PP,PRINT	;PUT IN OUTPUT FILE
	TRZ	FR,-1		;INDEX BY 0 FOR FILE 1
	PUSH	PP,[EXP QFIN2]	;FOR EOF
QFIN1:	JSP	C,GCHAR1	;DO INPUT
	SETOM	INBUF1+2	;CLEAR WORD COUNT
	JRST	QFIN1		;TRY AGAIN

QFIN2:	TLNE	FR,EOF2SW	;ONLY ONE FILE?
	JRST	FIN2		;SHOULD NOT HAPPEN BUT!!
	ANDI	FR,1		;INDEX BY 1 FOR FILE 2
	PUSH	PP,[EXP FIN2]	;FOR EOF
QFIN3:	JSP	C,GCHAR2	;INPUT
	SETOM	INBUF2+2
	JRST	QFIN3		;NO. LOOP
NAME1:	SETZB	ACDEV,ACDEL	;ZERO REGISTERS WHICH WILL RETURN THE NAMES
	SETZB	ACFILE,ACEXT
	SETZB	ACPPN,EXTFL2	;INIT PROJ,PROG NUMBER TO [0,0]
	TLZ	FR,CTYPF	;CLEAR COMMAND TYPED FLAG

NAME3:	MOVSI	ACPNTR,(POINT 6,0)	;SET POINTER
	SETZB	TT,0		;THE SIXBIT NAME WILL BE STORED IN THE AC0

GETIOC:	PUSHJ	PP,TTYIN	;GET INPUT CHARACTER
GETIC1:	CAIE	C,32		;AN EOF TERMINATES A FILE NAME
	CAIG	C,15		;THIS IS ANOTHER WAY TO GET A FILE NAME
	JRST	TERM		;CATCHES CR,LF,FF,VT
	CAIN	C,33		;ALT MODE?
	JRST	TERM		;YES
	CAIE	C,"_"		;ONE KIND OF SEPERATOR
	CAIN	C,","		;THIS ALSO MEANS WE HAVE FINISHED A TERM
	JRST	TERM		;TERM HAS BEEN READ
	CAIN	C,"/"		;IS THERE A SWITCH?
	JRST	GETSW		;YES
	TLO	FR,CTYPF	;SET COMMAND TYPED FLAG
	CAIN	C,":"		;HAVE WE BEEN GETTING A DEVICE NAME
	JRST	DEVICE		;YES
	CAIN	C,"."		;OR A FILE NAME
	JRST	NAME		;YES
	CAIN	C,"["		;THIS CHAR STARTS A PROJ,PROG NUMBER
	JRST	GETPP
		;ALL OTHER CHARACTERS SHOULD BE ALPHANUMERIC FOR FILENAMES
	CAIL	C,"A"
	CAILE	C,"Z"
	JRST	[CAIL C,"0"	;NOT ALPHABETIC, IS IT NUMERIC?
		CAILE C,"9"
		JRST CTLSER	;NOT ALPHANUMERIC, COMMAND ERROR
		JRST .+1]
	TRC	C,40		;CONVERT TO SIXBIT
	TLNE	ACPNTR,770000	;HAVE WE STORED SIX BYTES?
	IDPB	C,ACPNTR	;NO
	JRST	GETIOC		;GET ANOTHER CHAR.

TTYIN:	SOSG	CTIBUF+2	;DECREMENT CHARACTER COUNT, ANY LEFT?
	INPUT	CTL,		;NO, GET A BUFFER FULL
	ILDB	C,CTIBUF+1	;GET CHARACTER
	JUMPE	C,TTYIN		;FLUSH NULLS
	CAIE	C,176
	CAIN	C,175
	MOVEI	C,33		;CHANGE ALL ALT MODES TO NEW
	CAIN	C,"="
	MOVEI	C,"_"		;= WILL EVENTUALLY REPLACE _
	CAIL	C,"A"+40
	CAILE	C,"Z"+40
	JRST	.+2
	TRZ	C,40		;CHANGE LOWER CASE TO UPPER CASE
	CAIE	C," "		;SKIP BLANKS
	CAIN	C,TAB		;AND TABS
	JRST	TTYIN
	POPJ	PP,		;NO, EXIT
DEVICE:	SKIPA	ACDEV,0		;DEVICE NAME
NAME:	MOVE	ACFILE,0	;FILE NAME
	MOVE	ACDEL,C		;SET DELIMITER
	JRST	NAME3		;GET NEXT SYMBOL

TERM:	JUMPE	ACDEL,.+3	;IF NO PREVIOUS DELIMITOR, OR
	CAIE	ACDEL,":"	;IF PREVIOUS DELIMITER
	JRST	TERM1
	MOVE	ACFILE,0	;SET FILE
TERM1:	CAIE	ACDEL,"."	;IF PERIOD,
	POPJ	PP,
	HLLZ	ACEXT,0		;SET EXTENSION
	HLRZS	0		;PUT EXT IN RH
	MOVSI	T,EXTBL-EXTBLE	;NEGATIVE WORD COUNT
	CAIE	0,@EXTBL(T)	;MATCH EXT?
	AOBJN	T,.-1
	HLLZ	T,EXTBL(T)	;GET FLAGS
	MOVEM	T,EXTFL2	;SAVE  THEM
	POPJ	PP,		;EXIT

EXTBL:	XDFBIT,,'SAV'
	XDFBIT,,'LOW'
	XDFBIT,,'SVE'
	HSGBIT,,'SHR'
	HSGBIT,,'HGH'
	WDFBIT,,'REL'
	WDFBIT,,'XPN'
	WDFBIT,,'CHN'
	WDFBIT,,'DMP'
	WDFBIT,,'BIN'
	WDFBIT,,'RIM'
	WDFBIT,,'RTB'
	WDFBIT,,'RMT'
	WDFBIT,,'BAC'
	WDFBIT,,'BUG'
	WDFBIT,,'CAL'
	WDFBIT,,'DAE'
	WDFBIT,,'DCR'
	WDFBIT,,'MSB'
	WDFBIT,,'OVR'
	WDFBIT,,'QUC'
	WDFBIT,,'QUE'
	WDFBIT,,'QUF'
	WDFBIT,,'SFD'
	WDFBIT,,'SYS'
	WDFBIT,,'UFD'
EXTBLE:	0			;END OF TABLE
GETSW:	PUSHJ	PP,TTYIN	;A SWITCH HAS BEEN DETECTED
	MOVSI	T,SWTBL-SWTBLE	;SET UP NEG. COUNT FOR TABLE SEARCH
	CAIE	C,@SWTBL(T)	;FOUND CHAR? (INDIRECT=INDEX=0)
	AOBJN	T,.-1
	JUMPGE	T,GETSW1	;JUMP IF NOTHING FOUND
	TDOA	FR,SWTBL(T)	;TURN ON FLAG (GARBAGE IN RIGHT)
GETSWE:	SETOM	QSW		;SET /Q SEEN
	JRST	GETIOC		;GET NEXT PART OF COMMAND

GETSW1:	CAIN	C,"H"		;REQUEST FOR HELP?
	JRST	HELP		;YES
	CAIN	C,"Q"		;/Q?
	JRST	GETSWE		;YES
	SETZ	T,		;START WITH ZERO
	PUSHJ	PP,GETOC2	;BUILD OCTAL NUMBER IN T
	JUMPE	T,CTLSER	;ERROR IF NO NUMBER
	MOVEM	T,NUMLIN	;SAVE AS # EXTRA LINES TO MATCH (AFTER 1ST)
	CAIE	C,"L"		;TEST FOR LIMIT SWITCHES
	CAIN	C,"U"		;EITHER UPPER OR LOWER
	JRST	SETLIM		;FOUND ONE
	JRST	GETIC1

SETLIM:	CAIE	C,"L"		;TEST WHICH LIMIT
	SKIPA	UPPER,T		;UPPER LIMIT /0000U
	MOVE	LOWER,T		;LOWER LIMIT /0000L
	JRST	GETIOC		;GET MORE COMMAND

SWTBL:	SSWBIT,,"S"		;/S SUPPRESSES COMPARING SPACES, TABS
	CSWBIT!SSWBIT,,"C"	;/C DON'T COMP. COMMENTS OR SPACING
	ALLSW,,"B"		;/B ALLOWS COMPARING BLANK LINES
	ASWBIT,,"A"		;/A COMPARE LINE BY LINE (ASCII)
	WSWBIT,,"W"		;/W COMPARE WORD FOR WORD (BINARY)
	XSWBIT,,"X"		;/X EXPAND SAV FILE FIRST (BINARY)
	USWBIT+ALLSW,,"U"	;/U MANUAL UPDATE MODE
SWTBLE:		;END OF TABLE

GETPP:	PUSHJ	PP,GETOCT	;BUILD THE PROJ,PROG NUMBER
	CAIE	C,","
	JRST	CTLSER
	HRLZ	ACPPN,T		;PUT PROJ NUMBER IN LEFT HALF
	PUSHJ	PP,GETOCT
	CAIE	C,"]"
	JRST	CTLSER
	HRR	ACPPN,T		;PUT PROG NUM IN RIGHT HALF
	JRST	GETIOC		;CONTINUE COMMAND SCANNING

GETOCT:	MOVEI	T,0		;BUILD AN OCTAL NUMBER
GETOC1:	PUSHJ	PP,TTYIN
GETOC2:	CAIL	C,"0"
	CAILE	C,"7"
	POPJ	PP,		;RETURN ON A NON OCTAL DIGIT
	LSH	T,3
	ADDI	T,-"0"(C)
	JRST	GETOC1
;CREATE PAGE HEADER FOR LISTING FILES CONSISTING OF:
	;DEVICE:FILENAME.EXT[PROJ,PROG]	CREATED: MMHH DAY-MONTH-YEAR

HEADER:	HRLI	T,440700	;MAKE ADDRESS INTO BYTE POINTER
	MOVEM	T,HPOINT	;AND SAVE FOR FUTURE USE
	MOVE	T,INDEV1	;GET DEVICE NAME AND PRINT
	PUSHJ	PP,HEDST6
	MOVEI	C,":"
	PUSHJ	PP,HEDDPB	;DEPOSIT COLON INTO HEADER
	MOVE	T,INDEV1
	DEVCHR	T,		;GET DEVICE CHARACTERISTICS
	TLNN	T,(1B15)	;DOES DEVICE HAVE A DIRECTORY?
	JRST	HEAD8		;NO, DON'T BOTHER WITH FILENAME, ETC.
	SKIPE	T,INDIR1
	PUSHJ	PP,HEDST6	;IF FILE NAME NOT NULL, PRINT IT
	HLLZ	T,INDIR1+1	;ISOLATE EXTENSION
	JUMPE	T,HEAD2		;DON'T PRINT IF EXTENSION NULL
	MOVEI	C,"."
	PUSHJ	PP,HEDDPB	;PUT DOT INTO HEADER
	HLLZ	T,INDIR1+1
	PUSHJ	PP,HEDST6	;PRINT EXTENSION
HEAD2:	SKIPN	T,INDPPN	;IS PROJ,PROG 0,0?
	JRST	HEAD4		;YES
	MOVEI	C,"["		;NO, PRINT IT
	PUSHJ	PP,HEDDPB
	HLRZ	T,INDPPN
	PUSHJ	PP,HED8		;PRINT PROJECT #
	MOVEI	C,","
	PUSHJ	PP,HEDDPB
	HRRZ	T,INDPPN
	PUSHJ	PP,HED8		;PRINT PROGRAMMER #
	MOVEI	C,"]"
	PUSHJ	PP,HEDDPB

HEAD4:	MOVE	T,[ASCII /	crea/]
	PUSHJ	PP,HEDST7	;PUT "	CREA" INTO BUFFER
	MOVE	T,[ASCII /ted: /]
	PUSHJ	PP,HEDST7
	LDB	T,[POINT 11,INDIR1+2,23]	;GET CREATION TIME
	IDIVI	T,^D60		;CHANGE TO HOURS AND MINUTES
	PUSH	PP,T+1		;SAVE MINUTES
	PUSHJ	PP,HED10	;PRINT HOURS
	POP	PP,T
	PUSHJ	PP,HED10	;PRINT MINUTES
	MOVEI	C," "
	PUSHJ	PP,HEDDPB	;PUT A SPACE AFTER THE TIME
HEDDAT:	LDB	T,[POINT 12,INDIR1+2,35]	;GET LOW 12 BITS OF DATE
	LDB	T+1,[POINT 3,INDIR1+1,20]	;GET HIGH 3 BITS OF DATE
	DPB	T+1,[POINT 3,T,23]		;MERGE THE TWO PARTS
	IDIVI	T,^D31		;STRIP OFF DAY OF MONTH
	PUSH	PP,T