Google
 

Trailing-Edge - PDP-10 Archives - BB-KL11K-BM_1990 - t20src/filcom.mac
There are 45 other files named filcom.mac in the archive. Click here to see a list.
TITLE	FILCOM   PROGRAM TO COMPARE FILES - V22A(123)
SUBTTL	BOWERING/DMN/TWE/DMN/LCR/LLN/ILG/MFB/MS/PY/BAH	16=OCT-89



;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1979,1981,1984,1986,1988,1990.
;ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.




	VFILCM==22		;VERSION NUMBER
	VUPDATE==1		;DEC UPDATE
	VEDIT==123		;EDIT LEVEL
	VCUSTOM==0

%%FLCV==<VCUSTOM>B2+<VFILCM>B11+<VUPDATE>B17+VEDIT

INTERNAL .JBVER
LOC <.JBVER==137>
EXP %%FLCV
RELOC	0

EXTERNAL	.JBFF,	.JBREL,	.HELPR


	SEARCH UUOSYM,MACTEN		;[74]
	.REQUEST REL:HELPER		;[72] Add the request for HELPER
	.DIRECTIVE	FLBLST		;[100]
	SALL				;[100]

	TWOSEG
	RELOC 400000	;[101] IF MOVED UP, CHANGE BLANK LINE IM MEMORY BIT

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1990. ALL RIGHTS RESERVED.
\; END COPYRIGHT MACRO
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

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==50	;LENGTH OF PUSH DOWN LIST(HELPER NEEDS MORE THAN 20)
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
EXEBIT==400000		;COMPARING EXE FILES IN PROGRESS

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

MATCH==3		;# LINES TO BE MATCHED
LPP==^D56		;LINES/PAGE

MAXSFD==7		;MAXIMUM NUMBER OF SFD'S ALLOWED
PTHADR==4		;OFFSET TO PATH BLOCK
PTHPPN==6		;OFFSET TO PPN IN BLOCK
PTHSFD==7		;OFFSET TO SFD IN BLOCK
SUBTTL	REVISION HISTORY

;START OF VERSION 20A
;17		ADD DATE75 HACK

;START OF VERSION 21
;20	(10181)	CHECK FOR DOUBLE = IN BINARY MODE
;21	(14149) FORCE /1L IF /U IS SEEN TO PRINT ONE LINE CHANGES
;		ONLY.  02-OCT-74, JNT.
;22	(12251) CHANGE WORD COUNT FIELD TO 36 BITS TO PROVIDE
;	        FOR FILES LONGER THAN 2048 DISK BLOCKS.
;23		MAKES FILCOM GET THE JOB'S PROJ.NUMBER IF ONLY
;		PROGR.NUMBER IS SPECIFIED, AND THE PROGR.NUMBER IF ONLY
;		PROJ.NUMBER IS SPECIFIED. 03-JAN-75, IB.
;24	(15168)	FIX ERROR MESSAGES FOR FILES NOT FOUND ETC.
;		ILG  29-JAN-75
;
;25	ADD SUPPORT FOR EXE FILE COMPARISONS
;	SEB	12-MAR-75
;26	change "foo: z" to be "foo: block 1" so low seg
;	won't be created
;	ig
;
;27	make "tty:=foo.exe" work correctly.
;	seb	may 6

;30	MAKE SURE THAT THE '/Q' SWITCH TAKES A QUICK EXIT WHEN
;	DIFFERENCES ARE FOUND.
;	SPR # 19411  29-APR-76	LCR.
;
;
;31	CLEAR FILCOM'S BUFFERS DURING INITIALIZATION ROUTINE,
;	TO AVOID GETTING "FILES ARE DIFFERENT" WHEN COMPARING
;	BINARY FILES UNDER ASCII MODE.
;	SPR # 10-19442	30-APR-76	LCR.
;
;32	FIX ADDRESS CALCULATION WHEN EXPANDING .SAV FILES.  WHEN
;	FILCOM FOUND ONE END-OF-FILE, IT COULD GET CONFUSED
;	ABOUT THE ADDRESSES IN THE OTHER FILE.
;	SPR # 10-19991,  27-JUL-76	LLN.
;
;33	CORRECT SOME PROBLEMS ASSOCIATED WITH LINE NUMBERS -- NAMELY,
;	IF SKIPPING BLANK LINES, ALSO SKIP LINES HAVING ONLY A LINE
;	NUMBER.  ALSO, HANDLE PAGE MARKS AND BASIC FILES (WHICH
;	DON'T ALWAYS HAVE TABS AFTER LINE NUMBERS) CORRECTLY
;	BY EATING THE CHARACTER AFTER A LINE NUMBER ONLY IF IT
;	IS A TAB.
;	SPR # 10-20234,  13-AUG-76	LLN.
;34	Try harder to find multiple-line matches in update
;	mode.  This involves varying NUMLIN as the two files are
;	read, if no /L is given by the user.  This gives FILCOM
;	the look-ahead capability lost by edit 21, without
;	reintroducing the same problems edit 21 fixed.
;	SPR # 10-20346,  15-Oct-76	LLN.
;
;35	ADD SUPPORT FOR SFD'S
;	NO SPR	16-DEC-76	ILG
;
;
;36	HAVE HEADER CONTAIN TRUE PATH INFORMATION
;	REGARDLESS OF TYPED IN COMMAND STRING
;	NO SPR  16-DEC-76	ILG
;
;37	COMPARE EXE FILES PROPERLY WHEN ONE FILE HAS DIFFERENT
;	MAP FROM THE OTHER AND THE SECOND IS SHORTER.
;	NO SPR  16-DEC-76	ILG
;
;40	RESERVED FOR DECSYSTEM20.
;
;41	DON'T WRITE A NULL FILE IF NO DIFFERENCES ARE ENCOUNTERED ON
;	A COMPARISON.
;	SPR # 21610	ILG	16-DEC-76
;
;42	ALLOW A NULL SPECIFICATION FOR EXTENSION ON THE OUTPUT SIDE
;	NO SPR	ILG	16-DEC-76
;
;43	Handle .EXE files which have a directory
;	entry which encompasses more than 1000 pages.
;	LLN, SPR # 10-21429, 12-Jan-77
;
;Make this version 21A.
;
;44	Consider carriage-return to be an EOL character
;	if it is not followed by LF, VT, or FF.  This
;	gets underlining right in update mode.
;	LLN, SPR # 10-22466, 22-Apr-77
;
;45	Exit when through processing a command if ^Z was used
;	to terminate it.  LLN, SPR # 10-22854, 2-Jun-77
;
;46	Make buffers for headers big enough to handle the
;	longest possible filespecs.  LLN, SPR # 10-23644,
;	12-Sep-77
;
;47	Make all the month names 3 characters and lowercase.
;	LLN, SPR # 10-23642, 3-Oct-77
;
;50	Accept a line-terminating character in lieu of a
;	closing right-bracket.  LLN, SPR # 10-23642, 4-Oct-77
;
;51	Keep creation dates in the headers lined up.  Note:
;	this edit supercedes edit 46.  LLN, 5-Oct-77,
;	SPR # 10-23642.
;
;52	Always produce a file in update mode, even if
;	there are no differences.  LLN, SPR # 10-23873,
;	9-Dec-77
;
;53	If second input filespec was a magtape, and /W,
;	/E, or /X was specified, no comparison was done and
;	the first file was merely listed.  LLN, 15-Dec-77,
;	SPR # 10-23863.
;
;54	Finish teaching FILCOM about large (more than
;	a halfword) addresses in EXE files.
;	LLN, SPR # 10-25025, 13-Feb-78
;
;55	Prevent sporadic bogus differences with line-numbered
;	files.  LLN, SPR # 10-25063, 7-Apr-78
;
;56	EXE files were always being expanded, even if you
;	said /W.  Also, FILCOM was not skipping over the entry
;	vector portion of the directory properly, resulting
;	in the ?NOT IN EXE FORMAT message.  LLN, 12-Oct-78,
;	SPR # 10-26742
;
;57	Stop reading binary files as soon as the user-specified
;	upper limit is reached.  LLN, no SPR, 8-Jan-79
;
;60	Make this version 21B for TOPS20 release.  Fix address
;	calculation for EXE files so that bogus differences are
;	not reported.  LLN, no SPR, 30-Jan-79
;
;61	Make FILCOM recognize the extension UNV and use word compare
;	instead of the ASCII line compare.	MFB,	5-May-80
;	SPR # 10-28165
;
;62	Make the year in the header line of the output standard format
;	(i.e. YY not YYYY). MFB, 5-May-80, SPR # 10-27778
;
;63	Accept memory location greater than 777777 and print it
;	in the full word instead of regular halfword
;	typeout also jump to the new page first time to help readability
;	MS, 22-Jan-81	SPR 10-30551
;
;64	Deleted by edit 70.
;	Do not compare blank line which has spaces, tab or ";" followed
;	by CRLF on C and S switch
;	MS, 19-May-81, SPR #20-16170
;
;65	Deleted by edit 71.
;	Set the flag EFN to check the validity of the next character
;	after processing a switch.
;	MS, 21-Aug-81, SPR #10-31477
;
;66	Deleted by edit 70.
;	Correct edit 64.  Check the characters at GLINE3.
;	MS, 26-Aug-81, SPR 10-31463
;
;67	Fix off by one bug which will make two .EXE files which are
;	identical except for the directories appear very different.
;	PY, 16-Sep-81	SPR 20-16787
;
;70	Delete edits 64 and 66.
;	BAH, 10-Nov-81, SPR 10-31714.
;
;71	Delete edit 65; it broke command processing if a switch is specified
;	first.  Fix the original problem which allowed switches to be typed
;	in the middle of a filename.  This edit also reports if an unknown
;	switch has been typed and if more than one filename or extension has
;	been typed.  Therefore, some previously successful commands may now
;	produce an error message and terminate the process.
;	BAH, 21-Dec-81, SPR 10-31822
;
;72	Add a .REQUEST HELPER so loading isn't special cased.
;	BAH, 12-Jan-82.
;
;73	Make FILCOM recognize the extensions ATR, DBS, QUD, SCH, APL, OVL, and
;	SYM to use word compare instead of ASCII.
;	BAH, 12-Jan-82, SPR 10-32024.
;
;74	None.	2-Nov-82. 	BAH.
;	Search UUOSYM and MACTEN.  Then add big buffer open bit.  Also clean up
;	listing a bit for readability.
;
;75	None.	2-Nov-83.	BAH.
;	Extend edit 71 to report an error if a double extension is typed,
;	(TT:=FOO.BAR.BAR,FOO.BAR).  FILCOM LOOKUPed the file BAR.BAR.
;
;Start version 22
;76	None. 6-Jun-84.		TL.
;	Merge code from ADP to add /O support.  Modify it so output file
;	is same as before if no /O.  (For SIRUS, others who read FILCOM output.)
;
;77	None. 25-Jul-84.	TL.
;	Fix /O/B test for page break.
;
;100	None. 25-Jul-84.	TL.
;	More of edit 74.  Also, deal with CCL RUN UUOs.
;
;101	None. 25-Jul-84.	TL.
;	Try to get /U without /L to be a bit brighter.
;102	10-34246	31-Jul-84	BAH
;	If the right square bracket of the second input file spec is missing
;	in the command "=A.B[C,D,E],A.B[F,G]", FILCOM gives a LOOKUP error 23.
;	Edit 50 did not catch all cases.
;
;103	Eklund	8-Aug-84	TL
;	/O format didn't pass muster.  I'd rather switch than fight.
;
;104	WXD	28-Aug-84	TL
;	/O didn't count label offsets right in all cases.  Throw
;	out the ADP method, and invent our own bugs.
;
;105	TARL	18-Sep-84	TL
;	Revoke edit 41 if /T specified.  This makes monitor builds on
;	the -10 work better.
;
;106	RAP	19-Sep-84	TL
;	Fix obscure Ill mem ref in edit 101.
;
;107	10-35153	10-Apr-85	TL
;	101 produces yet another obscure Ill mem ref.
;
;110	10-35161	14-May-85	TL
;	101 didn't quite get blank line suppression right.  Deletion
;	in /U mode isn't pretty.
;
;111	KBY		3-Jun-85	TL
;	New HELPER needs more stack.  Increase it.
;
;112	None.	9-Aug-85	BAH
;	Do copyrights.
;
;113	None.	12-Sep-85	BAH
;	FILCOM compares too many job data area locations.  Do not compare
;	locations 0-40, 42, 43, 45-73, 77-111, 113, 114, and 132 inclusive.
;	Also FILCOM had a bug where it was erroneously comparing location 73.
;
;114	Deleted by edit 120.
;		868772	03-Feb-86	DRB
;	/1L doesn't work.  Apparent fencepost error.
;
;115	KBY/RDH	7-Apr-86	TL
;	/O very rarely gets the base tag wrong.  For example, if file 2 has
;	two insertions that are far enough apart to be distinct, but closer
;	than the length of the first insertion, the wrong tag would be used.
;	Edit 110 broke some cases of a difference in progress at EOF, 
;	causing loops.
;
;116	10-33206	16-Sep-86	BAH
;	Edit 101 did not take line sequenced blank lines when setting 
;	the 400K bit in the line header word.
;
;117	10-JMF-350987	25-Sep-87	TL
;	Add /I - Do case-blind comparisons.
;
;120	10-36057	11-Jan-88	BAH
;	Edit 114 broke /1L.  Remove the edit.  Since all traces of what edit
;	114 was trying to fix are gone, wait for another SPR to reproduce
;	that problem.
;
;121	10-36057,10-36057AI	15-Jun-88	JJF
;	Change sense of test used to see if we are in /L mode or not.
;	Edit 120 went too far in the clean-up.
;
;122	10-36057,10-36057AI,10-36057A	8-Sep-88	JJF
;	Another battle with /1L.  Check specially in the multi-line match
;	code to see if /1L was wanted.  If so, don't bother checking
;	how many extra multi-line matches were found, just undo the line
;	pointers and print out the differences.
;
;123	None		16-Oct-89	DPM
;	Remove reference to ".MCRV."; an unimplemented MACRO pseudo-op.
;	END OF REVISION HISTORY.
;
SUBTTL	FILE COMPARE

;PUT ONCE-ONLY INITIALIZATION HERE.
FILCOM:	JFCL			;[100] IN CASE OF CCL RUN
	SETZM	XITFLG		;[45] ^Z HAS NOT BEEN TYPED
	JRST	COMPGO		;[45]   SO GO PROCESS A COMMAND.
COMP:	CLOSE	CTL,
	RELEAS	CTL,
	RELEAS	IN1,
	RELEAS	IN2,
COMPGO:	SKIPE	XITFLG		;[45] EXIT BECAUSE OF ^Z?
	EXIT	1,		;[45] YES, A CONTINUE WILL RESTART
	RESET
	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		;UPPER LIMIT TO BE ZEROED
	MOVE	PPSET		;[31] ZERO OUT
	MOVEM	@.JBFF		;[31]	FIRST BUFFER POS.
	HRRZ	.JBFF		;[31] BEGINING OF AREA TO CLEAR
	ADDI	1		;[31] SET THE 'FROM' PART FOR THE 'BLT'
	CAML	.JBREL		;[31] IS THIS NECESARY?
	JRST	CMPGO1		;[31] NO, CONTINUE INITIALICING REST
	HRL	.JBFF		;[31] SET LH FOR 'BLT'
	BLT	@.JBREL		;[31] AND DO IT.
CMPGO1:	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 *
	SETZM	FILCNT		;CLEAR FILE COUNTER FOR NAME ROUTINE
	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:	PUSHJ	PP,EAT		;[45] CLEAR OUT THE BAD LINE
	JSP	T,ERROUT
	ASCIZ	/?Command error/

CTLSE1:	SETZM	OUTEXT		;ASSUME NO OUTPUT EXTENSION GIVEN
	CAIN	ACDEL,"."	;DOT THERE?
	SETOM	OUTEXT		;YES,SO THERE IS AN EXTENSION
	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

	AOS	FILCNT		;INCREMENT FILE COUNT
	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
	CAIG	C,.CHESC	;[20] [100] BUT ONLY ALLOW VALID EOF
	CAIGE	C,.CHLFD	;[20] [100] IF GREATER THAN ESC OR LESS THAN FF
	JRST	CTLSER		;[20] [100] GIVE ERROR
	CAILE	C,.CHCRT	;[20] [100] ONLY ALLOW LF, VT, FF, CR
	CAIL	C,.CHCNZ	;[20] [100] ^Z AND ESC
	CAIA			;[20] TO END LINE
	JRST	CTLSER		;[20] OTHERWISE GIVE 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,.IOASL	;[100] SET UP INPUT DATA MODE
	TXO	0,UU.LBF	;[74] USE BIG BUFFERS
				;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	ERRIA1		;[24]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 PROGER IN DIRECT BLOCK
	MOVEM	ACPPN,INDPPN	;SAVE P,P AGAIN

	MOVEI	0,.IOASL	;[100] INIT DEVICE IN ASCII LINE MODE
	TXO	0,UU.LBF	;[74] USE BIG BUFFERS
	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	ERRIA2		;[24]
	MOVEI	T,HBUF2
	PUSHJ	PP,HEADER	;CREATE HEADER LINE- FILE #2

	TLNE	FR,ASCSW	;ASCII SWITCHES SEEN
	JRST	INICTL		;YES, LEAVE WELL ALONE
	SETZ	T,		;[53] RESET DEFAULT MODE
	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	IN2,.IOBIN	;[100] CHANGE TO BINARY MODE
NOINP2:	MOVEI	0,(POINT 36,,35)
	IOR	FR,T		;SET MODE BINARY
	SETSTS	IN1,.IOBIN	;[100]
	HRLM	0,INBUF1+1	;CHANGE FROM ASCII
	HRLM	0,INBUF2+1
INICTL:	MOVEI	0,.IOASC	;[100] INIT OUTPUT DEVICE
	TXO	0,UU.LBF	;[74] USE BIG BUFFERS
	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,
	TXNN	TT,DV.OUT	;[100]
	JRST	ERRONO		;[24]NO
	TXNE	TT,DV.TTY	;[100] 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
	SKIPL	OUTEXT		;OUTPUT EXTENSION GIVEN?
	SKIPE	OUTDIR+1	;OR ONE IMPLIED?
	SKIPA			;RIGHT, NO NEED FOR CHANGE
	MOVEM	ACEXT,OUTDIR+1	;USE DEFAULT
	ENTER	CTL,OUTDIR	;AND TRY TO ENTER OUTPUT FILE NAME
	JRST	ERROEF		;[24]
	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"
	SETOM	LSTSYM+SYMLIN	;[104] MAKE SURE BEGINNING OF FILE IS LINE 0
	TLNN	FR,USWBIT	;SEE IF UPDATE MODE
	JRST	MAINST		;NO
	SKIPN	LSEEN		;[21] SEE IF HAD /L
	SETOM	USWFLG		;[21],[34] NO, SET A FLAG
	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 DETECTED 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

	MOVE	W1,NUMLIN	;[34] Make a temp copy
	MOVEM	W1,TNMLIN	;[34]  in case we are updating
MAIN12:	PUSHJ	PP,COMPL	;NOW SEE IF WE CAN MATCH THAT LINE
	JSP	W1,MULTI	;FOUND 1 LINE MATCH- LOOK FOR MULTIPLE
	MOVE	T,F2		;[107] TOP ON OTHER FILE
	CAMLE	T,TOP1		;[107] IS IT LONGER THAN TOP ON THIS FILE?
	 MOVE	T,TOP1		;[107] YES, USE TOP OF THIS FILE
	CAME	F1,T		;[107] HAVE WE LOOKED FROM THE MISMATCHED LINE
				;[107] TO THE CURRENT LINE?
	 AOJA	F1,MAIN12	;[107] NO--UP LINE POINTER AND TRY AGAIN
	SETZ	F2,		;[107] HAVEN'T FOUND A MATCH THIS TIME
				;[107] NOW TRY IT THE OTHER WAY
MAIN14:	MOVE	T,F1		;[107] TOP ON OTHER FILE
	CAMLE	T,TOP2		;[107] IS IT LONGER THAN TOP ON THIS FILE
	 MOVE	T,TOP2		;[107] YES, USE TOP OF THIS FILE
	CAML	F2,T		;[107] LOOKED FAR ENOUGH? (THIS VERSION HAS
				;THE INEFFICIENCY MENTIONED IN THE LIBRARY
				;WRITE UP REMOVED- TWE)
	JRST	CHECK		;[34] Probably, check for /U
	PUSHJ	PP,COMPL
	JSP	W1,MULTI	;LOOK FOR MULTI LINE MATCH
	AOJA	F2,MAIN14	;INDEX AND LOOK SOME MORE

CHECK:	SKIPN	USWFLG		;[34] Making special /U checks?
	JRST	MAIN10		;[34] No, looked far enough
	SOSGE	TNMLIN		;[34] Lines to check this time
	JRST	MAIN10		;[34] None, quit
	JRST	MAIN12		;[34] Try MULTI again


;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,PRNTXT	;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:	MOVEM	F1,TEMPF1	;[115] FAKE OUT MULT8
	MOVEM	F2,TEMPF2	;[115] ...JUST IN CASE WE END UP THERE
	JUMPGE	F1,MULT8	;PRINT DIFFERENCES IF EITHER BUFFER
	JUMPGE	F2,MULT8	;  HAS ANY LINES IN IT
				;NO LINES ANYWHERE
	SKIPE	OFSSWT		;[103] /O?
	 SKIPN	W1,NOHDR	;[103] DID ONE FILE END SHORT?
	JRST	FIN1		;[103] NO
	TRNN	W1,-1		;[103] YES, FILE 1?
	 PUSHJ	PP,PRNSEP	;[103] YES - SEP GOES AFTER EOF

FIN1:	MOVEI	W1,[ASCIZ /|
/]
	TLNE	FR,USWBIT	;"UPDATE" MODE?
	SKIPN	DIFFLG		;YES
	JRST	FIN2		;NO
	PUSHJ	PP,PPRINT	;PRINT MESS. IF 2ND FILE IS TRUNCATED 1ST FILE
FIN2:	MOVEI	T,[ASCIZ /No differences encountered/]
	SKIPN	ERRCNT		;ANY DIFFERENCES?
	JRST	[ TLNN FR,USWBIT;[52] IF WE ARE UPDATING
		   SKIPE OPTSWT	;[105] OR USER WANTS FILE ANYHOW
		  JRST	FIN3	;[105] WE WANT TO KEEP THIS
		  CLOSE CTL,1B30;[52] DON'T PRODUCE AN OUTPUT FILE
		  JRST FIN3 ]	;CONTINUE WITH MESSAGES
	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:	SKIPGE	NUMLIN		;[114][120][121] 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
MULT20:	SKIPN	USWFLG		;[101] FUNNY /U?
	 JRST	MULT44		;[101] NO
	PUSHJ	PP,SETP		;[101] POINT TO LINES
	MOVEI	W3,400K		;[101] BLANK LINE IN MEMORY BIT
	TDNE	W3,0(W2)	;[101] IS THIS ONE?
	 JRST	MULT41		;[101] YES, SKIP IT
	TDNN	W3,0(W1)	;[101] CHECK THE OTHER FILE
	 JRST	MULT44		;[101] NOPE
	TRZA	FR,-1		;[101] GET ANOTHER LINE
MULT41:	 HRRI	FR,1		;[101] FROM SOME FILE
	SETOM	GETCNT		;[101]
	SETOM	GETFIL		;[101]
	PUSHJ	PP,GLINE	;[101] READ
	SKIPGE	GETCNT		;[101] GOT ONE?
	 JRST	MULT4		;[101] NO, EOF
	JRST	MULT20		;[101] YUP, SEE IF ONE OF THEM IS BLANK

MULT44:	PUSHJ	PP,COMPL	;COMPARE THEM
	JRST	MULT6		;MATCH, TEST MULTI COUNTER
MULT4:	MOVE	F1,TEMPF1	;NO MATCH, RESET REGS
	MOVE	F2,TEMPF2
	SKIPG	T,USERL		;[122] USER-TYPED /L?
	 JRST	MULT45		;[122] NO
	CAIG	T,1		;[122] YES - IS IT /1L?
	 JRST	MULT8		;[122] YES - PRINT DIFFERENCES
MULT45:	JRST	@RTNTMP		;[122] RETURN TO WHERE WE GOT TO MULTI FROM

MULT6:	AOS	W1,NUMTMP	;INDEX MULTI-LINE COUNTER
	SKIPN	USWFLG		;[34] Update mode check?
	JRST	MULT64		;[34] No, regular one
	CAMGE	W1,TNMLIN	;[34] Test for end
	JRST	MULT2		;[34] Not yet, keep trying
	JRST	MULT66		;[34] Done
MULT64:	CAMGE	W1,NUMLIN	;[34] TEST FOR END
	JRST	MULT2		;TEST NEXT TWO
MULT66:	EXCH	F1,TEMPF1	;[34] [110] RESET TO 1ST COMPARISION
	EXCH	F2,TEMPF2	;[110]
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 POINTER WILL
;BE POINTING TO THE FIRST TWO LINES AFTER THE MATCHING LINES

	MOVE	F1,TEMPF1	;[110] CAUSE MOVEUP TO FLUSH ALL THE
	MOVE	F2,TEMPF2	;[110]   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))
;			BIT 18 OF WORD COUNT MEANS BLANK LINE IN CORE
;	   (/O) SYMBOL DEFINITION BLOCK FOR THIS LINE (5 WORDS)
;	   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+1,[TRZ  T,400K]	;[101] [106]
	MOVE	TT+3,[JRST SETON2]	;[101] SET UP AC
	MOVE	TT+2,.+1	;[101] SET UP AC
	SOJGE	W3,TT
			;TT/	ADD T,(T)	;ADD IN WORD COUNT FOR LINE
			;TT+1/	TRZ T,400K	;[101] CLEAR BLANK LINE BIT
			;TT+2/	SOJGE W3,TT	;MORE LINES LEFT?
			;TT+3/	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,

;[115] FIX A BYTE POINTER TO ACCOUNT FOR /O BLOCK

FIXBP:	 TRNN	FR,-1		;DON'T IF NOT FILE 0
FIXBPD:	SKIPN	OFSSWT		;ONLY IF /O
	 POPJ	PP,		;WORDS AREN'T THERE TO SKIP
	HRRI	W1,SSBLTE(W1)	;BUMP BYTE POINTER PAST SYMBOL BLOCK
	POPJ	PP,		;DONE
;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
	JUMPL	F2,[HRLZS DIFFLG	;[110] YES, INSERTION ?
		    POPJ PP,]	;[110] YES, REMEMBER THAT
	SETOM	TEMP		;INIT LINE COUNTER
	SOS	F2		;[110] BACK UP A LINE
	PUSH	PP,F2		;[110] SAVE
UPDAT1:	AOS	F2,TEMP		;[110] GET NUMBER OF NEXT LINE
	PUSHJ	PP,SETONE	;[110] NOW FETCH BYTE POINTER
	CAMLE	F2,(PP)		;[110] DONE?
	 JRST	UPDAT3		;[110] YES
	MOVEI	C,0		;[100] [110] PRINT VERTICAL BAR IF
	SKIPN	DIFFLG		;  "DIFFERENCE FLAG" IS SET, OR IF
	 JRST	UPDAT2		;  MORE THAN ONE LINE HAS BEEN LOOKED AT
	MOVEI	T,400K		;[110] UNLESS LINES ARE BLANK
	TDNE	T,(W2)		;[110] ...
	 JRST	UPDAT2		;[110] (THEY ARE)
	SETOM	DIFFLG		;[110] NOTE AT LEASE ONE VERTICAL BAR
	MOVEI	C,"|"		;[110]
UPDAT2:	PUSHJ	PP,UPDAT5	;[110] PRINT DIFFERENCE CHAR AND LINE
	JRST	UPDAT1		;[110] CONTINUE

UPDAT3:	MOVEI	C,0		;[110] DONE, DEFAULT TO NO CHANGE
	SKIPN	DIFFLG		;[110] IF NONE,
	 JRST	UPDAT4		;[110]  ASSUMPTION WON
	MOVEI	T,400K		;[110] SOME DIFFERENCE, BLANK LINE?
	TDNE	T,(W2)		;[110] IS IT?
	 JRST	[SKIPL	DIFFLG	;[110] YES, BLANK AND NO PREV "|"?
		  MOVEI C,"o"	;[110]        YES, DELETION
		 JRST	UPDAT4]	;[110] NO, BLANK + PREV "|", NO "|" HERE
	MOVE	T,DIFFLG	;[110] SEE WHAT KIND OF DIFFERENCE
	MOVEI	C,"o"		;[110] ASSUME DELETION
	 CAME	T,[-1]		;[110] IF END OF ORDINARY DIFFERENCE, "|"
	TLNN	T,-1		;[110] WAS IT A DELETION?
	 MOVEI	C,"|"		;[110] AN ORDINARY CHANGE.
UPDAT4:	PUSHJ	PP,UPDAT5	;[110] PRINT THE LINE
	SETZM	DIFFLG		;[110] NO DIFFERENCES KNOWN NOW
	POP	PP,F2		;[110] RESTORE F2
	AOJA	F2,CPOPJ	;[110] RESUME SCAN

UPDAT5:	PUSHJ	PP,PCHART	;[110] PRINT DIFFERENCE FLAG IF ANY
	MOVEI	C,.CHTAB	;[100] PRINT A TAB
	PUSHJ	PP,PCHAR
	MOVE	W1,W2		;GET BYTE POINTER INTO W1
	PUSHJ	PP,PRINT	;GO PRINT LINE
	MOVEI	C,.CHCRT	;[100]
	PUSHJ	PP,PCHAR	;PRINT CARRIAGE RETURN
	ILDB	C,W1		;GET LINE TERMINATING CHARACTER
	JRST	PCHAR		;[110] PRINT IT AND RETURN
;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
	CAMLE	W1,TOP(FR)	;[76] HAVE WE GONE OVER THE TOP?
	JRST	GLINEB		;[76] NO LINE -- GO GET ONE
	JRST	GLNXIT		;[104] GOT IT IN CORE, GO AWAY

GLINEA:	TLZ	C,400000	;[76] COUNT BLANK LINES
	TRNN	FR,-1		;[103] ONLY COUNT FOR FILE 1
	 CAIN	C,.CHFFD	;[76] [103] BUT NOT FORM-FEEDS
	CAIA			;[103] FILE 2 OR FFD
	 AOS	LSTSYM+SYMLIN	;[76] [104] COUNT LINES PAST SYMBOL
	SKIPA			;[76]

GLINEB:	SOS	F1(FR)		;NOT CLEAR YET THAT A NEW LINE EXISTS
	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,GLINEA	;[76] 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
	HLLZ	W2,PAGNUM(FR)	;[101] PICKUP PAGE # AT BEGINNING OF LINE
	SKIPGE	C		;[101] BLANK LINE?
	 TRO	W2,400K		;[101] YES, REMEMBER THE FACT
	MOVEM	W2,(W1)		;[101] SAVE WITH THIS LINE
	PUSHJ	PP,FIXBP	;[115] ADJUST TO TEXT AREA IF NESCESSARY
	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
	IOR	W1,(W3)		;[101] PRESERVE BLANK LINE BIT
	SKIPN	USWFLG		;[116] FUNNY /U MODE?
	JRST	GLINE4		;[116] NO. DON'T CHECK FOR LINE-SEQUENCED LINES
	MOVE	W2,1(W3)	;[116] GET THE FIRST WORD OF THE LINE
	TRNN	W2,1B35		;[116] IS IT A LINE-SEQUENCED LINE?
	JRST	GLINE4		;[116] NO. NO NEED TO CHECK IF THE LINE IS BLANK
	LDB	W2,[POINT 7,2(W3),6]	;[116] YES. GET THE FIRST CHARACTER
					;[116] AFTER THE LINE SEQUENCE NUMBER
	CAIE	W2,.CHTAB	;[116] IF IT'S A TAB, CHECK FURTHER
	JRST	GLINE4		;[116] OTHERWISE ASSUME NOT A BLANK LINE
	LDB	W2,[POINT 7,2(W3),13]	;[116] GET THE NEXT CHARACTER
	SKIPN	W2		;[116] CHECK FOR A BLANK LINE
	TRO	W1,400K		;[116] SIGNIFY THAT THIS IS A BLANK LINE
GLINE4:	HRRM	W1,(W3)		;SAVE WORD COUNT IN BUFFER
;SEE IF TEXT JUST READ IN IS A LINE-NUMBERED BLANK LINE
	TLNE	FR,ALLSW	;[33] SKIPPING BLANK LINES?
	JRST	GLEXIT		;[33] NO, DON'T CHECK TEXT
	PUSHJ	PP,SETONE	;[33] GET POINTER TO TEXT
	PUSHJ	PP,FIXBP	;[115] ADJUST FOR POSSIBLE SYMBOL BLOCK
	MOVE	W1,W1(FR)	;[33] PUT IN KNOWN PLACE
	MOVEI	W3,1		;[33] SET UP LINE NUMBER BIT
	TDNN	W3,1(W1)	;[33] IS IT SET?
	JRST	GLEXIT		;[33] NO, TEXT IS OK
	AOS	W1		;[33] YES, SKIP LINE NUMBER
	ILDB	T,W1		;[33] GET FIRST CHARACTER
	JUMPE	T,BLANK		;[33] IT'S NULL, LINE IS BLANK
	CAIE	T,.CHTAB	;[33] [100] IF A TAB, CHECK FURTHER
	JRST	GLEXIT		;[33] 
	ILDB	T,W1		;[33]  SO GET NEXT CHARACTER
	JUMPN	T,GLEXIT	;[33] IF NOT NULL, LINE IS REALLY THERE
BLANK:	SOS	F1(FR)		;[33] NO LINE; DECREMENT COUNT
	MOVEI	C,.CHLFD	;[104] THIS WASN'T A PAGE MARK
	JRST	GLINEA		;[33] [104] GET ANOTHER LINE
GLEXIT:	 SKIPE	OFSSWT		;[115] SKIP IF NOT /O
	TRNE	FR,-1		;[115] DON'T COPY SYMBOL UNLESS FILE 0
	 JRST	GLNXIT		;[115] DON'T COPY
	PUSHJ	PP,GLSYMB	;[104] LINE IS NOW IN - GET A SYMBOL
	HRRZ	W1,WCADR	;[115] GET START OF LINE
	AOJ	W1,		;[115] POINT TO SYMBOL BLOCK
	HRLI	W1,LSTSYM	;[115] PUT CURRENT SYMBOL THERE
	HRRZ	W2,W1		;[115] SAVE COPY OF DESTINATION
	BLT	W1,SSBLTE-1(W2)	;[115] ONWARDS
GLNXIT:	PUSHJ	PP,SETONE	;[101] FIND LINE POINTERS
	MOVE	W1,W1(FR)	;[101] ONLY THE ONE FOR CURRENT FILE
	MOVE	W1,0(W1)	;[101] CHECK BLANK BIT IN HEADER
	TRNE	W1,400K		;[101] TO SEE IF TO BE IGNORED
	 SKIPN	USWFLG		;[101] BUT ONLY IN FUNNY/U MODE
	CAIA			;[101] DON'T IGNORE
	 JRST	GLINE		;[101] DO
	AOS	GETCNT		;INDEX # LINES FOUND
	HRRZM	FR,GETFIL	;SAVE # OF THIS FILE
	POPJ	PP,		;[104] DONE.
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
	PUSHJ	PP,NOROOM	;[55] NO ROOM IN THE INN
	HLRZM	C,1(W1)		;PUT BIT17 INTO BIT35 (FOR SEQUENCE  #)
	POPJ	PP,
;[76] HERE TO SEE IF THE CURRENT LINE HAS A SYMBOL DEFINITION (FOO:)

GLSYMB:	SKIPE	OFSSWT		;[104] IF NOT /O
	 TRNE	FR,-1		;[104] OR THIS IS FILE 2
	POPJ	PP,		;[104] DO NOTHING
	PUSHJ	PP,SETONE	;[76] SET W1 TO CURRENT LINE'S TEXT
	PUSHJ	PP,FIXBPD	;[115] ADJUST FOR HEADER
	MOVE	W2,[POINT 7,PSYMB] ;[76] WHERE WE CAN BUILD IT INTO
	SETZM	PSYMB		;[76] CLEAR IT OUT
	SETZM	PSYMB+1		;[76]
	MOVEI	W3,^D10		;[76] ARBITRARY MAX SYMBOL LENGTH OF 10 CHARACTERS
	SETZ	TT,		;[76] START WITH NO NNN$ LABEL SEEN

GLSY.1:	ILDB	T,W1		;[76] FIRST EAT LEADING SPACES AND TABS
	CAIE	T,.CHTAB	;[76]
	CAIN	T," "		;[76]
	JRST	GLSY.1		;[76]
	SKIPA			;[76]  THEN SKIP FIRST ILDB WITH NON-SPACE

GLSY.2:	ILDB	T,W1		;[76] SCAN THROUGH A SYMBOL
	JUMPE	T,GLSY.N	;[76] [104] IF NO : BEFORE EOL, NO SYMBOL

	CAIL	T,"a"		;[76] LOWER CASE?
	CAILE	T,"z"		;[76]
	SKIPA			;[76] NO
	SUBI	T,"a"-"A"	;[76] YES, CONVERT TO UPPER CASE
	JUMPG	TT,GLSY.3	;[76] IF HAVE ALREADY SEEN A LETTER,
				;[76] THEN CONTINUE BUILDING SYMBOL
	CAIL	T,"0"		;[76] A NUMBER?
	CAILE	T,"9"		;[76]
	JRST	GLSY.3		;[76] NO, LOOK FOR LETTER
	AOJL	TT,[MOVEI TT,1	;[76] IF HAVE ALREADY SEEN 999$ THEN SYMBOL IS SCREWY
		    JRST  GLSY.3] ;[76] SO JUST ACCUMULATE STANDARD SYMBOL
	SETO	TT,		;[76] MARK THAT HAVE SEEN DIGIT
	JRST	GLSY.S		;[76] AND STORE CHARACTER INTO SYMBOL

GLSY.3:	CAIE	T,"$"		;[76] COULD IT BE A LOCAL PDP11 LABEL
	JRST	GLSY.4		;[76] NO, KEEP BUILDING LABEL
	AOJN	TT,[MOVEI TT,1	;[76] IS PDP11 LABEL IF HAVE SEEN ONLY DIGITS
		    JRST  GLSY.S] ;[76] HAVEN'T, SO JUST BUILD SCREWY LABEL
	HRREI	TT,-2		;[76] MARK THAT HAVE SEEN 999$ LABEL
	JRST	GLSY.S		;[76] AND GO STORE "$" INTO LABEL
GLSY.4:	CAIE	T,"."		;[76] IS THIS ONE OF THE SPECIAL SYMBOL
	CAIN	T,"%"		;[76]  CHARACTERS?
	JRST	GLSY.S		;[76] YES, GO STORE INTO LABEL
	CAIL	T,"A"		;[76] IS IT A LETTER?
	CAILE	T,"Z"		;[76]
	SKIPA			;[76] NO
	JRST	GLSY.S		;[76] YES, GO STORE INTO LABEL
	CAIN	T,":"		;[76] THE END OF A SYMBOL DEFINITION?
	JRST	GLSY.E		;[76] YES, GO END THIS LABEL
	JRST	GLSY.N		;[76] [104] MUST NOT BE A LABEL

GLSY.S:	IDPB	T,W2		;[76] HAVE ANOTHER SYMBOL CHARACTER, BUILD SYMBOL
	SOJG	W3,GLSY.2	;[76] BUT ONLY UP TO 10 CHARACTERS
	JRST	GLSY.N		;[76] [104] MUST NOT BE A SYMBOL

	;HERE, WE HAVE A SYMBOL.  FIGURE OUT WHICH SORT, AND STORE IT.

GLSY.E:	HRRZ	W1,DOLPTR	;[76] [103] FIRST TRY FOR 11 LOCAL LABEL
	AOJL	TT,GLSY.6	;[76] IT IS IF SWITCH WAS -2
	SETZM	0(W1)		;[76] OTHERWISE IT'S NOT, FORGET ANY FROM
	SETZM	1(W1)		;[76]  PREVIOUS LOCAL SYMBOL BLOCK
	HRRZ	W1,SYMPTR	;[76] [103]  AND SWITCH TO SYMBOL POINTER
GLSY.6:	MOVE	T,PSYMB		;[76] COPY SYMBOL TO WHEREEVER WE NEED IT
	MOVEM	T,0(W1)		;[76]
	MOVE	T,PSYMB+1	;[76]
	MOVEM	T,1(W1)		;[76]
	SETOM	LSTSYM+SYMLIN	;[76] [103] [104] RESTART LINES SINCE SYMBOL COUNT

	;HERE TO ACCOUNT FOR THIS LINE

GLSY.N:	PUSHJ	PP,SETONE	;[77] POINT TO LINE AGAIN
	HLRZ	T,SSBLTE+1(W1)	;[76] [115] GET THE FIRST DATA WORD OUT
	TRZ	T,<BYTE (7)0,0,.CHDEL>_-^D18 ;[76] LESS THE PART OF THE THIRD BYTE
	CAIE	T,(BYTE (7).CHNUL,.CHFFD) ;[76] [103] UNLESS THIS IS A BLANK LINE W/FFD
	 AOS	LSTSYM+SYMLIN	;[76] [104] COUNT A LINE SEEN LAST SYMBOL
	POPJ	PP,		;[76]
;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
	CORE	T,		;CORE UUO
	SKIPA	T,ROOM		;FAIL
	JRST	NOR3		;SUCCESS
	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
	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
	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
	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
	PUSHJ	PP,FIXBPD	;[115] FIX FILE 0 POINTER IF /O
	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	COMPL5		;[33] [100] NOT SEQ. #
	AOS	P1		;SKIP OVER SEQ. # AND
	ILDB	W1,P1		;[33] GET CHAR
	CAIN	W1,.CHTAB	;[100] [33] IS IT A TAB?
COMPL5:	ILDB	W1,P1		;[33] [100] YES, EAT IT

	;[100] HERE WITH FIRST GOOD CHAR FROM FILE 1 IN W1

	TDNN	W3,1(W2)	;SAME THING FOR FILE #2
	JRST	COMPL2		;[33]
	AOS	P2
	ILDB	W2,P2		;[33] GET NEXT CHAR
	CAIE	W2,.CHTAB	;[33] [100] IS IT A TAB?
	JRST	COMPL0		;[33] NO, DON'T EAT
	JRST	COMPL2		;[33] YES, DO EAT
COMPL1:	ILDB	W1,P1		;GET A CHARACTER FROM LINE FROM FIRST FILE
COMPL2:	ILDB	W2,P2		;AND ONE FROM SECOND FILE
COMPL0:	CAMN	W1,W2		;THIS IS THE BIG TEST--ARE THEY EQUAL
	JRST	COMPL7		;[117] YES, CONTINUE
	SKIPN	OPISWT		;[117] CASE-INVARIANT COMPARE?
	JRST	COMPL4		;NO
	CAIL	W1,"a"		;[117] YES, UPCASE BOTH CHARS
	CAILE	W1,"z"		;[117]
	CAIA			;[117]
	TRZ	W1,40		;[117] CONVERT TO UPPER CASE
	CAIL	W2,"a"		;[117] YES, UPCASE BOTH CHARS
	CAILE	W2,"z"		;[117]
	CAIA			;[117]
	TRZ	W2,40		;[117] CONVERT TO UPPER CASE
	CAME	W1,W2		;[117] TRY ONE MORE TIME
	JRST	COMPL4		;[117] FAILED AGAIN, FORGET IT
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,.CHTAB	;[100] 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,.CHTAB	;[100] 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
	MOVEI	W1,[ASCIZ /****/]
	PUSHJ	PP,PPRINT
	SKIPE	OFSSWT		;[76] IF /OFFSET, 
	 PUSHJ	PP,PNTTAG	;[103] ADD THE TAG
	PUSHJ	PP,PCRLF
	HRRI	FR,1		;THEN PRINT FILE 2 DIFFERENCES
	PUSHJ	PP,PNTTXT
	MOVEI	W1,[ASCIZ /**************/]
	PUSHJ	PP,PPRINT
	JRST	PCRLF		;PRINT CARRIAGE RETURN-LINE FEED


;THIS ROUTINE IMBEDS "SYMBOL+N" IN THE ASTERISK LINES
;THE "SYMBOL" MUST OCCUR WITHIN THE FIRST 10 CHARACTERS OF THE LINE

PNTTAG:	MOVEI	W1,[ASCIZ / ;At /]	;[76] [103] [115] NOISE
	PUSHJ	PP,PPRINT	;[76] [115]
	PUSH	PP,LBUFP1	;[115] SAVE POINTER JUST IN CASE
	SKIPN	NOHDR		;[115] SKIP IF FLUSHING AN EOF
	 JRST	PNTT.0		;[115] NOPE, NORMAL CASE
	MOVEI	W1,SAVSYM-1	;[115] YES, REDIRECT OUTPUT TO FAKE SYMBOL
	MOVEM	W1,LBUFP1	;[115] BECAUSE LBUFP1 LIES

PNTT.0:	MOVE	W1,LBUFP1	;[115] BOTTOM OF WINDOW IS LINE WITH TAG
	MOVE	W3,$SYMBL+1(W1)	;[76] [103] [115] GET LOCAL SYMBOL NAME
	JUMPE	W3,PNTT.1	;[76] [103] SKIP THIS IF NO LOCAL SYMBOL THERE
	MOVEI	W1,$SYMBL+1(W1)	;[76] [103] [115] POINT BACK AT LABEL
	PUSHJ	PP,PPRINT	;[76] [103] [115] DO IT
	JRST	PNTT.2		;[103] MAIN SYMBOL COMES LATER

PNTT.1:	MOVE	W1,LBUFP1	;[115] POINT TO TEXT AGAIN
	MOVEI	W1,SYMBOL+1(W1)	;[115] GET ADDRESS OF MAJOR LABEL
	SKIPN	W2,(W1)		;[103] IF NULL
	 MOVEI	W1,[ASCIZ /top of file /]	;[103] [115] SAY SOMETHING
	PUSHJ	PP,PPRINT	;[76] [103] [115] GET IT OUT

PNTT.2:	MOVE	W1,LBUFP1	;[115] POINT TO TEXT BLOCK
	SKIPN	T,SYMLIN+1(W1)	;[76] [103] [115] GET NUMBER OF LINES SINCE LAST SYMBOL
	JRST	PNTT.3		;[76] [103] NONE, SEE IF NEED A MAIN SYMBOL
	MOVEI	C,"+"		;[76] SOME, PUT IN PLUS
	PUSHJ	PP,TYO		;[76]
	PUSHJ	PP,PNTDEC	;[76] TYPE NUMBER OF LINES PAST SYMBOL
	MOVEI	C,"L"		;[103]
	PUSHJ	PP,TYO		;[103]
PNTT.3:	JUMPE	W3,PNTT.4	;[103] [115] IF ONLY MAIN SYMBOL, NO QUALIFIER
	MOVEI	W1,[ASCIZ / following /]	;[76] [103] [115] ENCLOSE SYMBOL
	PUSHJ	PP,PPRINT	;[76] [115]
	MOVE	W1,LBUFP1	;[115] GET ADDRESS ONE LAST TIME
	MOVEI	W1,SYMBOL+1(W1)	;[76] [115] POINT AT MAIN SYMBOL
	PUSHJ	PP,PPRINT	;[76] [103] [115] GET IT OUT

PNTT.4:	POP	PP,LBUFP1	;[115] RESTORE BUFFER POINTER
	POPJ	PP,		;[115] DONE
;THIS SUBROUTINE PRINTS ALL THE TEXT IN THE
;BUFFER SPECIFIED BY C(FR)R. I. E. FILE 1 OR FILE 2

PNTTXT:	SETOM	PAGEN		;[76] GUARANTEE PAGE # MISMATCH- THEREFORE PRINT IT
	SETOM	TEMP		;[76] START POINTER AT -1
PNTTX2:	AOS	W1,TEMP		;[76] 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	PNTTX2		;[76] FINISH OUT ALL LINES


;HERE WHEN ONE FILE IS SHORT, ONLY WANT *'S ONCE
PRNTXT:	SKIPE	OFSSWT		;[103] NO SEP IF NOT /O
	 SKIPE	NOHDR		;[76] BEEN HERE BEFORE?
	JRST	PNTTXT		;[76] [103] YES, HOP INTO THE MIDDLE AND PRINT A LINE

	;FAKE A START OF CONFLICT

	MOVE	W1,[XWD LSTSYM,SAVSYM] ;[104] SAVE LAST LABEL
	BLT	W1,SAVSYM+SSBLTE-1 ;[104] ...

	;IF READING FROM FILE 2, PRINT THE SEPERATOR LINE ABOVE

	TRNE	FR,-1		;[103] FILE 2?
	 PUSHJ	PP,PRNSEP	;[103] SEPARATOR
	PUSHJ	PP,PNTTXT	;[76] [103] PRINT THE LINE
	HRROM	FR,NOHDR	;[76] [103] REMEMBER WE DID
	POPJ	PP,		;[76]
PRNSEP:	MOVEI	W1,[ASCIZ /****/] ;[103]
	PUSHJ	PP,PPRINT	;[103]
	PUSHJ	PP,PNTTAG	;[103]
	PJRST	PCRLF		;[103]

PNTDEC:	IDIVI	T,^D10		;[76] YE OLDE DECIMAL PRINT ROUTINE
	HRLM	TT,0(PP)	;[76]
	SKIPE	T		;[76]
	PUSHJ	PP,PNTDEC	;[76]
	HLRZ	C,0(PP)		;[76]
	ADDI	C,"0"		;[76]
	PUSHJ	PP,TYO		;[76]
	AOS	TEMP		;[76] COUNT THAT CHARACTER
	POPJ	PP,		;[76]
;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,.CHTAB	;[100] PRINT TAB
	PUSHJ	PP,FIXBP	;[115] FIX BP TO POINT TO TEXT

PLINE3:	PUSHJ	PP,PCHART
PRINT:	ILDB	C,W1		;GET CHARACTER
	JUMPN	C,PLINE3	;LOOP UNTIL A NULL SHOWS UP
	POPJ	PP,

PPRINT:	HRLI	W1,(POINT 7,,)	;[115] MAKE ADDRESS INTO A BP
	JRST	PRINT		;[115] ...


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,^D10		;[100] 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,.CHTAB	;[100] IS CHAR BETWEEN 11 (TAB) AND
	CAILE	C,.CHCRT	;[100]   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,.CHFFD	;[100] FOR NEW PAGE, ISSUE FORM FEED
	TLNN	FR,NOFORM	;IF 1, SUPPRESS FORM FEED
	PUSHJ	PP,TYO
	MOVEI	W1,[ASCIZ /File 1)	/]
	PUSHJ	PP,PPRINT
	MOVEI	W1,HBUF1
	PUSHJ	PP,PPRINT	;PRINT FILE 1 NAME
	MOVEI	W1,HBUF1D	;[51]
	PUSHJ	PP,PPRINT	;[51] AND ITS CREATION DATE
	PUSHJ	PP,PCRLF
	MOVEI	W1,[ASCIZ /File 2)	/]
	PUSHJ	PP,PPRINT
	MOVEI	W1,HBUF2
	PUSHJ	PP,PPRINT	;PRINT FILE 2 NAME
	MOVEI	W1,HBUF2D	;[51]
	PUSHJ	PP,PPRINT	;[51] AND ITS CREATION DATE
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.


ERRIA1:	SKIPA	T,[[ASCIZ/?Input error for input file 1- /]]  ;
ERRIA2:	MOVEI	T,[ASCIZ/?Input error for input file 2- /]	;
ERRIA:	HRRZ	FIL,INDIR1+1	;SAVE ERROR CODE
	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:	PUSHJ	PP,ERCODP	;PRINT ERROR CODE
	MOVEI	T,[ASCIZ/) /]	;IN CASE OUT OF BOUNDS
	CAIG	FIL,ERRLN	;JUST PRINT CLOSE PARENS
	SKIPE	T,ERRTAB(FIL)	;PICK UP ERROR MESSAGE
	PUSHJ	PP,TYPMS0
	JRST	CARR		;THIS WILL OUTPUT TWO C.R. AND EXIT

ERRTAB:	[ASCIZ/) File not found/]	; 0
	[ASCIZ/) Non-existent UFD/]	; 1
	[ASCIZ/) Protection failure/]	; 2
	[ASCIZ/) File being modified/]	; 3
	0				; 4 NOT APPLICABLE
	0				; 5
	[ASCIZ/) UFD or RIB error/]	; 6
	0				; 7
	0				;10
	0				;11
	0				;12
	0				;13
	[ASCIZ/) No room or quota exceeded/] ;14
	[ASCIZ/) Write-lock error/]	;15
	[ASCIZ/) Not enough monitor table space/] ;16
	0				;17
	0				;20
	[ASCIZ/) Cannot supersede UFD/] ;21
	0				;22
	[ASCIZ/) SFD not found/]	;23
	[ASCIZ/) Search list empty/]	;24
	[ASCIZ/) SFD Nesting too deep/]	;25
	[ASCIZ/) Path error/]		;26
	0				;27
	[ASCIZ/) File cannot be updated/] ;30
	0				;31
	0				;32
	ERRLN==.-ERRTAB-1	;MAXIMUM ERROR CODE KNOWN
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


ERCODP:	MOVEI	C," "		;PRINT A SPACE
	PUSHJ	PP,TYO		;
	MOVEI	C,"("		;AND OPEN PARENS
	PUSHJ	PP,TYO		;
	MOVEI	T,(FIL)		;PICK UP ERROR CODE
ERCOD1:	IDIVI	T,10		;GET A DIGIT
	HRLM	TT,(PP)		;STASH IT
	SKIPE	T		;DONE?
	PUSHJ	PP,ERCOD1	;NO
	HLRZ	C,(PP)		;GET THE DIGIT
	ADDI	C,"0"		;ASCII-SIZE IT
	PUSHJ	PP,TYO		;OUT IT
	POPJ	PP,		;AND THATS IT
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," "-' '	;[100] CHANGE TO ASCII
	PUSHJ	PP,TYO
	JRST	PNTS1
CRLF:	MOVEI	C,.CHCRT	;[100] OUTPUT A CARRIAGE RETURN-LINE FEED
	PUSHJ	PP,TYO
	MOVEI	C,.CHLFD	;[100] 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,.CHLFD	;[100] 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/

ERRONO:	MOVEI	T,[ASCIZ/?Output device error- /]	
	PUSHJ	PP,TYPMSG			;[24]
	MOVE	T,OUTDEV			;[24]AND DEVICE
	PUSHJ	PP,PNTSIX			;[24]CANT DO OUTPUT
	MOVEI	T,[ASCIZ/: cannot do output/]	;[24]
	PUSHJ	PP,TYPMS0			;[24]
	JRST	CARR				;[24]FINISH UP
ERROEF:
	MOVE	T,OUTDIR	;[24]SET UP DIR
	MOVE	TT,OUTDIR+1	;[24]
	MOVEM	T,INDIR1	;[24]FOR TYPEOUT
	MOVEM	TT,INDIR1+1	;[24]
	MOVEI	T,[ASCIZ/?Output ENTER error for /]
	JRST	ERRIA		;[24]
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:	SKIPN	TT,DIG		;[63] IF ZERO MEANS HW SIZE NEEDED
	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

	SETZM	DIG		;[63] SET ZERO FOR NEXT TIME
TYCEL2:	MOVEI	C,0		;[63] ADD THE LABEL
	LSHC	C,3
	ADDI	C,"0"
	PUSHJ	PP,PCHAR
	SOJG	TT,TYCEL2	;[63]
	POPJ	PP,

TYPSP:	MOVEI	C," "
	JRST	TYO

TYPTB2:	PUSHJ	PP,TYPTAB
TYPTAB:	MOVEI	C,.CHTAB	;[100]
	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:	PUSHJ	PP,EAT		;[45] READ TO END OF LINE
	MOVE	1,['FILCOM']	;NAME OF HELP FILE
	PUSHJ	PP,.HELPR	;READ IT
	JRST	COMPGO		;PRINT * AGAIN
;ROUTINE TO GET A LEGITIMATE CHARACTER

GCHAR:	SKIPN	OLDCHR(FR)	;[44] CHARACTER LEFT FROM LAST TIME?
	JRST	GCHAR0		;[44] NO, PROCEED AS USUAL
	MOVE	C,OLDCHR(FR)	;[44] YES, USE IT INSTEAD OF A NEW ONE
	SETZM	OLDCHR(FR)	;[44] ZERO THE FLAG
	JRST	GCHR00		;[44] SKIP CHECKS ALREADY MADE
GCHAR0:	TLNE	FR,@EOFTBL(FR)	;[44] 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,.CHLFD	;[100] LINE FEED?
	CAIN	C,.CHVTB	;[100] NO-VERTICAL TAB?
	JRST	EOL		;YES, RETURN WITH LINE-END FLAG SET
	CAIN	C,.CHCRT	;[100] CARRIAGE RETURN?
	JRST	[SETOM CRSEEN(FR)	;[44] YES, POSSIBLY FLUSH
		 JRST GCHAR]	;[44] SO GO GET ANOTHER
	CAIN	C,.CHFFD	;[100] IS IT A FORM FEED?
	JRST	FORM		;YES
	SKIPN	CRSEEN(FR)	;[44] WAS LAST CHARACTER A CR?
	JRST	GCHR00		;[44] NO, WE HAVE WHAT WE WANT
	MOVEM	C,OLDCHR(FR)	;[44] YES, SAVE THIS ONE FOR NEXT TIME
	MOVEI	C,.CHCRT	;[44] [100] RETURN A CARRIAGE-RETURN
	JRST	EOL		;[44] AS AN EOL CHARACTER
GCHR00:	HRL	C,@SEQTBL(FR)	;[44] 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
	SETZM	CRSEEN(FR)	;[44] ZERO A FLAG
	POPJ	PP,

;HERE TO SKIP REST OF FILES, AND TAKE A QUICK EXIT.

QFIN:	AOS	ERRCNT		;ENSURE AT LEAST ONE ERROR SEEN
	JRST	FIN2		;[30] TAKE QUICK EXIT.
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
	CAIN	C,.CHCNZ	;[45] [100] AN EOF TERMINATES A FILE NAME
	JRST	[SETOM	XITFLG	;[45] [100]   AND CAUSES US TO EXIT LATER
		 JRST	TERM]	;[45] [100] HANDLE WHAT WE HAVE
	CAILE	C,.CHCRT	;[45] [100] THIS IS ANOTHER WAY TO GET A FILE NAME
	CAIN	C,.CHESC	;[100] 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	[CAIN	ACDEL,".";[75] IF WE'VE SEEN A . IN THE LAST PHRASE,
		JRST	ERRDEI	;[75] GIVE AN ERROR
		JRST	NAME]	;[75] OTHERWISE, PROCESS A FILENAME
	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," "^!' '	;[100] 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,.CHAL2	;[100]
	CAIN	C,.CHALT	;[100]
	MOVEI	C,.CHESC	;[100] CHANGE ALL ALT MODES TO NEW
	CAIN	C,"="
	MOVEI	C,"_"		;= WILL EVENTUALLY REPLACE _
	CAIL	C,"a"		;[100]
	CAILE	C,"z"		;[100]
	 CAIA			;[100]
	TRC	C,"a"^!"A"	;[100] CHANGE LOWER CASE TO UPPER CASE
	CAIE	C," "		;[100] SKIP BLANKS
	CAIN	C,.CHTAB	;[100] 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:	PUSHJ	PP,CHKTRM	;[71] CHECK FOR LAST DELIMETER SEEN
	CAIE	ACDEL,"."	;IF PERIOD,
	POPJ	PP,
	HLRZ	0,ACEXT		;[71] PUT EXTENSION IN RH FOR TABLE SEARCH
	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,,'UNV'		;[61]
	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'
	EXEBIT,,'EXE'
	WDFBIT,,'OVL'		;[73] Overlay
	WDFBIT,,'ATR'		;[73] SIMULA attribute file
	WDFBIT,,'DBS'		;[73] DBMS file
	WDFBIT,,'QUD'		;[73] Queue data file
	WDFBIT,,'SCH'		;[73] DBMS file
	WDFBIT,,'APL'		;[73] APL workspace default extension
	WDFBIT,,'SYM'		;[73] ALGOL file
EXTBLE:	0			;END OF TABLE
;CHKTRM - Routine to check if a filename or extension has been parsed into
;	AC0.  If so, store it in the appropriate AC (ACFILE or ACEXT).  This
;	routine also checks to see if double names have been typed and gives an
;	error message if true.  The only delimeters legally stored in ACDEL are
;	comma and colon; if anything else is there, the error is internal;
;	but don't report it since FILCOM is very simple minded about these
;	things.

CHKTRM:	JUMPE	0,CPOPJ		;[71] IF NO CHARACTERS STORED, CONTINUE
	CAIE	ACDEL,"."	;[71] IF DELIMETER IS A PERIOD, AC0 CONTAINS
	JRST	CHKTR1		;[71]  AN EXTENSION
	SKIPE	ACEXT		;[71] IF AN EXTENSION HAS ALREADY BEEN PARSED,
	JRST	ERRDEI		;[71]  GIVE AN ERROR
	HLLZ	ACEXT,0		;[71] STORE THE EXTENSION IN LH
	JRST	CHKTR3		;[71] NOW ZERO SOME STUFF AND RETURN


;[71] HERE IF DELIMETER IS NOT A PERIOD
CHKTR1:	JUMPE	ACDEL,CHKTR2	;[71] IF NO DELIMETER HAS BEEN TYPED OR IT'S A
	CAIE	ACDEL,":"	;[71]  COLON, THEN CHARS IN AC0 ARE A FILENAME
	POPJ	PP,		;[71] SHOULD NEVER GET HERE SINCE ONLY ":", "."
				;[71]  ARE STORED IN ACDEL. HOWEVER, CONTINUE
				;[71]  PARSING IN THE SPIRIT OF FILCOM
CHKTR2:	SKIPE	ACFILE		;[71] IF A FILENAME HAS ALREADY BEEN PARSED,
	JRST	ERRDFI		;[71]  GIVE AN ERROR
	MOVE	ACFILE,0	;[71] STORE THE FILENAME
				;[71] FALL INTO CHKTR2 ROUTINE

CHKTR3:	SETZB	TT,0		;[71] CLEAR AC'S
	MOVSI	ACPNTR,(POINT 6,0)	;[71] RESET BYTE POINTER
	POPJ	PP,		;[71] AND RETURN
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
	PUSHJ	PP,CHKTRM	;[71] CHECK IF CELLS NEED TO BE STORED
	JRST 	GETIOC		;GET NEXT PART OF COMMAND

GETSW1:	CAIN	C,"H"		;REQUEST FOR HELP?
	JRST	HELP		;YES
	CAIN	C,"Q"		;/Q?
	JRST	GETSWE		;YES
	CAIN	C,"O"		;[76] WANT SYMBOL OFFSETS?
	JRST	[SETOM	OFSSWT	;[76] YES
		 JRST	GETIOC]	;[76] GET NEXT PART OF COMMAND
	CAIN	C,"T"		;[105] WANT FILE ALWAYS?
	 JRST	[SETOM	OPTSWT	;[105] YES
		 JRST	GETIOC]	;[105] ON WITH COMMAND
	CAIN	C,"I"		;[117] WANT CASE INVARIANT COMPARE?
	 JRST	[SETOM	OPISWT	;[117] YES
		 JRST	GETIOC]	;[117] ONWARDS
	SETZ	T,		;START WITH ZERO
	PUSHJ	PP,GETOC2	;BUILD OCTAL NUMBER IN T
	JUMPE	T,ERRSWT	;[71] ERROR IF NO NUMBER
	MOVEM	T,NUMLIN	;SAVE AS # EXTRA LINES TO MATCH (AFTER 1ST)
	MOVEM	T,USERL		;[122] SAVE AN UNDOCTORABLE SECOND COPY
	CAIN	C,"L"		;[34] TEST FOR LIMIT SWITCHES
	JRST	[SETOM LSEEN	;[34] We saw the /L switch
		 JRST  SETLIM+1]	;[34] Set up limits
	CAIN	C,"U"		;EITHER UPPER OR LOWER
	JRST	SETLIM		;FOUND ONE
	JRST	ERRSWT		;[71] REPORT UNKNOWN SWITCH TYPED

SETLIM:	SKIPA	UPPER,T		;UPPER LIMIT /0000U
	MOVE	LOWER,T		;LOWER LIMIT /0000L
	PUSHJ	PP,CHKTRM	;[71] SEE IF SWITCH TERMINATED A CELL
	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)
	EXEBIT,,"E"		;/E COMPARE EXE FILES [25]
	USWBIT+ALLSW,,"U"	;/U MANUAL UPDATE MODE
SWTBLE:		;END OF TABLE
;ERROR MESSAGES FOR SWITCH PARSING IN COMMAND LINE

ERRSWT:	PUSH	PP,C		;[71] SAVE THE UNKNOWN SWITCH ARGUMENT
	PUSHJ	PP,EAT		;[71] GET THE COMMAND IN CASE A ^Z WAS TYPED
	MOVEI	T,[ASCIZ /?Command error -- Unknown switch /]	;[71]
	PUSHJ	PP,TYPMSG	;[71]
	POP	PP,C		;[71] RESTORE THE CHARACTER
	PUSHJ	PP,TYO		;[71] CHARACTER IS IN C ALREADY
	JRST	CARR		;[71] FINISH UP AND TRY AGAIN


ERRDFI:	PUSHJ	PP,EAT		;[71] GET THE COMMAND IN CASE A ^Z WAS TYPED
	JSP	T,ERROUT	;[71]
	ASCIZ /?Command error -- Double filename illegal/	;[71]


ERRDEI:	PUSHJ	PP,EAT		;[71] GET THE COMMAND IN CASE A ^Z WAS TYPED
	JSP	T,ERROUT	;[71] IF AN EXTENSION ALREADY EXISTS
	ASCIZ	/?Command error -- Double extension illegal/
GETPP:	PUSHJ	PP,CHKTRM	;[71] CHECK IF [ TERMINATED A CELL
	PUSHJ	PP,GETOCT	;BUILD THE PROJ,PROG NUMBER
	CAIN	C,"-"		;WAS THIS DASH? (DEFAULT PATH)
	JRST	[ JUMPN T,CTLSER;MUST BE ONLY CHAR THEN
		  JRST DEFPTH ]	;GO DEFAULT THE PATH
	CAIE	C,","
	JRST	CTLSER
	HRLZ	ACPPN,T		;PUT PROJ NUMBER IN LEFT HALF
	PUSHJ	PP,GETOCT
	HRR	ACPPN,T		;PUT PROG NUM IN RIGHT HALF
	GETPPN	T,		;[23] GET JOB'S PPN
	JFCL
	TLNN	ACPPN,777777	;[23] PROJ NUMBER 0?
	HLL	ACPPN,T		;[23] YES, PUT JOB'S PROJ NUMBER IN LEFT HALF
	TRNN	ACPPN,777777	;[23] PROG NUMBER 0?
	HRR	ACPPN,T		;[23] YES, PUT JOB'S PROG NUMBER IN RIGHT HALF
	CAIN	C,"]"		;SIMPLE PPN?
	JRST	GETIOC		;YES,CONTINUE WITH COMMAND
	PUSHJ	PP,CHKEOL	;[102] END OF LINE?
	JRST	TERM		;[102] YES, CONTINUE SCANNING
	MOVE	T,FILCNT	;GET FILE WE ARE DOING
	MOVE	T,[EXP OUTDIR,INDIR1](T) ;GET PROPER FILE
	MOVEM	ACPPN,PTHPPN(T)	;STORE PPN
	MOVEI	ACPPN,PTHADR(T)	;SET PPN TO POINT TO PATH BLOCK
	MOVEI	T,PTHSFD(T)	;SET UP FOR INPUT OF SFDS
	HRLI	T,-MAXSFD	;SET UP COUNTER TOO
GETPP1:	CAIN	C,"]"		;CLOSED WITH BRACKET?
	JRST	GETIOC		;YES,CONTINUE COMMAND SCANNING
	PUSHJ	PP,CHKEOL	;[102] END OF LINE?
	JRST	TERM		;[50] YES, CONTINUE SCANNING
	SKIPGE	T		;COUNT NEGATIVE?
	CAIE	C,","		;IS THIS SFD SPECIFICATION?
	JRST	CTLSER		;NO, INDICATE ERROR
	PUSHJ	PP,RD6		;READ THE SFD NAME
	JUMPE	TT,CTLSER	;IF NULL,ITS ERROR
	MOVEM	TT,0(T)		;STORE SFD
	SETZM	1(T)		;INSURE NULL TERMINATOR
	AOBJN	T,.+1		;INCREMENT BOTH PARTS OF SFD POINTER
	JRST	GETPP1		;LOOP FOR NEXT ONE


;CHKEOL - CALL HERE TO CHECK FOR END OF LINE CHARACTER.  RETURN IF END OF LINE,
;	SKIP RETURN IF NOT.

CHKEOL:	CAIN	C,.CHESC	;[50] [100] ESCAPE?
	POPJ	PP,		;YES.
	CAIE	C,.CHCNZ	;[50] [100] MAYBE AN END OF FILE?
	CAIG	C,.CHCRT	;[50] [100] LF, FF, ETC.?
	POPJ	PP,		;YES.
	JRST	CPOPJ1		;NOT END OF LINE.
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

RD6:	PUSH	PP,T		;SAVE T REG
	MOVE	T,[POINT 6,TT]	;STORE INTO TT
	SETZ	TT,		;CLEAR ARGUMENT
RD61:	PUSHJ	PP,TTYIN	;GET A CHARACTER
	CAIL	C,"0"		;LESS THAN 0?
	CAILE	C,"Z"		;OR GREATER THAN Z?
	JRST	TPOPJ		;YES,RETURN
	CAILE	C,"9"		;LESS THAN 9 OR
	CAIL	C,"A"		;GREATER THAN A?
	JRST	RD62		;ITS OK
TPOPJ:	POP	PP,T		;RESTORE TEMP REGISTER
	POPJ	PP,		;RETURN
RD62:	SUBI	C," "		;CONVERT TO SIXBIT
	TRNN	TT,77		;IF WORD NOT FULL,
	IDPB	C,T		;STORE BYTE 
	JRST	RD61		;LOOP FOR NEXT CHARACTER

DEFPTH:	MOVE	T,FILCNT	;GET FILE INDEX
	MOVE	T,[EXP OUTDIR,INDIR1](T) ;GET RIGHT DIR BLOCK
	MOVEI	ACPPN,PTHADR(T)	;PPN IS 0,,PATH BLOCK ADDRESS
	SETOM	PTHADR(T)	;READ DEFAULT PATH
	MOVEI	TT,PTHADR(T)	;POINT TO PATH BLOCK
	HRLI	TT,MAXSFD+4	;LENGTH OF AREA AVAILABLE
	PATH.	TT,		;ASK MONITOR FOR DEFAULT PATH
	  JRST	NOPTH		;NO AVAILABLE
	PUSHJ	PP,TTYIN	;GET NEXT CHARACTER
	CAIN	C,"]"		;CLOSES IT RIGHT?
	JRST	GETIOC		;RIGHT,GET REST OF STRING
	JRST	CTLSER		;OTHERWISE,COMPLAIN

NOPTH:	JSP	T,ERROUT	;IF PATH. UUO FAILED
	ASCIZ	/?PATH. UUO required to default file path/

EAT1:	PUSHJ	PP,TTYIN	;[45] GET A CHARACTER INTO C
EAT:	CAIG	C,.CHFFD	;[45] [100] IN THE RANGE OF FORM FEED
	CAIGE	C,.CHLFD	;[45] [100] DOWN TO LINE FEED?
	CAIN	C,.CHESC	;[45] [100] NO, IS IT AN ALTMODE?
	POPJ	PP,		;[45] YES! RETURN WITH EOL CHAR
	CAIN	C,.CHBEL	;[45] [100] IS IT A ^G?
	POPJ	PP,		;[45] YES, THAT ENDS LINE TOO
	CAIE	C,.CHCNZ	;[45] [100] IS IT A ^Z?
	JRST	EAT1		;[45] NO, EAT ANOTHER CHARACTER
	SETOM	XITFLG		;[45] IT'S ^Z, MARK TO EXIT LATER
	POPJ	PP,		;[45] RETURN
;CREATE PAGE HEADER FOR LISTING FILES CONSISTING OF:
;DEVICE:FILENAME.EXT[PROJ,PROG,SFD,SFD,..,SFD] CREATED MMHH DAY-MONTH-YEAR

HEADER:	MOVEI	TT,IN1		;ASSUME FIRST FILE
	SETZM	TEMP		;[51] SET SO WITH TEMP
	CAIE	T,HBUF1		;IS IT?
	JRST	[MOVEI	TT,IN2	;[51] NO
		 AOS	TEMP	;[51] MARK WITH TEMP
		 JRST	.+1]	;[51] RETURN TO MAINLINE CODE
	MOVEM	TT,PTHBLK+.PTFCN;STORE AS FUNCTION
	HRLI	T,440700	;MAKE ADDRESS INTO BYTE POINTER
	MOVEM	T,HPOINT	;AND SAVE FOR FUTURE USE
	MOVE	TT,[MAXSFD+4,,PTHBLK] ;SET UP FOR PATH.
	SETZM	PTHBLK+.PTPPN	;CLEAR PPN AND
	SETZM	PTHBLK+.PTPPN+1	;FIRST SFD FROM LIST
	PATH.	TT,		;DO IT
	  SKIPA	T,INDEV1	;USE DEVICE FROM LOOKUP BLOCK IF FAILS
	MOVE	T,PTHBLK+.PTFCN	;OTHERWISE USE THE PATH. DEVICE
	PUSHJ	PP,HEDST6
	MOVEI	C,":"
	PUSHJ	PP,HEDDPB	;DEPOSIT COLON INTO HEADER
	DEVCHR	T,		;GET DEVICE CHARACTERISTICS
	TLNN	T,(1B15)	;DOES DEVICE HAVE A DIRECTORY?
	JRST	[PUSHJ	PP,HEAD8;[51] DEPOSIT A NULL
		 JRST	PRETTY]	;[51] CLEAN UP HEADER AND RETURN
	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,PTHBLK+.PTPPN	;GET PPN FROM PATH, IF AVAILABLE
	MOVE	T,INDPPN	;OTHERWISE USE LOOKUP PPN
	JUMPE	T,HEAD4		;SKIP WHOLE THING IF STILL NO PPN
	MOVEI	C,"["		;PRINT IT
	PUSHJ	PP,HEDDPB
	SKIPE	PTHBLK+.PTPPN+1	;ANY SFD'S?
	JRST	PRTPTH		;IF PATH (SFDS) , PRINT DIFFERENTLY
	PUSH	PP,T		;SAVE PROJ,PROG NUMBER
	HLRZS	T		;CLEAR PROG NUMBER
	PUSHJ	PP,HED8		;PRINT PROJECT #
	MOVEI	C,","
	PUSHJ	PP,HEDDPB
	POP	PP,T		;RESTORE PROG NUMBER
	ANDI	T,-1		;ISOLATE IT
	PUSHJ	PP,HED8		;PRINT PROGRAMMER #
HEAD3:	MOVEI	C,"]"
	PUSHJ	PP,HEDDPB
HEAD4:	MOVE	TT,HPOINT	;[51] GET THE BYTE POINTER
	MOVEM	TT,HBPT2	;[51] ASSUME 2ND FILE AND STORE
	SKIPN	TEMP		;[51] WAS IT THE FIRST FILE?
	MOVEM	TT,HBPT1	;[51] YES, STORE IT RIGHT
	SETZ	C,		;[51] MAKE A NULL
	PUSHJ	PP,HEDDPB	;[51] TERMINATE THE FILESPEC
	MOVE	TT,[POINT 7,HBUF2D]	;[51] CREA. DATE POINTER
	SKIPN	TEMP		;[51] SECOND FILE?
	MOVE	TT,[POINT 7,HBUF1D]	;[51] NO, TRY AGAIN
	MOVEM	TT,HPOINT	;[51] SET UP FOR HEDDPB

	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		;SAVE THE REST
	MOVEI	T,1(T+1)
	PUSHJ	PP,HED10	;PRINT DAY
	POP	PP,T
	IDIVI	T,^D12
	PUSH	PP,T		;SAVE YEAR
	MOVE	T,MONTAB(T+1)	;GET MONTH TEXT
	PUSHJ	PP,HEDST7	;[47] PRINT IT IN ASCII
	POP	PP,T
	MOVEI	T,^D64(T)	;[62] GET YEAR
	PUSHJ	PP,HED10	;PRINT YEAR
	PUSHJ	PP,HEAD8	;[51] DEPOSIT A NULL
;	JRST	PRETTY		;[51] CLEAN UP HEADER AND RETURN
PRETTY:	SKIPN	TEMP		;[51] ARE WE ON THE 2ND FILE?
	POPJ	PP,		;[51] NO, CLEAN UP HEADERS LATER
	SKIPE	HBUF1D		;[51] DOES EITHER FILE
	SKIPN	HBUF2D		;[51]   LACK A CREATION DATE?
	POPJ	PP,		;[51] YES, NOTHING TO CLEAN UP
	HLRZ	TT,HBPT1	;[51] FIND 1ST FILE'S LAST CHAR
	HRLZI	T,-5		;[51] AOBJN COUNTER
PRET1:	CAME	TT,PRET4(T)	;[51] T'TH CHAR IN THE LAST WORD?
	AOBJN	T,PRET1		;[51] NO, TRY AGAIN
	HRRZ	TT,HBPT1	;[51] HOW MANY FULL WORDS?
	SUBI	TT,HBUF1	;[51] GET THAT BY SUBTRACTION
	IMULI	TT,5		;[51] GET NO. OF CHARS
	ADDI	TT,1(T)		;[51]  IN THE 1ST FILESPEC
	MOVEM	TT,TEMP		;[51] SAVE IT
	HLRZ	TT,HBPT2	;[51] NOW DO THE SAME
	HRLZI	T,-5		;[51] CALCULATION FOR THE
PRET2:	CAME	TT,PRET4(T)	;[51] SECOND FILE
	AOBJN	T,PRET2		;[51]
	HRRZ	TT,HBPT2	;[51] ADDRESS OF LAST WORD
	SUBI	TT,HBUF2	;[51] NO. OF FULL WORDS
	IMULI	TT,5		;[51] CHARS IN THOSE WORDS
	ADDI	TT,1(T)		;[51] PLUS SOME LEFT OVER
	CAMN	TT,TEMP		;[51] ARE THE COUNTS THE SAME?
	POPJ	PP,		;[51] YES, WE ARE DONE!
	MOVE	T,HBPT1		;[51] NO, ASSUME THE 1ST IS LESS
	CAMG	TT,TEMP		;[51] IS THE 2ND LESS?
	MOVE	T,HBPT2		;[51] YES, POINT TO ITS STRING
	SUB	TT,TEMP		;[51] GET THE DIFFERENCE IN LENGTH
	MOVMS	TT		;[51] MAKE SURE IT'S POSITIVE
	MOVEI	C," "		;[51] PAD THE STRING WITH SPACES
PRET3:	IDPB	C,T		;[51] ADD A SPACE
	SOJG	TT,PRET3	;[51] LOOP AROUND
	SETZ	C,		;[51] GET A NULL
	IDPB	C,T		;[51] END THE STRING WITH IT
	POPJ	PP,		;[51] WE ARE DONE

PRET4:	350700		;[51] LEFT HALVES OF ASCII BYTE POINTERS
	260700		;[51]
	170700		;[51]
	100700		;[51]
	010700		;[51]
HEAD8:	MOVEI	C,.CHNUL	;[100] PUT NULL INTO BUFFER
HEDDPB:	IDPB	C,HPOINT
	POPJ	PP,

HEDST7:	SKIPA	TT,[POINT 7,T]	;PRINT 7 BIT ASCII
HEDST6:	MOVE	TT,[POINT 6,T]	;PRINT SIXBIT
HEDS2:	TLNN	TT,760000
	POPJ	PP,		;DONE
	ILDB	C,TT
	JUMPE	C,HEDS2
	TLNN	TT,000100
	ADDI	C," "-' '	;[100] FOR SIXBIT, CONVERT TO ASCII
	PUSHJ	PP,HEDDPB	;OUTPUT CHARACTER
	JRST	HEDS2

HED8:	TDZA	W3,W3		;PRINT OCTAL NUMBERS
HED10:	MOVEI	W3,2		;PRINT DECIMAL NUMBERS
	MOVE	W2,W3		;FORCE 2 DIGITS FOR DECIMAL NUMBERS
HED10A:	IDIVI	T,8(W3)
	HRLM	T+1,(PP)
	SOSG	W2		;FORCE DIGITS UNTIL COUNT EXPIRES
	SKIPE	T
	PUSHJ	PP,HED10A
	HLRZ	C,(PP)
	ADDI	C,"0"
	JRST	HEDDPB

MONTAB:	ASCII	/-Jan-/
	ASCII	/-Feb-/
	ASCII	/-Mar-/
	ASCII	/-Apr-/
	ASCII	/-May-/
	ASCII	/-Jun-/
	ASCII	/-Jul-/
	ASCII	/-Aug-/
	ASCII	/-Sep-/
	ASCII	/-Oct-/
	ASCII	/-Nov-/
	ASCII	/-Dec-/
PRTPTH:	HLRZ	T,PTHBLK+.PTPPN		;GET PATH PPN
	PUSHJ	PP,HED8			;INSERT INTO HEADER
	MOVEI	C,","			;SEPARATE PROJ,PROG
	PUSHJ	PP,HEDDPB		;
	HRRZ	T,PTHBLK+.PTPPN		;GET PROG NUMBER
	PUSHJ	PP,HED8			;STORE INTO HEADER
	SETZ	W1,			;START AT BASE OF SFDS
PRTPLP:	MOVEI	C,","			;SEPARATE PPN,SFDS BY COMMA
	PUSHJ	PP,HEDDPB		;
	MOVE	T,PTHBLK+.PTPPN+1(W1)	;GET AN SFD NAME
	PUSHJ	PP,HEDST6		;STORE INTO HEADER
	SKIPN	PTHBLK+.PTPPN+2(W1)	;NEXT SFD THERE?
	JRST	HEAD3			;NO,FINISH UP
	AOJA	W1,PRTPLP		;ELSE LOOP FOR NEXT SFD
;HERE FOR BINARY COMPARE

BINCOM:	TLNE	FR,EOF2SW	;NO HEADER IF ONLY ONE FILE
	TLZ	FR,PAGSW	;FAKE AS NOT NEW PAGE
				;SORT OUT CONFLICTING SWITCHES AND EXTENSIONS
	TLNE	FR,WSWBIT		;EXPLICIT /W?
	TLZ	FR,XSWBIT!XDFBIT!EXEBIT	;[56] YES, THEN DON'T EXPAND
	TLNE	FR,XSWBIT		;EXPLICIT /X?
	TLZ	FR,HSGBIT!WDFBIT	;YES
	TLC	FR,XDFBIT!HSGBIT	;MUTUALLY EXCLUSIVE BITS
	TLCN	FR,XDFBIT!HSGBIT	;THERFORE THEY BETTER NOT BE BOTH ON
	TLZ	FR,XDFBIT!HSGBIT	;THEY WERE , YOU LOSE
	TLNE	FR,HSGBIT!WDFBIT	;WAS ONE FILE NOT IN SAV FORMAT?
	TLZ	FR,XDFBIT		;THEN IGNORE OTHER EXT
	TLNE	FR,XDFBIT!WDFBIT	;WAS ONE FILE NOT A HIGH SEGMENT
	TLZ	FR,HSGBIT	;YES, THEN IGNORE ONE THAT WAS
				;END OF THIS MESS
	TLNN	FR,HSGBIT	;TEST FOR EXT OF SHR, OR HGH
	TDZA	CNT,CNT		;NO, START AT 0
	MOVEI	CNT,400000	;YES, START AT HIGH SEG ADDRESS
	TLNN	FR,XSWBIT!XDFBIT;NEED TO EXPAND?
	JRST	COMP1		;NO
	JRST	SAV1		;YES



READ1A:	TRZ	FR,-1		;INDEX BY 0 FOR FILE 1
	JSP	C,GCHAR1
READ1:	SOSGE	INBUF1+2
	JRST	READ1A		;BUFFER EMPTY
	ILDB	W1,INBUF1+1
	AOS	(PP)
	POPJ	PP,

READ2A:	HRRI	FR,1		;INDEX BY 1 FOR FILE 2
	TLNE	FR,EOF2SW	;PREMATURE EOF
	JRST	ZPOPJ		;YES, AVOID I/O ERROR
	JSP	C,GCHAR2
READ2:	SOSGE	INBUF2+2
	JRST	READ2A		;BUFFER EMPTY
	ILDB	W2,INBUF2+1
	AOSA	(PP)
ZPOPJ:	SETZ	W2,		;RETURN NUL CHARS.
	POPJ	PP,
COMP1:	TLNE	FR,EXEBIT	;EXE FILE? [25]
	JRST	EXSTUF		;YES. GO ELSEWHERE [25]
	PUSHJ	PP,READ1	;GET WORD FROM FIRST FILE
	JRST	COMP10		;HERE IF A READ FAILURE
	PUSHJ	PP,READ2	;NOW GET WORD FROM SECOND FILE
	JRST	COMP12		;HERE IF READ FAILURE
	CAME	W1,W2		;THIS IS THE BIG TEST
	PUSHJ	PP,COMP2	;IT FAILED--THERE IS A DIFFERENCE
	AOS	CNT		;[57] NO DIFFERENCE, BUMP COUNT
	CAMLE	CNT,UPPER	;[57] HAVE WE FINISHED?
	JRST	FIN2		;[57] YES, EXIT QUICKLY
	JRST	COMP1		;[57] NO, TRY AGAIN

COMP2:	CAMGE	CNT,LOWER	;[22] IS LINE NUMBER IN BOUNDS?
	POPJ	PP,		;NO,TRY NEXT ONE
	CAMLE	CNT,UPPER	;[22] HAVE WE FINISHED?
	JRST	FIN2		;YES,SO EXIT QUICKLY
	SETZ	DIG		;[63] INITIALIZE
	HLLZ	T,CNT		;[63] MOVE LH OF CNT TO T
	JUMPN	T,COMP14	;[63] JUMP IF RH IS NON-ZERO
	HRLZ	T,CNT		;GET LINE NUMBER FOR PRINT OUT
COMP2A:	PUSHJ	PP,TYCELL	;[63] GO PRINT IT
	AOS	ERRCNT		;BUMP ERROR COUNT
	MOVE	T,1		;NO GET WORD FROM FIRST FILE
	PUSHJ	PP,TYPB		;PRINT IT WITH SPACES  BETWEEN HALF WORDS
	MOVE	T,2		;NOW WORD FROM SECOND FILE
	TLNE	FR,EXEBIT	;[27] IS THIS AN EXE FILE?
	TLNN	FR,EOF2SW	;[27] YES, IS THERE A 2ND FILE?
	SKIPA			;NO TO EITHER
	JRST	TCRLF		;[27] YES JUST PRINT CRLF
	PUSHJ	PP,TYPB		;AND PRINT IT
	MOVE	T,1		;NOW "OR" THE WORDS
	XOR	T,2
	TLNN	T,-1		;IF ONLY ADDRESS FIELD IS DIFFERENT
	JRST	COMP3		;HANDLE IT DIFFERENTLY
	PUSHJ	PP,TYPB		;NOW PRINT OUT THE "OR"ED WORD
	JRST	TCRLF		;OUTPUT A CARRIAGE RETURN-LINE FEED
COMP3:	MOVE	T,W1
	SUB	T,W2		;SUBTRACT ADDRESSES
	JUMPGE	T,.+2
	MOVNS	T
	MOVSS	T		;PUT IN LEFT HALF
	PUSHJ	PP,TYPTAB	;TYPE A TAB
	MOVEI	W1,7		;NEED 7 SPACES FOR ALLIGNMENT
	PUSHJ	PP,TYPSP	;TYPE A SPACE
	SOJG	W1,.-1		;LOOP
	PUSHJ	PP,TYCELL	;AND ADDRESS
	JRST	TCRLF		;AND CONTINUE

COMP10:	CAMG	CNT,UPPER	;[22] OUT OF BOUNDS?
	PUSHJ	PP,RDFIL2	;READ WORD FROM FILE 2 (REG OR EXE)
	JRST	FIN2
	CAMGE	CNT,LOWER	;[22]
	AOJA	CNT,COMP10	;GET NEXT WORD
	PUSHJ	PP,TYCNT	;TYPE LINE COUNT
	PUSHJ	PP,TYPTB2	;TWO TABS
	MOVE	T,W2
	PUSHJ	PP,TYPB
	PUSHJ	PP,TCRLF
	AOJA	CNT,COMP10

COMP12:	CAMGE	CNT,LOWER	;[22]
	JRST	COMP13
	PUSHJ	PP,TYCNT
	MOVE	T,W1
	PUSHJ	PP,TYPB
	PUSHJ	PP,TCRLF
	CAMGE	CNT,UPPER	;[22]
COMP13:	PUSHJ	PP,RDFIL1
	JRST	FIN2
	AOJA	CNT,COMP12


;COME HERE ONLY IF WE HAVE ADDRESS GREATER THAN 777777
;VERY FIRST TIME WHEN WE SEE FULL WORD ADDRESS WE ALSO JUMP TO NEW
;PAGE FOR READABILITY
;
COMP14:	SKIPN	FWA1ST		;[63] FULLWORD ADDRESS SEEN FIRST TIME?
	TLO	FR,PAGSW	;[63] THIS MEANS WE GET A NEW HEADING
	SETOM	FWA1ST		;[63] SET IT ONE FOR NEXT CHECK
	MOVEI	T,14		;[63] NUMBER OF DIGITS FOR THE FULL WORD
	MOVEM	T,DIG		;[63] SAVE IT FOR LATER USE
	MOVE	T,CNT		;[63] GET FULL WORD LINE NUMBER
	JRST	COMP2A		;[63] JUMP BACK TO TYPE
;COME HERE IF WE ARE COMPARING TWO EXE FILES. THIS OPERATION
; IS SOMEWHAT SIMILAR TO COMPARING TWO BINARY
; FILES EXCEPT THAT WE MUST ALSO CYLE THRU THE FILE DIRECTORY
; AS WE GO.
;
;FIRST, WE MUST READ IN THE DIRECTORY AND STORE IT SOMEPLACE.
EXSTUF:	TRZ	FR,-1		;SET FILE 1
EXSTF2:	PUSHJ	PP,EXERED	;READ THE FIRST WORD OF EXE FILE
	SETZM	DIRCTR		;CLEAR COUNTER OF DIRECTORY LENGTH
	HLRZ	T,W1		;GET LEFT HALF OF IT
	CAIE	T,.SVDIR	;[100] IS THIS A PROPER EXE FILE?
	JRST	EXERR0		;NO, GO PRINT APPROPRIATE ERROR MSG
	TLZ	W1,-1		;CLEAR HEADER CODE AND LEAVE LENGTH
	ADDM	W1,DIRCTR	;BUMP COUNTER
	SOS	W1		;=LENGTH OF DATA IN DIRECTORY
	MOVEM	W1,@[EXP DLNG1,DLNG2](FR)	;STORE LENGTH
	HRRZ	TT,.JBFF##	;GET TOP OF FREE SPACE
	MOVEM	TT,@[EXP DPTR1,DPTR2](FR)	;SET DIRECTORY POINTER
	ADDB	W1,.JBFF##	;=TOP OF NEW LOW SEGMENT
	CAMG	W1,.JBREL##	;IS THERE ENOUGH ROOM ALREADY?
	JRST	.+3		;YES
	CORE	W1,		;NO, GET MORE CORE TO HOLD DIRECTORY
	 JRST	CORERR		;NOT ENOUGH CORE, FATAL ERROR
	HRRZ	T,.JBFF##	;GET START OF FREE SPACE
	SUB	T,@[EXP DLNG1,DLNG2](FR)
	HRRZ	TT,@[EXP DLNG1,DLNG2](FR)	;GET LENGTH OF DIR
	PUSHJ	PP,EXERED	;READ A WORD FROM DIRECTORY
	MOVEM	W1,(T)		;STORE WORD IN FREE CORE
	AOS	T		;BUMP POINTER
	SOJG	TT,.-3		;LOOP UNTIL MOVED ENTIRE DIRECTORY
GETBLK:	PUSHJ	PP,EXERED	;GET NEXT WORD IN FILE
	HLRE	T,W1		;..AND ITS HEADER CODE
	JUMPL	T,EXERR0	;MUST BE POSITIVE
	CAIN	T,.SVEND	;[100] END BLOCK?
	JRST	GOTEND		;YES
	TLZ	W1,-1		;ISOLATE LENGTH
	ADDM	W1,DIRCTR	;BUMP TOTAL LENGTH
	SOJE	W1,GETBLK	;[56] WE HAVE READ ONE WORD ALREADY
	MOVE	T,W1		;[56] PUT COUNT IN AC THAT IS SAFE
	PUSHJ	PP,EXERED	;SKIP OVER IT
	SOJG	T,.-1		;[56]
	JRST	GETBLK		;GET NEXT BLOCK
GOTEND:	TLZ	W1,-1		;JUST IN CASE END-BLOCK INCREASES
				; IN THE FUTURE, ADD ITS LENGTH IN
	ADDM	W1,DIRCTR
	HRRZ	T,DIRCTR	;GET AMOUNT TO SKIP OVER
	IDIVI	T,^D512		;=# OF PAGES IN DIRECTORY
	MOVEI	T,^D512		;TT NOW HOLDS REMAINDER, WHICH IS
				; THE OFFSET INTO THE LAST PAGE
				; OF THE DIRECTORY
	SUB	T,TT		;=FREE SPACE ON LAST PAGE OF DIRECTORY
	PUSHJ	PP,@[EXP READ1,READ2](FR)	;PASS OVER DIRECTORY
	JRST	EXERR0		;
	SOJG	T,.-2		;LOOP UNTIL 1ST DATA PAGE IS IN
	tlne	fr,eof2sw	;2nd file ? [27]
	jrst	got2		;no [27]
	TRNN	FR,-1		;ARE WE READING IN FILE 1?
	AOJA	FR,EXSTF2	;YES, BUMP TO FILE 2 AND READ IT IN

;FALL THRU TO NEXT PAGE WHEN BOTH DIRECTORIES ARE READ IN
;WE MUST NOW SET UP THE CORRECT POINTERS AND COUNTERS FOR EACH
; DIRECTORY.
GOT2:	TRZ	FR,-1		;SET FILE 1
	PUSHJ	PP,MKNTRY	;SET UP AN IOWD FOR 1ST DIRECTORY ENTRY
	MOVE	S1,T		;RETURN WITH IOWD IN T
	TLNE	FR,EOF2SW		;[27] 2ND FILE?
	JRST	[HRLOI	S2,377777	;[60] NO, SET S2 HIGH
		 JRST	EXLOOP]		;[60] DO COMPARISON
	AOS	FR		;SET FILE 2
	PUSHJ	PP,MKNTRY	;SET UP IOWD FOR 1ST ENTRY HERE ALSO
	MOVE	S2,T		;SAVE IT IN S2

;HERE IS THE MAIN COMPARISON LOOP:

EXLOOP:	PUSHJ	PP,SETCNT	;[60] MOVE UP CNT IF POSSIBLE
	PUSHJ	PP,EXRED1	;READ A WORD FROM FILE1
	 JRST	[HRLOI	S1,377777	;[54] MAKE S1 TO BE VERY HIGH NUMBER SO
		 JRST	COMP10]	; SO S2 WILL CONTINUE TO PRINT
	PUSHJ	PP,EXRED2	;READ WORD FROM FILE2
	 JRST	[HRLOI	S2,377777	;[54] SAME FOR S2
		 JRST	COMP12]
	CAIG	CNT,132		;[113]
	CAIN	CNT,41		;[113]
	JRST	EXLOO1		;[113] COMPARE LOCS 41 AND GREATER THAN 132
	CAIN	CNT,44		;[113]
	JRST	EXLOO1		;[113] COMPARE LOC 44
	CAIGE	CNT,74		;[113]
	AOJA	CNT,EXLOOP	;[113] DON'T COMPARE LOCS 0-40 AND 42-73 SANS 44
	CAIG	CNT,76		;[113]
	JRST	EXLOO1		;[113] COMPARE LOCS 74-76
	CAIE	CNT,132		;[113]
	CAIG	CNT,111		;[113]
	AOJA	CNT,EXLOOP	;[113] DON'T COMPARE LOCS 77-111, 132
	CAIE	CNT,113		;[113]
	CAIN	CNT,114		;[113]
	AOJA	CNT,EXLOOP	;[113] DON'T COMPARE LOCS 113 AND 114
				;[113] HERE TO COMPARE LOCS 112, 115-131
EXLOO1:	TLNN	FR,EOF2SW	;DON'T COMPARE IF ONLY 1 FILE [27]
	CAME	W1,W2		;HERE IT IS!!!!!!!
	PUSHJ	PP,COMP2	;NO MATCH, PRINT LINE
	AOS	CNT		;[57] BUMP ADDRESS
	CAMLE	CNT,UPPER	;[57] HAVE WE FINISHED?
	JRST	FIN2		;[57] YES, EXIT QUICKLY
	JRST	EXLOOP		;[57] NO, TRY AGAIN
;Subroutine to form pointers from the current directory entry
;
;Call:
;	PUSHJ	PP,MKNTRY
;	Return here always
;
;On return, T will contain the address for the next word in
;the file.  EX1CNT or EX2CNT, as appropriate, will contain the
;negative of the number of words covered by this directory
;entry.
;
MKNTRY:	MOVE	TT,@[EXP DPTR1,DPTR2](FR)	;GET DIRECTORY POINTER
	LDB	T,[POINT 9,1(TT),8]	;GET REPEAT COUNT OF THIS ENTRY
	AOS	T		;=# OF PAGES IN THIS ENTRY
	IMUL	T,[-^D512]	;[43] =# OF WORDS IN THIS ENTRY
	MOVEM	T,@[EXP EX1CNT,EX2CNT](FR)	;[43] Store away
	HRRZ	T,1(TT)		;[43] GET PROCESS PAGE #
	LSH	T,9		;[43] MAKE INTO AN ADDRESS
	MOVEI	TT,40		;ASSUME THIS IS THE LOW SEG
	TRNN	T,-1		;IF THIS IS USER VIRTUAL PAGE 0
	PUSHJ	PP,SKPEXE	;SKIP UP TO LOC 41
	POPJ	PP,		;RETURN WITH ANSWER IN T
;SUBROUTINE TO READ ONE WORD FROM AN EXE FILE
;CALL:
;	PUSHJ	PP,EXRED1
;	 HERE IF EOF
;	HERE WITH WORD IN W1
;
EXRED1:	SETZ	W1,		;CLEAR WORD WHERE IT IS TO GO
	CAMGE	CNT,S1		;[54] DO THE FILE COUNTS MATCH UP?
	JRST	CPOPJ1		;NO, THIS FILE IS AHEAD OF THE
				; OTHER ONE, SO EXIT AS IF THE NEXT
				; WORD WERE A ZERO
	AOSG	EX1CNT		;[43],[60] Bump word count
	JRST	EXRD1A		;[43] Go get it
	MOVEI	T,2		;IF WE DIDN'T JUMP, THEN WE HAVE
				; EXHAUSTED THE CURRENT DIRECTORY ENTRY
				; AND WE MUST GET ANOUTHER ONE
	ADDM	T,DPTR1		;BUMP DIRECTORY POINTER BY 2
	TRZ	FR,-1		;SET FILE 1
	SOS	DLNG1		;DECREMENT LENGTH
	SOSG	DLNG1		;..IS THERE MORE IN THE DIRECTORY?
	POPJ	PP,		;NO, EXIT WITH ZERO
	PUSHJ	PP,MKNTRY	;MAKE A NEW IOWD FROM THIS DIRECT ENTRY
	MOVE	S1,T		;RESET S1
	TLNE	FR,EOF2SW	;[60] IS THERE A SECOND FILE?
	PUSHJ	PP,SETCNT	;[60] NO, SAFE TO RESET COUNT
	CAME	CNT,S1		;[60] HAVE WE JUMPED AHEAD OF FILE 2?
	JRST	CPOPJ1		;[60] YES, RETURN A ZERO
	AOS	EX1CNT		;[67] COUNT THE WORD WE ARE ABOUT TO READ
EXRD1A:	AOJ	S1,		;[60] BUMP ADDRESS
	HRRZ	T,@DPTR1	;GET CURRENT FILE PAGE #
	JUMPE	T,CPOPJ1	;IF ALLOCATED-BUT-ZERO, PRETEND THIS
				; IS A ZERO WORD
	JRST	READ1		;GO READ A WORD FROM FILE
;SUBROUTINE TO READ A WORD FROM EXE FILE #2
;
;CALLING CONVENTIONS SAME AS EXRED1
;
EXRED2:	SETZ	W2,		;CLEAR WORD
	CAMGE	CNT,S2		;[54] DO ADDRESSES MATCH?
	JRST	CPOPJ1		;NO, EXIT WITH 0
	AOSG	EX2CNT		;[43],[60] Bump word count
	JRST	EXRD2A		;[43] Go get it
	MOVEI	T,2		;DIRECTORY ENTRY IS THRU...
	ADDM	T,DPTR2		;...MAKE A NEW ONE
	HRRI	FR,1		;SET FILE 2
	SOS	DLNG2		;DECREMENT LENGTH
	SOSG	DLNG2		;MORE DIRECTORY ENTRIES?
	POPJ	PP,		;NO
	PUSHJ	PP,MKNTRY	;MAKE A NEW IOWD
	MOVE	S2,T		;SAVE IT IN S2
	TLNE	FR,EOF1SW	;[60] IS THERE A FIRST FILE?
	PUSHJ	PP,SETCNT	;[60] NO, SAFE TO RESET COUNT
	CAME	CNT,S2		;[54],[60] DID WE JUST LEAP AHEAD OF FILE 1?
	JRST	CPOPJ1		;YES,DEFER READ UNTIL FILE 1 CATCHES UP
	AOS	EX2CNT		;[67] COUNT THE WORD WE ARE ABOUT TO READ
EXRD2A:	AOJ	S2,		;[60] BUMP ADDRESS
	HRRZ	T,@DPTR2	;GET FILE PAGE #
	JUMPE	T,CPOPJ1	;IF ABZ, XIT WITH ZERO
	JRST	READ2		;GET A WORD FROM FILE 2


;SUBROUTINE TO READ A WORD FROM EITHER A REGULAR BINARY FILE
; OR AN EXE FILE. THIS ROUTINE IS CALLED ONLY ON EOF FROM 
; ONE OF THE FILES.
;
RDFIL1:	TLNN	FR,EXEBIT	;IS THIS AN EXE FILE?
	JRST	READ1		;NO, REGULAR READ
	JRST	EXRED1		;YES, EXE READ

RDFIL2:	TLNN	FR,EXEBIT	;EXE FILE?
	JRST	READ2		;NO
	JRST	EXRED2		;YES
;SUBROUTINE TO READ ONE WORD FROM EITHER
; EXE FILE
;
;CALL:
;	PUSHJ	PP,EXERED
;	RETURN HERE IF EOF (ERROR IF SO)
;	HERE WITH WORD IN W1
EXERED:	SETZB	W1,W2		;CLEAR BOTH
	PUSHJ	PP,@[EXP READ1,READ2](FR)	;READ A WORD
	 JRST	EXERR0		;BAD FORMAT (PREMATURE EOF)
	SKIPN	W1		;DID IT COME FROM FILE 1?
	MOVE	W1,W2		;NO, MOVE WORD TO W1
	POPJ	PP,		;RETURN


;SUBROUTINE TO SKIP OVER PART OF AN EXE FILE
;
;CALL:
;	MOVE	T,CURRENT-IOWD-POINTER
;	MOVEI	TT,# OF LOCS TO SKIP
;	PUSHJ	PP,SKPEXE
;	 RETURN HERE ALWAYS
;
SKPEXE:	PUSHJ	PP,@[EXP READ1,READ2](FR)
	 JRST	EXERR0		;ERROR
	AOSLE	@[EXP EX1CNT,EX2CNT](FR)	;[43]
	JRST	EXERR0		;[43] Should not occur
	AOJ	T,		;[43]
	SOJG	TT,SKPEXE	;[43] LOOP
	POPJ	PP,		;RETURN


;ROUTINE TO SET CNT TO LOWER OF S1,S2
;
SETCNT:	MOVE	CNT,S1		;[54] ASSUME IT'S S1
	CAMLE	CNT,S2		;[54] IS IT?
	MOVE	CNT,S2		;[54] NO
	POPJ	PP,
;THIS CODE EXPANDS SAV FILES BEFORE COMPARING THEM

READ1X:	PUSHJ	PP,READ1	;GET A WORD
	JRST	SAV9		;[32] EOF SEEN
	MOVE	S1,W1		;STORE AOBJN WORD
	JUMPGE	W1,SAVER1	;NOT SAV FORMAT
	MOVEI	CNT,1(S1)	;JUST INCASE NO 2ND FILE
	POPJ	PP,

READ2X:	PUSHJ	PP,READ2	;SAME FOR SECOND WORD
	JRST	SAV19		;[32]
	MOVE	S2,W2
	JUMPGE	W2,SAVER2
	POPJ	PP,

SAV1:	SETZB	S1,S2
READX1:	PUSHJ	PP,READ1X
	JUMPL	S2,SAV2
READX2:	PUSHJ	PP,READ2X
SAV2:	MOVEI	CNT,1(S1)	;GET FIRST LOCATION
	CAILE	CNT,1(S2)	;IS IT SMALLER OF THE TWO?
	MOVEI	CNT,1(S2)	;NO,SO USE S2

SAV3:	SETZB	W1,W2
	CAIE	CNT,1(S1)	;DO WE WANT THIS WORD
	JRST	.+4		;NO
	AOBJN	S1,.+1
	PUSHJ	PP,READ1
	JRST	SAV9		;[32]
	CAIE	CNT,1(S2)
	JRST	.+4
	AOBJN	S2,.+1
	PUSHJ	PP,READ2
	JRST	SAV19		;[32]
	CAME	W1,W2
	PUSHJ	PP,COMP2
	JUMPGE	S1,READX1	;GET ANOTHER AOBJN WORD
	JUMPGE	S2,READX2
	AOS	CNT		;[57] BUMP ADDRESS
	CAMLE	CNT,UPPER	;[57] HAVE WE FINISHED?
	JRST	FIN2		;[57] YES, EXIT QUICKLY
	JRST	SAV3		;[57] NO, TRY AGAIN
SAVER1:	HLRZS	S1
	XORI	S1,(JRST)
	TRNN	S1,777000	;TEST FOR TRANSFER WORD
	JRST	SAV9		;[32]
	JSP	T,ERROUT
	ASCIZ	/?File 1 not in SAV format/

SAVER2:	HLRZS	S2
	XORI	S2,(JRST)
	TRNN	S2,777000
	JRST	SAV19		;[32]
	JSP	T,ERROUT
	ASCIZ	/?File 2 not in SAV format/

SAV14:	HLRZ	S1,W2
	XORI	S1,(JRST)
	TRNN	S1,777000
	JRST	FIN2
	MOVE	S2,W2
SAV9:	MOVEI	CNT,1(S2)	;[32]
SAV10:	CAMG	CNT,UPPER	;[22]
	PUSHJ	PP,READ2
	JRST	FIN2
	JUMPGE	S2,SAV14
	CAMGE	CNT,LOWER	;[22]
	JRST	SAV10A
	PUSHJ	PP,TYCNT
	PUSHJ	PP,TYPTB2
	MOVE	T,W2
	PUSHJ	PP,TYPB
	PUSHJ	PP,TCRLF
SAV10A:	AOBJN	S2,.+1
	AOJA	CNT,SAV10

SAV24:	HLRZ	S2,W1
	XORI	S2,(JRST)
	TRNN	S2,777000
	JRST	FIN2
	MOVE	S1,W1
SAV19:	MOVEI	CNT,1(S1)	;[32]
SAV20:	CAMG	CNT,UPPER	;[22]
	PUSHJ	PP,READ1
	JRST	FIN2
	JUMPGE	S1,SAV24
	CAMGE	CNT,LOWER	;[22]
	JRST	SAV20A
	PUSHJ	PP,TYCNT
	MOVE	T,W1
	PUSHJ	PP,TYPB
	PUSHJ	PP,TCRLF
SAV20A:	AOBJN	S1,.+1
	AOJA	CNT,SAV20
;ERROR MESSAGES FOR EXE FILE PROCESSING
;
;
;COME HERE IF EITHER FILE WAS NOT A EXE FILE
EXERR0:	TRNE	FR,-1		;WAS IT FILE 1?
	JRST	EXERR2		;NO
	JSP	T,ERROUT	;YES
	ASCIZ	/?File 1 not in correct EXE format/

;HERE IF FILE 2 IS BAD
EXERR2:	JSP	T,ERROUT
	ASCIZ	/?File 2 not in correct EXE format/

;HERE IF CAN'T READ DIRECTORY
CORERR:	JSP	T,ERROUT
	ASCIZ	/?Not enough core available to hold directory/
SYMPTR:	POINT	7,LSTSYM+SYMBOL	;[76] [104] POINTER TO LAST SYMBOL
DOLPTR:	POINT	7,LSTSYM+$SYMBL	;[76] [104] POINTER TO LAST LOCAL SYMBOL

	RELOC			;IMPURE AREA

PPSET:	BLOCK	LPDL		;PUSH DOWN LIST STORAGE

CTIBUF:	BLOCK	3
CTOBUF:	BLOCK	3
INBUF1:	BLOCK	3
INBUF2:	BLOCK	3
ERRCNT:	BLOCK	1		;DIFFERENCES COUNTER (0 MEANS NO DIFFERENCES)
DIFFLG:	BLOCK	1		;"DIFFERENCE IN PROGRESS" FLAG (0 MEANS NO DIFF)

INDEV1:	BLOCK	1

INDIR1:	BLOCK	4+3+MAXSFD+1
INDPPN:	BLOCK	1		;HOLD PROJECT,PROGRAMMER #

PTHBLK:	BLOCK	MAXSFD+4	;SFDS,OVERHEAD AND 0 DELIMITER WORD

OUTDEV:	BLOCK	1		;OUTPUT DEVICE
OUTEXT:	BLOCK	1		;FLAG FOR EXTENSION SEEN ON OUTPUT
OUTDIR:	BLOCK	4+3+MAXSFD+1

FILCNT:	BLOCK	1		;COUNT OF CURRENT FILE

TOP:				;CONTAINS # LINES ACTUALLY STORED IN BUFFER FOR:
TOP1:	BLOCK	1		;FILE #1
TOP2:	BLOCK	1		;FILE #2

LBUFP:
LBUFP1:	BLOCK	1		;POINTER TO BEGINNING OF LINE STORAGE FOR FILE #1
LBUFP2:	BLOCK	1		;DITTO FILE #2

CRSEEN:	BLOCK	2		;[44] DECIDE WHAT TO DO WITH CR'S
OLDCHR:	BLOCK	2		;[44] HOLDS THE CHAR AFTER THE CR

P1:	BLOCK	1		;BYTE POINTERS USED BY "COMPL" SUBROUTINE
P2:	BLOCK	1

HPOINT:	BLOCK	1		;HOLD BYTE POINTER FOR CREATING HEADERS
; *** KEEP THE NEXT 4 BLOCKS IN ORDER ***
HBUF1:	BLOCK	^D14		;[51] HOLDS HEADER FOR FIRST FILE
HBUF1D:	BLOCK	^D6		;[51] ITS CREATION DATE
HBUF2:	BLOCK	^D14		;[51] FOR SECOND FILE
HBUF2D:	BLOCK	^D6		;[51] ITS CREATION DATE
;-- END OF SPECIAL ORDER --

HBPT1:	BLOCK	1		;[51] POINTER TO END OF HBUF1
HBPT2:	BLOCK	1		;[51] POINTER TO END OF HBUF2

PAGNUM:	BLOCK	2		;PAGE NUMBERS FOR THE TWO FILES
				;  LH(# AT BEGIN OF LINE), RH(# AFTER LAST CHAR)
PAGEN:	BLOCK	1		;TEMPORARY FOR PAGE #'S IN PLINEN SUBROUTINE
OLDNUM:	BLOCK	2		;LAST LINE # USED IN "SETONE"
OLDPNT:	BLOCK	2		;LAST BYTE POINTER CALCULATED BY "SETONE"

SAVEXS:	BLOCK	17		;STORAGE FOR AC'S WHEN PRINTING PAGE HEADERS

TEMP:	BLOCK	1
LINCNT:	BLOCK	1
RTNTMP:	BLOCK	1		;RETURN ADDRESS FOR "MULTI" SUBROUTINE
WCADR:	BLOCK	1		;TEMP IN GLINE SUBROUTINE
HIGH:	BLOCK	1		;USED BY NOROOM
ROOM:	BLOCK	1		;USED BY "NOROOM"
GETCNT:	BLOCK	1		;# LINES (-1) "GETTWO" GOT
GETFIL:	BLOCK	1		;# OF FILE FROM WHICH "GETTWO" GOT LINE (.L. 0 IF NONE)
NUMLIN:	BLOCK	1		;# LINES FOR A MATCH
NUMTMP:	BLOCK	1		;TEMP FOR NUMLIN
USERL:	BLOCK	1		;WRITE-ONCE COPY OF NUMLIN
TEMPF1:	BLOCK	1		;TEMP FOR F1
TEMPF2:	BLOCK	1		;TEMP FOR F2
EXTFL1:	BLOCK	1		;DEFAULT FLAGS FROM EXT OF FILE 1
EXTFL2:	BLOCK	1		;DITTO FOR FILE 2
LSEEN:	BLOCK	1		;[21] -1 IF /0000L SEEN
USWFLG:	BLOCK	1		;[34] -1 if /U but not /L
TNMLIN:	BLOCK	1		;[34] Temporary NUMLIN
QSW:	BLOCK	1		;-1 IF /Q SEEN
FWA1ST:	BLOCK	1		;[63] 0 MEANS SAW FULL WORD ADDRESS 1ST TIME
DIG:	BLOCK	1		;[63] NUMBER OF DIGITS
XITFLG:	BLOCK	1		;[45] -1 IF WE EXIT AFTER COMMAND
;EXE FILE TEMPS
DIRCTR:	BLOCK	1	;TOTAL LENGTH OF ENTIRE DIRECTORY
DPTR1:	BLOCK	1	;POINTER TO DIRECTORY FOR FILE 1
DPTR2:	BLOCK	1	;SAME FOR FILE 2
DLNG1:	BLOCK	1	;COUNTER FOR DIRECTORY LENGTH OF FILE 1
DLNG2:	BLOCK	1	;SAME FOR FILE 2
EX1CNT:	BLOCK	1	;[43] Word count for file 1 directory entry
EX2CNT:	BLOCK	1	;[43] Same for file 2
;END OF EXE TEMPS
OFSSWT:	BLOCK	1		;[76] SET IF LABEL OFFSETS WANTED
OPTSWT:	BLOCK	1		;[105] /T (KEEP OUTPUT FILE) SPECIFIED
OPISWT:	BLOCK	1		;[117] /I (IGNORE CASE) SPECIFIED

LSTSYM:	PHASE	0		;[104] LAST SYMBOL SEEN IN INPUT BASE FILE
SYMBOL:	BLOCK	2		;[76] LAST SYMBOL SEEN IN FILE 1
$SYMBL:	BLOCK	2		;[76] LAST LOCAL SYMBOL SEEN IN FILE 1
SYMLIN:	BLOCK	1		;[76] NUMBER OF LINES SEEN SINCE LAST SYMBOL
SSBLTE==.-SYMBOL		;[76] LENGTH FOR BLT'S
	DEPHASE

SAVSYM:	BLOCK	SSBLTE		;[104]

NOHDR:	BLOCK	1		;[76] -1 IF UNEQUAL LENGTH FILES, PRINTED *******
PSYMB:	BLOCK	2		;[76] COPY OF SYMBOL WHILE SEEING IF IT IS ONE
VAR		;JUST IN CASE

ENDP:
RELOC		;DUMP LITS IN HIGH SEGMENT

	END	FILCOM