Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93k-bb - 10,7/direct/direct.mac
There are 64 other files named direct.mac in the archive. Click here to see a list.
	TITLE	DIRECT %7A(504) DIRECTORY LISTING CUSP
	SUBTTL	P.CONKLIN/PFC/JBC/DCE/MD/JEF/LLN/LCR/MHK/WCL/RDH  1-AUG-88

	SEARCH	JOBDAT,	MACTEN,	UUOSYM	;STANDARD DEFINITIONS
	SEARCH	SWIL			;SWIL PACKAGE DEFINITIONS

	.REQUE	REL:SWIL		;SWIL PACKAGE ROUTINES

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000

COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1987. ALL RIGHTS RESERVED.
\;END OF COPYRIGHT MACRO

	COMMENT	\

DIRECT  --  Perform directory listings

;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1987. 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.

\


;DIRECT VERSION IDENTIFICATION

MAJVER==7		;MAJOR VERSION LEVEL
MINVER==1		;MINOR (MAINTENANCE RELEASE) LEVEL
CSTVER==0		;CUSTOMER VERSION (WHO LAST . . .)
EDTVER==504		;EDIT LEVEL

%%DIRE==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>

IF2,<	PURGE	CSTVER,MAJVER,MINVER,EDTVER>
	SUBTTL	TABLE OF CONTENTS

;       	TABLE OF CONTENTS FOR DIRECT
;
;
;                          SECTION                            PAGE
;    1. REVISION HISTORY......................................   4
;    2. STANDARD MNEMONICS--REGISTERS, BITS, UUOS.............   7
;    3. INITIALIZE............................................  13
;    4. MAIN LOOP FOR COMMAND SCANNING........................  14
;    5. FILL IN DEFAULTS AFTER COMMAND SCANNING...............  16
;    6. PERFORM ONE DISK DIRECTORY LISTING....................  21
;    7. PERFORM MAG TAPE DIRECTORY LISTING....................  25
;    8. PERFORM MAG TAPE DIRECTORY LISTING--BACKUP/RESTORE....  34
;    9. PERFORM MAG TAPE DIRECTORY LISTING--FAILSAFE..........  38
;   10. PERFORM MAG TAPE DIRECTORY LISTING--SUBROUTINES.......  43
;   11. ROUTINE FOR DISK AND MAGTAPE DIRECTORY LINE...........  47
;   12. PERFORM DECTAPE DIRECTORY LISTING.....................  72
;   13. PERFORM TMPCOR DIRECTORY LISTING......................  75
;   14. MISC. DIRECTORY SUBROUTINES...........................  77
;   15. SUBROUTINES FOR LISTING OUTPUT........................  84
;   16. STORAGE............................................... 102
	SUBTTL	REVISION HISTORY

;%1 -- 6/71 WITH 5.03 MONITOR

;A)  REARRANGE TO USE SCAN.MAC AND ELIMINATE THE
;	BUILT IN SCANNER.  THIS GIVES INDIRECT FILES AND ALL
;	THE SCAN IMPROVEMENTS OVER SCANER.
;B)  EXPAND TOTAL LINE TO INCLUDE NUMBER OF LOOKUP FAILURES
;C)  FIX BUG ASSOCIATED WITH SYS: AND + UNDER 5.03
;D)  EXPAND TO HANDLE SUB-FILE DIRECTORIES.
;E)  REARRANGE TO USE REVAMPED LOKWLD (WILD)
;F)  IN /SORT, GIVE DATES AS " YYYYMMDD"
;G)  IN /SORT, LIST DIRECTORY IF AND ONLY IF THE REQUEST HAS
;	WILD CARDS IN THE DIRECTORY
;H)  IN /WIDTH, LIST STR OR DIRECTORY AS A SEPARATE LINE
;I)  IN /SORT, LIST STR IF AND ONLY IF DSK OR WILDCARDS
;J)  CHANGE DTA TO USE 300 MODE
;K)  ADD SWITCH /WORDS TO PRINT DISK LENGTHS IN WORDS NOT BLOCKS
;L)  IF MAG TAPE, INTERPRET FAILSAFE TAPE AS DISK DIRECTORY
;M)  OUTPUT VERSION IN FRONT OF STRUCTURE AND DIRECTORY
;N)  OUTPUT SPOOLED NAME (IF NON-ZERO) AT RIGHT END
;O)  /F/SUM WILL GIVE FAST LIST PLUS A SUMMARY
;P)  ADD FREE SPACE TO TMP: DIRECTORY
;Q)  /DETAIL WILL GIVE A LISTING LIKE LOOKFL DID (IE, ALL INTERESTING
;	ITEMS FROM THE EXTENDED LOOKUP
;R)  SUPPORT /DENSITY, /PROTECT, /PARITY SWITCHES FROM SCAN
;S)  DETECT ANSI-LIKE LABELS AND BACKUP TAPES
;T)  CORRECT A BUG WHICH GAVE EXTRA NON-EX. MESSAGES
;U)  ADD SUBTOTALS FOR EACH DIRECTORY AND STRUCTURE
;V)  INCLUDE CHECKSUM IN TOTALS
;W)  SUPPORT /BEFORE AND /SINCE
;X)  ADD /MARKS
;Y)  HANDLE + ON MTA, DTA, TMPCOR
;Z)  USE VERSION FROM RIB IF PRESENT.  IN /DETAIL, GIVE BOTH IF
;	DIFFERENT.
;AA)  REMOVE 'UFD' IN REGULAR LISTING SO COLUMNS LINE UP.
;AB)  USE 317 MODE ON DECTAPES.
;AC)  EXPAND ALL TABS IN /SORT MODE
;AD)  FIX TYPE/LIST LOGIC TO NOT TYPE TITLES, OR DOUBLE TYPE SUMMARIES.
;AE)  FIX BUG TO CORRECTLY SUPPRESS TRAILING TABS.
;%2(125) -- 5/72 WITH SCAN AND WILD

;126	(7613) LIST DIRECTORIES IF WILD AND /SORT
;127	MOVE SWITCHES AIMED AT F TO WORD FLAGS FOR SCAN %3
;	ALSO MOVE S.LODV AND S.TITL TO S.MIN AREA.
;130	CALL .OSCAN TO IMPLEMENT USER OPTIONS
;	ALSO ADD /NORMAL TO OVERRIDE /FAST IN OPTIONS FILE
;131	(8314) SUMMARY OF LOOKUP ERRORS WAS PREMATURE
;132	(8280) DIRECTORY CHECKSUMS WERE INCORRECT IN SUMMARY
;133	(QAR 149) NEEDED 3 EOFS TO END MAG TAPE
;134	(7635) CORRECT MAG TAPE SUB-TOTALS TO COME AT RIGHT TIME
;135	HANDLE FILE NOT MATCHING ON MAG TAPE
;136	OUTPUT RIB INTERNAL FORMAT CREATION TIME IN HUMAN TERMS
;137	(7613) IF /SORT, LIST DIRECTORIES AS 2*6 DIGITS
;140	CORRECT FORMATTING ERROR IN FIXED FORMAT OCTAL 7.
;141	ADD /NOREWIND, /NOEOT, /FILES:N  (QAR 177)
;142	FIX /MARKS TO INDICATE LAST EOF AS WELL (IE, EOT)
;143	CORRECT NULL DEVICE BUG INTRODUCED BY 127.
;144	CORRECT INF.0 BUG INTRODUCED BY 140.
;145	RESTORE .JBFF EACH OPEN. ALSO USE 10. BUFFER RING ON DISK INPUT
;146	ADD /NOSUMMARY, /NODETAIL, AND /NOUNITS.
;147	IF /DETAIL/SUMMARY, DO BOTH. IF /NOSUM NEVER GIVE ONE. IF
;	/NOUNITS, ALWAYS GIVE STR.
;150	IF /SORT, ALLOCATE 15 COLUMNS FOR VERSION
;151	/SORT OF MTA FAILED TO INCLUDE STRUCTURE
;152	IF /SUM, ALWAYS INCLUDE SUMMARIES

;%3(152) 12/72

;153	(10-9943) GET LAST SUB-TOTAL
;154	(10-10979) AVOID ILL UUO ON SOME COMMAND ERRORS
;155	(10-10590) AVOID "NO FILES" ON MTA:/F
;156	MTA BUFFER HEADER INDICATED LENGTH WAS 2 TOO BIG
;157	DEFAULT /OKPROT IF WILDCARDS IN UFD
;160	IF OUTPUT NOT TO TTY:, FORCE ALL SUMMARIES
;161	(10-9981) REJECT NUL: GRACEFULLY IN 5.07
;162	SUPPORT DATE75
;163	HANDLE INDEFINITE NUMBER OF INPUT FILES IN SPEC
;164	STANDARDIZE ERROR MESSAGES
;165	CHANGE TO USE .STOPN TO SUPPORT OUTPUT SFD
;166	GIVE RIGHT MESSAGE ON MTA ERRORS
;167	HANDLE NULL COMMAND (BUG IN EDIT 163)
;170	FIX BUG IN 155
;171	(10-XXXX) PRINT LH(.RBELB) AS CONI IN OCTAL
;172	PICK UP 507 MTCHR. DATA ON TAPES
;173	(10-10324) USE % PREFIX ON FILE NOT FOUND
;174	(10-11580) ADD /AUTHOR /PRDIRECTORY /PRDEVICE
;175	SUPPRESS TOTAL OF 0 FILES MESSAGE
;176	FIX BUGS IN EDIT 162
;177	FIX FORMAT BUG IN 173
;200	(10-11,233) PRINT RIB BLOCK NUMBER IN /DETAIL
;201	COUNT BLOCKS ON DTA FOR /SUM LINE
;202	SUPPRESS TITLES ON DTA, TMP LISTINGS
;203	COMMENT OUT BACKUP/RESTORE CODE
;204	USE C,SCNMAC AS UNIVERSALS
;205	PRINT SUMMARIES BEFORE SUBSEQUENT ERROR MESSAGES
;206	PRINT UFD NAME AS [P,PN] IN FILE READING ERROR MESSAGE
;207	LIST SFD CONTENTS AFTER DIRECTORY CONTAINING SFD
;210	EXTEND 164 TO SUPPORT /MESSAGE LEVEL
;211	REMOVE BUG OF LISTING [,,SFD] TWICE
;212	IN /F WITHOUT /W, GIVE NAME.EXT FOR SPEED
;213	RECOGNIZE SIXBIT TAPE LABELS
;214	(10-11,493) FORCE OUTPUT AT END OF DIRECTORY IN /F
;215	(10-12,805) INDICATE THAT /DEN/PAR ARE AS READ, NOT AS WRITTEN
;216	(10-12,995) WARN OF PARITY ERROR ON DTA, BUT STILL GIVE DIRECTORY
;217	DON'T FORCE OUTPUT ON A TAB
;220	(10-13049) IMPLEMELT /SUM IF DTA, TMP
;221	(10-13048) IMPLEMELT /CHECK, /AUTH, /ACCESS IF IN /F
;222	EXCLUDE THE RIBS FROM MTA CHECKSUM
;223	HANDLE /F/SUM TO NOT SAY 0 BLOCKS
;224	FIX MISC BUGS SINCE V. 3
;225	(10-13458) ADD /FDTA
;226	(QAR 2173) ALLOW DTA3:=DTA3:, ETC.
;227	CANCEL 157
;230	ADD FRS FORMAT AND PRELIMINARY BACKUP FORMAT
;231	ADD FS.NFS
;232	SUPPORT .OSDFS
;233	SUPPORT /OKPROTECTION
;234	(Q2811-2) CANCEL 227 WITH FT$IPF

;%4(234) 11/74

;235	(10-14824) CORRECTION FOR FRS FORMAT
;236	(10-14820) REMOVE DOT IN F.EXT WHEN /F/SORT
;237	(10-14828) FIX PROBLEM WITH FILE CONSTRAINTS BEING IGNORED
;240	(10-14942) FIX PROBLEM WITH JUNK LABELS CAUSING ILL MEM REF
;241	(10-14972) FIX BAD MFS ERROR MESSAGE DURING FRS DIRECTORIES
;242	(10-14975) FIX FRS TAPE ERROR PROCESSING FOR ILL UUO, ETC.
;243	(10-15399) FIX FRS %DRTJFS ERROR FOR NULL FILES
;244	(10-15717) FIX BUG CAUSING ALL FILE OUTPUT TO BE
;		DUPLICATED ON TTY AFTER PREFIX-ONLY "DRTLKE"
;245	(10-16555) BREAK FOR SUBTOTALS CORRECTLY AND
;		SHOW UNIT ONLY WHEN /UNITS
;246	(10-16552) /SORT SUPPRESS PUTTING DIRECTORY AND
;		STRUCTURE ON SEPARATE LINE IN /WIDTH
;300	(10-15,415) IMPROVE EDIT 243
;301	FIX BACKUP BUGS
;302	SUPPORT REWORKED BACKUP FORMAT TO /INTERCHANGE LEVEL
;303	CHANGE ASSEMBLY PROCEEDURE TO USE .REQUEST
;304	CHANGE SYMBOLS F$???? TO B$????
;305	FIX BUG IN FRS/CHECKSUM IF DISK FILE WAS 4(MOD 5) BLOCKS
;306	SUPPORT .EXE FILES
;307	(S70-427) BUG-SUPPRESS DIRECTORY FROM SUMMARY
;		IF 2 ONE FILE OUTPUTS
;310	(Q2489) LIST VERSION Z, AZ, BZ CORRECTLY
;311	(Q2990) SPEED UP BY LETTING WILD KEEP CHANNEL 0 OPEN
;312	DON'T FORCE LINES ON LPT:
;313	(S55-134) CLEAR INITIAL FLAGS SO TCHR OK FROM .ISCAN
;314	(S70-152) CHANGE "INPUT" TO "SOURCE" IN MESSAGES
;315	ADD FEATURE TESTS FOR MAGTAPE CODE
;316	EXTEND 302 TO FILES NOT STARTING AT 0
;317	ADD /COMPARE TO SUPPRESS ALL OVERHEAD LINES
;320	(SER 55-219) IMPROVE /W WITH /N, ETC.
;321	REMOVE WAIT FOR LPT (VIA FT$LPW)
;322	ADD /INDIRECT TO MAKE AN INDIRECT FILE
;323	(QAR 3647) FIX PRINT DECISION ON /UNITS
;324	REMOVE EXTRA BLANK LINES INADVERTENTLY INSERTED
;		BY EDIT 307
;325	USE JOBDAT AS A UNIVERSAL; CHANGE EXTERNS TO ##
;326	CORRECT BUG IN WHICH OUTPUT FILE DIRECTORY WAS IGNORED
;327	REMOVE BLANK LINES ON /SUMMARY
;330	PERMIT /W FOR DECTAPES TOO
;331	FIX LISTING OF BACKUP FORMAT MAG-TAPE WITH SFD'S
;332	(SPR-17317) SEARCH SYS AFTER NEW IF ERSATZ DEVICE SYS
;	REQUESTED AND /NEW ENABLED.
;333	MAKE VERSION CHECKING FOR .EXE FILES WORK
;334	MAKE [226] WORK WHEN EXPLICIT EXTENSION GIVEN (OR NOT A DISK)
;335	CLEAN UP LISTINGS UNDER /TITLE (NOTE THAT THE "SPOOLING"
;	WORD IS NOT REALLY HANDLED - SPACED - CORRECTLY YET)
;336	FIX /NOPRDEVICE & /NOPRDIRECTORY WITH /INDIRECT
;
;%5(336) 5/76
;
;337	(10-19832) Fix problems with edit 221 to allow /ACCESS
;	when running /F mode.
;340	(10-19987) If /L is being used, always send
;	output to the LPT:, unless an explicit output
;	device is specified.
;
;341	SPR # 10-20668	L.C.R	28-Oct-76.
;	Allow for a file length  of up to 8 digits so that the /SORT
;	/WORDS switches can be used together.
;	Areas affected: FLEXT5+4, LDEC8:, to LDEC5:
;
;342	SPR # 10-21432	L.C.R	18-Jan-77.
;	Make DIRECT ignore /AUTHOR when using /INDIRECT.
;	Areas affected: INDEF2 +15(6).
;		NOTE:: Also changed DIRECT to search MACTEN & UUOSYM
;		       instead of C.
;
;343	SPR # 10-21445	L.C.R.	18-JAN-77.
;	Allow for a 'UFD' of up to four digits so that the listing
;	is aligned when using the /SORT switch even when combined
;	 with the /WORDS switch.
;	Areas affected: FLEXT3: + 4.
;
;344	SPR # 10-21921	L.C.R.	15-FEB-77.
;EDITS 344-357 ARE RESERVED FOR MAINTENANCE FIXES
;
;	Make DIRECT check the concatenation requirements
;	before counting any lookup errors.
;	Areas affected:	E.DFLL.
;
;345	SPR #10-21653 AND 10-21654	LCR.	28-FEB-77.
;	Make direct give the correct file lenght when the format is unknown,
;	also clear the R.MTOH bit when done with a mag tape
;	DIRECT will give the correct checksum if the file comes from DISK.
;	Areas affected: MTSVST,
;			MTDONX, ADD LABEL KCHKSM TO HOLD THE CURRENT CHECKSUM TEPMORARALY.
;

;346	When printing the length of a file, check to see
;	if the /WORDS switch was specified
;	before spacing to 8 places.
;
;347	SPR # 10-22018	LCR.	07-JUN-77.
;	Teach DIRECT to check the file requirements before doing the LOOKUP
;	in order to avoid unnecesary LOOKUPs when using the construct
;	.DIRECT SYS:'NOT'.EXE
;	Areas affected: DOLOK1:.
;
;350	SPR # 10-22319   LCR	27-JUN-77.
;	Make /COMPARE more intelligent when doing a directory of
;	non-standard file names IE: [1,1]
;	Areas affected:	FLUFD:,LCHR1:. also create new label S.FUFD
;
;351	SPR # 10-22614	LCR.	30-JUN-77.
;	Teach DIRECT not to print a line over the WIDTH limit when using /F/W:x.
;	Areas affected:	GLDEF2:, FILEND:,
;			create label S.LENT to hold the maximun length of an entry
;
;352	SPR # 10-23040	MHK	30-AUG-77
;	TEACH DIRECT TO RECOGNIZE THE /NOPRDEV AND /NOPRDIR SWITCHES
;	WHEN THE /WIDTH SWITCH IS SET.
;	AREAS AFFECTED: SSTRD7+11
;
;%6(400)
;
;400	ADD SUPPORT FOR NEW WORDS DEFINED IN THE RIB BY 6.03
;	UNITS WRITTEN WORD, LAST ACCOUNTING DATE/TIME (UFD), EXPIRATION
;	DATE/TIME (UFD), AND ACCOUNT STRING (FILE RIB)
;
;401	NO SPR	LCR	09-06-77.
;	FIX THE /TIME SWITCHES. THIS CODE WAS BROKEN BY EDIT 347.
;	AREAS AFFECTED: DOLOK1 + 3.
;
;402	SPR # 10-22690	LCR	09-SEP-77.
;	Eliminate the multiple printing of crlf's
;	as well as title lines on empty pages.
;	Areas affected: TITLEX,LCRLF,LCHR1
;			  Create new flag  L.CRLF
;
;403	NO SPR #	LCR	16-SEP-77.
;	Move the label S.FUFD down from the S.MIN area
;	so that /COMPARE is not ignored.
;	Area affected: S.FUFD
;
;404	NO SPR #	LCR	21-SEP-77.
;	Move three lines of code at DOLOK1 down to DOLOK3
;	before the LOOKUP.
;	This will insure that AC T1 has the correct information
;	for the LOOKUP.
;	This cures the problem of DIRECT printing garbage on the
;	lenght field when using the "OR" or the "+" notation.
;	Areas affected: DOLOK1, DOLOK3
;
;405    SPR # 10-25184  WCL     30-MAY-78.
;       Avoid checksumming files when searching for Version No. unless
;       specifically requested
;	Areas affected: NEXDT3
;
;406	SPR # 10-24955  WCL     31-MAY-78.
;	Make PDL 20 words longer (LN$PDL)
;
;407	SPR # 10-24595  WCL	1-JUNE-78.
;	Much time wasted looking for 1776 identification code in block header
;	preparatory to searching for .JBVER if file is null (CRASH.EXE for example);
;	make it ignore version search if first word of file = 0
;	Areas affected: VERE.1
;
;410	SPR # 10-25016  WCL	23-JUNE-78
;	Make aware of new format of RIBELB (same as BAFELB)
;	Areas affected: DLERRB
;
;411	SPR # 10-26027  WCL	11-JULY-78
;	Checksums taken incorrectly under certain circumstances; CHKSUM
;	not zeroed after every file
;	Areas affected: LCHECK
;
;412	RDH	22-AUG-78
;	ADD /FNDDAT SWITCH TO GENERATE FIND DATABASE OUTPUT. ADD
;	/DIRECT TO GENERATE ASCII LISTING OUTPUT. ADD /MVOLUM TO
;	ASK OPERATOR TO MOUNT MULTI VOLUMES FOR BACKUP SAVESETS.
;	DEFAULT /WID FOR TTY TO TTY-WIDTH ELSE AD.WID; ADD NEW
;	SWITCHS /FLSDIR TO PRINT FIRST-LINE STR/DIR (CURRENT DE-
;	FAULT) AND /HDSDIR TO PRINT STR/DIR AS "HEADER" (AS CUR-
;	RENTLY DOES ON /WID). ADD /PRVERS TO FORCE PRINTING
;	(/NOPRVE TO SUPPRESS ALWAYS) THE VERSION FIELD. SPEED
;	UP CHECKSUMMING.
;
;413	RDH	14-SEP-78
;	[412] MESSED UP /INDIRECT
;
;414	RDH	24-NOV-78
;	[412] CONFUSED TOTALS IF /WORDS; MAKE /ACCESS TAKE LARGE
;	VALUES.
;
;415	VLR	14-SEP-78	SPR # 10-26384
;	"+" Notation not working for directories of Mag tapes.
;	Areas affected: MTDONX
;
;416	RDH	22-DEC-78
;	ADD /[NO]RETRY TO CONTROL AUTOMATIC MONITOR RETRY ON I/O ERROR
;	SO CAN FIND SOFT ERROR FILES WHICH BOOTS CAN'T READ.
;
;417	RDH	21-JAN-79
;	HANDLE MORE GRACEFULLY (THAN ?ILL MEM REF) INTERCHANGE TAPES
;	WRITTEN BY DUMPER (WHICH LEAVES ALL SORTS OF JUNK ON THE TAPE).
;
;420	RDH	3-NOV-79
;	CHANGE /FNDDAT TO /FNDBLD, ADD /FIND TO READ THE DATA FILES
;	WRITTEN BY /FNDBLD, ADD /FNDDAT:<FILE> TO SPECIFY THE DATA FILES
;	TO READ ON /FIND (DEFAULT IS SYS:FNDDAT).
;
;421	RDH	8-NOV-79
;	FIX CASE OF "ACCOUNT" IN DETAILED LISTING. KEEP DIRECTORY OPENED
;	ON SEPARATE CHANNEL. THIS SPEEDS UP DIRECTORY LISTINGS OF AREAS
;	OTHER THAN JOB'S PATH BY ABOUT 20%.
;
;422	RDH	20-NOV-79
;	/NOMARKS TYPED EXPLICITLY AS COMMAND GETS OVER-RIDDEN BY /MARKS
;	IN SWITCH.INI; JUNK TAPES (E.G., WRITTEN BY PIP) ATTEMPT TO LIST
;	CHECKSUM EVEN IF NO CHECKSUM HAS BEEN CALCULATED.
;
;423	RDH	4-JAN-80
;	421 DIDN'T QUITE WORK. ELAPSED TIME FOR DIRECTORIES OTHER THAN
;	JOB'S PATH IS REDUCED BY APPROXIMATELY ONE HALF (SINGLE RP04, LOTS
;	OF SMALL (TYPICALLY 10-20 FILES) DIRECTORIES.
;
;424	RDH	2-FEB-80
;	FIND DATA FILES CREATED WITH BUM CREATION DATE BY ZAPPING RH(.RBEXT).
;
;425	DC	4-MAR-80
;	ON MAGTAPES, TRY TO PRINT HEADER INFO FROM .TFLPR TAPOP.
;
;426	RDH	11-MAY-80
;	ALLOW FILE LENGTHS TO BE 5 DIGITS WIDE
;
;427	TARL	21-JULY-80	SPR 10-29355
;	INCORRECT PATH WHEN GIVING A FULL FILE-SPECIFICATION AND
;	/SCAN, /LIB, /SYS, OR /SEARCH ARE SET. DO PATH. UUOS
;	MORE OFTEN.
;
;430	RDH	22-JUL-80
;	C(.RBDED) = .INFIN MEANS "ETERNITY".
;
;431	RDH	15-SEP-80	QAR 10-04624
;	.RBXTR OFF BY ONE (TOO SMALL)
;
;432	RDH	24-SEP-80	QAR <ASSORTED>
;	TYPE OUT MORE INFORMATION ON I/O ERRORS, IN PARTICULAR, READ
;	AND LIST THE "EXTENDED I/O ERROR" STATUS. ADD /[NO]ERLOG TO
;	CONTROL ERROR LOGGING. SUPPRESS TAPE LABEL GENERATION AND
;	VERSION IF ZERO.
;
;433	RDH	27-OCT-80	QAR 10-04838
;	EMBEDDED BLANKS IN /INDIRECT OUTPUT.
;
;434	RDH	27-OCT-80	QAR 10-04841
;	-1 DOESN'T SUCCESSFULLY FOOL WILD IF USER HAS SETSRC-STYLE LIB:
;	DEFINED.
;
;435	RDH	20-NOV-80	QAR 10-04971
;	EDIT 427 DOESN'T WORK; "MOVEI" SHOULD BE A "MOVE"
;
;436	RDH	7-JAN-81	QAR 10-05221
;	IF ON A LABELED TAPE (MEANING PROCESSED BY PULSAR) NO GENERATION
;	IS PRESENT THE TRAILING QUOTE GETS LEFT OFF OF THE NAME STRING.
;
;437	RDH	13-JAN-81	QAR 10-05244/05265
;	DEFEAT EDIT 427 UNTIL WILD VERSION 7 B GETS TO THE FIELD
;	(ERSATZ:FILE.EXT FAILS)
;
;440	RDH	2-JUN-81	QAR 10-05956
;	/FNDBLD/NODIRECT NOT AS FAST AS IT SHOULD BE
;
;441	AWC	12-JUN-81	QAR 10-06068
;	FIX DIRECTORIES OF LABELED MAG TAPES
;
;DIRECT %6(441) RELEASED JUNE, 1981
;442	AH	3-MAY-82	SPR # 10-32298
;	DIRECT/WIDTH:80 DOES NOT DISPLAY IN 2 COLUMNS
;	This edit undoes [412] in so far as the default width of the
;	/NORMAL directory listing is concerned - [412] made DIRECT assume
;	a default of 8 spaces for the version field if no /[NO]PRVERSION,
;	0 if /NOPRVERSION, and 16 if /PRVERSION. Revert to simply 0 unless
;	/PRVERSION, in which case use 16. This will mean /NORMAL listing
;	will try to fit into 40-space columns (so that 2 will fit into
;	80-column TTYs), but if a version field gets typed then the column
;	will be messed up (this is what DIRECT used to do prior to [412]).
;
;
;443	AH	08-JUL-82	SPR 10-32768
;	DIRECT/WIDTH:80 EXTENDED PAST COLUMN 80 AND WRAPPED AROUND
;	EDIT [351] dealt with DIRECT/F/W:X so that it would not wrap around.
;	DIRECT/W:X now acknowledges the width if /F is or is not used
;	If a directory is going to be larger than 80 columns
;	a new directory line is output.
;
;444	RDH	16-Aug-82	SPR 10-31928
;	/INDIRECT of a magtape confused the structure name of the first
;	file for each structure.
;
;445	ERS	20-SEP-82	SPR 10-32184 
;	Make DIRECT/ACCOUNT/SORT space correctly.
;
;446	ERS 	20-SEP-82
;	DIRECT/SORT/NOPRDEV (or DIRECT/SORT dev:) does not create fixed length
;	records which is useful in SORTing.
;
;447	RDH	1-FEB-83	SPR 10-33339
;	More tape-label-error message problems.
;	NO SPR
;	Address check if /FNDBLD/DIRECT - OUTIN set E.LC one too large.
;
;450	BAH	11-Mar-83	SPR 10-33633
;	A directory of an FRS-formatted tape containing SFDs does not print
;	the SFD on the summary line.
;
;451	RDH	3-Jan-84	SPR 10-33907
;	/TITLE misaligned if /WORDS specified.
;
;452	RDH	3-Jan-84	SPR 10-33368
;	/PRDIR/PRDEV confuses multi-column listing (/WIDTH) if /HDSDIR
;
;453	AQH/RDH	3-Jan-84	SPR 10-34256
;	/MVOLUME doesn't work with MDA-controlled tapes (/LABEL:USER-EOT)
;
;454	RDH	12-Jan-84	SPR 10-32532
;	/FNDBLD of a BACKUP/INTERCHANGE tape writes garbage for directories.
;
;455	RDH	12-Jan-84
;	Add new DEVOP. error codes
;
;456	RDH	20-Mar-84	SPR 10-34253
;	/MVOLUME confused by multiple save-set names on continuation tapes

;457	RDH	25-Mar-84
;	Create DIRECT version 7 from "DIR" sources, consolidate all directory
;	listing formats, add /DTA and /TMPCOR switches to get "old" DECtape
;	and TMPCOR listing formats, remove /FDTA, use SWIL (supersedes %7
;	SCAN/WILD/HELPER).
;
;460	RDH	23-Oct-84
;	Make /ALLOCATE switch "*" unique, as it conflicts with the SWIL
;	switch of the same name; remove /BLOCKS switch as it conflicts
;	with the SWIL switch of the same name, instead make /NOWORDS do
;	the same thing. Teach DIRECT to respect the /BLOCKSIZE and /BUFFERS
;	switches for magtape support.
;
;461	RDH	22-Jan-85
;	Add .RBTYP/BSZ/RSZ/FFB fields to /DETAIL listing format.
;
;462	RDH	2-Feb-85	SPR 10-35076
;	Issue the "Attributes May be Wrong" message no more than once
;	per tape save set.
;
;463	RDH	13-Feb-85	SPR 10-34249
;	Spurious "%Tape mark..." messages
;
;464	RDH	13-Feb-85	SPR 10-34253
;	Inform user of BACKUP file which crosses volume boundry, and
;	list the file only when actual EOF is reached.
;
;465	RDH	14-Feb-85	No SPR
;	BACKUP doesn't light GF$RPT for repeater records, so look for
;	record number being repeated (otherwise reported file checksum
;	is wrong). Add DRTSBR Skipping record message to indicate that
;	a BACKUP/FRS repeater record was encountered. Add /SBRMSG to
;	control issuance of said message (default is no message).
;
;466	RDH	15-Feb-85	SPR 10-34255
;	/MVOLUME may fail for INTERCHANGE tapes.
;
;467	RDH	8-JUN-85	QAR 868067
;	/DETAIL heading for .RBIDT wrong.
;
;470	RDH	25-Jul-85	SPR 10-35230
;	/ACCOUNT doesn't work for listing BACKUP-format tapes - the
;	account string is not copied from the file attributes block
;	on tape into the "LOOKUP" block for typeout. Also setup .RBIDT.
;
;471	RDH	25-Jul-85
;	Setup .RBIDT, and .RBTYP and friends from BACKUP tape. Other mis-
;	cellaneous code "cleanup".
;
;472	RDH	14-Aug-85	SPR 10-35276
;	The automatic-buffer-expansion code didn't get along well with PULSAR.
;	Remove a "CLOSE" that doesn't seem to do anything.
;
;473	RDH	14-Aug-85
;	AN MTBSR. operation on a labeled tape causes the label info to be lost,
;	causing bad label typeout from DIRECT. This is a MONITOR/PULSAR problem,
;	but not likely to be fixed immediately, so provide a workaround in
;	DIRECT until the real problem is fixed (and this edit can be removed).
;
;474	LEO	16-AUG-85
;	DO COPYRIGHTS.
;
;475	RDH	26-Dec-85
;	Summaries wrong if first file(s) in a directory is(are) protected.
;
;476	RDH	26-Dec-85
;	[443] leads to premature <CR><LF> if /F/W and listing a file with
;	a non-null version (e.g., SYS:*.EXE/F/W/LENGTH:1).
;
;477	RDH	26-Dec-85
;	MCO 12262 complicated DIRECT/WILD's handling of DECtapes. Make sure
;	to always RELEASe the DTA before each call to .LKWLD. Always RELEASe
;	the device when finally done (DIRED/DIRDON). Requires SWIL edit 1032
;	or later.
;
;500	RDH	28-Dec-85
;	File type (extension) should default to "*", not previous spec's
;	extension.
;
;501	RDH	18-Feb-86
;	Edit [475] lost leading error character ("%", "?", etc.) on error
;	messages.
;
;502	RDH	19-Feb-86
;	/DETAIL confused on (e.g.,) RP20/CI disks where unit number is
;	greater than 7(8) (the monitor leaves the unit field blank).
;
;503	BAH	19-JAN-87
;	Begin Version 7A.  Report the reelid stored in the records written
;	by BACKUP.
;
;504	DPM	 1-AUG-88
;	Add /BLOCKINGFACTOR:n switch to support large BACKUP records.
;
;	End of Revision History
VERWRD==<12,,%%FXVE>		;SCAN/WILD INTERFACE PROTOCOL VERSION


	LOC	.JBVER
	EXP	%%DIRECT
	RELOC
	SUBTTL	MACRO DEFINITIONS

;N$FAIL <XYZ,FOO> SENDS FOO WITH PREFIX "DRTXYZ" AS A FATAL ERROR

DEFINE	N$FAIL ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	PJSP	T2,ERROR
	XLIST
	ASCIZ	\$TEXT\
	LIST
>


;N$FAIX <XYZ,FOO> SEND FOO WITH PREFIX "DRTXYZ" AS START OF A FATAL MESSAGE
;FINAL CALL TO .TCRLF MUST BE LABELLED "X$$XYZ"

DEFINE	N$FAIX ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,ERRORC
	TXNN	T1,JWW.FL
	JRST	X$$'$PFX'
	LIST
>


;N$FAIN <XYZ,FOO> SENDS FOO WITH PREFIX "DRTXYZ" AS A FATAL ERROR
;WITH P3 IN SIXBIT

DEFINE	N$FAIN ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,ERRORC
	TXNN	T1,JWW.FL
	JRST	LFERX
	MOVE	T1,P3
	PUSHJ	P,.TSIXN##
	JRST	LFERX
	LIST
>
;N$FAID <XYZ,FOO> SENDS FOO WITH PREFIX "DRTXYZ" AS A FATAL ERROR
;WITH P3 IN DECIMAL

DEFINE	N$FAID ($PFX,$TEXT) <
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,ERRORC
	TXNN	T1,JWW.FL
	JRST	LFERX
	MOVE	T1,P3
	PUSHJ	P,.TDECW##
	JRST	LFERX
	LIST	
>


;N$FAIO <XYZ,FOO> SENDS FOO WITH PREFIX "DRTXYZ" AS A FATAL ERROR
;WITH P3 IN OCTAL

DEFINE	N$FAIO ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,ERRORC
	TXNN	T1,JWW.FL
	JRST	LFERX
	MOVE	T1,P3
	PUSHJ	P,.TOCTW##
	JRST	LFERX
	LIST
>


;N$FAII <XYZ,FOO> SENDS FOO WITH PREFIX "DRTXYZ" AS A FATAL ERROR
;WITH P3 IN I/O CHANNEL STATUS

DEFINE	N$FAII ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,ERRORC
	TXNN	T1,JWW.FL
	JRST	LFERX
	MOVE	T1,P3
	PUSHJ	P,IOERM
	JRST	LFERX
	LIST
>
;N$WARN <XYZ,FOO> SEND FOO WITH PREFIX "DRTXYZ" AS A WARNING MESSAGE

DEFINE	N$WARN ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
	MOVEI	T2,[ASCIZ \$TEXT\]
	PUSHJ	P,WARN
	PUSHJ	P,.TCRLF##
	LIST
>


;N$WRNX <XYZ,FOO> SEND FOO WITH PREFIX "DRTXYZ" AS START OF A WARNING MESSAGE
;FINAL CALL TO .TCRLF MUST BE LABELLED "X$$XYZ"

DEFINE	N$WRNX ($PFX,$TEXT),<
E$$'$PFX':
	MOVEI	T1,''$PFX''
	XLIST
IFNB <$TEXT>,<	MOVEI	T2,[ASCIZ \$TEXT \] >
IFB  <$TEXT>,<	MOVEI	T2,0 >
	PUSHJ	P,WARN
	TXNN	T1,JWW.FL
	JRST	X$$'$PFX'
	LIST
>
	SUBTTL	ASSEMBLY PARAMETERS

;ASSEMBLY INSTRUCTIONS:
;
;	.LOAD DIRECT
;	.NSSAVE
;
;ASSUMES MACTEN.UNV, JOBDAT.UNV, UUOSYM.UNV, AND NSCAN.UNV ON UNV:
;	 SCAN.REL, HELPER.REL, AND WILD.REL ON REL:

;ASSEMBLY PARAMETERS

ND	FT$LPW,0	;1=WAIT IF LPT NOT AVAILABLE
ND	FT$MTA,-1	;INCLUDE MAGTAPE FEATURES IN GENERAL
ND	FT$MTB,-1	;INCLUDE MAGTAPE FEATURES FOR BACKUP
ND	FT$MTF,-1	;INCLUDE MAGTAPE FEATURES FOR FAILSAFE
ND	FT$MTL,-1	;INCLUDE MAGTAPE LABELING FEATURES (.TFLPR)
ND	FT$MTR,0	;INCLUDE MAGTAPE FEATURES FOR OLD BACKUP/RESTORE
ND	FT$MTS,-1	;INCLUDE MAGTAPE FEATURES FOR FRS

ND	LN$LPP,^D55	;LINES PER PAGE OF DATA
ND	LN$PDL,200	;LENGTH OF PUSH-DOWN LIST
ND	LN$RIB,55	;LENGTH OF DIRECTORY LOOKUP BLOCK
ND	LN$BLK,200	;LENGTH OF SCRATCH BLOCK - MIN:200 (DECTAPE, ETC.)
ND	LN$DBF,^D128	;LENGTH OF "STANDARD" DISK/ETC. BUFFER
ND	LN$LBS,^D1024	;LENGTH OF "LARGE" DISK BUFFER
ND	LN$MRC,^D674	;LENGTH OF DEFAULT MINIMUM MAG TAPE RECORD
ND	LN$FCT,^D96	;MAXIMUM BACKUP BLOCKING FACTOR

ND	NM$DBF,^D10	;NUMBER OF "STANDARD" DISK BUFFERS FOR INPUT
ND	NM$LBS,^D04	;NUMBER OF "LARGE" DISK BUFFERS FOR INPUT
ND	NM$MBF,^D05	;NUMBER OF MAGTAPE BUFFERS FOR INPUT


IFE FT$MTA,<	FT$MTB==0
		FT$MTF==0
		FT$MTR==0
		FT$MTS==0>

IFN FT$MTS,<	FT$MTB==-1>

IFL LN$RIB-41,<PRINTX ? RIB BLOCK TOO SMALL FOR FAILSAFE>



;SWITCH DEFAULTS

	RADIX	10
DM	ACC,^O1777777777,0,5
DM	FCT,LN$FCT,4,4
DM	FIL,100000,0,1
DM	WID,250,132,0
	RADIX	8
	SUBTTL	SYMBOLS - REGISTERS; I/O CHANNELS

;AC NAMES

F=0		;FLAGS (LH=PERMANENT, RH=TEMPORARY)
T1=1		;TEMPORARIES
T2=2
T3=3
T4=4

P1=5		;PRESERVED
P2=6
P3=7
P4=10

I=11		;GENERAL INDEX REGISTERS
J=12

C=14		;TEMP DEFS FOR LISTING ROUTINES
N=15
M=16
P=17		;PUSH-DOWN POINTER

	.XCREF	F, T1, T2, T3, T4, P1, P2, P3	;CONSERVE PAPER
	.XCREF	P4, I, J, C, N, M, P		;CONSERVE TREES

;I/O CHANNELS

DC==1		;READ DATA FILE
LC==2		;OUTPUT (DIRECTORY LISTING)
DF==3		;DATA FILE OUTPUT (/FNDBLD OUTPUT)
PF==4		;POINTER FILE OUTPUT (/FNDBLD OUTPUT)
DG==5		;DATA FILE INPUT (/FIND)
PG==6		;POINTER FILE INPUT (/FIND)
TW==7		;DIRECTORY CHANNEL TO HOLD ACCESS TABLE OPEN
	SUBTTL	SYMBOLS - FLAG BITS IN "F"

;FLAGS (LH)

L.SVST==(1B0)	;SAVE SET FLAG FOR MT UNTANGLING
L.FKEF==(1B1)	;FAKE EOF TO TRICK DISK CODE
L.BKSS==(1B2)	;OLD BACKUP/RESTORE STYLE SAVE SET
L.SVDW==(1B3)	;SAVED WORD IN INPUT AREA
L.FEOF==(1B4)	;END OF FIND DATA FILE (IN DFGET)
L.ILEN==(1B5)	;INCORRECT LENGTH
L.IMLB==(1B6)	;IMBEDDED LABEL
L.LENT==(1B7)	;LONG ENTER OK
L.FRSS==(1B8)	;BACKUP/FRS SAVE SET
L.FRMT==(1B9)	;FORMAT OUTPUT (I.E., EITHER /SORT OR /TITLES)
L.CRLF==(1B10)	;SUPPRESS MULTIPLE CRLF'S.
L.SBTT==(1B11)	;LAST LINE WAS SUB/TOTAL (WANT BLANK LINE)
L.BPOP==(1B12)	;POPJ FLAG USED BY NEXDV
L.MLBL==(1B14)	;TAPE IS LABELLED NICELY
L.MLBP==(1B15)	;TAPE CONTROLLED BY LABEL PROCESSOR

;FLAGS (RH)

R.WORD==1B18	;QUANTITIES ARE IN WORDS NOT BLOCKS
R.TYPE==1B19	;FORCE TYPEOUT AS WELL AS LISTING
R.ACCS==1B20	;FORCE A FILE ACCESS
R.LSOM==1B21	;SOME OUTPUT SENT
R.OUTD==1B22	;OUTPUT DEVICE INITTED
R.OUTL==1B23	;FORCE OUTPUT AFTER EACH LINE
R.SLOW==1B24	;SLOW FORMAT  --DO NOT MOVE OR INTERCHANGE
R.FAST==1B25	;FAST FORMAT  --THIS ORDER REQUIRED
R.OUTO==1B26	;OUTPUT DEVICE OPEN AND IT IS OUR TTY:
R.LPTB==1B27	;LPT BUSY--WAITING
R.LTAB==1B28	;SET IF TAB TO BE LISTED NEXT
R.FEAT==1B27	;EAT FILES (SPECIAL DTA MODE IN DIRLP)
R.NDSK==1B30	;SET IF NOT A DISK DIRECTORY
R.LBSX==1B31	;SET IF SIXBIT LABELS
R.MTOH==1B32	;MT OVERHEAD WORD COMING NEXT
R.NSF==1B33	;NOT START OF FILE
R.SPLN==1B34	;SUPPRESS LINE
R.STAB==1B35	;SUPPRESS NEXT TAB (AT CALL TO LTAB)
	SUBTTL	SYMBOLS - FILE BLOCK NAMES

IF2,<		;ONLY PASS 2 SINCE LOCATION OF LOOKUP BLOCK DEFINED AT END

	DEFINE DR(A,B),<IFL .RB'B-LN$RIB,<A=LBLOCK+.RB'B>>
	DEFINE DQ(A),<DR (F'A,A)>

DR	RIBLEN,CNT;	BLOCK LENGTH
DR	UFDPPN,PPN;	PROJECT-PROGRAMMER NUMBER OR POINTER TO DIRECTORY
DQ	NAM;		FILE NAME
DQ	EXT;		FILE EXTENSION
	FACD==FEXT;	ACCESS DATE
	FCRX==FEXT;	CREATION DATE EXTENSION BITS
DQ	PRV;		PROTECTION, CREATION, ETC.
	FMOD==FPRV;	FILE I/O MODE
	FCRE==FPRV;	CREATION DATE/TIME (MOST OF IT ANYWAYS)
DQ	SIZ;		FILE SIZE/LENGTH
DQ	VER;		VERSION
DQ	SPL;		SPOOLED NAME
DQ	EST;		ESTIMATED LENGTH
DQ	ALC;		ALLOCATED LENGTH
DQ	POS;		POSITION ALLOCATED
DQ	UFW;		UNITS WHICH WROTE FILE (UNIT,, CONTROLLER-APR SERIAL #)
DQ	NCA;		CUSTOMER NON-PRIV
DQ	MTA;		DISK BACKUP TAPE
DQ	DEV;		LOGICAL UNIT
DQ	STS;		FILE STATUS BITS
DQ	ELB;		ERROR LOGICAL BLOCK
DQ	EUN;		ERROR UNIT AND LENGTH
DQ	QTF;		FCFS QUOTA (DIRECTORY FILE)
DQ	TYP;  -- OR --	FILE DATA TYPE, ETC. (DATA FILE)
DQ	QTO;		LOGGED OUT QUOTA (DIRECTORY FILE)
DQ	BSZ;  -- OR --	BYTE/ETC. SIZES (DATA FILE)
DQ	QTR;		RESERVED QUOTA (DIRECTORY FILE)
DQ	RSZ;  -- OR --	RECORD/ETC. SIZES (DATA FILE)
DQ	USD;		BLOCKS USED (DIRECTORY FILE)
DQ	FFB;  -- OR --	FIRST FREE BYTE (DATA FILE)
DQ	AUT;		AUTHOR
DQ	NXT;		CONTINUED STR
DQ	IDT;		BACKUP INCREMENTAL DATE/TIME
DQ	PCA;		PRIV CUSTOMER ARG
DQ	UFD;		POINTER BACK TO UFD
DQ	FLR;		RELATIVE BLOCK IN FILE COVERED BY THIS RIB
DQ	XRA;		POINTER TO NEXT RIB IN CHAIN
DQ	TIM;		CREATION DATE,,TIME IN INTERNAL FORMAT
DQ	LAD;		LAST ACCOUNTING DATE/TIME
DQ	DED;		DIRECOTRY EXPIRATION DATE/TIME
DQ	ACT;		FIRST WORD OF THE ACCOUNT STRING
DQ	AC2;		SECOND WORD OF THE ACCOUNT STRING
DQ	AC3;		THIRD WORD OF THE ACCOUNT STRING
DQ	AC4;		FOURTH WORD OF THE ACCOUNT STRING
DQ	AC5;		FIFTH WORD OF THE ACCOUNT STRING
DQ	AC6;		SIXTH WORD OF THE ACCOUNT STRING
DQ	AC7;		SEVENTH WORD OF THE ACCOUNT STRING
DQ	AC8;		EIGHTH WORD OF THE ACCOUNT STRING

	.RBXTR==.RBAC8+1	;LAST THING WE KNOW ABOUT

DQ XTR;	EXTRA RIB WORDS START HERE

>	;END IF2
	SUBTTL	SYMBOLS - MAGTAPE -- BACKUP FORMAT

;Each tape record has a 32(10) word header:

G$TYPE==0		;RECORD TYPE
	T$LBL==1	;TAPE LABEL
	T$SSS==2	;START SAVE SET
	T$ESS==3	;END SAVE SET
	T$FIL==4	;DISK FILE DATA
	T$DIR==5	;DIRECTORY RECORD
	T$EOV==6	;END OF VOLUME
	T$CMT==7	;COMMENT
	T$CSS==10	;CONTINUE SAVE SET
	T$MAX==10	;LARGEST RECORD TYPE
G$SEQN==1		;RECORD SEQUENCE NUMBER
G$RTNM==2		;RELATIVE TAPE NUMBER
G$FLAG==3		;RECORD DEPENDENT BITS
	GF$EOF==1B0	;LAST RECORD OF FILE
	GF$RPT==1B1	;REPEAT OF LAST RECORD WRITE ERROR
	GF$NCH==1B2	;THIS RECORD NOT CHECKSUMMED
	GF$SOF==1B3	;THIS RECORD IS START OF FILE
	GF$DF0==1B4	;FIRST DISK FILE BLOCK (ON TAPE) HAD ERROR
	GF$DF1==1B5	;SECOND DISK FILE BLOCK (ON TAPE) HAD ERROR
	GF$DF2==1B6	;THIRD DISK FILE BLOCK (ON TAPE) HAD ERROR
	GF$DF3==1B7	;FOURTH DISK FILE BLOCK (ON TAPE) HAD ERROR
G$CHK==4		;CHECKSUM
G$SIZ==5		;NUMBER OF DATA WORDS
G$LND==6		;TOTAL LENGTH OF NON-DATA SECTION
G$CUSW==13		;RESERVED FOR CUSTOMER USE

A$FHLN==0		;ATTRIBUTE HEADER FIXED LENGTH REGION
A$FLGS==1		;ATTRIBUTE FLAGS
A$WRIT==2		;LAST WRITE DATE
A$ALLS==3		;ALLOCATED SIZE
A$MODE==4		;MODE
A$LENG==5		;LENGTH
A$BSIZ==6		;BYTE SIZE
A$VERS==7		;VERSION
A$PROT==10		;PROTECTION
	PR$ATR==7B31	;ATTRIBUTES
	PR$WRT==3B33	;WRITE
	PR$RED==3B35	;READ
A$ACCT==11		;[470] ACCOUNT STRING (BYTE POINTER)
A$NOTE==12		;ANNOTATION
A$CRET==13		;CREATION DATE/TIME
A$REDT==14		;LAST READ (ACCESS) DATE/TIME
A$MODT==15		;LAST WRITE DATE/TIME
A$ESTS==16		;ESTIMATED SIZE (WORDS)
A$RADR==17		;REQUESTED ADDRESS
A$FSIZ==20		;MAXIMUM FILE SIZE (WORDS)
A$MUSR==21		;WHO LAST MODIFIED STRING (BYTE POINTER)
A$CUSR==22		;AUTHOR STRING (BYTE POINTER)
A$BKID==23		;LAST BACKUP TAPE SAVE SET (BYTE POINTER)
A$BKDT==24		;LAST BACKUP DATE/TIME
A$NGRT==25		;GENERATION RETENTION COUNT
A$NRDS==26		;NUMBER OF OPEN-FOR-READS
A$NWRT==27		;NUMBER OF OPEN-FOR-WRITES
A$USRW==30		;NON-PRIVILEGED CUSTOMER WORD
A$PCAW==31		;PRIVILEGED CUSTOMER WORD
A$FTYP==32		;FILE TYPE AND FLAGS
A$FBSZ==33		;BYTE SIZES
A$FRSZ==34		;RECORD AND BLOCK SIZES
A$FFFB==35		;APPLICATION/CUSTOMER WORD

.FCDEV==1		;DEVICE
.FCNAM==2		;NAME
.FCEXT==3		;EXTENSION
.FCVER==4		;VERSION
.FCGEN==5		;GENERATION
.FCDIR==40		;TOP LEVEL DIRECTORY
.FCSFD==41		;SFD NAME

;ALSO SEE STORAGE BLOCKS B$???? IN STORAGE SECTION
	SUBTTL	STARTUP AND INITIALIZATION

;HERE AFTER START OR RUN OR DIRECTORY COMMAND OR RUN UUO

DIRECT:	TDZA	T1,T1		;CLEAR OFFSET
	MOVEI	T1,1		;SET OFFSET
	MOVEM	T1,OFFSET	;STORE IT

	RESET			;RESET ANY EXTERNAL I/O
	SETZB	F,ZCOR		;CLEAR CORE
	MOVE	T1,[ZCOR,,ZCOR+1]
	BLT	T1,EZCOR
	MOVE	P,[IOWD LN$PDL,PDLST]	;ESTABLISH PUSH-DOWN LIST

	MOVE	T1,[ 4,,[VERWRD
			IOWD  1,['DIRECT']
			OFFSET,,'DIR'
			0,,TCHR]]
	PUSHJ	P,.ISCAN##	;INITIALIZE COMMAND SCANNER

	MOVE	T1,.JBFF	;SAVE ORIGINAL VALUE
	HRL	T1,.JBREL	; OF .JBREL AND
	MOVEM	T1,ORGFF	; OF .JBFF

;CONTINUED ON NEXT PAGE
	SUBTTL	MAIN LOOP FOR COMMAND SCANNING

;FALL HERE FROM PREVIOUS PAGE

MAINLP:	MOVE	P,[IOWD LN$PDL,PDLST]
	MOVE	T1,[ 7,,[VERWRD
			IOWD DRSWTL,DRSWTN
			DRSWTD,,DRSWTM
			0,,DRSWTP
			'DIRECT'
			CLANS,,0
			AIN,,AOUT]]
	PUSHJ	P,.TSCAN##	;GET THE COMMAND
	SKIPN	I.NXZR		;SEE IF ANYTHING
	JRST	[PUSHJ P,.CLRFL##  ;NO--CLEAR FILE AREA
		 PUSHJ P,AIN	;ALLOCATE ONE SPEC
		 PUSHJ P,.GTSPC##  ;COPY IT IN
		 JRST  .+1]	;AND PROCEED
	MOVE	T1,[ 6,,[VERWRD
			IOWD DRSWTL,DRSWTN
			DRSWTD,,DRSWTM
			0,,DRSWTP
			'DIRECT'
			'DIRECT']]
	PUSHJ	P,.OSCAN##	;SCAN USER OPTIONS
	MOVE	F,FLAGS		;GET INITIAL FLAGS
	JRST	DEFAUL		;GO FILL IN DEFAULTS


;SUBROUTINE TO CLEAR ANSWER AREA

CLANS:	SETZM	S.ZER		;ZERO OUT COMMAND ACCUMULATORS
	MOVE	T1,[S.ZER,,S.ZER+1]
	BLT	T1,S.EZER
	SETOM	S.MIN		;PRESET SWITCH PARAMETERS
	MOVE	T1,[S.MIN,,S.MIN+1]
	BLT	T1,S.EMIN
	SETZM	I.NXZR		;AND FOR SCANING
	CLOSE	LC,CL.ACS!CL.DAT;TERMINATE LISTING IF OPEN
	RELEAS	LC,		;  IN CASE OF ERROR RESTART
	CLOSE	DF,CL.ACS!CL.DAT;CLOSE OFF DATA FILE
	RELEAS	DF,		;AND DUMP DEVICE
	CLOSE	PF,CL.ACS!CL.DAT;CLOSE OFF POINTER FILE
	RELEAS	PF,		;AND DITCH IT TOO.
	SETZM	B.LC+.BFPTR	;SET FLAG FOR LISTING CLOSED
	TRZ	F,-1		;CLEAR ALL LOCAL FLAGS
	HRRZ	T1,ORGFF	;RESTORE ORIGINAL VALUE
	MOVEM	T1,.JBFF	; OF .JBFF
	MOVEM	T1,I.INZR	; FOR .WILD
	HLRZ	T1,ORGFF	;RESTORE .JBREL
	CAME	T1,.JBREL	; UNLESS OK
	CORE	T1,		; TELL MONITOR
	  JFCL			;(IGNORE ERROR)
	POPJ	P,		;RETURN
;SUBROUTINE TO ALLOCATE OUTPUT FILE AREA

AOUT:	MOVEI	T1,O.BLK	;POINT TO IT
	MOVEI	T2,.FXLEN	;AND LENGTH
	POPJ	P,		;AND RETURN

;SUBROUTINE TO ALLOCATE INPUT FILE AREA

AIN:	MOVEI	T1,.FXLEN	;ADVANCE ALLOCATION
	SKIPN	I.NXZR		;SEE IF STARTED YET
	MOVE	T1,I.INZR	;NO--START AT BEGINNING
	ADDB	T1,I.NXZR	;AND STORE NEW VALUE
	MOVEI	T2,.FXLEN(T1)	;COMPUTE NEXT FREE
	MOVEM	T2,.JBFF	; STORE FOR LATER
	SOS	T2		;GET END
	CAMG	T2,.JBREL	;SEE IF IN CORE
	JRST	AINX		;YES--NO SWEAT
	CORE	T2,		;NO--GET MORE CORE
	  JRST	E$$TMI		;ERROR IF NO ROOM
AINX:	HRLZ	T2,T1		;POINT TO START
	HRRI	T2,1(T1)	;SETUP NEXT ADDR
	SETZM	(T1)		;CLEAR NEW
	BLT	T2,.FXLEN-1(T1)	; AREA
	MOVEI	T2,.FXLEN	;SET LENGTH
	POPJ	P,		;RETURN
	SUBTTL	FILL IN DEFAULTS AFTER COMMAND SCANNING

;HERE AT END OF COMMAND -- SUPPLY ABSENT FILE DEFAULTS

DEFAUL:	MOVEI	P1,O.BLK	;ADDRESS OF OUTPUT FILE SPEC BLOCK
OUDEF0:	MOVE	T1,P1		;ADDRESS OF OUTPUT FILE SPEC BLOCK
	MOVEI	T2,O.LZER	;LENGTH OF OUTPUT FILE SPEC BLOCK
	PUSHJ	P,.OSDFS##	;APPLY SWITCH.INI DEFAULTS AS NEEDED
	MOVE	P2,O.BLK+.FXFLD	;GET FIELD FLAGS
	TXNE	P2,FX.WXX	;WERE ANY WILDCARDS TYPED?
	JRST	E.OWI		;YES, BOMB OUT NOW
	SKIPLE	S.FBLD		;IF /FNDBLD,
	SETOM	S.DODV		; THEN DON'T ALLOW /L
	TXNE	P2,FX.UDV	;DID USER SUPPLY A DEVICE?
	JRST	OUDEF1		;YES
	SKIPG	S.FBLD		;IF /FNDBLD, OR
	TXNE	P2,FX.UND!FX.UDR!FX.UNM!FX.UEX  ;ANYTHING ELSE TYPED,
	SKIPA	T1,['DSK   ']	;THEN LIST ON DISK
	MOVSI	T1,'TTY'	;NO, THEN LIST ON CONTROLLING TTY
	SKIPLE	S.DODV		;SEE IF /L SWITCH
	MOVSI	T1,'LPT'	;YES, DEFAULT OUTPUT DEVICE TO LPT:
	SETO	T2,		;FULLY NON-WILD
	DMOVEM	T1,.FXDEV(P1)	;SET OUTPUT DEVICE IN FILE SPEC BLOCK

OUDEF1:	HRLOI	T1,'DIR'	;DEFAULT OUTPUT EXTENSION
	SKIPLE	S.IND		;IF /INDIRECT,
	HRLOI	T1,'CCL'	;USE DIFFERENT DEFAULT
	SKIPN	.FXEXT(P1)	;HAVE AN EXTENSION?
	MOVEM	T1,.FXEXT(P1)	;NO, SET DEFAULT

	MOVE	T4,.FXDEV(P1)	;GET "LISTING" DEVICE
	MOVE	T1,.FXMOD(P1)	;GET PHYSICAL FLAG
	TXNN	T1,FX.PHY	;SEE IF /PHY
	DEVCHR	T4,		;NO, LOGICAL DEVICE REFERENCE
	TXNE	T1,FX.PHY	;SEE IF /PHY
	DEVCHR	T4,UU.PHY	;YES, PHYSICAL DEVICE REFERENCE
	TXNE	T4,DV.DSK	;SEE IF DISK
	TLOA	F,L.LENT	;YES--INDICATE LONG ENTER
	TLZ	F,L.LENT	;NO
	TXNN	T4,DV.LPT	;SEE IF TYPE LPT
	JRST	OUDEF2		;NO--PROCEED
	TRNN	F,R.FAST!R.SLOW	;SEE IF ANY SPEED SWITCH
	TRO	F,R.SLOW	;NONE--SET TO SLOW MODE
	MOVEI	T1,1		;  (PRESET VALUE)
	SKIPGE	S.TITL		;  AND NO TITLE SWITCH
	MOVEM	T1,S.TITL	;YES--SET DEFAULT TITLE ON
OUDEF2:	MOVE	T1,S.SUM	;GET /SUMMARY
	TXNE	T4,DV.TTA	;SEE IF CONTROLLING TTY
	TROA	F,R.OUTO	;YES--SET FLAG
	JRST	[SKIPGE T1		;UNLESS USER SET /SUM, FORCE SUMMARIES
		MOVEI	T1,1		;  OK--SET SUMMARIES
		JRST	.+1]		;PROCEED
	MOVEM	T1,FLFSUM	;STORE FLAG FOR FORCED SUMMARIES
	TXNE	T4,DV.TTY	;SEE IF LINE MODE DEVICE
	TRO	F,R.OUTL	;YES, DO OUTPUT ON EVERY LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	SKIPN	.FXNAM(P1)	;WAS OUTPUT FILE NAME GIVEN?
	TXNN	T4,DV.DIR	;NO, SEE IF FILE NAME NEEDED
	JRST	OUDEF8		;NO--GO ON
	TLC	T4,-1-<(DV.TTA)>;SEE IF NUL:
	TLCN	T4,-1-<(DV.TTA)>; ..
	JRST	OUDEF8		;YES--ENTER NOT NEEDED
	SKIPLE	S.FBLD		;/FNDBLD?
	JRST	[MOVE	T1,['FNDDAT']	;YES, DEFAULT FILENAME
		SETO	T2,		;INDICATE NON-WILD
		DMOVEM	T1,.FXNAM(P1)	;STORE IN SCAN BLOCK
		JRST	OUDEF6]		;FINISH DEFAULTS
	MSTIME	T1,		;YES--MANUFACTURE NAME HHMMSS
	IDIVI	T1,^D1000	;GET SECONDS
	MOVE	T4,[POINT 6,.FXNAM(P1)]	;SETUP BYTE POINTER
	MOVSI	T3,-6		;INITIALIZE LOOP COUNTER
OUDEF4:	IDIV	T1,[^D36000
		    ^D3600
		    ^D600
		    ^D60
		    ^D10
		    ^D1](T3)	;GET NEXT DIGIT
	ADDI	T1,'0'		;CONVERT TO SIXBIT DIGIT
	IDPB	T1,T4		;STORE INTO NAME
	MOVE	T1,T2		;RESTORE REMAINDER
	AOBJN	T3,OUDEF4	;LOOP
	SETOM	.FXNMM(P1)	;INDICATE NOT WILD
OUDEF6:	N$WRNX	(DLF,Directory listing to file /)
	MOVE	T1,P1		;ADDRESS OF OUTPUT FILE SPEC BLOCK
	PUSHJ	P,.TFBLK##	;TYPE IT OUT
X$$DLF:	PUSHJ	P,.TCRLF##	;CAP OFF "WARNING" WITH A CRLF

OUDEF8:	SETZM	H.ZER		;CLEAR OUT SUMMARY AREA FOR OUTPUT
	MOVE	T1,[H.ZER,,H.ZER+1]
	BLT	T1,H.EZER
	SETOM	LNPP		;PRESET TO FORCE PAGE EJECT

;OUTPUT FILE DEFAULTED, SET IT UP FOR LISTING OUTPUT

OUDEF9:	PUSHJ	P,OUTIN		;OPEN OUTPUT FILE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO SUPPLY INPUT SIDE DEFAULTS

INDEF:	MOVE	P1,I.INZR	;INITIALIZE BLOCK POINTER

INDEF0:	MOVE	T1,P1		;POINT TO SPEC
	MOVEI	T2,.FXLEN	;INDICATE LENGTH
	PUSHJ	P,.OSDFS##	;APPLY SWITCH.INI DEFAULTS AS NEEDED
	SKIPLE	S.FIND		;/FIND?
	SKIPA	T1,['*     ']	;YES, DEFAULT DEVICE TO MATCH ANYTHING
	MOVSI	T1,'DSK'	;FORCE DEFAULT DEVICE
	MOVE	T4,.FXMOD(P1)	;GET THE SWITCHES AND BITS WORD
;SCAN BUG - AT THIS POINT FX.NDV WILL BE SET FOR CONSTRUCTIONS OF THE FORM
; "BLKC:*.* ([*,*])" WHICH CAUSE US ALL SORTS OF TROUBLE . . . THEREFORE WE
;USE A STUPID SKIP INSTEAD. SIGH. -RDH
	SKIPN	T2,.FXDEV(P1)	;SIGH.
	JRST	.+4		;SIGH.
	TXZE	T4,FX.NDV	;NO DEVICE GIVEN (HA!)?
	CAME	T2,['DSK   ']	;MAYBE, SCAN LEAVE US A "DSK:"
	JRST	INDEF1		;NO, THEN SCAN GOT DEVICE FROM USER, KEEP IT
	CAMN	T1,['*     ']	;WHAT SORT OF DEFAULT DEVICE?
	TDZA	T2,T2		;A WILD ONE
	SETO	T2,		;A NON-WILD ONE
	DMOVEM	T1,.FXDEV(P1)	;USE OUR DEFAULT DEVICE
	MOVX	T1,FX.WDV	;THE WILDCARDS-IN-DEVICE BIT
	AOJE	T2,.+2		;WILDCARDS PRESENT?
	IORM	T1,.FXFLD(P1)	;YES

INDEF1:	SKIPLE	S.FIND		;/FIND?
	SKIPE	.FXDIR(P1)	;YES, USER GIVE A DIRECTORY?
	JRST	INDEF4		;NOT /FIND OR USER SUPPLIED A DIRECTORY
	MOVEI	T3,.FXDIR(P1)	;ADDRESS OF DIRECTORY WORDS
	HRLI	T3,-.FXLND	;LENGTH (COUNTING UFD)
	SETZ	T2,		;ALL DIRECTORY LEVELS TO BE FULLY-WILD
	SKIPA	T1,[377777,,377777]  ;UFD WILDCARD
INDEF2:	MOVSI	T1,'*  '	;SFD WILDCARD
	DMOVEM	T1,(T3)		;DEFAULT DIRECTORY ENTRY
	ADDI	T3,1		;POINT TO WILDCARD MASK
	AOBJN	T3,INDEF2	;FILL OUT FULL DIRECTORY BLOCK
	MOVX	T2,FX.WDR	;THE DIRECTORY WILDCARDS BIT
	IORM	T2,.FXFLD(P1)	;SET IN FIELDS FLAGS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

INDEF4:	SKIPE	.FXNAM(P1)	;SEE IF FILE NAME
	JRST	INDEF6		;YES--NO DEFAULT
	MOVSI	T1,'*  '	;NO--SET WILD DEFAULT
	SETZ	T2,		;FULL WILD MASK
	CAME	P1,I.INZR	; FOR FIRST ONE
	DMOVE	T1,.FXNAM-.FXLEN(P1)	;PREVIOUS FOR REST
	DMOVEM	T1,.FXNAM(P1)	;STORE IN ARRAY
	MOVX	T1,FX.WNM	;THE FILE NAME WILDCARDED FLAG
	AOSE	T2		;WILDCARDS PRESENT IN FILE NAME?
	IORM	T1,.FXFLD(P1)	;YES, SET IN THE SCAN BLOCK

INDEF6:	SKIPN	T2,.FXEXT(P1)	;SIGH.
	JRST	.+4		;SIGH.
	TXZE	T4,FX.NUL	;NULL EXTENSION?
	TLNE	T2,-1		;MAYBE - ANYTHING THERE?
	JRST	INDEF7		;TRUST ALREADY EXTANT EXTENSION
	MOVSI	T1,'*  '	;DEFAULT EXTENSION
	MOVEM	T1,.FXEXT(P1)	;SET DEFAULT EXTENSION
	MOVX	T2,FX.WEX	;THE WILDCARDED EXTENSION FLAG
	IORM	T2,.FXFLD(P1)	;REMEMBER FOR WILD

INDEF7:	MOVX	T1,FX.STR	;SET MULTIPLE STR CODE
	TDNN	T1,.FXMOM(P1)	;UNLESS USER HAS DEFEATED IT
	IORM	T1,.FXMOD(P1)	;SET IN THE MOD WORD
	MOVX	T1,FX.PRT	;DEFAULT TO /ERPROT
	TDNN	T1,.FXMOM(P1)	; ..
	IORM	T1,.FXMOM(P1)	; ..

	ADDI	P1,.FXLEN	;ADVANCE POINTER
	CAMG	P1,I.NXZR	;SEE IF DONE YET
	JRST	INDEF0		;NO--LOOP BACK

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO SUPPLY DEFAULTS FOR GLOBAL SWITCHES

GIDEF:	SKIPG	S.FIND		;/FIND SPECIFIED?
	JRST	GIDEF1		;NO, NORMAL INPUT
	SKIPLE	S.ACCS		;/ACCESS ALSO?
	PUSHJ	P,[N$WARN (IF1,/ACCESS ignored in conjunction with /FIND)
		SETOM	S.ACCS	;ZAPETH THE SWITCH
		POPJ	P,]	;NO MORE /ACCESS
	SKIPLE	S.ACCT		;OR /ACCOUNT?
	PUSHJ	P,[N$WARN (IF2,/ACCOUNT ignored in conjunction with /FIND)
		SETOM	S.ACCT	;ZAPETH THE SWITCH
		POPJ	P,]	;NO MORE /ACCOUNT
	SKIPLE	S.ALC		;OR /ALLOCATE?
	PUSHJ	P,[N$WARN (IF3,/ALLOCATE ignored in conjunction with /FIND)
		SETOM	S.ALC	;ZAPETH THE SWITCH
		POPJ	P,]	;NO MORE /ACCOUNT
	SKIPLE	S.AUT		;OR /AUTHOR?
	PUSHJ	P,[N$WARN (IF4,/AUTHOR ignored in conjunction with /FIND)
		SETOM	S.AUT	;ZAPETH THE SWITCH
		POPJ	P,]	;NO MORE /AUTHOR
	SKIPLE	S.DTL		;OR /DETAIL?
	PUSHJ	P,[N$WARN (IF5,Not all /DETAIL file information available with /FIND)
		POPJ	P,]	;BUT DO WHAT WE CAN
	SKIPL	S.UNIT		;OR /UNIT?
	PUSHJ	P,[N$WARN (IF6,/UNIT ignored in conjunction with /FIND)
		SETOM	S.UNIT	;ZAPETH THE SWITCH
		POPJ	P,]	;NO MORE /UNIT
	MOVEI	T1,1		;"ON" SWITCH SETTING
	SKIPGE	S.PRDE		;USER GIVE EXPLICIT DEVICE/
	SKIPL	S.PRDI		;DIRECTORY PRINTING CONTROL?
	JRST	GIDEF1		;YES, LEAVE IT ALONE THEN
;	SKIPGE	S.PRVE		;OR USER GIVE VERSION/
	SKIPL	S.CHK		;CHECKSUM PRINTING CONTROL?
	JRST	GIDEF1		;YES, LEAVE IT ALONE THEN
	MOVEM	T1,S.PRDE	;NO, DEFAULT TO /PRDEVICE AND
	MOVEM	T1,S.PRDI	;/PRDIRECTORY ON /FIND
;	MOVEM	T1,S.PRVE	;/PRVERSION ALSO
	MOVEM	T1,S.CHK	;/CHECKSUM AS WELL

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SET UP SWITCHS FOR /INDIRECT OUTPUT

GIDEF1:	SKIPG	S.IND		;/INDIRECT SPECIFIED?
	JRST	GIDEF3		;NO
	TRZ	F,R.SLOW	;CLEAR /S
	TRO	F,R.FAST	;SET /F
	MOVEI	T1,1		;SET VALUE
	SETZM	S.ACCT		;CLEAR /ACCOUNT
	SETZM	S.AUT		;CLEAR /AUTHOR
	MOVEM	T1,S.CMP	;SET /COMPARE (KILL HEADERS)
	SETZM	S.DTL		;CLEAR /DETAIL
	MOVEM	T1,S.FLSD	;SET /FLSDIR (PRINT STR/DIR)
	SETZM	S.HDSD		;CLEAR /HDSDIR
	SKIPGE	S.PRDE		;/[NO]PRDEVICE?
	MOVEM	T1,S.PRDE	;NO, DEFAULT /PRDEVICE
	SKIPGE	S.PRDI		;/[NO]PRDIRECTORY?
	MOVEM	T1,S.PRDI	;NO, DEFAULT /PRDIRECTORY
	SETZM	S.SORT		;CLEAR /SORT
	SETZM	S.WDTH		;SET /WIDTH:0

GIDEF3:	SKIPLE	S.CMP		;IF /COMPARE,
	SKIPL	S.TITL		; AND NO /TITLE
	SKIPA			;NO
	SETZM	S.TITL		; SET /NOTITLE

	SKIPLE	S.DTL		;SEE IF /DETAIL
	TRZ	F,R.FAST!R.SLOW	;YES--CLEAR /FAST/SLOW
	SKIPGE	S.SORT		;IS SORT MODE SPECIFIED
	SETZM	S.SORT		;NO--CLEAR FLAG

	MOVEI	T1,1
	SKIPGE	S.REWS		;SEE IF /NOREW
	MOVEM	T1,S.REWS	;NO--SET /REW
	SKIPGE	S.EOT		;SEE IF /NOEOT
	MOVEM	T1,S.EOT	;NO--SET /EOT
	SKIPLE	S.FBLD		;/FNDBLD?
	MOVEM	T1,S.CHK	;YES, FORCE /CHECKSUM
	SKIPLE	S.FBLD		;/FNDBLD?
	SKIPL	S.MVOL		;AND /MVOL OR /NOMVOL?
	SKIPA			;NO TO ONE OF ABOVE
	MOVEM	T1,S.MVOL	;YES, DEFAULT TO /MVOLUM

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVN	T2,S.FLSD	;/FLSDIR
	SUB	T2,S.HDSD	;/HDSDIR
	SUB	T2,S.PRDE	;/PRDEVICE
	SUB	T2,S.PRDI	;/PRDIRECTORY
	CAIE	T2,4		;IF ANY OF ABOVE GIVEN
	JRST	GLDEF2		;AT LEAST ONE OF ABOVE
	SKIPL	S.WDTH		;/WIDTH OF SOME FORM?
	JRST	GLDEF1		;YES, DEFAULT /HDSDIR
	MOVEM	T1,S.FLSD	;NO,  DEFAULT /FLSDIR
	SETZM	S.HDSD		;NO, DEFAULT /NOHDSDIR
	JRST	GLDEF2		;GO CHECK FOR /DETAIL

GLDEF1:	SETZM	S.FLSD		;DEFAULT /NOFLSDIR
	MOVEM	T1,S.HDSD	;DEFAULT /HDSDIR

GLDEF2:	SKIPG	S.DTL		;/DETAIL?
	JRST	GLDEF3		;NO
	SETZM	S.FLSD		;YES, FORCE /NOFLSDIR
	SETZM	S.HDSD		;YES, FORCE /NOHDSDIR

GLDEF3:	SKIPN	S.PRDE		;IF NOT /NOPRDEVICE
	SKIPE	S.PRDI		;AND NOT /NOPRDIRECTORY
	JRST	GLDEF4		;(IT'S NOT)
	SETZM	S.FLSD		;/NOPRDE/NOPRDI, FORCE
	SETZM	S.HDSD		;/NOFLSDIR/NOHDSDIR

GLDEF4:	SKIPGE	S.FLSD		;IF NOT SOME FORM OF
	SKIPL	S.HDSD		;/[NO]FLSDIR OR /[NO]HDSDIR
	SKIPA			;(AT LEAST ONE SPECIFIED)
	MOVEM	T1,S.FLSD	;DEFAULT TO /FLSDIR

	SKIPL	S.FLSD		;IF /[NO]FLSDIR
	SKIPL	S.HDSD		;AND NOT /[NO]HDSDIR
	SKIPA			;(IT'S NOT)
	SETZM	S.HDSD		;FORCE /NOHDSDIR

	SKIPGE	S.FLSD		;IF NOT /[NO]FLSDIR
	SKIPGE	S.HDSD		;AND /[NO]HDSDIR
	SKIPA			;(IT'S NOT)
	SETZM	S.FLSD		;FORCE /NOFLSDIR

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

GLDEG:	SKIPLE	S.IND		;/INDIRECT?
	JRST	GLDEW		;YES, LEAVE /WIDTH ALONE
	MOVEI	T1,AD.WID	;DEFAULT LINE WIDTH
	TRNN	F,R.OUTL	;OUTPUT TO A TTY?
	JRST	GLDEG2		;NO, USE CURRENT DEFAULT
	MOVEI	T3,LC		;YES, I/O CHANNEL
	IONDX.	T3,		;FROM WHICH TO GET UDX
	 JRST	GLDEG2		;???
	MOVE	T1,[2,,T2]	;TRMOP. POINTER TO
	MOVEI	T2,.TOWID	;READ TTY WIDTH
	TRMOP.	T1,		;ASK MONITOR FOR TTY WIDTH
	 MOVEI	T1,AD.WID	;???
GLDEG2:	SKIPN	S.WDTH		;/WIDTH WITH NO VALUE?
	MOVEM	T1,S.WDTH	;YES, USE DEFAULT
	SKIPGE	S.WDTH		;/WIDTH OF ANY TYPE?
	SETZM	S.WDTH		;NO, SET FOR INTERNAL USE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

GLDEW:	TRNN	F,R.FAST	;/FAST?
	JRST	GLDEW3		;NO
	MOVEI	T1,^D16		;YES, BASIC /FAST WIDTH
	SKIPLE	S.CHK		;/CHECKSUM?
	ADDI	T1,^D8		;YES
	SKIPLE	S.HDSD		;DOING /HDSDIR FORMAT LISTING?
	JRST	GLDEW6		;YES, THEN /PRDIR/PRDEV DON'T COUNT
	SKIPLE	S.PRDE		;/PRDEVICE?
	ADDI	T1,^D8		;YES
	SKIPLE	S.PRDI		;/PRDIRECTORY?
	ADDI	T1,^D24		;YES, USUALLY FITS IN 24 SPACES
	JRST	GLDEW6		;GO CHECK ON NUMBER OF COLUMNS

GLDEW3:	MOVEI	T1,^D40		;WIDTH IF /N
	TRNE	F,R.SLOW	;
	MOVEI	T1,^D64		;/S
	SKIPLE	S.CHK		;
	ADDI	T1,^D8		;/CHECKSUM
	SKIPLE	S.AUT		;
	ADDI	T1,^D16		;/AUTHOR
	SKIPLE	S.PRDE		;/PRDEVICE?
	SKIPLE	S.HDSD		;DOING /HDSDIR FORMAT LISTING?
	JRST	GLDEW4		;YES, THEN /PRDIR/PRDEV DON'T COUNT
	ADDI	T1,^D8		;YES
	SKIPLE	S.PRDI		;/PRDIRECTORY?
	ADDI	T1,^D24		;YES, USUALLY FITS IN 24 SPACES
GLDEW4:				;
;	SKIPE	S.PRVE		;[442] /NOPRVERSION?
;	ADDI	T1,^D8		;[442] NO, USUALLY FITS IN 8 SPACES
;	SKIPLE	S.PRVE		;[442] /PRVERSION?
;	ADDI	T1,^D8		;[442] YES, FITS IN 16 SPACES TOTAL
;	SKIPLE	S.PRVE		;[442] [443] /PRVERSION?
;	ADDI	T1,^D16		;[442] [443] YES, ASSURE 16 SPACES FOR VERSION

GLDEW6:	MOVEM	T1,S.LENT	;SAVE THE MAX LENGTH OF AN ENTRY
	SKIPLE	T2,S.WDTH	;GET /WIDTH
	SUB	T2,T1		;REMOVE LENGTH OF AN ENTRY
	SKIPL	T2		;IF NEGATIVE
	SKIPLE	S.DTL		; OR /DETAIL
	MOVEI	T2,0		; KILL WIDTH
	MOVEM	T2,MXWDTH	;STORE AS RIGHTMOST BEFORE NEW LINE
	SKIPG	S.TITL		;IF TITLE'ING, OR
	SKIPLE	S.SORT		;IF SORT'ING
	 TLO	F,L.FRMT	;THEN FLAG FORMATTED OUTPUT

;CONTINUED ON NEXT PAGE
	SUBTTL	DIRECTORY LISTING LOOP

;CONTINUED FROM PREVIOUS PAGE

;HERE TO RUN OVER THE INPUTS, AND DO THE WORK

DOIT:	MOVE	T1,I.INZR	;INITIALIZE POINTER
	MOVEM	T1,I.NXRD	;  TO INTERP. COMMANDS
	MOVE	T1,.JBFF	;SAVE INPUT
	MOVEM	T1,SVJBFF	; .JBFF

ISLOOP:	PUSHJ	P,DIR		;GO DO A DIRECTORY
	 JFCL			;HOHUM
	SKIPN	B.LC+.BFPTR	;SEE IF OPEN
	JRST	ISLOP1		;NO--SKIP THE CLOSE
	CLOSE	LC,		;CLOSE OFF LISTING FILE
	STATZ	LC,IO.ERR	;SEE IF ANY ERROR
	  PUSHJ	P,LCHRWR	;YES--REPORT IT
	RELEAS	LC,		;AND RELEASE DEVICE
ISLOP1:	SETZM	B.LC+.BFPTR	;CLEAR INITED FLAG

	SKIPG	S.FBLD		;/FNDBLD?
	JRST	ISLOP4		;NO, DON'T CLOSE FIND FILES THEN
	WAIT	DF,		;FLUSH OUT ALL DATA FILE DATA
	STATZ	DF,IO.ERR	;ANY LAST MOMENT ERRORS?
	  JRST	DFERR		;OOPS - GIVE ERROR MESSAGE
	WAIT	PF,		;FLUSH OUT ALL POINTER FILE DATA
	STATZ	PF,IO.ERR	;ANY LAST MOMENT ERRORS
	  JRST	PFERR		;YES, ABORT AND GIVE MESSAGE
	CLOSE	DF,		;CLOSE OFF DATA FILE
	RELEAS	DF,		;DITCH DEVICE
	CLOSE	PF,		;CLOSE OFF POINTER FILE
	RELEAS	PF,		;GET RID OF DEVICE

ISLOP4:	JRST	MAINLP		;ALL DONE
;FILE SCANNING ERRORS

E$$TMI:	MOVE	T1,['DRTTMI']	;INDICATE DIRECT MESSAGE CODE
	MOVE	T2,["?",,[ ASCIZ \Too many source files\ ] ] ;
	MOVEI	T3,E$$TMI	;POINT TO ERROR CODE
	PUSHJ	P,.ERMSA##	;ISSUE MESSAGE
	PJRST	.FMSGE##	;COMPLETE ERROR PROCESSING
	SUBTTL	DIRECTORY LISTING

;DIR -- PERFORM A DIRECTORY LISTING
;CALL:	PUSHJ	P,DIR
;	RETURN WHEN DONE
;OUTPUT FILE ALREADY OPENED; INPUT POINTED TO BY I.NXRD

DIR:	SETZM	H.ZER1		;CLEAR OUT COUNTERS
	MOVE	T1,[H.ZER1,,H.ZER1+1]
	BLT	T1,H.EZER
	SETZM	ABORTI		;CLEAR ABORTION BLAG
	MOVEI	I,0		;FLAG LOKWLD TO START
	SKIPLE	S.WORD		;SEE IF /WORD
	TROA	F,R.WORD	;YES--SET WORD MODE
	TRZ	F,R.WORD	;NO--CLEAR WORD MODE
	SKIPLE	S.FIND		;/FIND?
	JRST	FNDIR		;YES, SPECIAL FILE SERVICE

;HERE TO LOOP ON USER-SPECIFIED FILE SPECIFICATIONS, HANDLING ANY
;SPECIAL CASES (SUCH AS MAGTAPE OR TMPCOR) AS THEY ARISE IN THE
;INPUT FILE STREAM.

DIRLP:	DMOVE	P3,FOBLK+.FOIOS	;GET PREVIOUS /PHYSICAL AND DEVICE
	TRNN	F,R.NDSK	;[477] LOOPING ON DECTAPE?
	JRST	DIRLP0		;[477] NO
	RELEAS	DC,		;[477] YES, ALWAYS RELEASE BEFORE CALL TO WILD
	SETZ	P4,		;[477] AND ALWAYS FORCE A/NOTHER OPEN
DIRLP0:	MOVE	T1,[6,,[VERWRD		;PROTOCOL VERSION
		I.NXRD,,I.NXZR		;POINTER TO FIRST,,LAST FSB
		FOBLK+.FOIOS,,LBLOCK	;OPEN,,LOOKUP BLOCK ADDRESS
		.FXLEN,,LN$RIB+1	;LENGTH OF FSB,,LOOKUP
		FW.ADO!FW.DBS + I	;ALL DEVS; DIR BEFORE SUBDIR;
		WLDEOD ]]		;END OF DIRECTORY ROUTINE
	PUSHJ	P,.LKWLD##	;GET NEXT FILE
	  JRST	DIRED		;ALL DONE--OUTPUT TOTALS
;RDH	PUSHJ	P,CHKNXF	;CHECK FOR NON-EXISTENT PREVIOUS FILE
	XOR	P3,FOBLK+.FOIOS	;COMPARE /PHYS
	JUMPL	P3,DIRLP3	;IF /PHYS DIFFERENT, DO OPEN
	CAMN	P4,FOBLK+.FODEV	;SEE IF DEVICE IS DIFFERENT
	JRST	DSDEV		;DEVICE SPECIFICATION UNCHANGED, THEREFORE
				; IT IS A DISK (OR DECTAPE), SO JUST PROCESS
				; THE NEXT FILE RETURNED FROM WILD

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;A DIFFERENT DEVICE SPECIFICATION, MUST OPEN IT TO SEE WHAT TO DO NEXT

DIRLP3:	TRZ	F,R.FEAT!R.NDSK	;DON'T KNOW ABOUT DEVICE YET
	SETZM	FFPRV		; ANOTHER STICKY FLAG TO BE CLEARED
	MOVX	T1,IO.MOD	;THE I/O MODE FIELD
	ANDCA	T1,FOBLK+.FOIOS	;GET OPEN BLOCK I/O STATUS WORD
	IORI	T1,.IOBIN	;READ IN BINARY MODE
	SKIPE	S.RETR		;/NORETRY?
	TXZA	T1,UU.DER	;NO, LET MONITOR RETRY ON ERROR
	TXO	T1,UU.DER	;YES, FIND SOFT ERRORS TOO
	SKIPE	S.ERLO		;/NOERLOG?
	TXZA	T1,UU.DEL	;NO, ALLOW ERROR LOGGING
	TXO	T1,UU.DEL	;YES, DISABLE ERROR LOGGING
	TXO	T1,UU.SOE	;SYNCHRONIZE ON ERRORS
	MOVEM	T1,FOBLK+.FOIOS	;SET OPEN BLOCK
	MOVEI	T1,BFHD		;SET FOR OUR
	MOVEM	T1,FOBLK+.FOBRH	;  BUFFERS
	MOVE	T1,SVJBFF	;RESTORE INPUT
	MOVEM	T1,.JBFF	; .JBFF
	SETZM	BFHD+.BFADR	;NO BUFFERS YET
	SETZM	FOBLK+.FONBF	;NO BUFFERS TO BE BUILT (YET)
	SETZM	FOBLK+.FOLEB	;NO LOOKUP BLOCK (YET)
	SETZM	FOBLK+.FOPAT	;NO PATH BLOCK (YET)
	SETZM	FOBLK+.FOPPN	;NO ON-BEHALF-OF PPN
	MOVE	T1,[FO.PRV+<DC,,.FORED>]  ;READ ONLY FUNCTION ON DATA CHANNEL
	MOVEM	T1,FOBLK+.FOFNC	;SET FILOP. FUNCTION WORD

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DIRLP5:	MOVE	T1,[.FONBF+1,,FOBLK]  ;FILOP. ARG POINTER TO
	FILOP.	T1,		;OPEN WILD'S SUGGESTED NEW DEVICE
	  JRST	[MOVS	T4,FOBLK+.FODEV	;COPY OF DEVICE THAT FAILED
		CAIN	T4,'TMP'	;WANT TMP:?
		JRST	TMDEV		;YES, FAKE IT OUT
		PUSHJ	P,E.DFF##	;ISSUE OPEN ERROR MESSAGE
		AOSE	T1		;IS THIS AN IGNORABLE ERROR?
		AOS	SNFILR		;NO, COUNT AS FILE ERROR
		SETZM	FOBLK+.FODEV	;ENSURE DEVICE IS DIFFERENT
		JRST	DIRLP]		;GO BACK AND TRY FOR MORE
	MOVEI	T1,DC		;DATA FILE CHANNEL
	DEVCHR	T1,		;SEE WHAT WE ACTUALLY GOT
	TLC	T1,-1-<(DV.TTA)>;SEE IF
	TLCN	T1,-1-<(DV.TTA)>;  NUL:
	JRST	E.NDD		;YES--ERROR
	TXNE	T1,DV.DSK	;LOOKING AT A DISK?
	JRST	DSDEV		;YES
	TXNE	T1,DV.DTA	;SEE IF DECTAPE
	JRST	DTDEV		;YES--GO OUTPUT IT
IFN FT$MTA,<	;MAGTAPES
	TXNE	T1,DV.MTA	;SEE IF MAG TAPE
	JRST	MTDEV		;YES--GO OUTPUT IT
>;END IFN FT$MTA
	TXNN	T1,DV.DIR	;UNKNOWN--SEE IF DIRECTORY TYPE
	JRST	E.NDD		;NO--ISSUE MESSAGE
E.UDV:	N$WRNX	(UDV,Unknown device type )
	MOVE	T1,FOBLK+.FODEV	;GET OFFENDING DEVICE
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
X$$UDV:	PUSHJ	P,.TCRLF##	;CAP OFF THE MESSAGE
	SETZM	FOBLK+.FODEV	;FORCE A NEW LOOKUP
	JRST	DIRLP		;LOOK FOR MORE TO DO

E.NDD:	N$WRNX	(NDD,Not a directory device)
	MOVE	T1,FOBLK+.FODEV	;GET OFFENDING DEVICE
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
X$$NDD:	PUSHJ	P,.TCRLF##	;CAP OFF THE MESSAGE
	SETZM	FOBLK+.FODEV	;FORCE A NEW LOOKUP
	JRST	DIRLP		;LOOK FOR MORE TO DO
;HERE ON DISK (THE NORMAL CASE)

DSDEV:	TRNE	F,R.FEAT	;EATING .LKWLD'S DECTAPE FILES?
	JRST	DIRLP		;YES, IGNORE THIS FILE THEN
	PUSHJ	P,DSDIR		;DO A DISK-BASED DIRECTORY (OF ONE FILE)
	 JFCL			;HOHUM
	JRST	DIRLP		;TRY FOR MORE


;HERE FOR DECTAPE

DTDEV:	PUSHJ	P,DTDIR		;DO A DECTAPE DIRECTORY
	 JFCL			;HOHUM
	JRST	DIRLP		;TRY FOR MORE


;HERE FOR MAGTAPE

MTDEV:	PUSHJ	P,MTDIR		;DO A MAGTAPE DIRECTORY
	 JFCL			;HOHUM
	SETZM	FOBLK+.FODEV	;ENSURE A NEW OPEN IS DONE
	JRST	DIRLP		;TRY FOR MORE


;HERE FOR TMPCOR

TMDEV:	PUSHJ	P,TMDIR		;DO A TMP: DIRECTORY (LIST TMPCOR)
	 JFCL			;HOHUM
	SETZM	FOBLK+.FODEV	;ENSURE A NEW OPEN IS ATTEMPTED
	JRST	DIRLP		;TRY FOR MORE TO DO
	SUBTTL	DIRECTORY LISTING - DISK

;HERE FOR A DISK-BASED DIRECTORY (ONE FILE AT A TIME)

DSDIR:	TRZ	F,R.ACCS	;CLEAR ACCESS NEEDED FLAG
	MOVE	T3,.WIFIR##	;GET FIRST SPEC OF CURRENT SET
	CAMN	T3,LWIFIR	;SAME AS LAST TIME WE WERE HERE?
	JRST	DSLOK		;YES
	MOVEM	T3,LWIFIR	;NO, NOTE WE GOT THIS FAR
	SETZM	FRCLOK		;ASSUME NO LOOKUP REALLY NEEDED
	TRNE	F,R.FAST	;SEE IF SUPER-SPEEDY MODE
	SKIPL	.WLDFL##	;YES--SEE IF WILD CARD
	SETOM	FRCLOK		;NO--NEED A LOOKUP
	SKIPG	S.SUM		;SEE IF/SUM
	SKIPLE	S.AUT		; OR IF /AUTHOR
	SETOM	FRCLOK		;YES--FORCE LOOKUP
	SKIPG	S.CHK		;SEE IF /CHECKSUM
	SKIPL	S.ACCS		;SEE IF /ACCESS
	SETOM	FRCLOK		;YES--FORCE LOOKUP
	SKIPLE	S.ACCT		;SEE IF /ACCOUNT
	SETOM	FRCLOK		;YES--FORCE LOOKUP
	SKIPE	FRCLOK		;DIRECTORY MODE REQUIRE A LOOKUP?
	JRST	DSLOK		;YES

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE IF FAST LISTING MODE NOT NEEDING A LOOKUP (JUST WANT FILE NAME
;AND EXTENSION) - UNLESS ANY SWITCH CONSTRAINTS WERE SPECIFIED
;(SUCH AS /BEFORE OR /LENGTH).

	MOVE	T3,.WIFIR##	;START AT START
DSDIR3:	SETO	T4,		;NO-VALUE VALUE
	CAMN	T4,.FXBFR(T3)	;SEE IF /BEFORE
	CAME	T4,.FXSNC(T3)	; OR /SINCE
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	CAMN	T4,.FXABF(T3)	;SEE IF /ABEFORE
	CAME	T4,.FXASN(T3)	; OR /ASINCE
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	CAMN	T4,.FXPBF(T3)	;SEE IF /PBEFORE
	CAME	T4,.FXPSN(T3)	; OR /PSINCE
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	CAMN	T4,.FXFLI(T3)	;SEE IF MIN /LENGTH
	CAME	T4,.FXFLM(T3)	; OR MAX /LENGTH
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	LDB	T4,[POINTR .FXMOD(T3),FX.TRM]  ;GET FILE SPEC TERMINATOR
	CAIE	T4,.FXTIS	;'IFSAME' ?
	CAIN	T4,.FXTID	;'IFDIFFERENT' ?
	SETOM	 FRCLOK		;YES--NEED A LOOKUP
	CAIE	T4,.FXTIO	;'IFOLDER' ?
	CAIN	T4,.FXTIY	;'IFNEWER' ?
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	CAIE	T4,.FXTIL	;'IFSMALLER' ?
	CAIN	T4,.FXTIB	;'IFBIGGER' ?
	SETOM	FRCLOK		;YES--NEED A LOOKUP
	ADDI	T3,.FXLEN	;ON ONE FILE SPEC
	CAMG	T3,.WILAS##	;SEE IF DONE ALL
	JRST	DSDIR3		;NO, LOOP

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LOOKUP THE FILE IF NEEDED

DSLOK:	SKIPE	FRCLOK		;IS A LOOKUP NECESSARY?
	JRST	DSLOK2		;YES, DO IT THE HARD AND SLOW WAY

;HERE IF NO LOOKUP NEEDED, JUST VERIFY THE BASIC FILE SPECIFICATION

	TRNE	F,R.NDSK	;LOOKING AT A DISK?
	SETZM	UFDPPN		;NO, DECTAPE, DON'T MISLEAD .CHKTA
	PUSHJ	P,.CHKTA##	;SEE IF FILE IS REALLY OK
	 POPJ	P,		;NO, FILE REJECTED
	JRST	DSLOK8		;FILE IS OK, GO LIST IT

;HERE WHEN A LOOKUP IS NEEDED FOR THE FILE

DSLOK2:	MOVEI	T1,LBLOCK	;ADDRESS OF FILE LOOKUP BLOCK
	MOVEM	T1,FOBLK+.FOLEB	;SET IN FILOP. BLOCK
	MOVE	T1,[.PTMAX,,THSPTH]  ;ADDRESS OF FILE PATH BLOCK
	MOVEM	T1,FOBLK+.FOPAT	;SET IN FILOP. BLOCK
	SETZM	FOBLK+.FOPPN	;NO ON-BEHALF-OF PPN
	MOVX	T1,FO.PRV!FO.UOC+<DC,,.FORED>  ;LOOKUP FILE ON OPENED CHANNEL
	MOVEM	T1,FOBLK+.FOFNC	;SET FILOP. FUNCTION WORD
	MOVE	T1,[.FOPAT+1,,FOBLK]  ;FILOP. ARG POINTER TO
	TRNE	F,R.NDSK	;*** LOOKING AT A DECTAPE?
	JRST	[LOOKUP DC,LBLOCK	;*** YES, FILOP. SCREWS UP
		CAIA			;*** LOOKUP FAILED
		JRST	.+3		;*** CONTINUE WITH SUCCESSFUL LOOKUP
		HRRZ	T1,FEXT		;*** POSITION ERROR CODE
		JRST	.+2]		;*** PRETEND FILOP. CORRECTLY FAILED
	FILOP.	T1,		;LOOKUP WILD'S LATEST SUGGESTED FILE
	 PJRST	DSLOE		;[475] FILOP/LOOKUP ERROR, GO PLAY WITH IT
	MOVEI	T2,THSPTH	;ADDRESS OF RETURNED PATH BLOCK
	MOVEM	T2,UFDPPN	;SET TRUE FILE PATH
	TRNE	F,R.NDSK	;IS THIS REALLY A DISK FILE?
	JRST	[SETZM	UFDPPN		;DECTAPE, NO DIRECTORY EVER
		SETOM	FFPRV		;NO PROTECTION EITHER
		SKIPG	T2,FSIZ		;GET A POSITIVE WORD COUNT?
		HLRE	T2,FSIZ		;NO, NEGATIVE IN LH (DTA'S ARE WIERD)
		MOVMM	T2,FSIZ		;SET POSITIVE WORD COUNT
		JRST	.+1]		;AND KEEP PRETENDING TO BE A DISK
	PUSHJ	P,.CHKTA##	;GOT THE FILE, SEE IF WE REALLY WANTED IT
	 JRST	[MOVEI	T3,CL.ACS	;DON'T UPDATE ACCESS DATE
		MOVE	T2,[DC,,.FOCLS]	;WITH THE FILOP. CLOSE FUNCTION
		MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
		FILOP.	T1,		;CLOSE THE SUCCESSFULLY-LOOKUP'ED FILE
		 JFCL			;DUH?
		POPJ	P,]		;TOSS THIS FILE AND LOOK FOR ANOTHER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW ALLOCATE DISK BUFFERS, IF NOT ALREADY SETUP

	SKIPE	BFHD+.BFADR	;GOT A BUFFER RING?
	JRST	DSLOK4		;YES
	HRROI	T3,.GTLBS	;GETTAB ARGUMENT TO
	GETTAB	T3,		;READ DEFAULT LARGE BUFFER SIZE
	 SKIPA	T1,[NM$DBF,,LN$DBF]  ;UNDEFINED, REVERT TO STANDARD BUFFERING
	MOVE	T1,[NM$LBS,,LN$LBS]  ;SELECT LARGE BUFFERING
	TRNE	F,R.NDSK	;ACTUALLY GOT A DECTAPE?
	HRRI	T1,LN$BLK	;YES, USE SMALL BUFFERS
	SKIPLE	.FXBLS(I)	;DID USER GIVE /BLOCKSIZE?
	HRR	T1,.FXBLS(I)	;YES, USE HIS VALUE THEN
	SKIPLE	.FXBFN(I)	;DID USER GIVE /BUFFERS?
	HRL	T1,.FXBFN(I)	;YES, USE HER VALUE THEN
	MOVEI	T2,BFHD		;ADDRESS OF BUFFER RING HEADER
	PUSHJ	P,MAKBUF	;BUILD DISK INPUT BUFFER RING

DSLOK4:	TRNN	F,R.NDSK	;IF LOOKING AT A DISK
	SKIPG	S.DTL		;SEE IF /DETAIL
	JRST	DSLOK8		;NOT A DISK, OR NOT /DETAIL
	USETI	DC,0		;POSITION TO RIB
	IN	DC,		;READ RIB
	  SKIPA	T1,BFHD+.BFPTR	;GET BUFFER POINTER
	JRST	DSLOK8		;ERROR--CAN'T READ RIB
	MOVE	T1,200(T1)	;GET POINTER TO SELF
	MOVEM	T1,FRIBLK	;SAVE FOR OUTPUT
	MOVNI	T1,200		;SIZE OF BLOCK 0 (RIB)
	ADDM	T1,BFHD+.BFCTR	;SKIP IT (WANT TO CHECKSUM ONLY USER DATA)
	MOVEI	T1,200		;SIZE OF BLOCK 0 (RIB)
	ADDM	T1,BFHD+.BFPTR	;ADVANCE BYTE POINTER PAST BLOCK 0

;FILE IS GOOD, GO LIST IT

DSLOK8:	PUSHJ	P,ANALYZ	;GO ANALYZE AND PRINT RESULTS
	 JFCL			;IGNORE
	SKIPE	FRCLOK		;WAS A LOOKUP PERFORMED?
	CLOSE	DC,CL.ACS	;YES, MAKE SURE IT GOES AWAY PEACEABLY
	JRST	.POPJ1##	;RETURN FOR ANOTHER FILE
;[475] HERE IF FILOP./LOOKUP ERROR

DSLOE:	PUSH	P,T1		;SAVE FILOP. ERROR CODE
	MOVEI	T1,DSLOF	;SPECIAL OUTPUT INTERCEPT ROUTINE (GROAN)
	PUSHJ	P,.TYOCH##	;IN CASE ERROR MESSAGE OUTPUT
	MOVEM	T1,DSLOET	;SAVE ORIGINAL OUTPUT ROUTINE
	POP	P,T1		;RESTORE FILOP. ERROR CODE
	PUSHJ	P,E.DFF##	;NOTE FILE ACCESS FAILURE
	AOSE	T1		;WAS IT AN IGNORABLE ERROR?
	AOS	SNFILR		;NO, COUNT AS FILE ERROR
	SKIPE	T1,DSLOET	;NEED TO RESTORE TYPEOUT ROUTINE?
	PUSHJ	P,.TYOCH##	;YES
	POPJ	P,		;SO MUCH FOR THAT FILE


;HERE IF ABOUT TO OUTPUT AN ERROR MESSAGE (?PROT FAILURE, ETC.), MUST FIRST
;CALL SSTRDR TO MAKE SURE ANY DEV/DIR HEADER IS DONE, AND ENSURE THAT THE
;ERROR SUMMARY IS KEPT REASONABLY ACCURATE

DSLOF:	PUSHJ	P,.PSH4T##	;SAVE THE T'S
	PUSH	P,P1		;AND P1 TOO
	SETZ	T1,		;CLEAR TYPEOUT ROUTINE
	EXCH	T1,DSLOET	;AND FETCH ORIGINAL
	PUSHJ	P,.TYOCH##	;MAKE OUTPUT HAPPEN AGAIN
	TRNE	F,R.NDSK	;DISK OR OTHERWISE?
	JRST	[SETZM	UFDPPN		;OTHERWISE (DECTAPE), NO DIRECTORY
		JRST	DSLOF6]		;LET SSTRDR DO ITS THING
	MOVEI	T1,THSPTH	;ADDRESS WHERE WE WANT THE PATH
	MOVE	P1,UFDPPN	;GET REAL (MAYBE) PPN/PATH POINTER
	TLNE	P1,-1		;PPN OR PATH?
	JRST	[MOVEM	P1,.PTPPN(T1)	;PPN, SET IN PATH BLOCK
		SETZM	.PTSFD(T1)	;NO SFD'S THIS TIME
		JRST	DSLOF5]		;GO POINT TO PATH BLOCK
	HRL	T1,P1		;PATH, CONCOCT BLT POINTER TO
	BLT	T1,THSPTH+.PTMAX-1  ;COPY OVER PATH SPECIFICATION
DSLOF5:	MOVEI	T1,THSPTH	;ADDRESS OF PATH BLOCK
	MOVEM	T1,UFDPPN	;SET SO AS NOT TO CONFUSE SSTRDR
DSLOF6:	SETZ	P1,		;CLEAR FOR FOLLOWING CALL TO SSTRDR TO
	PUSHJ	P,SSTRDR	;TRACK DIRECTORIES CORRECTLY FOR SUMMARIES
	POP	P,P1		;RESTORE P1
	PUSHJ	P,.POP4T##	;RESTORE THE T'S
	PJRST	.TCHAR##	;[501] NOW GO DO THE ERROR MESSAGE
;HERE AT END OF DISK DIRECTORY

DIRED:	PUSH	P,T1		;SAVE .LKWLD TERMINATION CODE
	MOVEM	I,I.NXRD	;STORE PROGRESS
	JUMPE	P4,DIRDON	;IF NO DISKS PENDING, GO WRAP UP
DIREDF:	PUSHJ	P,DIRET		;GO OUTPUT TOTALS LINE

;HERE WHEN DONE WITH DISKS--SEE IF NEXT DEVICE IS REASONABLE AND GO DISPATCH

DIRDON:	CLOSE	DC,CL.ACS	;[477] MAKE SURE FILE (IF ANY) IS LEFT IN PEACE
	RELEAS	DC,		;[477] AND GET RID OF THE DEVICE (IF ANY)
	MOVE	T1,SVJBFF	;RESTORE INPUT
	MOVEM	T1,.JBFF	; .JBFF
	SETZM	H.ZER1		;CLEAR ACCUMULATION AREA
	MOVE	T2,[H.ZER1,,H.ZER1+1]  ; ..
	BLT	T2,H.EZER	; ..
	POP	P,T1		;RESTORE DEVCHR OF NEXT DEVICE
	CAMN	T1,[-1]		;SEE IF ALL DONE
	POPJ	P,		;YES--RETURN
	N$FAIL	(LEU,.LKWLD returned unknown termination reason)

;CALLED FROM WILD AT END OF DIRECTORY

WLDEOD:;RDH	PUSHJ	P,CHKNXF	;CHECK FOR NON-EX FILE ERROR
	TRNE	F,R.FAST	;IF /F
	SKIPLE	S.SUM		; AND NOT /SUM
	SKIPN	.WLDFL##	;SEE IF MULTIPLE DIRECTORIES
	PJRST	.TNEWL		;RETURN
	PJRST	SUBTOT		;YES--ISSUE SUBTOTALS
	SUBTTL	DIRECTORY LISTING - DECTAPE

;HERE WHEN DEVICE IS A DECTAPE
;
;UNLESS /DTA WAS SPECIFIED, TREAT DECTAPE JUST LIKE DISKS, PUTTING
;WHATEVER SMARTS ARE NEEDED IN "NORMAL" DISK SERVICE TO HANDLE DECTAPES'
;VARIOUS IDIOSYNCASIES . . .

DTDIR:	TRO	F,R.NDSK	;INDICATE NOT A DISK
	SKIPG	S.DTA		;/DTA (OLD COMPACT LISTING FORMAT)?
	JRST	DSDIR		;NO, TREAT AS "NORMAL" DIRECTORY DEVICE
	TRO	F,R.FEAT	;YES, MUST EAT SOME .LKWLD RETURNS
	SETSTS	DC,IO.SSD!IO.NSD!.IODMP  ;CHANGE TO SPECIAL MODE
	USETI	DC,^D100	;READ DIRECTORY BLOCK
	MOVE	T1,[IOWD 200,DIRB]
	MOVEI	T2,0
	IN	DC,T1		;READ IN THE DIRECTORY BLOCK
	  JRST	.+2		;IF OK
	PUSHJ	P,DTERR		;IF ERROR READING

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DTDIR4:	SETSTS	DC,.IOASC	;SET TO ASCII (BUFFER) IN CASE
				; SAME DEVICE IS LISTING DEVICE
	SKIPE	T2,DIRB+177	;SEE IF TAPE IDENT FIELD
	CAMN	T2,[-1]		;IS 0 OR -1
	JRST	DTDIR5		;YES--DON'T PRINT
	MOVEI	M,[ASCIZ /Tape ID: /]
	PUSHJ	P,LSTR		;LIST NAME
	PUSHJ	P,LSIX		;LIST IDENTIFICATION
	PUSHJ	P,LCRLF		;END OF LINE

DTDIR5:	MOVEI	M,[ASCIZ /Free: /]
	PUSHJ	P,LSTR		;LIST LABEL FOR SPACE
	MOVSI	J,-27		;COUNT FREE BLOCKS
				;  ALSO PRESET J FOR LATER
	PUSHJ	P,DTCNT		;FREE IF IN FILE #0
	PUSH	P,T1		;SAVE BLOCK COUNT
	PUSHJ	P,LDEC3		;PRINT AS 3 DIGITS
	POP	P,T1		;RESTORE BLOCK COUNT
	MOVEI	M,[ASCIZ\ blocks, \]  ;ASSUME PLURAL
	CAIN	T1,1		;EXACTLY ONE BLOCK?
	MOVEI	M,[ASCIZ\ block, \]  ;YES, USE SINGULAR FORM INSTEAD
	PUSHJ	P,LSTR		;IDENTIFY COUNT FIELD

	MOVEI	T1,0		;INITIALIZE FREE FILE COUNTER
	MOVEI	T2,26		;INITIALIZE FILE COUNTER
DTDIR6:	SKIPN	DIRB+122(T2)	;LOOK AT FILE NAME FIELD
	ADDI	T1,1		;IF =0, COUNT FREE
	SOJG	T2,DTDIR6	;LOOP FOR 22 FILES
	PUSH	P,T1		;SAVE FILE COUNT
	PUSHJ	P,LDEC2		;PRINT RESULT
	POP	P,T1		;RETRIEVE FREE-FILE COUNT
	MOVEI	M,[ASCIZ\ files\]  ;ASSUME PLURAL
	CAIN	T1,1		;EXACTLY ONE FILE?
	MOVEI	M,[ASCIZ\ file\];YES, SINGULAR THEN
	PUSHJ	P,LSTR		;AND FINISH LABELING
	PUSHJ	P,LCRLF		;AND FINISH LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO LOOP OVER FILES AND PRINT ONE LINE EACH

DTFIL0:	AOBJP	J,DTDON		;INCREMENT TO NEXT FILE
	SKIPN	T1,DIRB+122(J)	;SEE IF IN USE
	JRST	DTFIL0		;NO--LOOP BACK
	MOVEM	T1,FNAM		;SAVE FILE NAME
	HLLZ	T1,DIRB+150(J)	;GET EXTENSION
	MOVEM	T1,FEXT		;SAVE
	SETZM	UFDPPN		;CLEAR DIRECTORY WORD
	AOS	NOFIL		;COUNT A FILE SEEN
	PUSHJ	P,.CHKTA##	;SEE IF THIS FILE MATCHES
	 JRST	DTFIL0		;NO, REJECT IT AND TRY ANOTHER ONE
	AOS	NOFILF		;GOOD FILE, COUNT IT AS FILE FOUND
	AOS	NXFCNT		;AND AS FILE PROCESSED

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DTFIL1:	TRNN	F,R.FAST	;SEE IF /FAST
	SKIPG	S.SUM		; OR NOT /SUM
	SKIPA			;YES--PROCEED
	JRST	DTFIL4		;NO--SKIP OUTPUT
	MOVE	T2,FNAM		;GET FILE NAME
	MOVEI	T3,6		;USE 6 SPACES
	PUSHJ	P,LSIXC		;LIST IT
	MOVEI	C,"."		;USE . AS SEPARATOR
	PUSHJ	P,LCHR		;PRINT IT
	HLLZ	T2,FEXT		;GET EXTENSION
	MOVEI	T3,3		;USE 3 SPACES
	PUSHJ	P,LSIXC		;LIST IT
DTFIL4:	PUSHJ	P,DTCNT		;COUNT BLOCKS
	ADDM	T1,NOBLKS	;COUNT FOR SUMMARY
	SKIPG	S.SUM		;IF /SUMMARY
	TRNE	F,R.FAST	;SEE IF /FAST SWITCH
	JRST	DTFIL6		;YES--THAT'S ALL
	PUSHJ	P,LSPC		;NO--ADD A SPACE
	PUSHJ	P,LDEC3		;TYPE AS THREE DIGITS
	PUSHJ	P,LSPC2		;TYPE TWO SPACES
	LDB	T4,[POINT 12,DIRB+150(J),35]	;GET CREATION
	HRRZ	T1,J		;GET FILE NUMBER (1-22.)
	MOVEI	T2,1		;GET A TEST BIT
	TDNE	T2,DIRB+^D43(J)	;TEST THE EXTENSION BITS
	TRO	T4,1B21		; AND COPY TO RESULT
	TDNE	T2,DIRB+^D21(J)	; ..
	TRO	T4,1B22		; ..
	TDNE	T2,DIRB-1(J)	; ..
	TRO	T4,1B23		; ..
	PUSHJ	P,LDATE		;LIST CREATION DATE
DTFIL6:	TRNE	F,R.FAST	;IF /F
	JRST	DTFIL7		;THEN DON'T TEST /SUM
	SKIPLE	S.SUM		;IF /SUM
	JRST	DTFIL0		;BACK FOR MORE FILES
DTFIL7:	MOVE	T2,NOCHRS	;GET # CHARS SO FAR
	CAMG	T2,MXWDTH	;END OF LINE?
	JRST	DTFIL8		;NO, OUTPUT TAB
	PUSHJ	P,LCRLF		;FINISH OFF LINE
	JRST	DTFIL0		;LOOP BACK FOR MORE
DTFIL8:	PUSHJ	P,LTAB		;OUTPUT TAB
	JRST	DTFIL0		;LOOP BACK FOR MORE

DTDON:	RELEASE	DC,		;GIVE DEVICE BACK NOW
	SETZM	FOBLK+.FODEV	;ENSURE A NEW OPEN IS ATTEMPTED
	JRST	DIREND		;CAP OFF THE DIRECTORY
;DTCNT -- ROUTINE TO COUNT NUMBER OF BLOCKS IN A FILE
;CALL:	HRRI	J,FILE NUMBER (0-22)
;	PUSHJ	P,DTCNT
;	RETURN	WITH T1=NUMBER OF BLOCKS ALLOCATED
;USES T2, T3, T4

DTCNT:	MOVEI	T1,0		;PRESET COUNT
	MOVE	T2,[POINT 5,DIRB]	;PRESET POINTER TO ALLOCATION TABLE
	MOVEI	T3,1101		;PRESET COUNT OF NUMBER ON TAPE
DTCNT1:	ILDB	T4,T2		;PICK UP FILE OF NEXT BLOCK ON TAPE
	CAIN	T4,(J)		;COMPARE WITH REQUEST
	ADDI	T1,1		;MATCHES--COUNT
	SOJG	T3,DTCNT1	;LOOP OVER ENTIRE TAPE
	POPJ	P,		;RETURN


;ERRORS

DTERR:	GETSTS	DC,P3		;GET STATUS
	SETSTS	DC,.IOASC	;SET TO ASCII (BUFFER) FOR LISTING
	TXNN	P3,IO.DTE!IO.DER;UNLESS PAR.ERR. OR DEV.ERR.,
	PJRST	E.TFR		; GO GIVE FATAL ERROR
	TXNN	P3,IO.DTE	;SEE IF PARITY ERROR
	JRST	E$$DDM		;NO--MUST BE DEVICE ERROR
	N$WRNX	(DPE,<Parity error, status>)
	JRST	DTERR1		;GO DO COMMON STUFF
	N$WRNX	(DDM,<Data missed, status>)
DTERR1:	HRRZ	T1,P3		;GET STATUS
	PUSHJ	P,.TOCTW##	;ISSUE IN OCTAL
	MOVEI	T1,[ASCIZ \, in directory block on \]
	PUSHJ	P,.TSTRG##	;ISSUE EXPLANATION
	MOVE	T1,.FXDEV(I)	;GET DEVICE
	PUSHJ	P,.TSIXN##	;ISSUE IN SIXBIT
	PUSHJ	P,.TCOLN##	;INDICATE IT'S A DEVICE
X$$DDM:!
X$$DPE:	PJRST	.TCRLF##	;END MESSAGE

E.TFR:	N$FAIO	(TFR,Data error reading DECtape directory, status)
	SUBTTL	DIRECTORY LISTING - MAGTAPE

IFN FT$MTA,<	;MAGTAPES

;HERE WHEN MAG TAPE IS DISCOVERED

MTDIR:	TLZ	F,L.MLBL!L.MLBP	;DON'T KNOW ABOUT LABELS YET
	SKIPE	S.REWS		;UNLESS /NOREW
	MTREW.	DC,		;REWIND TAPE TO START
	SKIPLE	S.WORD		;SEE IF /WORD
	TRO	F,R.WORD	;YES--SET FLAG

;SETUP FOR .CHKTA CALLS TO VERIFY SELECTED FILE

	SOS	.CTFLS##	;BACKOFF WILD'S "FILES SEEN" FLAG
	SOS	.CTFLF##	;BACKOFF WILD'S "FILES FOUND" FLAG
				; LEAVE THE OTHER COUNTERS ALONE. WILD WILL
				; CHOOSE AN APPROPRIATE ERROR MESSAGE LATER
				; FROM "NO SUCH FILES" OR "ALL FILES REJECTED"
				; SHOULD ANY BE NEEDED
	SETOM	.WXPRC##	;FORCE FULL FILE SPECIFICATION CHECK
	MOVE	T3,.WIFIR##	;ADDRESS OF [PRESUMED] FILE SPEC BLOCK
	DMOVE	T1,.FXDEV(T3)	;GET ACTUAL DEVICE SPEC
	DMOVEM	T1,MTXDEV	;SAVE IT AWAY
	MOVSI	T1,'*  '	;FULL WILD NAME
	SETZ	T2,		;FULL WILD MASK
	DMOVEM	T1,.FXDEV(T3)	;INDICATE ANY "STR" ACCEPTABLE TO START WITH
	MOVX	T1,FX.WDV	;THE WILDCARDS-IN-DEVICE FLAG
	IORM	T1,.FXFLD(T3)	;SET THAT ON G.P.'S
	SKIPN	T1,.WLDFL##	;SEE IF NO WILD FILE OR STR
	AOS	T1,.WLDFL##	;YES--MAKE WILD STR ONLY
	CAMN	T1,[-1]		;SEE IF WILD FILE ONLY
	SOS	.WLDFL##	;YES--MAKE WILD FILE AND STR

	MOVE	T1,.JBFF	;SAVE .JBFF TO AVOID
	MOVEM	T1,MTSVFF	;  CORE GROWTH ON REOPENS
	MOVEI	T1,DC		;GET PHYSICAL
	DEVNAM	T1,		; NAME OF TAPE
	  MOVE	T1,FOBLK+.FODEV	;(OR LOGICAL IF UNKNOWN)
	MOVEM	T1,MTNAME	;DRIVE FOR MESSAGES
	MOVE	T1,S.FILE	;SET /FILE
	MOVEM	T1,MTFLCT	;INTO FILE COUNTER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;ALLOCATE I/O BUFFERS FOR TAPE READING

	MOVE	T1,FOBLK+.FOIOS	;GET "OPEN" BLOCK STATUS
	MOVEI	T2,DC		;AND "DEVICE"
	MOVEI	T4,T1		;ADDRESS OF "OPEN" BLOCK
	DEVSIZ	T4,		;ASK FOR A FALL-BACK BUFFERING SIZE
	 MOVEI	T4,LN$MRC+3	;??? ASSUME A DEFAULT
	MOVEI	T3,DC		;"ADDRESS" OF MAGTAPE DEVICE
	MOVEI	T2,.TFBSZ	;RETURN BUFFER SIZE FUNCTION
	MOVE	T1,[2,,T2]	;TAPOP. ARG POINTER TO
	TAPOP.	T1,		;ASK FOR TAPE BLOCKSIZE
	 MOVEI	T1,-2(T4)	;USE DEVSIZ DEFAULT THEN
	SUBI	T1,1		;ACCOUNT FOR RING OVERHEAD WORD IN TAPOP.
	CAIGE	T1,LN$MRC	;SEE IF MIN TAPE OR BIGGER SIZE
	MOVEI	T1,LN$MRC	;NO--FORCE UP

	PUSH	P,T1		;SAVE TEMPORARILY
	SKIPG	T2,S.BFCT	;GET /BLOCKINGFACTOR
	MOVEI	T2,AD.FCT	;NOT SPECIFIED SO USE OLD VALUE
	MOVE	T1,[%CCTYP]	;GETTAB ARGUMENT
	CAILE	T2,^D56		;ABOVE KS10 UNIBUS ADAPTER LIMITATION?
	GETTAB	T1,		;YES--GET CPU TYPE FROM MONITOR
	  SETZ	T1,		;???
	CAIN	T1,.CCKSX	;KS10?
	MOVEI	T2,^D56		;REDUCE TO KS10 MAXIMUM
	IMULI	T2,200		;TIMES WORDS PER DISK BLOCK
	ADDI	T2,^D32		;PLUS BACKUP OVERHEAD
	MOVEM	T2,MTFFTB	;SAVE FOR LATER
	ADDI	T2,3		;PLUS BUFFER RING OVERHEAD
	POP	P,T1		;RESTORE T1

	SKIPLE	.FXBLS(I)	;DID USER SAY /BLOCKSIZE ???
	HRRZ	T1,.FXBLS(I)	;YES, ASSUME HE KNOWS BETTER THAN WE DO
	SKIPLE	S.BFCT		;/BLOCKINGFACTOR?
	MOVE	T1,T2		;USE COMPUTED BUFFER SIZE VALUE
	MOVEM	T1,MTFBSZ	;SAVE BUFFERSIZE
	PUSH	P,[-1]		;[473] INIT THE KRUFTY LABEL BUG WORKAROUND
MTDIR4:	HRLI	T1,NM$MBF	;NUMBER OF BUFFERS
	SKIPLE	.FXBFN(I)	;DID USER SPECIFY NUMBER OF BUFFERS?
	HRL	T1,.FXBFN(I)	;YES, TAKE HER WORD FOR IT.
	MOVEI	T2,BFHD		;POINT TO HEADER
	PUSHJ	P,MAKBUF	;MAKE A BUFFER RING

;NOW DO A "DUMMY" IN TO FORCE THE TAPE DENSITY CORRECT

	GETSTS	DC,T1		;CURRENT I/O STATUS
	TXO	T1,IO.SYN	;FORCE SYCHRONOUS MODE
	SETSTS	DC,(T1)		;TELL MONITOR TO READ ONLY ONE BUFFER
	MTWAT.	DC,		;WAIT FOR THE TAPE TO SETTLE DOWN
	IN	DC,		;READ FIRST BLOCK (SET DENSITY, CHECK BLOCKSIZE)
	 JRST	MTDRH		;EVERYBODY SEEMS HAPPY ENOUGH . . .
	AOSN	0(P)		;[473] FIRST TIME HERE?
	PUSHJ	P,MTLBIN	;[473] READ LABEL INFO NOW, MTBSR. DESTROYS IT!
	GETSTS	DC,T4		;SOMEBODY IS UNHAPPY
	TXNE	T4,IO.EOF	;START OFF WITH END OF FILE?
	JRST	[CLOSE	DC,		;YES, CLEAR END OF FILE
		MTBSF.	DC,		;BACKSPACE OVER IT
		JRST	MTDRH]		;AND BLUNDER ONWARDS
	TXC	T4,IO.ERR	;NOT END OF FILE, MUST BE ERROR OF SOME SORT
	MTBSR.	DC,		;BACKSPACE OVER THE OFFENDING RECORD
	TXCE	T4,IO.ERR	;EXTENDED I/O ERROR STATUS?
	TXNN	T4,IO.BKT	;NO, NORMAL - BLOCK TOO LARGE?
	JRST	MTDRH		;NOT BLOCK TOO LARGE, GO SEE WHAT HAPPENS
	SKIPLE	.FXBLS(I)	;DID USER EXERT EXPLICIT CONTROL OVER BLOCKSIZE?
	JRST	MTDRH		;YES, NO DEFAULTING ON OUR PART THEN (HE LOSES)

;CONTINUED ON NEXT PAGE
;CONTINUED ON NEXT PAGE

;OUR TAPE BUFFERS ARE NOT BIG ENOUGH, TRY TO GROW THEM

	TXZ	T4,IO.BKT	;CLEAR ERROR BIT
	SETSTS	DC,(T4)		;AND TELL THE MONITOR TO CLEAR ITS COPY
;[472]	CLOSE	DC,		;TRY TO SYNC WITH TAPE SERVICE
	MOVE	T1,MTFBSZ	;GET CURRENT BLOCKSIZE
	ADDI	T1,2000		;ADVANCE A K
	ANDCMI	T1,1777		;ESTHETICALLY PLEASING BIT PATTERN(S)
	MOVEM	T1,MTFBSZ	;SET NEW PROPOSED BLOCK SIZE
	N$WRNX	(XMB,Expanding magtape I/O buffers to )
	MOVE	T1,MTFBSZ	;GET NEW SIZE
	PUSHJ	P,.TDECW##	;TELL USER
	MOVEI	T1,[ASCIZ\ words\]  ;A HARMLESS NOISE WORD
	PUSHJ	P,.TSTRG##	;PUT IT OUT TOO
X$$XMB:	PUSHJ	P,.TCRLF##	;CAP OFF THE WARNING MESSAGE

	MOVE	T1,MTSVFF	;GET BACK OLD START OF BUFFER ALLOCATION
	MOVEM	T1,.JBFF	;RESET FOR NEW BUFFER ALLOCATION ATTEMPT
	MOVE	T1,MTFBSZ	;RETRIEVE NEW PROPOSED BUFFERSIZE
	JRST	MTDIR4		;GO REBUILD BUFFERS AND TRY AGAIN
MTDRH:	GETSTS	DC,T1		;READ CURRENT I/O STATUS
	TXZ	T1,IO.SYN!IO.EOF!IO.ERR	;CLEAR OUT OBNOXIOUS BITS
	SETSTS	DC,(T1)		;AND TELL THE MONITOR TO TAKE OFF
	MTWAT.	DC,		; (NOT THAT I DON'T TRUST TAPSER, BUT . . .)
	POP	P,T1		;[473] RETRIEVE MTLBIN COUNTER
	AOSN	T1		;[473] CALL MTLBIN IF HAVEN'T ALREADY DONE SO
	PUSHJ	P,MTLBIN	;SETUP TAPE LABEL PARAMETERS (IF ANY)
	SETZB	P1,P2		;CLEAR REGISTERS FOR LATER
	MOVE	T4,[2,,T2]	;SETUP FOR 5.07 MTCHR.
	MOVEI	T2,DC		;POINT TO RIGHT CHANNEL
	MTCHR.	T4,		;TRY IT
	  JRST	MTDN57		;NOT 5.07 YET
	MOVE	T2,T4		;OK--COPY AC BITS
	MOVE	P2,T3		;SAVE REELID
	TRNE	T4,1B32		;COPY 7-TRACK FLAG
	TRO	P1,1B32		;(SAME AS DEVSTS)
	TRNE	T4,1B31		;COPY RING STATUS
	TRO	P1,1B33		;(SAME AS DEVSTS)
	JRST	MTDI57		;AND PROCEED

MTDN57:	SETOM	P1		;FLAG DEVSTS NEEDED
	MOVEI	T2,DC		;GET TAPE DENSITY
	MTCHR.	T2,		; FROM MONITOR
	  JRST	[GETSTS DC,T2	;NO--FROM INIT
		 ANDI	T2,IO.DEN  ;JUST GET DENSITY
		 JUMPE	T2,MTNODN  ;JUMP IF UNKNOWN
		 LSH	T2,^D33-^L<IO.DEN>  ;POSITION
		 JRST	.+1]	;PROCEED
MTDI57:	MOVEI	T1,[ASCIZ /  Read Density:/]
	PUSHJ	P,.TSTRG##	;LIST LABEL
	ANDI	T2,7		;MASK TO DENSITY
	MOVE	T2,[ASCIZ /???/
		    ASCIZ /200/
		    ASCIZ /556/
		    ASCIZ /800/
		    ASCIZ /1600/
		    ASCIZ /6250/
		    ASCIZ /(6)/
		    ASCIZ /(7)/](T2)
	MOVEI	T1,T2		;SET MESSAGE
	PUSHJ	P,.TSTRG##	;LIST IT
>;END IFN FT$MTA

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTA,<	;MAGTAPES

MTNODN:	MOVEI	T1,[ASCIZ /  Parity:/]
	PUSHJ	P,.TSTRG##	;LABEL
	MOVEI	T1,[ASCIZ /Odd/]
	STATZ	DC,IO.PAR
	  MOVEI	T1,[ASCIZ /Even/]
	PUSHJ	P,.TSTRG##	;LIST PARITY
	JUMPGE	P1,MTNODO	;SKIP DEVSTS IF 5.07
	MOVEI	P1,DC		;NOW GET DEVICE STATUS
	DEVSTS	P1,		;(HARDWARE STATUS SINCE SOFTWARE LOOSES)
	  JRST	MTNODS		;GIVE UP IF WE CAN'T
MTNODO:	MOVEI	T1,[ASCIZ /  7-Track/]
	TRNN	P1,1B33		;CHECK NUMBER OF TRACKS
	MOVEI	T1,[ASCIZ /  9-Track/]
	PUSHJ	P,.TSTRG##	;LIST THAT
	MOVEI	T1,[ASCIZ /  Read only/]
	TRNN	P1,1B32		;CHECK WRITE LOCK
	MOVEI	T1,[ASCIZ /  Write enabled/]
	PUSHJ	P,.TSTRG##	;LIST THAT
	JUMPE	P2,MTNODS	;DONE IF NO REELID
	MOVEI	T1,[ASCIZ /  REELID:/]
	PUSHJ	P,.TSTRG##	;ISSUE PREFIX
	MOVE	T1,P2		;GET ID
	PUSHJ	P,.TSIXN##	;OUTPUT IT

MTNODS:	PUSHJ	P,.TCRLF##	;END LINE
	TLZN	F,L.FKEF	;CHECK IF EOF
	JRST	MTFIND		;NO--GO HANDLE DATA
	SKIPGE	ABORTI		;TIME TO ABORT INPUT OPERATIONS?
	JRST	MTABO		;YES - TAPE IS USELESS NOW
	PUSHJ	P,MTLPRT	;PRINT FILE INFO IF ANY
	N$WARN	(TSM,Tape starts with tape mark)
MTSTEF:	CLOSE	DC,		;CLEAR END-OF-FILE
	SOSN	MTFLCT		;DO /FILE ACCOUNTING
	JRST	MTDONX		;EXIT IF /FILE COUNTED OUT
	PUSHJ	P,NEXOVW	;AGAIN, TRY TO READ A WORD
	  JRST	.+2		;ANOTHER EOF
	JRST	MTEXAM		;NO--GO EXAMINE TAPE
	N$WARN	(ATM,     and another tape mark)
	TLNE	F,L.MLBP	;CONTROLLED BY TAPE LABEL PROCESSOR
	JRST	MTDONE		;YES, THEN THERE IS NO HOPE
	JRST	MTSTEF		;LOOP UNTIL WE GET SOME DATA
>;END IFN FT$MTA
IFN FT$MTA,<	;MAGTAPES

;HERE WHEN DEVICE IS OPEN AND TIME TO LOOK AT NEXT FILE TO SEE IF
;IT IS A SAVE SET
;FORMATS:	IF THE FIRST WORD IS NON-ZERO AND,
;	0-17 = 0, THEN BACKUP FORMAT
;	0-14 = 0, 15-17 NOT 0, THEN FRS FORMAT
;	0-17 = 1???, THEN .EXE OR SOME SUCH
;	0-17 GE 27, THEN FAILSA (LEVEL-D) FORMAT
;     [ 0-5 NOT 0, 6-17 = 0, THEN OLD BACKUP/RESTORE FORMAT ]
;	0-17 NEGATIVE, THEN EITHER:
;		ASCII OR SIXBIT LABEL
;		HRI FORMAT
;		SAVE FORMAT

MTFIND:	PUSHJ	P,NEXOVW	;GET NEXT WORD
	  JRST	MTEOF		;END OF FILE--GO HANDLE THAT CASE
MTEXAM:	MOVEM	T1,CHKSUM	;SETUP CHECKSUM IN CASE THAT'S IMPORTANT
IFN FT$MTL<	;LABELS/VIA TAPOP
	PUSHJ	P,MTLPRT	;TRY TO TELL ABOUT FILE
	MOVE	T1,CHKSUM	;GET BACK FIRST DATA WORD
>;END IFN FT$MTL
	MOVEI	T2,1		;SET WORD COUNTER
IFN FT$MTB,<	;BACKUP/FRS
	TLNN	T1,777770	;SEE IF FRS OR BACKUP
	JUMPN	T1,MTFRSS	;YES--GO HANDLE
>;END IFN FT$MTB
IFN FT$MTR,<	;OLD BACKUP/RESTORE
	TLNN	T1,7777		;SEE IF OLD BACKUP/RESTORE SAVE SET
	JRST	MTBKSS		;YES--GO PROCESS
>;END IFN FT$MTR
	TLNN	T1,776000	;IF 1???
	TLNN	T1,1000		; ..
	SKIPA			;NO--PROCEED
	JRST	MTIOW		;YES--HANDLE AS SAVE FILE
IFN FT$MTF, JUMPG T1,MTSVST	;JUMP IF LOOKS LIKE FAILSA SAVE SET
>;END IFN FT$MTA

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTA,<	;MAGTAPES

	MOVE	T3,T1		;GET COPY OF WORD
	TRZ	T3,77777	;REDUCE TO FIRST THREE ASCII CHARS
	MOVSI	T4,-LNLBLT	;POINT TO LABEL TYPES TABLE
	CAME	T3,LABTYP(T4)	;SEE IF ASCII LABEL
	AOBJN	T4,.-1		;LOOP TO MATCH
	JUMPL	T4,MTLABL	;YES--GO READ ASCII LABEL
	TRZ	T3,-1		;CLEAR DOWN TO SIXBIT TYPE
	MOVSI	T4,-LNLB6T	;POINT TO SIXBIT LABELS TABLE
	CAME	T3,LABTY6(T4)	;SEE IF SIXBIT LABEL
	AOBJN	T4,.-1		;LOOP TO MATCH
	JUMPL	T4,MTLAB6	;YES--GO READ SIXBIT LABEL
	JRST	MTIOW		;ELSE, GO READ AS SAVE OR HRI FILE

;ASCII LABELS
LABTYP:	ASCII	/VOL/		;BEGINNING OF VOLUME
	ASCII	/UVL/		;USER VOLUME
	ASCII	/EOV/		;END OF VOLUME
	ASCII	/UTL/		;USER TRAILER
	ASCII	/HDR/		;BEGINNING OF FILE
	ASCII	/UHL/		;USER HEADER
	ASCII	/EOF/		;END OF FILE
LNLBLT==.-LABTYP

;SIXBIT LABELS
LABTY6:	SIXBIT	/VOL/		;BEGINNING OF VOLUME
	SIXBIT	/UVL/		;USER VOLUME
	SIXBIT	/EOV/		;END OF VOLUME
	SIXBIT	/UTL/		;USER TRAILER
	SIXBIT	/HDR/		;BEGINNING OF FILE
	SIXBIT	/UHL/		;USER HEADER
	SIXBIT	/EOF/		;END OF FILE
LNLB6T==.-LABTY6
>;END IFN FT$MTA
IFN FT$MTL,<	;IF DOING LABEL INFO VIA TAPOP...

;This routine will try to print information about a labeled tape
; which can be obtained via the .TFLPR TAPOP.
; The magtape should be open on DC
; The tape is not moved.

MTLBIN:	PUSHJ	P,.SAVE4##	;PRESERVE THE P ACS
	MOVE	P1,[2,,P2]	;POINT AT THE ARG BLOCK
	MOVEI	P2,.TFLBL	;CODE TO GET LABEL TYPE
	MOVEI	P3,DC		;GET OPEN CHANNEL
	MOVEM	P3,M.MTLB+.TPDEV;SAVE DEVICE SPECIFIER (CHAN #)
	TAPOP.	P1,		;FIND OUT THE LABEL TYPE
	 POPJ	P,		;CAN'T, SO GET OUT
	CAIN	P1,0		;CONTROLLED BY LABEL PROCESSOR
	POPJ	P,		;NO, NOTHING TO DO WITH LABELS
	TLO	F,L.MLBP	;YES, EVEN IF "UNLABELED"
	CAIL	P1,.TFLAL	;IS IT ANSI ?
	CAILE	P1,.TFLIU	;OR EBCDIC (IBM)
	 POPJ	P,		;NO, NO LABELS TO READ
	MOVEI	P1,.TFLPR	;FUNCTION CODE - LABEL PARAMETERS
	MOVEM	P1,M.MTLB+.TPFUN;SAVE FUNCTION CODE
	MOVE	P1,[.TPLEN,,M.MTLB]  ;AIM AT THE LABEL PARAMETER BLOCK
	TAPOP.	P1,		;READ THE LABEL PARAMS OF THE NEXT FILE
	 POPJ	P,		;CAN'T, SO GET OUT NOW!
	TLO	F,L.MLBL	;TAPE CONTROLLED BY LABEL PROCESSOR
	POPJ	P,		;NOW RETURN
;RINT OUT THE TAPE LABEL INFORMATION AS SUPPLIED BY MTLBIN

MTLPRT:	SKIPN	M.MTLB+.TPFNM	;ANY DATA THERE ???
	POPJ	P,		;NO, RETURN
	PUSHJ	P,.SAVE4##	;PRESERVE THE P ACS
	TLZ	F,L.CRLF	;DAMMIT, A NEW LINE!
	PUSHJ	P,LCRLF		;BLANK LINE
	MOVEI	M,[ASCIZ/  Labeled tape file information:/]
	PUSHJ	P,LSTR		;TYPE THAT
	PUSHJ	P,LCRLF		;START A NEW LINE
	MOVEI	M,[ASCIZ/    File Name:"/]
	PUSHJ	P,LSTR		;TYPE THAT
	MOVEI	M,M.MTLB+.TPFNM	;AIM AT FILENAME
	PUSHJ	P,LSTR		;TYPE FILENAME STRING
	MOVEI	C,""""		;TRAILING QUOTE
	PUSHJ	P,LCHR		;ALWAYS CLOSE OFF THE FILENAME
	LDB	T1,[POINTR M.MTLB+.TPGEN,TP.GEN] ;GET GENERATION NUMBER
	JUMPE	T1,MTLPR3	;SKIP IF NOT GENERATION DATASET
	MOVEI	M,[ASCIZ/, Generation:/]
	PUSHJ	P,LSTR		;LIST DESCRIPTOR
	PUSHJ	P,LDEC		;LIST GENERATION AS DECIMAL
MTLPR3:	LDB	T1,[POINTR M.MTLB+.TPGEN,TP.VER] ;GET VERSION NUMBER
	JUMPE	T1,MTLPR4	;SKIP IF NO VERSION FIELD
	MOVEI	M,[ASCIZ/, Version:/]
	PUSHJ	P,LSTR		;LIST DESCRIPTOR
	PUSHJ	P,LDEC		;LIST VERSION AS DECIMAL
MTLPR4:	PUSHJ	P,LCRLF		;CAP OFF THIS LINE
	MOVEI	M,[ASCIZ/    Protection:/]
	PUSHJ	P,LSTR		;TYPE THAT
	MOVE	T1,M.MTLB+.TPPRO;GET PROTECTION
	PUSHJ	P,LOCT3Z	;LIST WITH LEADING ZEROS
	MOVEI	M,[ASCIZ/, Creation Date:/]
	PUSHJ	P,LSTR		;DELIMIT CREATION FIELD
	LDB	T4,[POINTR M.MTLB+.TPEXP,TP.ECR] ;GET THE CREATION DATE
	PUSHJ	P,LDATE		;CONVERT AND OUTPUT DATE
	MOVEI	M,[ASCIZ/, Expiration Date:/]
	PUSHJ	P,LSTR		;DELIMIT EXPIRATION FIELD
	LDB	T4,[POINTR M.MTLB+.TPEXP,TP.EEX] ;GET THE EXPIRATION DATE
	PUSHJ	P,LDATE		;CONVERT AND OUTPUT DATE
	PUSHJ	P,LCRLF		;CLEAN LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVEI	M,[ASCIZ/    Block size:/]
	PUSHJ	P,LSTR		;LIST DESCRIPTOR
	MOVE	T1,M.MTLB+.TPBSZ;GET THE BLOCK SIZE
	PUSHJ	P,LDEC		;LIST THAT
	MOVEI	M,[ASCIZ/, Record size:/]
	PUSHJ	P,LSTR		;LIST DESCRIPTOR
	MOVE	T1,M.MTLB+.TPRSZ;GET THE RECORD SIZE
	PUSHJ	P,LDEC		;LIST THAT
	PUSHJ	P,LCRLF		;CLEAN LINE
	MOVEI	M,[ASCIZ/    Record Format:/]
	PUSHJ	P,LSTR		;LIST DESCRIPTOR
	LDB	T1,[POINTR M.MTLB+.TPREC,TR.RFM] ;GET THE RECORD FORMAT CODE
	MOVE	M,MTRCFM(T1)	;AIM AT RECORD FORMAT STRING
	PUSHJ	P,LSTR		;AND LIST THE RECORD FORMAT TYPE
	MOVEI	M,[ASCIZ/, Form control:/]
	PUSHJ	P,LSTR		;IDENTIFY NEXT FIELD
	LDB	T1,[POINTR M.MTLB+.TPREC,TR.FCT] ;GET THE FORM CONTROL
	MOVE	M,MTFCTL(T1)	;AIM AT FORM CONTROL STRING
	PUSHJ	P,LSTR		;AND TYPE IT OUT TOO
	PUSHJ	P,LCRLF		;CLEAN LINE
	SETZM	M.MTLB		;CLEAR THE FIRST WORD
	MOVE	T1,[M.MTLB,,M.MTLB+1]  ;GET BLT PARMS
	BLT	T1,M.MTLB+.TPLEN-1  ;ZERO THE PARAMETER BLOCK
	POPJ	P,		;ALL DONE!
;LERTAB:	[ASCIZ/No errors/]
;	[ASCIZ/Continue processing/]
;	[ASCIZ/EOF/]
;	[ASCIZ/Label type error/]
;	[ASCIZ/Header label error/]
;	[ASCIZ/Trailer label error/]
;	[ASCIZ/Volume label error/]
;	[ASCIZ/Device error/]
;	[ASCIZ/Data error/]
;	[ASCIZ/Write-lock error/]
;	[ASCIZ/Positioning error/]
;	[ASCIZ/BOT/]
;	[ASCIZ/Illegal operation/]
;	[ASCIZ/File not found/]

;Table of record format names

MTRCFM:	[ASCIZ/Default/]
	[ASCIZ/Fixed/]
	[ASCIZ/Variable/]
	[ASCIZ/Spanned/]
	[ASCIZ/Undefined/]

;Table of form control names

MTFCTL:	[ASCIZ/????/]
	[ASCIZ/None/]
	[ASCIZ/ANSI/]
	[ASCIZ/Embedded/]

> ;END INF FT$MTL
IFN FT$MTA,<	;MAGTAPES

;HERE WHEN THE FILE IS AN IOWD (IE, SAVE OR HRI FORMAT) OR .EXE

MTIOW:	SETOM	P1		;SET FLAG FOR FIRST IOWD
	SETZM	FVER		;CLEAR VERSION NUMBER
	JUMPG	T1,MTEXE	;IF .EXE, GO HANDLE
MTIOWD:	MOVE	T3,T1		;GET COUNT OF IOWD
	JUMPE	T1,MTIOHR	;IF ZERO, JUNK OR HRI FORMAT
	AOS	P1		;ADVANCE IOWD COUNTER
	JUMPG	T1,MTIOJK	;JUMP IF JUNK FORMAT
MTIODT:	PUSHJ	P,NEXDTW	;GET DATA WORD
	  JRST	MTIOJF		;JUMP IF EOF
	AOS	T2		;COUNT WORD READ
	MOVEI	T4,1(T3)	;GET LOCATION OF DATA
	CAIN	T4,.JBVER	;SEE IF VERSION NUMBER
	MOVEM	T1,FVER		;YES--SAVE FOR LATER
	MOVE	T4,T1		;SAVE DATA WORD IN CASE OF HRI FORMAT
	AOBJN	T3,MTIODT	;COUNT OFF WORDS IN IOWD
	PUSHJ	P,NEXDTW	;GET NEXT IOWD OR JRST
	  JRST	MTIOHE		;SEE IF HRI FORMAT
	AOS	T2		;COUNT WORD READ
	JUMPLE	T1,MTIOWD	;LOOP IF ANOTHER IOWD
	MOVE	T4,T1		;NO--SAVE DATA WORD (MAYBE JRST WORD)

MTIODN:	PUSHJ	P,NEXDTW	;GET ANY MORE OF RECORD
	  JRST	.+2		;JUMP TO OUTPUT
	AOJA	T2,MTIODN	;LOOP UNTIL DONE
	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	P1,[ASCIZ /  Save format:    length = /]
	JRST	MTIOJM		;GO CHECK FOR JRST WORD

;HERE IF LOOKS LIKE HRI FORMAT

MTIOHR:	PUSHJ	P,NEXDTW	;IF ONLY ZEROS TO EOF
	  JRST	MTIOHE		;  THEN MUST BE OK
	JUMPN	T1,MTIOJK	;NO--JUNK
	AOJA	T2,MTIOHR	;LOOP TO EOF

MTIOHE:	JUMPN	P1,MTIOJK	;JUNK IF NOT FIRST IOWD
	MOVE	T1,T4		;RESTORE LAST DATA WORD
	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	P1,[ASCIZ /  HRI format:     length = /]
	SETZM	FVER		;CLEAR VERSION NUMBER
	JRST	MTIOJM		;GO FINISH UP
;STILL IN IFN FT$MTA

MTEXE:	MOVEI	T3,0		;CLEAR PROGRESS COUNT
	JRST	MTEX.1		;START WITH FIRST WORD
MTEX.0:	PUSHJ	P,NEXDTW	;GET BLOCK TYPE OF HEADER
	  JRST	MTIOJF		;NONE IF EOF
	AOS	T2		;COUNT WORD
	AOS	T3		;COUNT WORD
MTEX.1:	HLRZ	P1,T1		;GET BLOCK TYPE
	CAIN	P1,1776		;SEE IF EXE DIRECTORY
	JRST	MTEX.3		;YES--GO LOOKUP PAGE 0
	CAIL	P1,1776		;IF NOT VALID TYPE,
	JRST	MTIOJK		; EXIT WITHOUT VERSION
	HRRZ	P1,T1		;OK--GET BLOCK SIZE
MTEX.2:	SOJLE	T1,MTEX.0	;(ALLOW FOR FIRST WORD)
	PUSHJ	P,NEXDTW	;SKIP THIS BLOCK
	  JRST	MTIOJF		;GIVE UP IF EOF
	AOS	T2		;COUNT WORD
	AOS	T3		;COUNT PROGRESS
	JRST	MTEX.2		;LOOP
MTEX.3:	HRRZ	T4,T1		;DIRECTORY--GET SIZE
	LSH	T4,-1		;GET COUNT OF BIWORDS
MTEX.4:	SOJL	T4,MTIOJK	;GIVE UP IF NOT IN DIRECTORY
	PUSHJ	P,NEXDTW	;GET FIRST WORD OF PAIR
	  JRST	MTIOJF		;GIVE UP IF END
	AOS	T2		;COUNT WORD
	MOVE	P1,T1		;SAVE FOR A MINUTE
	PUSHJ	P,NEXDTW	;GET SECOND WORD OF PAIR
	  JRST	MTIOJF		;GIVE UP
	AOS	T2		;COUNT WORD
	ADDI	T3,2		;COUNT PROGRESS
	TRNE	T1,-1		;SEE IF PAGE 0
	JRST	MTEX.4		;NO--LOOP OVER DIRECTORY
	HRRZ	T4,P1		;GET POSITION IN FILE
	LSH	T4,^D9		;CONVERT TO WORDS
	SUB	T4,T3		;ALLOW FOR CURRENT POSITION
	JUMPLE	T4,MTIOJK	;ERROR IF BEHIND US
	ADDI	T4,.JBVER	;SET TO VERSION LOCATION
MTEX.5:	PUSHJ	P,NEXDTW	;ADVANCE TO WORD
	  JRST	MTIOJF		;GIVE UP IF END
	AOS	T2		;COUNT WORD
	SOJGE	T4,MTEX.5	;LOOP THROUGH .JBVER


MTEX.9:	PUSHJ	P,NEXDTW	;LOOP TO END
	  SKIPA			;DONE
	AOJA	T2,MTEX.9	;LOOP
	TLNE	F,L.MLBL	;HAVE WE TYPED OUT LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENT THEN
	MOVEI	P1,[ASCIZ /  .EXE format:    length = /]
	MOVEI	T4,0		;INDICATE NO START ADDRESS KNOWN
	JRST	MTIOJN		;OUTPUT MESSAGE
;STILL IN IFN FT$MTA

;HERE WHEN DONE WITH HRI OR SAVE FORMAT READ

MTIOJM:	HLRZ	T3,T4		;SEE IF START
	TRZ	T3,(<HALT>-<JRST>)  ;CLEAR HALT BITS
	CAIE	T3,(JRST)	;TEST FOR JUMP
	JRST	MTIOJK		;NO--JUNK
MTIOJN:	MOVE	M,P1		;FETCH CORRECT MESSAGE
	PUSHJ	P,LSTR		;TYPE LABEL
	MOVE	T1,T2		;GET LENGTH IN WORDS
	PUSHJ	P,LDEC		;LIST DECIMAL
	MOVEI	M,[ASCIZ /, start = /]
	SKIPE	T4		;IF KNOWN,
	PUSHJ	P,LSTR		;LIST LABEL
	HRRZ	T1,T4		;GET START ADDRESS
	SKIPE	T4		;IF KNOWN,
	PUSHJ	P,LOCT		;LIST OCTAL
	MOVEI	M,[ASCIZ /, checksum = /]
	SKIPG	S.CHK		;/CHECKSUM GIVEN?
	JRST	.+3		;NO
	PUSHJ	P,LSTR		;LIST LABEL
	PUSHJ	P,LCHECK	;LIST CHECKSUM
	MOVEI	M,[ASCIZ /, version = /]
	SKIPE	T4,FVER		;SEE IF VERSION
	PUSHJ	P,LSTR		;YES--PREFIX IT
	PUSHJ	P,LVER		;AND LIST IT
	PUSHJ	P,LCRLF		;END LINE
	AOS	.CTFLS##	;COUNT THIS AS A FILE SEEN
	AOS	.CTFLF##	;AND FOUND
	JRST	MTEF		;JUMP TO END OF FILE PROCESSING
;STILL IN IFN FT$MTA

;HERE IF JUNK BUT NOT YET EOF

MTIOJK:	PUSHJ	P,NEXDTW	;GET NEXT WORD
	  JRST	MTIOJF		;JUMP WHEN DONE
	AOJA	T2,MTIOJK	;LOOP COUNTING WORDS

;HERE IF JUNK AT EOF

MTIOJF:	AOS	.CTFLS##	;COUNT A FILE SEEN
	AOS	.CTFLF##	;AND FOUND
				; THIS RATHER QUESTIONABLE TACTIC SUPRESSES
				; "SPURIOUS" %WLDNSD NO SUCH DIRECTORY MES-
				; SAGES . . .
	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  Unknown format: length =/]
	PUSHJ	P,LSTR		;LIST LABEL
	MOVE	T1,T2		;GET LENGTH
	PUSHJ	P,LDEC		;LIST DECIMAL
	MOVEI	M,[ASCIZ /, checksum = /]
	SKIPG	S.CHK		;/CHECKSUM GIVEN?
	JRST	.+3		;NO
	PUSHJ	P,LSTR		;LIST LABEL
	PUSHJ	P,LCHECK	;LIST CHECKSUM
	PUSHJ	P,LCRLF		;END LINE

;HERE AT EOF AFTER JUNK OR IOWD FILE

MTEF:	SKIPGE	ABORTI		;TIME TO ABORT INPUT?
	JRST	MTABO		;YES
	MOVEI	M,[ASCIZ /<Tape mark>
/]
MTEFM:	SKIPLE	S.MARK		;/MARKS?
	PUSHJ	P,LSTR		;YES--TELL USER
MTEFX:	REPEAT	0,<		;NEED THIS ONLY IF TAPE ENDS WITH 3 EOFS
	CLOSE	DC,		;CLEAR END-OF-FILE
	SOSN	MTFLCT		;DO /FILE ACCOUNTING
	JRST	MTDONX		;EXIT IF /FILE COUNTED OUT
	JRST	MTFIND		;NEW FILE--GO PROCESS IT
>
	JRST	MTEOFH		;HANDLE EOF
;HERE AFTER NEW FILE FOUND EOF

MTEOF:	SKIPGE	ABORTI		;TAPE USELESS?
	JRST	MTABO		;YES, ABORT TAPE DIRECTORY
	MOVEI	M,[ASCIZ /<Tape mark>
/]
	SKIPLE	S.MARK		;/MARKS?
	PUSHJ	P,LSTR		;YES--LIST COMMENT
MTEOFH:	CLOSE	DC,		;CLEAR END-OF-FILE
	SOSN	MTFLCT		;ACCOUNT FOR /FILE
	JRST	MTDONX		;JUMP IF DONE WITH /FILES
	PUSHJ	P,NEXOVW	;READ WORD TO SEE IF DOUBLE EOF
	  JRST	.+2		;YES--CLEAN UP
	JRST	MTEXAM		;NO--START OVER
	MOVEI	M,[ASCIZ /<Second tape mark in succession>
/]
	SKIPLE	S.MARK		;/MARKS?
	PUSHJ	P,LSTR		;YES--LIST COMMENT
	JRST	MTDONE		;AND GO FINISH UP



;HERE TO ABORT THE TAPE OPERATIONS

MTABO:	N$FAIX	(ADE,<Aborting directory listing due to device error(s)>)
X$$ADE:	PUSHJ	P,.TCRLF##	;CAP OFF THE ERROR MESSAGE
	JRST	MTDONY		;AND LEAVE THIS VALE OF TEARS
;STILL IN IFN FT$MTA

;HERE WHEN ANSI-LIKE TAPE LABEL SEEN

MTLAB6:	MOVEI	M,[ASCIZ /	 SIXBIT Label "/]
	TROA	F,R.LBSX	;INDICATE SIXBIT LABEL
MTLABL:	MOVEI	M,[ASCIZ /	 Label "/]
MTLABR:	MOVE	T4,BFHD+.BFCTR	;GET LENGTH
MTLABS:	PUSHJ	P,LSTR		;LIST PREFIX
	MOVEI	T2,^D80/5	;GET ASCII LABEL LENGTH
	TRNE	F,R.LBSX	;SEE IF SIXBIT
	MOVEI	T2,^D80/6	;YES--GET SIXBIT LABEL LENGTH
				;NOTE--COBOL WRITES 78 CHARS, NOT 84
	CAIE	T4,-1(T2)	;SEE IF STANDARD LABEL LENGTH
	TLO	F,L.ILEN	;NO--SET FLAG
	MOVEI	P1,1(T4)	;SET END TO LENGTH
	CAILE	P1,(T2)		;BUT NOT BEYOND
	MOVEI	P1,(T2)		;  STANDARD LENGTH
	MOVEI	T2,1		;PRESET WORD COUNT
MTLAB1:	MOVE	T4,T1		;MOVE WORD TO PAIR
	MOVEI	T1,5		;SET TO COUNT CHARS
	TRNE	F,R.LBSX	;IF SIXBIT,
	MOVEI	T1,6		; GET 6 CHARS PER WORD

;HERE FOR EACH CHARACTER IN LABEL

MTLAB2:	MOVEI	T3,0		;CLEAR RESULT
	TRNE	F,R.LBSX	;SEE IF SIXBIT LABEL
	JRST	[LSHC T3,6	;YES--GET NEXT CHAR
		 ADDI T3,40	;CONVERT TO ASCII
		 JRST MTLAB4]	;AND GO OUTPUT IT
	LSHC	T3,7		;GET CHAR
	CAILE	T3,37		;SEE IF CONTROL CHAR (OR NULL)
	JRST	MTLAB3		;NO--PROCEED
	MOVEI	C,"^"		;YES--LIST FLAG
	PUSHJ	P,LCHR		; FOR USER
	ADDI	T3,100		;CONVERT TO ALPHA
MTLAB3:	CAIGE	T3,140		;SEE IF LOWER CASE
	JRST	MTLAB4		;NO--PROCEED
	MOVEI	C,"'"		;YES--LIST FLAG
	PUSHJ	P,LCHR		; FOR USER
	SUBI	T3,40		;CONVERT TO UPPER CASE
MTLAB4:	MOVE	C,T3		;GET CHAR
	PUSHJ	P,LCHR		;LIST
	SOJG	T1,MTLAB2	;LOOP FOR THIS WORD
	PUSHJ	P,NEXDTW	;GO GET NEXT WORD
	  JRST	MTLABX		;AT EOF
	CAIE	T2,(P1)		;DON'T GO TOO FAR
	AOJA	T2,MTLAB1	;LOOP DOWN LABEL

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTA

	TLO	F,L.FKEF	;TOO FAR, SET FAKE EOF FLAG
	MOVE	P1,T1		;SAVE WORD FOR LATER

;HERE AT END OF LABEL

MTLABX:	TRZ	F,R.LBSX	;CLEAR SIXBIT LABEL INDICATOR
	MOVEI	C,""""		;END OF QUOTE
	PUSHJ	P,LCHR		;LIST END
	PUSHJ	P,LCRLF		;END LINE
	TLNN	F,L.ILEN!L.FKEF	;SEE IF BAD LENGTH
	JRST	MTEF		;NO--GO CLEAR EOF AND PROCEED
	TLZN	F,L.ILEN	;TEST INCORRECT LENGTH
	JRST	MTLNOK		;LENGTH OK
	N$WARN	(ILL,Incorrect length for label)
MTLNOK:	TLZN	F,L.FKEF	;CLEAR FAKE EOF
	JRST	MTEF		;NOT SET--PROCEED
IFN FT$MTR,<	;OLD BACKUP/RESTORE
	TLZE	F,L.IMLB	;SEE IF IMBEDDED LABEL
	JRST	MTBKSR		;YES--RETURN TO THAT LOOP
>;END IFN FT$MTR

	MOVE	T3,P1		;GET NEXT WORD
	TRZ	T3,77777	;REDUCE TO FIRST THREE ASCII CHARS
	MOVSI	T4,-LNLBLT	;POINT TO LABEL TYPES TABLE
	CAME	T3,LABTYP(T4)	;SEE IF LABEL
	AOBJN	T4,.-1		;LOOP TO MATCH
	JUMPL	T4,MTLBCN	;CONSECUTIVE LABELS
	TRZ	T3,-1		;REDUCE TO FIRST THREE SIXBIT CHARS
	MOVSI	T4,-LNLB6T	;POINT TO SIXBIT LABEL TYPES TABLE
	CAME	T3,LABTY6(T4)	;SEE IF SIXBIT LABEL
	AOBJN	T4,.-1		;LOOP TO MATCH
	JUMPL	T4,MTLBC6	;CONSECUTIVE SIXBIT LABELS
	N$WARN	(MTM,Missing tape mark after label)
	MOVE	T1,P1		;RESTORE WORD
	JRST	MTEXAM		;AND GO EXAMINE DATA

MTLBC6:	MOVEI	M,[ASCIZ / Grouped SIXBIT label "/]
	TROA	F,R.LBSX	;SET SIXBIT LABEL FLAG
MTLBCN:	MOVEI	M,[ASCIZ / Grouped label "/]
	MOVE	T1,P1		;RESTORE WORD
	JRST	MTLABR		;GO DO NEXT LABEL
>;END IFN FT$MTA
	SUBTTL	DIRECTORY LISTING - MAGTAPE -- OLD BACKUP/RESTORE

IFN FT$MTR,<	;OLD BACKUP/RESTORE

MTBKSR:	PUSHJ	P,NEXOVW	;GET NEXT CONTROL WORD
	  JRST	E$$MBS		;UNEXPECTED EOF
MTBKSS:	TLO	F,L.LEVD	;SET LEVEL-D DATA
	MOVEM	T1,MTSVVR	;SAVE HEADER WORD
	HLRZ	T2,T1		;GET CONTROL WORD
	CAIE	T2,100000	;SEE IF FILE HEADER
	CAIN	T2,200000	;SEE IF DIRECTORY HEADER
	JRST	MTBKLK		;YES--GO READ LOOKUP BLOCK
	CAIN	T2,40000	;SEE IF IMBEDDED LABEL
	JRST	MTBKIL		;YES--GO HANDLE IT

;HERE WHEN JUNK IN OLD BACKUP/RESTORE SET

	N$WARN	(JBS,Junk during BACKUP/RESTORE save set)
MTBKJL:	TLO	F,L.BKSS	;SET FLAG FOR SAVE SET
	PUSHJ	P,NEXOVW	;READ ON
	  JRST	MTBKJM		;AT END OF DATA
	MOVE	T1,BFHD+.BFCTR	;GET DATA LEFT IN BLOCK
	SOJG	T1,MTBKJL	;SOME--LOOP THRU DATA
MTBKJM:	TLZ	F,L.BKSS!L.FKEF	;CLEAR FLAGS
	PUSHJ	P,NEXOVW	;LOOK AT RESULTS
	  JRST	MTBKJG		;EOF--GO HANDLE
	HLRZ	T2,T1		;GET HEADER TYPE
	CAIE	T2,100000	;SEE IF DIRECTORY
	CAIN	T2,200000	; OR FILE HEADER
	JRST	MTBKSS		;YES--GO PROCESS IT
	CAIN	T2,40000	;SEE IF LABEL
	JRST	MTBKIL		;YES--GO HANDLE
	JRST	MTBKJL		;NO--LOOP ONWARDS
>;END IFN FT$MTR
IFN FT$MTR,<	;OLD BACKUP/RESTORE

;HERE AT UNEXPECTED EOF

	N$WARN	(MBS,Tape mark during BACKUP/RESTORE save set)
MTBKJG:	JRST	MTEFX		;GO ISSUE MESSAGE

;HERE AT IMBEDDED LABEL

MTBKIL:	ANDI	T1,777		;GET LABEL LENGTH
	SOSG	T4,T1		;MOVE TO LOC. FOR LABEL PRINTER
	JRST	E$$JBS		;NO--JUNK
	TLO	F,L.IMLB	;YES--SET FLAG
	PUSHJ	P,NEXOVW	;SKIP CHECKSUM
	  JRST	E$$MBS		;GIVE UP
	PUSHJ	P,NEXOVW	;GET START OF LABEL
	  JRST	MTBKIF		;GO HANDLE EOF
	MOVEI	M,[ASCIZ / Blocked label "/]
	JRST	MTLABS		;GO DO LABEL

;HERE WHEN IMBEDDED LABEL IS SEPARATE FILE

MTBKIF:	MOVEI	M,[ASCIZ /<Tape mark preceeded by label flag>
/]
	JRST	MTEFM		;GO ISSUE MESSAGE
>;END IFN FT$MTR
IFN FT$MTR,<	;OLD BACKUP/RESTORE

;HERE WHEN LOOKUP BLOCK COMING

MTBKLK:	MOVEI	T2,(T1)		;GET LOOKUP WORDS
	ANDI	T2,777		;CLEAR JUNK
	CAILE	T2,LN$RIB	;PROTECT LOOKUP AREA
	JRST	E$$JBS		;BAD--GIVE UP
	MOVEI	T3,0		;SET TO START OF LOOKUP BLOCK
	PUSHJ	P,NEXOVW	;GET NEXT WORD
	  JRST	E$$MBS		;BAD TO EOF HERE
				;THROW AWAY WORD
MTBKLL:	PUSHJ	P,NEXOVW	;GET NEXT LOOKUP WORD
	  JRST	E$$MBS		;BAD TO EOF IN MIDDLE
	MOVEM	T1,LBLOCK(T3)	;SAVE IN STANDARD AREA
	AOS	T3		;ADVANCE BLOCK
	SOJG	T2,MTBKLL	;LOOP UNTIL DONE
	HRRZ	T2,MTSVVR	;GET LENGTH AGAIN
	SOS	T2		;SUBTRACT ONE
	ANDI	T2,777		;MASK TO FORWARD LENGTH
	CAME	T2,RIBLEN	;COMPARE TO LOOKUP LENGTH
	JRST	E$$JBS		;BAD--GIVE UP
	SKIPLE	S.MARK		;/MARKS?
	JRST	MTBKLM		;YES--TYPE UFD
	HLRZ	T2,MTSVVR	;REFETCH HEADER
	CAIE	T2,100000	;SEE IF FILE HEADER
	JRST	MTBKNW		;NO--SKIP TO NEXT HEADER
>;END IFN FT$MTR

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTR,<	;OLD BACKUP/RESTORE

;HERE WHEN FILE HEADER IS IN LOOKUP AREA

MTBKLM:	MOVE	T1,FMTA		;GET MAG TAPE WORD
	MOVEM	T1,FSTR		;STORE AS STUCTURE
	SETZM	FMTA		;CLEAR OUT TAPE WORD
	TLO	F,L.BKSS	;SET SAVE SET FLAG
	PUSHJ	P,MTDOFL	;GO DO MAG TAPE FILE

	TLZ	F,L.BKSS!L.FKEF	;CLEAR SCREWBALL FLAGS
	HLRZ	T2,MTSVVR	;SEE WHAT KIND OF FILE
	CAIE	T2,100000	;CHECK FILE
	JRST	MTBKNW		;NO--SKIP BELOW
	PUSHJ	P,NEXOVW	;GET NEXT CONTROL
	  JRST	E$$MBS		;NEED END OF DATA FILE
	HLRZ	T2,T1		;GET TYPE
	CAIE	T2,20000	;SEE IF END OF FILE
	JRST	E$$JBS		;NO--JUNK
	PUSHJ	P,NEXOVW	;YES--GET CHECKSUM
	  JRST	E$$MBS		;ERROR IF ABSENT
MTBKNW:	PUSHJ	P,NEXOVW	;GET NEXT HEADER WORD
	  JRST	MTEF		;GO TO EOF PROCESSING
	TLNN	T1,7777		;SEE IF OLD BACKUP/RESTORE HEADER
	JRST	MTBKSS		;GO HANDLE HEADER
	PUSH	P,T1		;SAVE NEXT WORD
	N$WARN	(MMB,Missing tape mark after BACKUP/RESTORE save set)
	POP	P,T1		;RESTORE NEXT WORD
	JRST	MTEXAM		;GO EXAMINE THE DATA
>;END IFN FT$MTR
IFE FT$MTR,<
	E$$JBS==6B20	;SAVE SYMBOL
	E$$MBS==6B20	;SAVE SYMBOL
	E$$MMB==6B20	;SAVE SYMBOL
>;END IFE FT$MTB
	SUBTTL	DIRECTORY LISTING - MAGTAPE -- BACKUP AND FRS

IFN FT$MTB,<	;BACKUP/FRS

MTFRSS:	SETZM	H.MZER		;CLEAR FOR THIS SAVESET
	MOVE	T3,[H.MZER,,H.MZER+1]
	BLT	T3,H.EMZR	; ..
	PUSHJ	P,FRSLAH	;DO BACKUP/FRS LOOK-AHEAD
	JRST	MTFRSH		;GO HANDLE HEADER

;BACK HERE AFTER EACH RECORD

MTFRSR:	PUSHJ	P,NEXOVW	;GET FIRST WORD
	  JRST	E$$MFS		;END OF FILE IS ERROR
	PUSHJ	P,FRSLAH	;DO BACKUP/FRS LOOK-AHEAD
IFN FT$MTS,<	;FRS
	HLLZ	T4,T1		;GET COPY OF FRS/BACKUP FLAG
	TLNE	T4,-1		;IF FRS,
	TLO	T4,-1		; SET WHOLE FLAG
	XOR	T4,B$GTYP	;COMPARE WITH PREVIOUS RECORD
	JUMPL	T4,E$$JFS	;JUNK IF DIFFERENT
>;END IFN FT$MTS

MTFRSH:	TLNN	T1,-1		;SEE IF BACKUP FORMAT
	JRST	MTFRSP		;YES--GO HANDLE HEADER
IFN FT$MTS,<	;FRS
	TLNE	T1,777770	;SEE IF VALID FOR FRS
	JRST	E$$JFS		;NO, GO PROCESS AS JUNK
>;END IFN FT$MTS
>;END IFN FT$MTB

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTS,<	;FRS

;HERE IF FRS HEADER FORMAT--READ HEADER AND CONVERT TO BACKUP FORMAT

	HRLZM	T1,B$GFLG	;STORE FLAGS
	HLRZS	T1		;POSITION RECORD TYPE
	MOVE	T1,[0		;ERROR
		    1		;LABEL
		    2		;START SAVE SET
		    3		;END SAVE SET
		    4		;FILE DATA
		    5		;DIRECTORY DATA
		    0		;ERROR
		    0](T1)	;ERROR
	JUMPE	T1,MTFJKB	;JUNK IF ERROR(NOT FRS FORMAT)
	HRROM	T1,B$GTYP	;SET AS TYPE
	PUSHJ	P,NEXOVR	;GET RELATIVE VOLUME NUMBER
	  JRST	MTFJKB		;JUNK
	MOVEM	T1,B$GRTN	;SAVE
	MOVE	T4,B$GTYP	;GET TYPE
	MOVE	T4,FRSTBL-1(T4)	;GET TABLE OF TRANSLATIONS
MTFRSL:	MOVE	T1,(T4)		;GET -COUNT,,ITEM
	TLNN	T1,-1		;IF BLANK,
	TLO	T1,-1		; SET FOR ONE WORD
	PUSHJ	P,BLKOVR	;COPY TO STORAGE AREA
	  JRST	MTFJKB		;JUNK IF END
	AOBJN	T4,MTFRSL	;LOOP OVER HEADER
	JRST	MTFRSD		;GO HANDLE DATA PORTION
;STILL IN IFN FT$MTS

;FRS TRANSLATION TABLE POINTERS

FRSTBL:	-FRSLLB,,FRSTLB		;BACKUP 1=LABEL
	-FRSLSS,,FRSTSS		;BACKUP 2=START SAVE SET
	-FRSLSS,,FRSTSS		;BACKUP 3=END SAVE SET
	-FRSLFL,,FRSTFL		;BACKUP 4=FILE
	-FRSLDR,,FRSTDR		;BACKUP 5=DIRECTORY

;TABLES CONTAINING -NO WORDS (0=1),,ADDRESS TO STORE

FRSTLB:				;LABEL
	    B$LREL		;REEL
	-21,,B$LTIM		;TIME, DATE, DESTROY DATE, LABEL COMMENT
FRSLLB==.-FRSTLB


FRSTSS:				;START/END SAVE SET
	-5,,B$SSNM		;SYSTEM NAME
	    B$SSVR		;VERSION
	-2,,B$SFMT		;FORMAT VERSION, FRS VERSION
	-5,,B$STIM		;TIME, DATE, MODE, TRACKS, SAVE SET NAME
	    B$SDEV		;DEVICE
	-4,,B$SCMT		;COMMENT
FRSLSS==.-FRSTSS

FRSTDR:				;DIRECTORY
	    B$USTR		;UFD STRUCTURE
	    B$ULVL		;DIRECTORY LEVEL
	-20,,DIRB		;DISCARD JUNK
FRSLDR==.-FRSTDR


FRSTFL:				;FILE
	-11,,B$FSTR		;STR, NAME, EXT, PPN, REL BLK,
				;  CHECKSUM, BLKS IN REC,
				;  WRDS IN L.BLK, DIRECTORY LEVEL
	-11,,DIRB		;DISCARD JUNK
FRSLFL==.-FRSTFL
>;END IFN FT$MTS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTB,<	;BACKUP/FRS
MTFJKB:	N$WARN	(JFS,Junk during BACKUP/FRS save set)
MTFJKL:	SETZM	BFHD+.BFCTR	;CLEAR REST OF RECORD
	PUSHJ	P,NEXOVW	;GET START OF NEXT RECORD
	  JRST	MTFJKG		;EOF--GO HANDLE
	TLNE	T1,777770	;SEE IF OK YET
	JRST	MTFJKL		;NO--LOOP ON
	HLLZ	T4,T1		;GET BACKUP/FRS FLAG
	TLNE	T4,-1		;IF FRS,
	TLO	T4,-1		; SET WHOLE HALF WORD
	XOR	T4,B$GTYP	;COMPARE WITH FRS FLAG
	JUMPL	T4,MTFJKL	;IF DIFFERENT, JUNK
	JRST	MTFRSH		;ELSE, GO HANDLE HEADER

	N$WARN	(MFS,Tape mark during BACKUP/FRS save set)
MTFJKG:	JRST	MTEFX		;GO HANDLE EOF
;STILL IN IFN FT$MTB

;HERE TO HANDLE BACKUP STYLE HEADER

MTFRSP:	JUMPLE	T1,MTFJKB	;ERROR IF BAD TYPE
	CAILE	T1,T$MAX	;SEE IF VALID
	JRST	MTFJKB		;NO--ERROR
	MOVEM	T1,B$GTYP	;STORE TYPE
	MOVE	T1,[-^D11,,B$GBNM] ;GET REST
	PUSHJ	P,BLKOVR	; OF STANDARD HEADER
	  JRST	MTFJKB		;JUNK IF TRUNCATED

	MOVE	T1,B$GTYP	;GET TYPE
	MOVE	T1,[B$LBL	;1=LABEL
		    B$SSS	;2=START OF SAVE SET
		    B$SSS	;3=END OF SAVE SET
		    B$FIL	;4=FILE
		    B$DIR	;5=DIRECTORY
		    B$EOV	;6=END OF VOLUME
		    B$CMT	;7=COMMENT
		    B$SSS]-1(T1);10=CONTINUE SAVE SET
	HRLI	T1,-^D20	;SET REST OF HEADER LENGTH
	PUSHJ	P,BLKOVR	;GET REST OF HEADER
	  JRST	MTFJKB		;JUNK IF NOT ALL THERE

;HERE WHEN HEADER READ

MTFRSD:	MOVE	T4,B$GTYP	;GET RECORD TYPE
	JRST	@[MTFLBL	;1=LABEL
		  MTFSSS	;2=START OF SAVE SET
		  MTFESS	;3=END OF SAVE SET
		  MTFFIL	;4=FILE
		  MTFDIR	;5=DIRECTORY
		  MTFEOV	;6=END OF VOLUME
		  MTFCMT	;7=COMMENT
		  MTFCSS]-1(T4)	;10=CONTINUE SAVE SET
;STILL IN IFN FT$MTB

;HERE ON BACKUP/FRS LABEL RECORD

MTFLBL:	SETZM	BFHD+.BFCTR	;CLEAR REST OF BLOCK
	PUSHJ	P,NEXOVW	;GET EOF
	  SKIPA			;OK
	JRST	E$$JSS		;ERROR IF NOT EOF

	SKIPL	B$GTYP		;SEE IF BACKUP
	SKIPN	T1,B$LDDT	;GET LABEL DESTROY DATE
	JRST	MTFLB1		;CLEAR--LEAVE ALONE
	PUSHJ	P,.CNTDT##	;SPLIT IT
	MOVEM	T2,B$LDSD	;STORE DESTROY DATE
MTFLB1:	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  BACKUP label /]
IFN FT$MTS,<	;FRS
	SKIPGE	B$GTYP		;IF FRS,
	MOVEI	M,[ASCIZ /  FRS label /]
>;END IFN FT$MTS
	PUSHJ	P,LSTR		;LIST LABEL
	MOVEI	M,[ASCIZ / reel=/]
	SKIPE	T2,B$LREL	;IF REEL,
	PUSHJ	P,LSTR		; LABEL OUTPUT
	PUSHJ	P,LSIX		; AND OUTPUT REEL
	MOVEI	M,[ASCIZ / destroy on /]
	SKIPE	T4,B$LDSD	;IF DESTROY DATE,
	PUSHJ	P,LSTR		; LABEL OUTPUT
	SKIPE	T4		; AND
	PUSHJ	P,LDATE		; OUTPUT DESTROY DATE
	PUSHJ	P,LCRLF		;END LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVE	T1,[B$LCDT,,B$SCDT] ;COPY STANDARD STUFF
	BLT	T1,B$SMTC	; WHERE SAVE-SET HEADERS
	MOVE	T1,[B$LTIM,,B$STIM]
	BLT	T1,B$SDAT
	SETZM	B$SMOD
	SETZM	B$STRK
	SETZM	B$BSYS
	PUSHJ	P,MTFXSL	;ISSUE LINES COMMON TO SAVE-SET
	SKIPE	B$LCMT		;SEE IF COMMENT
	JRST	[TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
		PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENT
		MOVEI	M,[ASCIZ /    Comment: /]
		PUSHJ	P,LSTR		;LABEL RESULT
		SETZM	B$LCMT+16	;PROTECT ASCIZ
		MOVEI	M,B$LCMT	;POINT TO COMMENT
		PUSHJ	P,LSTR		;OUTPUT IT
		PUSHJ	P,LCRLF		;END LINE
		JRST  .+1]
	JRST	MTEOF		;GO CLEAR FAKE EOF AND REPEAT BACKUP PROCESSING
;STILL IN IFN FT$MTB

;HERE ON BACKUP/FRS END OF VOLUME

MTFEOV:	SETZM	BFHD+.BFCTR
	PUSHJ	P,NEXOVW	;GET NEXT WORD
	  SKIPA			;EOF--OK
	JRST	E$$JFS		;ELSE JUNK

;HERE AFTER READING END OF VOLUME

MTFEO0:	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  BACKUP end of volume/]
	PUSHJ	P,LSTR		;INDICATE EOV
	TLNE	F,L.BPOP	;[464] IN MIDST OF DATA FILE?
	PUSHJ	P,[MOVEI M,[ASCIZ\ reading file \]  ;[464] YES
		PUSHJ	P,LSTR		;[464] SO TELL USER
		PUSHJ	P,LSTFNM	;[464] LIST THE FILE NAME
		PUSHJ	P,LDOT		;[464] SEPARATE NAME AND EXTENSION
		HLLZ	T2,FEXT		;[464] EXTRACT THE EXTENSION
		PJRST	LSIXN]		;[464] AND LIST IT TOO
	PUSHJ	P,LCRLF		;END OF LINE
	PUSHJ	P,LCRLF		;PLUS BLANK LINE FOR NEATNESS
	SKIPG	S.MVOL		;MULTI-VOLUME CONTINUE?
	JRST	MTENDS		;NO - GO END LISTING OF SAVE SET
;[453]	MTUNL.	DC,		;YES - UNLOAD OLD TAPE
	CLOSE	DC,		;[463] BLAST THE "EOF" I/O STATUS
	MOVE	T1,B$GRTN	;RELATIVE TAPE NUMBER
	ADDI	T1,1		;NEXT TAPE NUMBER
	MOVEM	T1,B$HRTN	;HOLD IT FOR VERIFICATION
	MOVE	T1,[B$BSSN,,B$HSSN] ;BLT POINTER TO
	BLT	T1,B$HSSN+6	;SAVE SAVE-SET NAME
	MOVEI	T1,0		;OUTPUT TO TTY:
	PUSHJ	P,.TYOCH##	;FORCE IT THERE
	PUSH	P,T1		;SAVE OLD OUTPUT ROUTINE
	MOVEI	T1,[ASCIZ/"End of volume reached on /]
	PUSHJ	P,.TSTRG##	;TELL USER/OPERATOR
	MOVE	T1,MTNAME	;NAME OF TAPE DRIVE
	PUSHJ	P,.TSIXN##	;GIVE DRIVE NAME
	MOVEI	T1,[ASCIZ/:
/]
	PUSHJ	P,.TSTRG##	;CAP OFF DRIVE
	JRST	MTFEO2		;NOW ASK FOR NEW TAPE
;STILL IN FT$MTB

MTFEO1:	MOVEI	T1,0		;OUTPUT TO TTY:
	PUSHJ	P,.TYOCH##	;REDIRECT SCAN
	PUSH	P,T1		;SAVE OLD TYPEOUT
MTFEO2:	TLNN	F,L.MLBP	;[453] CONTROLLED BY MDA?
	JRST	MTFEO4		;[453] NO, ASK USER TO MANUALLY MOUNT NEW TAPE
	MOVEI	T1,[ASCIZ\"Asking MDA for automatic volume-switch . . .
\]				;[453] NICE INFORMATIVE TEXT
	PUSHJ	P,.TSTRG##	;[453] TO TELL THE USER WHAT IS HAPPENING
	MOVEI	T3,DC		;[453] TAPE CHANNEL
	MOVEI	T2,.TFFEV	;[453] TAPOP. FUNCTION
	MOVE	T1,[2,,T2]	;[453] AND TAPOP. ARG POINTER TO
	TAPOP.	T1,		;[453] ASK MONITOR/MDA TO SWITCH VOLUMES
	 SKIPA	P3,T1		;[453] FAILED!
	JRST	MTFEO5		;[453] CONTINUE PROCESSING NEXT TAPE VOLUME
	N$FAIO	(CGN,Couldn't get next volume, error )

MTFEO4:	MTUNL.	DC,		;[453] PUNT CURRENT TAPE VOLUME
	MOVEI	T1,[ASCIZ/$Mount next volume, type "C" to continue, "E" to exit: /]
	PUSHJ	P,.TSTRG##	;ASK FOR COMMAND
	CLRBFI			;JUST TO MAKE SURE
	INCHWL	T1		;FIRST CHARACTER
	CLRBFI			;EAT REST OF LINE
	CAIE	T1,"E"		;EXIT (ABORT)?
	CAIN	T1,"e"		;ALTERNATE WAY OF SAME?
	JRST	[POP	P,T1		;RESTORE TYPEOUT ADDRESS
		PUSHJ	P,.TYOCH##	;TELL SCAN
		SETZM	MTNAME		;FLAG NO LONGER HAVE TAPE
		TLZE	F,L.BPOP	;CALLED FROM NEXDV?
		POPJ	P,		;YES, THEN RETURN TO THERE
		JRST	MTENDS]		;END OUTPUT FILES ALSO
	CAIE	T1,"C"		;CONTINUE?
	CAIN	T1,"c"		;. . . ?
	CAIA			;YES
	JRST	MTFEO2		;GARBAGE, TRY AGAIN
MTFEO5:	POP	P,T1		;RESTORE ADDRESS OF TYPEOUT
	PUSHJ	P,.TYOCH##	;TELL SCAN
	TLZE	F,L.BPOP	;CALLED FROM NEXDV?
	JRST	.POPJ1		;YES, SUCCESSFUL RETURN TO THERE
	JRST	MTFRSR		;NEXT RECORD PROCESSING
;STILL IN FT$MTB

;HERE FOR WRONG TAPE MOUNTED

MTFEO6:	MOVEI	T1,0		;FORCE OUTPUT TO TTY:
	PUSHJ	P,.TYOCH##	;REDIRECT SCAN'S OUTPUT
	PUSH	P,T1		;REMEMBER OLD OUTPUT
	MOVEI	T1,[ASCIZ\$Wrong volume mounted, expecting tape # \]
	PUSHJ	P,.TSTRG##	;START OFF MESSAGE
	MOVE	T1,B$HRTN	;TAPE NUMBER WE WERE EXPECTING
	PUSHJ	P,.TDECW##	;TELL USER THAT
	MOVEI	T1,[ASCIZ\; mounted tape is # \]
	PUSHJ	P,.TSTRG##	;MORE ASCII TEXT
	MOVE	T1,B$GRTN	;THIS TAPE NUMBER
	PUSHJ	P,.TDECW##	;TELL USER
	PUSHJ	P,.TCRLF##	;END THE LINE
	TLZE	F,L.BPOP	;CALLED FROM NEXDV?
	JRST	MTFEO9		;YES, ERROR RETURN TO THERE
	JRST	MTFEO2		;LOOP BACK AND ASK FOR NEW TAPE

MTFEO7:	MOVEI	T1,0		;FORCE OUTPUT TO TTY:
	PUSHJ	P,.TYOCH##	;REDIRECT SCAN'S OUTPUT
	PUSH	P,T1		;REMEMBER OLD OUTPUT
	MOVEI	T1,[ASCIZ/$Wrong volume mounted, expecting save set /]
	PUSHJ	P,.TSTRG##	;START OFF MESSAGE
	MOVEI	T1,B$HSSN	;SAVE SET WE WERE EXPECTING
	PUSHJ	P,.TSTRG##	;TELL USER
	MOVEI	T1,[ASCIZ\; mounted tape is save set \]
	PUSHJ	P,.TSTRG##	;MORE ASCII TEXT
	MOVEI	T1,B$BSSN	;THIS TAPE SAVE SET
	PUSHJ	P,.TSTRG##	;TELL USER
	PUSHJ	P,.TCRLF##	;END THE LINE
	TLZN	F,L.BPOP	;CALLED FROM NEXDV?
	JRST	MTFEO2		;NO, LOOP BACK AND ASK FOR NEW TAPE

MTFEO9:	POP	P,T1		;OLD TYPEOUT ADDRESS
	PJRST	.TYOCH##	;RESTORE IT
;STILL IN FT$MTB

;HERE ON BACKUP/FRS COMMENT

MTFCMT:	SETZM	BFHD+.BFCTR	;CLEAR REST OF BLOCK
	PUSHJ	P,NEXOVW	;GET NEXT WORD
	  SKIPA			;EOF--OK
	JRST	MTFJKB		;ELSE JUNK

;HERE AFTER READING COMMENT

	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  BACKUP comment: /]
	PUSHJ	P,LSTR		;INDICATE COMMENT
	MOVEI	M,B$CMT		;POINT TO COMMENT AREA
	PUSHJ	P,LSTR		;ISSUE IT
	JRST	MTENDS		;GO END LISTING OF SAVE SET

;HERE ON BACKUP/FRS END OF SAVE SET

MTFESS:	PUSHJ	P,MTFBGO	;UPDATE ANY OVERHEAD REGIONS
	  JRST	MTFJKB		;ERROR IF GARBAGED
	SETZM	BFHD+.BFCTR	;DISCARD REST OF BLOCK
;[417]	@ MTFESS:+3L
;[417]	PUSHJ	P,NEXOVW	;GET NEXT WORD
;[417]	  SKIPA			;EOF--OK
;[417]	JRST	MTIOJK		;ELSE JUNK

;HERE AFTER READING END OF SAVE SET

	PUSHJ	P,DIRE		;GIVE TOTAL LINE
	MOVEI	T1,[ASCIZ /end/]
	PUSHJ	P,MTFXSS	;INDICATE END OF SAVE SET
	PUSHJ	P,NEXOVW	;TRY READING ANOTHER RECORD
	  JRST	MTENDT		;GO END LISTING OF SAVE SET
	PUSH	P,T1		;SAVE NEW START OF RECORD
	TLZ	F,L.CRLF	;SAVE SET (FILE) DIDN'T END
	PUSHJ	P,LCRLF		;CAP OFF END SAVE SET MESSAGE
	SETZM	H.MZER		;CLEAR TOTALS
	MOVE	T1,[H.MZER,,H.MZER+1]  ;. . .
	BLT	T1,H.EMZR	;. . .
	PUSHJ	P,WRNTMM	;WARN ABOUT MISSING END OF FILE
	POP	P,T1		;RESTORE NEW RECORD TYPE
	JRST	MTEXAM		;AND SEE IF ANOTHER SAVE SET FOLLOWS
				; (WHICH DUMPER IS PRONE TO DO)

WRNTMM:	N$WARN	(TMM,Tape mark missing after end of save set)
	POPJ	P,		;CONTINUE MERRILY . . .
;STILL IN IFN FT$MTB

;HERE AT START OR CONTINUATION OF FRS OR BACKUP SAVE SET

MTFSSS:	MOVEI	T1,[ASCIZ /start/]  ;[462] INDICATE START OF SAVE SET
	SETOM	AMWCNT		;[462] INIT AMW COUNTER ONLY ON "START"
	CAIA			;[462] JOIN COMMON START/CONTINUE CODE
MTFCSS:	MOVEI	T1,[ASCIZ /continue/]  ;[462] INDICATE CONTINUATION
	PUSH	P,T1		;SAVE LABEL
	MOVE	T1,MTFBOT+3	;CLEAR SYSTEM HEADER
	PUSHJ	P,MTFBCB	; ..
	MOVE	T1,MTFBOT+4	;CLEAR SAVE SET NAME
	PUSHJ	P,MTFBCB	; ..
	PUSHJ	P,MTFBGO	;UPDATE OVERHEAD REGIONS
	  JRST	MTFJKB		;ERROR IF GARBAGED
	POP	P,T1		;RESTORE LABEL
	SKIPG	T2,B$HRTN	;THIS A CONTINUATION TAPE?
	JRST	MTFSS6		;NO
	CAME	T2,B$GRTN	;YES, TAPE WE WERE EXPECTING?
	JRST	MTFEO6		;NO, GO COMPLAIN AT OPERATOR
	MOVSI	T2,-7		;LENGTH OF SAVE SET NAME TEXT
MTFSS4:	MOVE	T3,B$BSSN(T2)	;THIS TAPE SAVE SET NAME
	CAMN	T3,B$HSSN(T2)	;MATCH EXPECTED SAVE SET NAME?
	AOBJN	T2,MTFSS4	;YES, LOOP FOR WHOLE SAVE SET NAME
	JUMPL	T2,MTFEO7	;NO, WRONG TAPE MOUNTED
	SETZM	B$HRTN		;[456] CLEAR NEW-TAPE-VERIFICATION FLAG
MTFSS6:	SETZM	BFHD+.BFCTR	;DISCARD REST OF BLOCK
	PUSHJ	P,MTFXSS	;OUTPUT START
	SKIPG	S.IND		;[444] IF A NORMAL (NOT /INDIRECT) LISTING,
	TLO	F,L.SBTT	;HEADER IS SAME AS TOTAL FOR SSTRDR
	TLZE	F,L.BPOP	;CALLED FROM NEXDV?
	JRST	.POPJ1		;YES
	JRST	MTFRSR		;RESUME FRS LISTING
;STILL IN IFN FT$MTB

;ROUTINE TO OUTPUT START, CONTINUATION, OR END OF SAVE SET

MTFXSS:	TLZ	F,L.CRLF	;REALLY HONESTLY AND TRULY
	PUSHJ	P,LCRLF		;WANT A BLANK LINE HERE!
	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  BACKUP /]
IFN FT$MTS,<	;FRS
	SKIPGE	B$GTYP		;SEE IF FRS
	MOVEI	M,[ASCIZ /  FRS /]
>;END IFN FT$MTS
	PUSHJ	P,LSTR		;ISSUE SAVER
	PUSH	P,T1		;SAVE START/END TEXT
	MOVEI	M,[ASCIZ/reel number /]
	PUSHJ	P,LSTR		;LIST TEXT
	MOVE	T1,B$GRTN	;GET THIS REEL NUMBER
	PUSHJ	P,LDEC		;AND LIST IT
	MOVEI	M,[ASCIZ/; /]	;AND SEPARATE FROM
	PUSHJ	P,LSTR		;ENSUING START/END INDICATOR
	POP	P,M		;GET START/END TEXT
	PUSHJ	P,LSTR		;ISSUE IT
	MOVEI	M,[ASCIZ / save set: /]
	PUSHJ	P,LSTR		;ISSUE START OF SAVE SET
	SKIPL	B$GTYP		;IF BACKUP,
	JRST	[MOVEI M,B$BSSN	; POINT TO SAVE SET NAME
		 PUSHJ P,LSTR	; LIST IT
		 JRST  MTFXS1]	; AND PROCEED
	MOVE	T2,B$SNAM	;GET SAVE SET NAME
	PUSHJ	P,LSIXN		;ISSUE IT
MTFXS1:	PUSHJ	P,LCRLF		;END LINE
	PUSHJ	P,MTFXSL	;ISSUE LINES COMMON TO LABEL
	SKIPE	B$SCMT		;SEE IF COMMENT
	JRST	[TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
		PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENT
		MOVEI	M,[ASCIZ /    Comment: /]
		PUSHJ	P,LSTR		;LABEL IT
		SETZM	B$SCMT+4	;PROTECT ASCIZ
		MOVEI	M,B$SCMT	;OUTPUT
		PUSHJ	P,LSTR		; COMMENT
		PUSHJ	P,LCRLF	;END LINE
		JRST  .+1]	;RETURN
	POPJ	P,		;RETURN
;STILL IN IFN FT$MTB

;ISSUE LINES COMMON BETWEEN LABEL AND SAVE SET HEADERS

MTFXSL:	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	PUSHJ	P,LSPC3		;INDENT
	MOVEI	M,[ASCIZ / by version /]
	SKIPE	T4,B$SVER	;IF FRS/BACKUP VERSION SET,
	PUSHJ	P,LSTR		;INDICATE VERSION
	SKIPE	T4		;IF SET,
	PUSHJ	P,LVER		;LIST IT

	SKIPL	B$GTYP		;IF NOT FRS
	SKIPN	T1,B$SCDT	;AND DATE SET
	JRST	MTFXS2		;NO--SKIP ON
	PUSHJ	P,.CNTDT##	;SPLIT
	MOVEM	T1,B$STIM	;STORE CREATION TIME
	MOVEM	T2,B$SDAT	;STORE CREATION DATE
MTFXS2:
IFN FT$MTS,<	;FRS
	SKIPE	T1,B$STRK	;GET 7-TRACK FLAG
	MOVX	T1,MT.7TR	;SET FOR MTCHR.
	LDB	T2,[POINTR (B$SMOD,IO.DEN)]
	DPB	T2,[POINTR (T1,MT.DEN)]
	SKIPGE	B$GTYP		;IF FRS,
	MOVEM	T1,B$SMTC	; STORE MTCHR.
>;END IFN FT$MTS

	MOVEI	M,[ASCIZ / at /]
	PUSHJ	P,LSTR		;LABEL TIME
	MOVE	T1,B$STIM	;GET TIME
	PUSHJ	P,LMSECS	;LIST IT
	MOVEI	M,[ASCIZ / on /]
	PUSHJ	P,LSTR		;LABEL DATE
	MOVE	T4,B$SDAT	;GET DATE
	PUSHJ	P,LDATE		;LIST IT
	PUSHJ	P,LCRLF		;END LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTB

	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	PUSHJ	P,LSPC3		;SPACE IN
	MOVEI	M,[ASCIZ / written on /]
	SKIPE	T2,B$SDEV	;IF DEVICE,
	PUSHJ	P,LSTR		;LABEL DEVICE
	SKIPE	T2		;SKIP IF BLANK
	PUSHJ	P,LSIXCL	;LIST DEVICE
	MOVEI	M,[ASCIZ /, reel /]
	SKIPE	T2,B$SREL	;LIST REELID IF IT'S THERE
	PUSHJ	P,LSTR
	SKIPE	T2
	PUSHJ	P,LSIXN
	PUSHJ	P,LCOMMA
	MOVEI	M,[ASCIZ \ on S/N \]
	SKIPE	T1,B$SAPR
	PUSHJ	P,LSTR
	SKIPE	T1
	PUSHJ	P,LDEC
	LDB	T1,[POINTR (B$SMTC,MT.DEN)]
	JUMPE	T1,MTFXS3	;IF DENSITY SET,
	MOVEI	M,[ASCIZ / at /]
	PUSHJ	P,LSTR
	MOVE	T1,[ASCII /200/
		    ASCII /556/
		    ASCII /800/
		    ASCII /1600/
		    ASCII /6250/
		    ASCII /(6)/
		    ASCII /(7)/]-1(T1)
	MOVEI	M,T1		;ASCII OF DENSITY
	PUSHJ	P,LSTR		;ISSUE IT
	MOVX	T1,MT.7TR	;LOOK AT 7-TRACK FLAG
	MOVEI	M,[ASCIZ / 9TK/]
	TDNE	T1,B$SMTC	;SEE IF ON
	MOVEI	M,[ASCIZ / 7TK/]
	PUSHJ	P,LSTR		;ISSUE TRACKS
	MOVEI	M,[ASCIZ /; Blocking factor /]
	PUSHJ	P,LSTR		;PRINT TEXT
	SKIPN	T1,B$SFCT	;GET BLOCKING FACTOR
	MOVEI	T1,4		;OLD TAPE
	PUSHJ	P,LDEC		;PRINT BLOCK SIZE
MTFXS3:	PUSHJ	P,LCRLF		;GO TO NEW LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTB

	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	PUSHJ	P,LSPC3		;SPACE 5
	MOVEI	M,[ASCIZ / under/]
	PUSHJ	P,LSTR		;ISSUE LABEL
	SKIPGE	B$SMTY		;GET SYSTEM TYPE
	TDZA	T1,T1		;IGNORE IF FUNNY
	LDB	T1,[POINTR (B$SMTY,CN%MNT)]
	CAILE	T1,3		;IS IT KNOWN?
	MOVEI	T1,0		;NO--FORGET IT
	MOVE	M,[	[ASCIZ \\]
			[ASCIZ \ TOPS-10\]
			[ASCIZ \ I.T.S.\]
			[ASCIZ \ TENEX\]  ](T1)
	PUSHJ	P,LSTR		;GIVE SYSTEM TYPE
	MOVEI	M,[ASCIZ / system/]
	PUSHJ	P,LSTR		;LABEL SYSTEM VERSION
	SKIPE	B$SSVR		;AND
	PUSHJ	P,LSPC		;SPACE
	SKIPE	T4,B$SSVR	;GET SYSTEM VERSION
	PUSHJ	P,LVER		;LIST IN VERSION
	MOVEI	M,[ASCIZ /: /]
	PUSHJ	P,LSTR		;SEPARATE SYSTEM NAME
	MOVEI	M,B$SSNM	;POINT TO SYSTEM NAME
	SKIPL	B$GTYP		;IF BACKUP,
	MOVEI	M,B$BSYS	; POINT TO SPECIAL REGION
	PUSHJ	P,LSTR		;OUTPUT IT
	PJRST	LCRLF		;END LINE
;STILL IN IFN FT$MTB

;HERE ON BACKUP/FRS DIRECTORY

MTFDIR:	PUSHJ	P,WLDEOD	;OUTPUT SUMMARIES
	SETZM	BFHD+.BFCTR	;DISCARD REST OF BLOCK
	JRST	MTFRSR		;AND CONTINUE ONWARD

;HERE ON BACKUP/FRS FILE

MTFFIL:	SETZM	LBLOCK		;CLEAR OUT ANY EXCESS
	MOVE	T1,[LBLOCK,,LBLOCK+1]
	BLT	T1,FRIBLK	; ..
IFN FT$MTS,<	;FRS
	SKIPL	B$GTYP		;IF BACKUP,
	JRST	MTFBFL		; GO HANDLE SEPARATELY
	MOVE	T1,B$FRBN	;GET RELATIVE BLOCK NO.
	LSH	T1,7		;CONVERT TO WORDS
	MOVEM	T1,B$FRDW	;STORE SIMILAR TO BACKUP
	SKIPL	T1,B$FNDW	;GET NUMBER OF WORDS
	CAILE	T1,200		;SEE IF OK
	JRST	MTFJKB		;NO--ERROR
	SKIPN	T1,B$FNDB	;GET NUMBER OF DATA BLOCKS
	SKIPGE	B$GFLG		;UNLESS EOF
	SKIPA			;YES
	MOVEI	T1,5		;(BUG IN OLD VERSION OF FRS)
	SKIPL	T1		;SEE IF
	CAILE	T1,20		; MAKES SENSE
	JRST	MTFJKB		;NO--ERROR
	IMULI	T1,200		;CONVERT TO WORDS
	ADD	T1,B$FNDW	;ADD LAST PARTIAL BLOCK
	CAIL	T1,200		;IN CASE JUST RIB, SKIP
	SUBI	T1,200		; REMOVE LAST BLOCK IN COUNT
	MOVEM	T1,BFHD+.BFCTR	;STORE AS ACTUAL DATA LENGTH
	MOVE	T1,B$FSTR	;GET STRUCTURE
	MOVEM	T1,FSTR		;SET FOR LISTER
	SKIPE	B$FRBN		;GET STARTING BLOCK
	JRST	[MOVE  T1,B$FNAM;GET HEADER NAME
		 MOVEM T1,FNAM	;STORE
		 MOVE  T1,B$FEXT;GET EXTENSION
		 HLLZM T1,FEXT	;STORE
		 MOVE  T1,B$FUFD;GET DIRECTORY
		 MOVEM T1,UFDPPN;STORE DIRECTORY
		 JRST  MTFDFM]	;GO STORE
>;END IFN FT$MTS
>;END IFN FT$MTB

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTS,<	;FRS

	MOVNI	T2,177-.FXLND	;PRESET COUNT OF RIB
	PUSHJ	P,NEXOVR	;GET RIB POINTER
	  JRST	E$$JFS		;UNEXPECTED END OF RECORD
	HRRZM	T1,RIBLEN	;SET AS RIB LENGTH
	TLZ	T1,-1		;CLEAR JUNK
	CAILE	T1,LN$RIB	;SEE IF IT FITS
	JRST	E$$JFS		;NO--ERROR
	MOVNS	T1		;GET NEGATIVE COUNT
	HRLZS	T1		;POSITION FOR AOBJN
	HRRI	T1,LBLOCK+1	;POINT TO RIB
	PUSHJ	P,BLKOVR	;TRANSFER BLOCK OF DATA
	  JRST	E$$JFS		;JUNK IF NOT THERE
MTFFR2:	PUSHJ	P,NEXOVR	;GET JUNK RIB
	  JRST	E$$JFS		;UNEXPECTED END OF RECORD
	JUMPN	T2,MTFFR2	;LOOP UNTIL DONE
	MOVEI	T4,.FXLND	;GET SFD DEPTH
	SETZM	THSPTH+.PTPPN(T4) ;[450]SET END FLAG
MTFFR3:	PUSHJ	P,NEXOVR	;GET SFD
	  JRST	E$$JFS		;UNEXPECTED END OF RECORD
	MOVEM	T1,THSPTH+.PTPPN(T4) ;STORE SFD
	SOJGE	T4,MTFFR3	;GO GET NEXT ONE
	MOVE	T1,B$FLVL	;GET SFD LEVEL
	SETZM	THSPTH+.PTPPN+1(T1) ; CLEAR BEYOND IT

	SETZM	THSPTH		;CLEAR UNUSED AREA
	SETZM	THSPTH+1	; ..
	MOVEI	T1,THSPTH	;POINT TO SFD AREA
	SKIPE	THSPTH+.PTPPN+1	;SEE IF SFD NEEDED
	MOVEM	T1,UFDPPN	;YES--POINT TO IT
	JRST	MTFDFL		;GO HANDLE FILE
>;END IFN FT$MTS
IFN FT$MTB,<;	BACKUP/FRS

;HERE ON START OF BACKUP FILE TO ACQUIRE ATTRIBUTES, ETC.

MTFBFL:	MOVE	T1,MTFBOT	;CLEAR
	PUSHJ	P,MTFBCB	; NAME BLOCK
	MOVE	T1,MTFBOT+1	;CLEAR
	PUSHJ	P,MTFBCB	; ATTRIBUTES BLOCK
	MOVE	T1,B$GFLG	;GET RECORD FLAGS
	TXNN	T1,GF$SOF	;TRUE START OF FILE?
	JRST	[TRO	F,R.NSF	;RECOVER NAME
		 JRST	MTFB.1]	;GO PROCESS
	PUSHJ	P,MTFBGO	;GET OVERHEAD DATA
	  JRST	E$$JFS		;JUNK IF SCREWY
MTFB.1:	MOVEI	T1,.FCDEV	;GET
	PUSHJ	P,MTFBDT	; DEVICE
	MOVEM	T1,FSTR		;SAVE FOR DIRECTORY
	MOVEI	T1,.FCNAM	;GET
	PUSHJ	P,MTFBDT	; NAME
	MOVEM	T1,FNAM		;SAVE
	MOVEI	T1,.FCEXT	;GET
	PUSHJ	P,MTFBDT	; EXTENSION
	MOVEM	T1,FEXT		;SAVE
	MOVEI	T1,.FCDIR	;INDICATE UFD
	PUSHJ	P,MTFBDT	; GET IT
	JUMPE	T1,MTFB.3	;JUMP IF NOT THERE
	MOVEM	T1,MTPATH+.PTPPN;ELSE SET IN PATH
	MOVSI	P1,1-.FXLND	;COUNT SFDS
MTFB.2:	MOVEI	T1,.FCSFD(P1)	;INDICATE SFD
	PUSHJ	P,MTFBDT	;GET IT
	MOVEM	T1,MTPATH+.PTPPN+1(P1) ;STORE IT
	SKIPE	T1		;UNLESS DONE,
	AOBJN	P1,MTFB.2	; LOOP
	MOVEI	T1,MTPATH	;POINT TO PATH
MTFB.3:	MOVEM	T1,UFDPPN	;STORE AS DIRECTORY
	TRZE	F,R.NSF		;IF NOT START AT START,
	JRST	MTFDFM		; GO ISSUE MESSAGE
	MOVE	T1,B$BATT+A$FHLN;GET ATTRIBUTE LENGTH
	CAIGE	T1,^D8		;MAKE SURE BIG ENOUGH
	PUSHJ	P,[AOSE	AMWCNT		;[462] FIRST TIME THIS SAVE SET?
		POPJ	P,		;[462] NO, IGNORE FURTHER JUNK
		N$WARN (AMW,<File attributes may be wrong, proceeding . . .>)
		POPJ	P,]		;DUMPER IS KNOWN TO DO THIS (CNT=0)
	MOVEI	T1,LN$RIB	;SET FULL
	MOVEM	T1,RIBLEN	; RIB LENGTH

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTB

;NOW DO ATTRIBUTES

	MOVEI	T2,0		;PRECLEAR ACCESS
	SKIPE	T1,B$BATT+A$REDT;GET ACCESS TIME
	PUSHJ	P,.CNTDT##	;CONVERT FORMAT
	DPB	T2,[POINTR (FACD,RB.ACD)]
	SKIPE	T1,B$BATT+A$PROT;GET PROTECTION
	PUSHJ	P,MTFDPR	;CONVERT TO TOPS-10
	DPB	T1,[POINTR (FPRV,RB.PRV)]
	SKIPN	B$BATT+A$PROT	;IF MISSING PROTECTION,
	SETOM	FFPRV		;NO PROTECTION IN INTERCHANGE
	MOVE	T1,B$BATT+A$MODE;GET MODE
	DPB	T1,[POINTR (FMOD,RB.MOD)]
	MOVE	T1,B$BATT+A$WRIT;GET WRITE DATE
	PUSHJ	P,.CNTDT##	;TAKE APART
	DPB	T2,[POINTR (FCRE,RB.CRD)]
	LSH	T2,-^D12	;DATE75 EXCESS
	DPB	T2,[POINTR (FCRX,RB.CRX)]
	IDIVI	T1,^D60000	;CONVERT TO MINUTES
	SKIPE	T2		;IF EXCESS,
	AOS	T1		; ROUND UP
	DPB	T1,[POINTR (FCRE,RB.CRT)]
	MOVEI	T2,^D36		;GET WORD WIDTH IN BITS
	IDIV	T2,B$BATT+A$BSIZ;CONVERT TO LENGTH IN BYTES
	SKIPGE	T1,B$BATT+A$LENG;LENGTH IN BYTES
	MOVEI	T2,1		;IF OVERFLOW, KILL DIVISOR
	IDIV	T1,T2		;CONVERT TO LENGTH IN WORDS
	SKIPE	T2		;IF PARTIAL WORD,
	AOS	T1		; ROUND UP
	MOVEM	T1,FSIZ		;STORE AS SIZE
	MOVE	T1,B$BATT+A$VERS;GET VERSION
	MOVEM	T1,FVER		;STORE
	MOVE	T1,B$BATT+A$NOTE;POINT TO ANNOTATION
	PUSHJ	P,MTGTSX	;CONVERT TO SIXBIT
	MOVEM	T1,FSPL		;SET IN SPOOL WORD
	MOVEI	T2,0		;PRECLEAR
	SKIPL	T1,B$BATT+A$ESTS;GET ESTIMATE
	IDIVI	T1,^D128	;CONVERT TO BLOCKS
	SKIPE	T2		;IF OVERFLOW,
	AOS	T1		; INCREMENT
	MOVEM	T1,FEST		;SET AS ESTIMATE
	MOVEI	T2,0		;PRECLEAR
	SKIPL	T1,B$BATT+A$ALLS;ALLOCATED SIZE IN WORDS
	IDIVI	T1,^D128	;CONVERT TO BLOCKS
	SKIPE	T2		;IF PARTIAL BLOCK,
	AOS	T1		; ROUND UP
	MOVEM	T1,FALC		;STORE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTB

	SKIPL	T1,B$BATT+A$RADR;GET REQUESTED ADDRESS
	IDIVI	T1,^D128	;CONVERT TO BLOCKS
	MOVEM	T1,FPOS		;STORE
	MOVE	T1,B$BATT+A$USRW;GET USER WORD
	MOVEM	T1,FNCA		;STORE
	MOVE	T1,B$BATT+A$BKID;GET LAST BACKUP TAPE
	PUSHJ	P,MTGTSX	;CONVERT TO SIXBIT
	MOVEM	T1,FMTA		;STORE
	MOVEI	T1,0		;PRECLEAR STATUS BITS
	MOVSI	T2,(1B0)	;SET FIRST BIT
	MOVSI	T3,-LMTRBT	;SET LOOP LENGTH
MTFB.4:	TDNE	T2,B$BATT+A$FLGS;TEST BACKUP FLAG
	IOR	T1,MTRBT(T3)	;ON--SET TOPS-10 BIT
	LSH	T2,-1		;MOVE TO NEXT BACKUP BIT
	AOBJN	T3,MTFB.4	;LOOP OVER TABLE
	MOVEM	T1,FSTS		;STORE STATUS
	MOVE	T1,B$BATT+A$CUSR;GET AUTHOR
	PUSHJ	P,MTGTPP	;CONVERT TO PPN
	MOVEM	T1,FAUT		;STORE
	MOVE	T1,B$BATT+A$BKDT;BACKUP DATE/TIME
	MOVEM	T1,FIDT		;STORE AS BACKUP INCREMENTAL DATE/TIME
	MOVE	T1,B$BATT+A$PCAW;GET PRIV USER WORD
	MOVEM	T1,FPCA		;STORE
	SKIPN	T1,B$BATT+A$ACCT;[470] ACCOUNT STRING BYTE POINTER
	JRST	MTFB.6		;NONE
	MOVE	T2,[POINT 7,FACT]  ;[470] PROTOTYPE .RBACT STRING POINTER
	MOVEI	T4,<<.RBAC8-.RBACT+1>*5>-1  ;[470] MAXIMUM CHARACTER COUNT
	PUSHJ	P,MTGTST	;[470] GET (AND COPY) ACCOUNT STRING
MTFB.6:	HRRZ	T1,B$BATT	;LENGTH OF ATTRIBUTES BLOCK FIXED HEADER
	CAIG	T1,A$FFFB	;INCLUDE THE FILE-TYPE/ETC. WORDS?
	JRST	MTFDFL		;NO (PRE-VERSION-5 BACKUP), ALL DONE
	SKIPE	T1,B$BATT+A$FTYP;FILE TYPE-AND-FLAGS WORD
	MOVEM	T1,FTYP		;STORE IN .RBTYP WORD
	SKIPE	T1,B$BATT+A$FBSZ;FILE BYTE/FRAME/ETC VALUES
	MOVEM	T1,FBSZ		;STORE IN .RBBSZ WORD
	SKIPE	T1,B$BATT+A$FRSZ;RECORD AND BLOCK SIZES
	MOVEM	T1,FRSZ		;STORE IN .RBRSZ WORD
	SKIPE	T1,B$BATT+A$FFFB;FIRST-FREE-BYTE, CUSTOMER VALUE
	MOVEM	T1,FFFB		;STORE IN .RBFFB WORD
	JRST	MTFDFL		;GO HANDLE FILE
;(STILL IFN FT$MTB)

;TABLE OF TOPS-10 FILE RIB STATUS BITS IN BACKUP ORDER

MTRBT:	RP.NDL
	Z
	Z
	RP.ABU
	RP.NQC
	RP.ABC
	RP.FCE
	RP.FWE
	RP.BFA
	RP.BDA
LMTRBT==.-MTRBT
;STILL IN IFN FT$MTB

;HERE WHEN FILE ACTUALLY FOUND ON TAPE

MTFDFM:	MOVEI	M,[ASCIZ \ File starts in middle: \]
	PUSHJ	P,LSTR		;NOT START OF FILE!

MTFDFL:	TLO	F,L.FRSS	;INDICATE FRS/BACKUP DATA
	PUSHJ	P,MTDOFL	;GO HANDLE FILE

	TLZ	F,L.FRSS!L.FKEF	;CLEAR FLAGS
	JRST	MTFRSR		;PROCEED TO NEXT BLOCK
>;END FT$MTB
	SUBTTL	DIRECTORY LISTING - MAGTAPE -- FAILSAFE

IFN FT$MTF,<	;FAILSAFE

MTSVST:	MOVE	T3,CHKSUM	;SAVE THE CURRENT CHECKSUM
	MOVEM	T3,KCHKSM	;..
	SETZM	H.MZER		;CLEAR FOR THIS SAVESET
	MOVE	T3,[H.MZER,,H.MZER+1]
	BLT	T3,H.EMZR	; ..
	MOVE	T3,KCHKSM	;RESTORE THE SAVED CHECKSUM
	MOVEM	T3,CHKSUM	;..
	MOVEM	T1,MTSVVR	;SAVE HEADER
	PUSHJ	P,NEXOVW	;GET CODE WORD
	  JRST	MTIOJF		;JUNK
	PUSHJ	P,NEXDT3	;DO THE CHECKSUM
	JFCL			;SILLY RETURN
	AOS	T2		;COUNT WORD
	CAME	T1,[SIXBIT /*FAILS/]
	JRST	MTIOJK		;NOT FAILSAFE TAPE
	SETZM	CHKSUM		;CLEAR THE CHKSUM FOR THIS SAVE SET
	PUSHJ	P,NEXOVW	;GET TAPE NUMBER
	  JRST	MTIOJF		;DEATH
	AOS	T2		;COUNT STILL
	HRRM	T1,MTSVVR	;SAVE TAPE NUMBER
	TRZ	T1,377777	;CLEAR TAPE NUMBER
	CAME	T1,[SIXBIT /AFE/]
	JRST	MTIOJK		;JUNK
	PUSHJ	P,NEXOVW	;GET DATE, ETC.
	  JRST	MTIOJF		;NOT ENOUGH
	AOS	T2		;COUNT RECORD
	MOVE	P2,T1		;SAVE TAPE AND DATE
	PUSHJ	P,NEXOVW	;LAST WORD
	  JRST	MTIOJF		;SORRY
	AOS	T2		;COUNT WORD IN RECORD
	CAME	T1,[1,,2]	;CHECK THAT TOO
	JRST	MTIOJK		;NO--GIVE UP
	PUSHJ	P,NEXOVW	;READ THE EOF
	  JRST	.+2		;GOOD
	AOJA	T2,MTIOJK	;NO--JUNK

	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  FAILSAFE save set by version /]
	PUSHJ	P,LSTR		;LIST LABEL
	HLRZ	T1,MTSVVR	;GET VERSION OF FAILSA
	PUSHJ	P,LOCT		;LIST OCTAL
	PUSHJ	P,MTLTDT	;LIST TAPE'S DATE AND TIME
	MOVEI	M,[ASCIZ /  tape /]
	PUSHJ	P,LSTR		;LIST LABEL
	HRRZ	T1,MTSVVR	;GET TAPE NUMBER
	PUSHJ	P,LDEC		;LIST IT
	PUSHJ	P,LCRLF		;END LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;STILL IN IFN FT$MTF

;HERE AFTER SAVE SET HEADER IS OUTPUT AND
;BACK HERE AFTER EACH FILE TO LOOK FOR NEXT USER/STR

MTUSER:	MOVEI	M,[ASCIZ /<Tape mark>
/]
	SKIPLE	S.MARK		;/MARKS?
	PUSHJ	P,LSTR		;YES--TELL USER
	STATZ	DC,IO.EOT	;SEE IF EOT
	  JRST	E$$PET		;YES--GO WRAP UP
	CLOSE	DC,		;CLEAR END-OF-FILE
	SOSN	MTFLCT		;DO /FILE ACCOUNTING
	JRST	MTDONX		;JUMP IF DONE WITH /FILE
	PUSHJ	P,NEXOVW	;READ NEXT HEADER
	  JRST	[N$WARN	(DTM,Double tape mark)
		 JRST  MTUSER]	;AND TRY AGAIN

;BACK HERE TO PROCESS NEXT FILE

MTLOOK:	JUMPGE	T1,MTRAIL	;MUST BE AT TRAILER
	TLC	T1,-1		;FLIP FLAG
	TLNN	T1,-1		;MAKE SURE IT WAS -1
	CAIGE	T1,42		;MAKE SURE FULL BLOCK THERE
	JRST	MTSVJK		;NO--JUNK IN SAVE SET
	PUSHJ	P,NEXOVW	;GET STR NAME
	  JRST	E$$JSS		;ERROR
	MOVEM	T1,FSTR		;SAVE FOR TYPEOUT
	MOVSI	P1,-41		;PRESET LOOKUP COPY LOOP
MTLOK1:	PUSHJ	P,NEXOVW	;GET WORD
	  JRST	E$$JSS		;ERROR
	MOVEM	T1,LBLOCK(P1)	;SAVE WORD
	AOBJN	P1,MTLOK1	;LOOP UNTIL DONE
	MOVE	T1,RIBLEN	;GET COUNT FROM TAPE
	CAIE	T1,40		;MUST BE 40
	JRST	MTSVJK		;NO--JUNK
	TLO	F,L.SVST	;FLAG SAVE SET READ TO SKIP OVER
				;  THE RECORD PREFIXES

;HERE WHEN FILE FOUND ON TAPE

	PUSHJ	P,MTDOFL	;GO HANDLE FILE

	TLZ	F,L.SVST	;CLEAR FUNNY MODE
	TLZN	F,L.FKEF	;SEE IF REAL OR FAKE EOF
	JRST	MTUSER		;REAL--GO TO NEXT STR OR PPN OR TRAILER
	MOVE	T1,MTSVHD	;FAKE--GET NEXT HEADER
	JRST	MTLOOK		;GO PROCESS NEXT FILE
>;END IFN FT$MTF
IFN FT$MTB!FT$MTF!FT$MTR,<	;BACKUP/FRS, FAILSAFE, OLD BACKUP/RESTORE

;MTDOFL -- ROUTINE TO ANALYZE FILE IF USER WANTS IT AND SKIP OVER DATA
;USES T1-4

MTDOFL:	AOS	.CTFLS##	;COUNT UP FILES SEEN ON TAPE
	AOS	.CTFLF##	;ASSUME FILE FOUND (.CHKTA WILL DECREMENT
				; THIS IF IT REJECTS THE FILE)
	PUSHJ	P,.CHKTA##	;SEE IF FILE MATCHES
	 JRST	MTSKIP		;REJECTED, ADVANCE TO NEXT FILE
	PUSHJ	P,ANALYZ	;GO LIST IN APPROPRIATE FORMAT
	 JFCL			;HOHUM

MTSKIP:	PUSHJ	P,NEXDTW	;READ REST OF DATA FILE
	  POPJ	P,		;GOOD--WE'RE DONE
	JRST	MTSKIP		;LOOP TO FILE'S END
>;END IFN FT$MTB!FT$MTF!FT$MTR
IFN FT$MTF,<	;FAILSAFE

;HERE WHEN TRAILER SEEN ON TAPE

MTRAIL:	HLLZ	T2,MTSVVR	;GET VERSION FROM HEADER
	PUSHJ	P,NEXOVW	;GET CHECK WORD
	  JRST	E$$JSS		;ERROR
	CAME	T1,[SIXBIT /*FAILS/]
	JRST	MTSVJK		;JUNK
	PUSHJ	P,NEXOVW	;AND COUNT
	  JRST	E$$JSS		;ERROR
	HRRZ	T2,MTSVVR	;GET SAVED TAPE NUMBER
	ADD	T1,T2		;MATCH AGAINST TRAILER'S
	CAME	T1,[<SIXBIT /AFE/>+1B17]
	JRST	MTSVJK		;ERROR
	PUSHJ	P,NEXOVW	;GET DATE, ETC.
	  JRST	E$$JSS		;ERROR
	MOVE	P2,T1		;SAVE FOR OUTPUT ROUTINE
	PUSHJ	P,NEXOVW	;GET FINAL CHECK
	  JRST	E$$JSS		;ERROR
	CAME	T1,[1,,2]	;CHECK CODE
	JRST	MTSVJK		;ERROR
	PUSHJ	P,NEXOVW	;READ EOF
	  JRST	.+2		;GOOD
	JRST	MTSVJK		;ERROR

;HERE AFTER READING THE TRAILER FILE

	PUSHJ	P,DIRE		;GIVE TOTAL LINE
	TLZ	F,L.CRLF	;WE REALLY WANT A BLANK
	PUSHJ	P,LCRLF		;(I.E., A "BLANK") LINE
	TLNE	F,L.MLBL	;HAVE WE TYPED LABEL INFO?
	PUSHJ	P,LSPC2		;YES, ANOTHER LEVEL OF INDENTATION THEN
	MOVEI	M,[ASCIZ /  End of save set/]
	PUSHJ	P,LSTR		;TYPE INDICATOR
	PUSHJ	P,MTLTDT	;LIST TIME AND DATE
MTENDS:	PUSHJ	P,LCRLF		;AND END LINE
MTENDT:	TLZ	F,L.CRLF	;SEPARATE SAVE SETS FOR NEATNESS
	PUSHJ	P,LCRLF		;AND ADD A BLANK LINE
	SETZM	H.MZER		;CLEAR TOTALS
	MOVE	T1,[H.MZER,,H.MZER+1]
	BLT	T1,H.EMZR
	SKIPN	MTNAME		;STILL HAVE A TAPE MOUNTED?
	JRST	MTDONY		;NO, JUST CAP OFF AND QUIT
	JRST	MTFIND		;GO BACK TO START
>;END IFN FT$MTF
IFN FT$MTA,<	;MAGTAPES
IFN FT$MTF,<	;FAILSAFE

;HERE WHEN JUNK IN SAVE SET

MTSVJK:	SETZM	BFHD+.BFCTR	;CLEAR REST OF RECORD
	PUSHJ	P,NEXOVW	;READ ON TO EOF
	  JRST	E$$JSS		;GOT IT
	JRST	MTSVJK		;NO--LOOP
>;END IFN FT$MTF

;HERE WHEN EOF JUNK

	N$WARN	(JSS,Junk in save set)
	JRST	MTUSER		;GO START OVER

IFN FT$MTF,<	;FAILSAFE

;HERE ON PREMATURE EOT

	N$WARN	(PET,Premature end of tape in save set)
	PUSHJ	P,DIRE		;GIVE FINAL TOTALS
>;END IFN FT$MTF

;HERE AT EOT ON MAG TAPE

MTDONE:	SKIPE	S.EOT		;SEE IF /NOEOT
	JRST	MTDONX		;NO--GO FINISH UP
	CLOSE	DC,		;CLEAR END-OF-FILE
	SOSE	MTFLCT		;DO /FILE ACCOUNTING
	JRST	MTFIND		;START OVER UNLESS /FILE COUNTED OUT

;HERE WHEN TRULY TIME TO STOP

MTDONX:	SKIPE	S.REWS		;SEE IF /NOREW
	MTREW.	DC,		;REWIND TAPE AT END
MTDONY:	PUSHJ	P,DIRET		;ISSUE TOTALS, ETC.
	RELEAS	DC,		;RELEASE THE DATA CHANNEL
	SETZM	FOBLK+.FODEV	;INDICATE DEVICE IS NO LONGER WITH US
	DMOVE	T1,MTXDEV	;ORIGINAL DEVICE SPEC
	MOVE	T3,.WIFIR##	;COMMANDING FILE SPEC BLOCK ADDRESS
	DMOVEM	T1,.FXDEV(T3)	;RESTORE ON G.P.'S
	TRZ	F,R.WORD+R.MTOH	;CLEAR WORD MODE AND TAPE OVERHEAD
	JRST	.POPJ1##	;RETURN HAPPILY
>;END IFN FT$MTA
	SUBTTL	DIRECTORY LISTING - MAGTAPE -- MISCELLANEOUS SUBROUTINES

IFN FT$MTF,<	;FAILSAFE

;MTLTDT -- ROUTINE TO LIST TIME AND DATE FROM FAILSAFE TAPE
;CALL:	MOVE	P2,WORD FROM HEADER
;	PUSHJ	P,MTLTDT
;LISTS " AT HH:MM:SS ON DATE"

MTLTDT:	PUSHJ	P,.SAVE1	;SAVE P1
	MOVEI	M,[ASCIZ / at /]
	PUSHJ	P,LSTR		;LIST LABEL
	HLRZ	T1,MTSVVR	;GET VERSION NUMBER
	CAIG	T1,27		;IF SINCE V.27 OK
	JRST	[LDB	T4,[POINT 11,P2,23]
		 PUSHJ	P,LTIME
		 JRST	MTSVDT]
	LDB	T4,[POINT 17,P2,23]
	CAILE	T1,77		;SEE IF V.100
	LDB	T4,[POINT 17,P2,20]  ;YES--GET NEW FORMAT
	PUSHJ	P,LSECS		;ISSUE TIME IN SECONDS
MTSVDT:	MOVEI	M,[ASCIZ / on /]
	PUSHJ	P,LSTR		;LIST LABEL
	HRRZ	T4,P2		;GET DATE
	ANDI	T4,77777	;MASK TO DATE
	HLRZ	T1,MTSVVR	;GET FAILSA VERSION
	CAIG	T1,77		;IF BEFORE VERSION 100,
	ANDI	T4,7777		;MASK OUT JUNK
	PJRST	LDATE		;LIST IT AND RETURN
>;END IFN FT$MTF
REPEAT	0,<

IFN FT$MTA,<	;MAGTAPES

;SUBROUTINE TO OPEN MAG TAPE
;CALL:	PUSHJ	P,MTOPEN
;RETURNS T1=0 IF FILE COUNT DONE (/FILE SWITCH)

MTOPEN:	MOVE	T1,MTSVFF	;RESTORE JOBFF
	MOVEM	T1,.JBFF	;  TO AVOID GROWTH
	MOVX	T1,FX.PAR	;CHECK FOR /PARITY
	TDNN	T1,.FXMOD(I)	; SUPPLIED BY USER
	TDZA	T1,T1		;NO--CLEAR IT
	MOVX	T1,IO.PAR	;YES--SET IT
	LDB	T2,[POINTR (.FXMOD(I),FX.DEN)]
	DPB	T2,[POINTR (T1,IO.DEN)]
	MOVE	T2,.FXMOD(I)	;GET PHYSICAL BIT
	TXNE	T2,FX.PHY	;TEST IT
	TXO	T1,UU.PHS	;YES--SET FOR OPEN
	IORI	T1,.IOBIN	;SET BINARY MODE
	SKIPN	S.RETR		;/NORETRY?
	TXO	T1,UU.DER	;YES, SUPPRESS AUTOMATIC RETRY
	SKIPN	S.ERLO		;/NOERLOG?
	TXO	T1,UU.DEL	;YES, DISABLE ERROR LOGGING
	MOVE	T2,.FXDEV(I)	;GET DEVICE NAME
	MOVEI	T3,BFHD		;GET INPUT BUFFER HEADERS
	OPEN	DC,T1		;OPEN CHANNEL
	  POPJ	P,		;RETURN WITH ERROR

;HERE WHEN TAPE IS OPENED--SETUP BUFFERS

	MOVEI	T4,T1		;GET SYSTEM BUFFERING
	DEVSIZ	T4,		;FROM MONITOR
	 MOVEI	T4,LN$MRC+3	;ASSUME DEFAULT
	HRRZI	T1,-3(T4)	;GET BUFFER SIZE
	CAIGE	T1,LN$MRC	;SEE IF MIN TAPE OR BIGGER SIZE
	MOVEI	T1,LN$MRC	;NO--FORCE UP
	SKIPLE	.FXBLS(I)	;DID USER EXERT EXPLICIT BLOCKSIZE REQUEST?
	HRRZ	T1,.FXBLS(I)	;YES, THEN HE WINS.
	HRLI	T1,NM$MBF	;NUMBER OF BUFFERS
	SKIPLE	.FXBFN(I)	;DID USER SPECIFY COUNT OF BUFFERS?
	HRL	T1,.FXBFN(I)	;YES, THEN HE WINS.
	MOVEI	T2,BFHD		;POINT TO HEADER
	PUSHJ	P,MAKBUF	;MAKE A BUFFER RING
	SETOM	MTAEOF		;SET NEW MTA FILE FLAG
	SOS	T1,MTFLCT	;COUNT DOWN FILE COUNTER
	JRST	.POPJ1##	;WIN RETURN
>;END IFN FT$MTA

> ;END OF REPEAT 0
IFN FT$MTB,<	;BACKUP/FRS

;MTFBGO -- GET OVERHEAD REGIONS FROM BACKUP/FRS TAPE
;CALL:	PUSHJ	P,MTFBGO
;	RETURN +1 IF ERRORS
;	RETURN +2 IF OK

MTFBGO:	PUSHJ	P,.SAVE3##	;MAKE SOME WORK ROOM
	HRRZ	P1,B$GLND	;LENGTH (DUMPER LEAVES JUNK IN LH)

;LOOP OVER OVERHEAD BLOCKS
MTFG.1:	SOJL	P1,MTFG.3	;EXIT IF DONE
	PUSHJ	P,NEXOVR	;GET NEXT BLOCK HEADER
	  POPJ	P,		;ERROR IF MISSING
	HLRZ	P3,T1		;GET TYPE
	CAILE	P3,MTFBOL	;SEE IF TOO BIG
	POPJ	P,		;ERROR IF SO
	MOVEI	P2,-1(T1)	;GET LENGTH OF DATA PORTION
	SUB	P1,P2		;COUNT IF DOWN
	JUMPL	P1,.POPJ##	;ERROR IF TOO LONG
	MOVE	T1,MTFBOT-1(P3)	;GET AREA
	PUSHJ	P,MTFBCB	;CLEAR OUT AREA
	HLRE	T3,MTFBOT-1(P3)	;GET MAX LENGTH WE CAN HANDLE
	MOVN	T1,P2		;GET NEGATIVE LENGTH
	CAMG	T1,T3		;IF TOO NEGATIVE TO FIT,
	MOVE	T1,T3		; JUST USE OUR SPACE
	ADD	P2,T1		;SUBTRACT FROM TAPE SIZE
	HRLZS	T1		;POSITION FOR AOBJN
	HRR	T1,MTFBOT-1(P3)	;GET START
	PUSHJ	P,BLKOVR	;GET BLOCK OF DATA
	  POPJ	P,		;ERROR IF NOT ALL THERE
	MOVEI	T1,377		;MASK OF RIGHTMOST ASCIZ CHARACTER
	SKIPE	MTFBOU-1(P3)	;IF SET,
	ANDCAM	T1,@MTFBOU-1(P3); PROTECT AGAINST JUNK
MTFG.2:	JUMPLE	P2,MTFG.1	;SKIP REST
	PUSHJ	P,NEXOVR	; IF WE DIDN'T USE IT
	  POPJ	P,		;ERROR IF NOT ALL THERE
	SOJA	P2,MTFG.2	; LOOP
MTFG.3:	MOVE	T1,B$GSIZ	;UPDATE
	MOVEM	T1,BFHD+.BFCTR	; WORDS OF DATA
	JRST	.POPJ1##	;GIVE GOOD RETURN
>;END IFN FT$MTB

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTB,<	;BACKUP/FRS

MTFBOT:	-^D30,,B$BNAM	;1=NAME BLOCK
	-^D50,,B$BATT	;2=FILE ATTRIBUTES
	0		;3=DIRECTORY ATTRIBUTES
	 -^D6,,B$BSYS	;4=SYSTEM HEADER
	 -^D7,,B$BSSN	;5=SAVE SET NAME
MTFBOL==.-MTFBOT

MTFBOU:	0		;1=NAME BLOCK
	0		;2=FILE ATTRIBUTES
	0		;3=DIRECTORY ATTRIBUTES
	B$BSYS+5	;4=SYSTEM HEADER
	B$BSSN+6	;5=SAVE SET NAME


;MTFBCB -- ROUTINE TO CLEAR A SPECIFIC OVERHEAD BLOCK
;CALL:	T1/ AOBJN TO BLOCK
;	PUSHJ	P,MTFBCB
;	RETURN +1
;USES T1

MTFBCB:	SKIPGE	T1		;UNLESS NULL,
	SETZM	(T1)		; CLEAR WORD
	AOBJN	T1,.-1		;LOOP
	POPJ	P,		;RETURN
>;END IFN FT$MTB
IFN FT$MTB,<

;MTFBDT -- ROUTINE TO GET A SPECIFIC NAME COMPONENT
;CALL:	T1/ CODE OF COMPONENT TO GET
;	PUSHJ	P,MTFBDT
;	RETURN +1 WITH T1/ VALUE (CONVERTED TO SIXBIT) OR 0

MTFBDT:	PUSHJ	P,.SAVE2##	;SAVE SPACE
	MOVE	P2,T1		;COPY REQUEST FOR SAFE KEEPING
	MOVEI	P1,0		;SET COUNT
	TRNE	F,R.NSF		;IF NOT AT START,
	MOVEI	P1,B$FPTH-1	; USE RECOVERY HEADER
MTFD.1:	TRNE	F,R.NSF		;IF NOT AT START,
	JRST	[HRLI P1,(POINT 7,,35)
		 ILDB T2,P1	;GET SUB-BLOCK CODE
		 ILDB T4,P1	;GET LENGTH
		 JRST MTFD.2]	;AND PROCEED
	HLRZ	T2,B$BNAM(P1)	;GET NEXT SUB-BLOCK CODE
	HRRZ	T4,B$BNAM(P1)	;GET LENGTH
MTFD.2:	SKIPN	T4		;IF EMPTY,
	MOVEI	T4,1		; SET FOR JUST HEADER
	CAMN	T2,P2		;SEE IF MATCH
	JRST	MTFD.4		;YES--GO HANDLE
	TRNE	F,R.NSF		;IF NOT AT START,
	JRST	[HRRZ  T2,P1	;GET CURRENT WORD
		 CAIGE T2,B$FPTH+^D12 ;MAKE SURE FITS
		 JRST  MTFD.1	;OK--CONTINUE
		 JRST  MTFD.3]	;BAD--LOOSE
	ADD	P1,T4		;NO--ADVANCE
	CAIGE	P1,^D30		;SEE IF OVERFLOW YET
	JRST	MTFD.1		;NO--TRY AGAIN
MTFD.3:	MOVEI	T1,0		;YES--RETURN 0
	POPJ	P,		; TO CALLER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE (STILL IFN FT$MTB)

;HERE WHEN FOUND THE COMPONENT

MTFD.4:	TRNE	F,R.NSF		;IF NOT AT START,
	JRST	[HRRZ  T1,P1	;GET LOCATION
		 MOVNS T1	;GET -AMOUNT USED
		 CAILE T4,B$FPTH+^D12(T1) ;SEE IF FITS
		 MOVEI T4,B$FPTH+^D12(T1) ;NO--TRUNCATE
		 IMULI T4,5	;GET CHARACTER COUNT
		 SUBI  T4,2	;ALLOW FOR OVERHEAD
		 JRST  MTFD.5]	;AND PROCEED
	MOVN	T1,P1		;GET -AMOUNT USED
	CAILE	T4,^D30(T1)	;SEE IF LENGTH FITS
	MOVEI	T4,^D30(T1)	;NO--USE ACTUAL IN CORE
	SOS	T4		;REMOVE OVERHEAD WORD
	IMULI	T4,^D5		;CONVERT TO CHARACTERS
	ADD	P1,[POINT 7,B$BNAM,35] ;POINT TO START IN NEXT WORD
MTFD.5:	MOVEI	T1,0		;CLEAR SIXBIT ANSWER
	MOVE	T2,[POINT 6,T1]	;POINT TO ANSWER
	CAIN	P2,.FCDIR	;IF UFD,
MTFDPP:	JRST	[PUSHJ	P,MTFD.G	;GET FIRST CHARACTER
		CAILE	T3,"7"		;IF ALPHA,
		JRST	MTFD.7		; HANDLE AS SIXBIT
		JRST	MTFD.8]		;ELSE, HANDLE IN OCTAL
MTFDSX:!
MTFD.6:	PUSHJ	P,MTFD.G	;GET NEXT CHARACTER
MTFD.7:	JUMPE	T3,.POPJ##	;EXIT WHEN DONE
	CAIG	T3,137		; IN ASCII COL 0-5
	TRC	T3,40		; FORCE TO ALPHA (COL 4-5)
	IDPB	T3,T2		;STORE
	TLNE	T2,(77B5)	;IF NOT DONE,
	JRST	MTFD.6		; LOOP FOR MORE
	POPJ	P,		;RETURN WHEN FULL

MTFD.8:	PUSHJ	P,MTFOCT	;UFD--GET PROJECT IN OCTAL
	PUSH	P,T1		;SAVE
	PUSHJ	P,MTFD.G	;SKIP SEPARATOR (_)
	PUSHJ	P,MTFOCT	;GET PROGRAMMER IN OCTAL
	HRL	T1,(P)		;INSERT PROJECT
	POP	P,(P)		;DISCARD TEMP
	POPJ	P,		;RETURN UFD
;(STILL IFN FT$MTB)

;MTGTPP -- ROUTINE TO CONVERT ATTRIBUTE STRING TO UFD
;CALL:	1/ RELATIVE BYTE POINTER IN ATTRIBUTES
;	PUSHJ	P,MTGTPP
;	1/ CONVERSION

MTGTPP:	PUSHJ	P,.SAVE1	;SAVE P1
	PUSHJ	P,MTGT.P	;FIXUP POINTER SET COUNT
	MOVEI	T1,0		;PRESET ANSWER
	MOVE	T2,[POINT 6,T1]	;POINT TO ANSWER
	PJRST	MTFDPP		;GO USE ABOVE ROUTINE



;MTGTSX -- ROUTINE TO CONVERT ATTRIBUTE STRING TO SIXBIT
;CALL:	1/ RELATIVE BYTE POINTER IN ATTRIBUTES
;	PUSHJ	P,MTGTSX
;	1/ CONVERSION

MTGTSX:	PUSHJ	P,.SAVE1	;SAVE P1
	PUSHJ	P,MTGT.P	;FIXUP POINTER SET COUNT
	MOVEI	T1,0		;PRESET ANSWER
	MOVE	T2,[POINT 6,T1]	;POINT TO ANSWER
	PJRST	MTFDSX		;GO USE ABOVE ROUTINE



;MTGTST -- ROUTINE TO COPY ASCIZ ATTRIBUTE STRING
;CALL:	T1/ RELATIVE BYTE POINTER TO ATTRIBUTE BLOCK
;	T2/ DESTINATION BYTE POINTER
;	T3/ SCRATCH
;	T4/ MAXIMUM BYTE COUNT
;
;	PUSHJ	P,MTGTST
;	RETURN
;
;<MAXIMUM> BYTES WILL BE COPIED (NULL FILLED WHEN ATTRIBUTES STRING
;TERMINATES), THEN A NULL WILL BE APPENDED.

MTGTST:	CAIE	T1,0		;NULL POINTER?
	ADDI	T1,B$BATT	;NO, RELOCATE POINTER INTO ATTRIBUTES BLOCK
	SKIPA	T3,T1		;SKIP INTO LOOP
MTGTS1:	IDPB	T3,T2		;STORE NEXT STRING CHARACTER
	CAIE	T3,0		;NO MORE CHARACTERS AFTER A NULL
	ILDB	T3,T1		;FETCH NEXT STRING CHAR FROM ATTRIBUTES BLOCK
	SOJGE	T4,MTGTS1	;LOOP FOR ALL CHARACTERS
	SETZ	T3,		;FORCE A NULL CHARACTER
	IDPB	T3,T2		;TO TERMINATE THE COPIED ASCIZ STRING
	POPJ	P,		;ALL DONE, RETURN
;(STILL IFN FT$MTB)

;HELPER TO CONVERT OCTAL

MTFOCT:	TDZA	T1,T1		;STARTS WITH CHAR
MTFO.1:	PUSHJ	P,MTFD.G	;GET CHAR
	CAIL	T3,"0"		;IF
	CAILE	T3,"7"		; OCTAL DIGIT,
	POPJ	P,		;NO--DONE
	LSH	T1,3		;ADVANCE RESULT
	ADDI	T1,-"0"(T3)	;INCLUDE DIGIT
	JRST	MTFO.1		;LOOP


;HELPER ROUTINE TO GET NEXT CHARACTER
; COUNTS IN T4, POINTER IN P1
; RESULT IN T3

MTFD.G:	SOSGE	T4		;SEE IF ROOM
	TDZA	T3,T3		;NO--GIVE NULL
	ILDB	T3,P1		;YES--GET IT
	POPJ	P,		;RETURN


;HELPER TO SET STRING POINTER

MTGT.P:	MOVEI	T4,0		;PRESET TO DONE
	JUMPE	T1,.POPJ	;RETURN IF NO POINTER
	HRRZ	T2,T1		;GET ADDRESS OF POINTER
	CAIL	T2,^D50		;SEE IF BAD
	POPJ	P,		;YES--GIVE UP
	HRRI	T1,B$BATT(T2)	;COMPUTE REAL LOCATION
	MOVE	P1,T1		;SET FOR CHAR GETTER
	MOVEI	T4,^D50		;SET MAX LENGTH
	SUB	T4,T2		;REMOVE HEADER
	IMULI	T4,5		;CONVERT TO BYTES
	POPJ	P,		;RETURN
;(STILL IFN FT$MTB)

;MTFDPR -- ROUTINE TO CONVERT PROTECTION ATTRIBUTE
;CALL:	1/ BACKUP PROTECTION
;	PUSHJ	P,MTFDPR
;	1/ TOPS-10 PROTECTION

MTFDPR:	PUSH	P,T1		;SAVE ARG
	LSH	T1,-^D16	;GET OWNER
	PUSHJ	P,MTFDPF	;CONVERT OWNER FIELD
	MOVE	T4,T1		;SAVE
	MOVE	T1,(P)		;GET ARG
	LSH	T1,-^D8		;GET AFFINITY GROUP
	PUSHJ	P,MTFDPF	;CONVERT AFFINITY
	LSH	T4,3		;SHIFT ANSWER
	IOR	T4,T1		;INCLUDE GROUP
	POP	P,T1		;RESTORE WORLD
	PUSHJ	P,MTFDPF	;CONVERT WORLD
	LSH	T4,3		;POSITON ANSWER
	IOR	T1,T4		;COMBINE RESULT
	POPJ	P,		;RETURN

;HELPER TO CONVERT ONE FIELD

MTFDPF:	MOVEI	T3,7		;SET WORST
	LDB	T2,[POINTR (T1,PR$RED)]
	SUB	T3,T2		;REMOVE READ ACCESS
	CAIGE	T3,5		;BUT NOT LESS
	MOVEI	T3,5		; THAN 5
	LDB	T2,[POINTR (T1,PR$WRT)]
	JUMPN	T2,[MOVEI T3,5	;IF SOME WRITE,
		    SUB   T3,T2	; USE THAT INSTEAD
		    JRST  .+1]	; AND CONTINUE
	LDB	T2,[POINTR (T1,PR$ATR)]
	CAIN	T2,7		;IF DELETE,
	MOVEI	T3,1		; SET THAT
	CAIN	T2,6		;IF CHANGE PROT,
	MOVEI	T3,0		; SET THAT
	MOVE	T1,T3		;SET RESULT
	POPJ	P,		;RETURN
>;END IFN FT$MTB
	SUBTTL	DIRECTORY LISTING - TMPCOR

;HERE WHEN DEVICE IS "TMP:" AND DOES NOT EXIST

TMDIR:	PUSHJ	P,.SAVE4##	;WANT SOME ACS
	TRO	F,R.WORD!R.NDSK	;SET WORD MODE AND NOT A DISK
	MOVEI	P1,20		;RANDOM DEFAULT TMPCOR DIRECTORY SIZE
	SOS	.CTFLS##	;BACK OFF WILD'S "FILES SEEN" FLAG
	SOS	.CTFLF##	;BACK OFF WILD'S "FILES FOUND" FLAG

;ALLOCATE A BUFFER INTO WHICH TO DUMP THE TMPCOR DIRECTORY

TMDIR1:	MOVE	T1,P1		;GET NEEDED TMPCOR DIRECTORY SIZE
	PUSHJ	P,GETCOR	;GET A BUFFER
	MOVE	P2,T1		;SAVE START ADDRESS (OLDE .JBFF)
	MOVN	T4,P1		;NEGATIVE LENGTH
	HRLZ	T4,T4		;IN THE LEFT HALF
	HRRI	T4,-1(P2)	;T4:=IOWD POINTER TO DIRECTORY BUFFER
	SETZ	T3,		;NO PARTICULAR NAME
	MOVE	T1,[.TCRRD,,T3]	;TMPCOR ARG POINTER TO
	TMPCOR	T1,		;READ TMPCOR DIRECTORY
	  JRST	E$$NTD		;ERROR IF NOT IMPLEMENTED
	JUMPE	T1,[MOVEI M,[ASCIZ\TMPCOR directory is empty
\]
		PUSHJ	P,LSTR		;TELL USER OF NO FILES
		MOVEM	P2,.JBFF	;DEALLOCATE THE DIRECTORY BUFFER
		JRST	.POPJ1##]	;RETURN HAPPILY
	CAMGE	T1,P1		;IS DIRECTORY BIGGER THAN THE BUFFER?
	JRST	TMDIR4		;NO, ALL SET
	MOVE	P1,T1		;YES, SET NEEDED DIRECTORY BUFFER SIZE
	MOVEM	P2,.JBFF	;BACK OFF .JBFF TO RECLAIM OLD DIRECTORY
	JRST	TMDIR1		;RE-READ DIRECTORY WITH LARGER BUFFER

TMDIR4:	MOVE	J,T4		;IOWD POINTER TO DIRECTORY BUFFER
	SETOM	NXFCNT		;NO FILES FOUND YET
	SETOM	.WXPRC##	;FORCE FULL FILE SPEC VERIFICATION
;RDH	MOVEI	M,[ASCIZ /TMPCOR directory
;RDH/]
;RDH	PUSHJ	P,LSTR		;OUTPUT HEADING
;RDH	MOVEI	M,[ASCIZ\Free: \]
;RDH	PUSHJ	P,LSTR		;PREFIX FREE COUNT
;RDH	MOVEI	T1,.TCRFS	;GET FREE COUNT
;RDH	TMPCOR	T1,		;FROM MONITOR
;RDH	  JRST	E$$NTD		;IF POSSIBLE
;RDH	PUSHJ	P,LDEC		;AND TELL USER
;RDH	PUSHJ	P,LCRLF		;THEN END LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

TMDLP:	AOBJP	J,TMDON		;SEE IF DONE
	SKIPN	T2,(J)		;SEE IF ENTRY NEXT
	JRST	TMDLP		;NO--LOOP BACK
	HLLZM	T2,FNAM		;SAVE NAME
	HRRZM	T2,FSIZ		;SAVE FILE LENGTH
	SETZM	FEXT		;CLEAR EXTENSION
	SETZM	UFDPPN		;CLEAR DIRECTORY
	AOS	.CTFLS##	;COUNT A FILE PRESENT
	AOS	.CTFLF##	;AND ASSUME IT MATCHES
	PUSHJ	P,.CHKTA##	;SEE IF IT MATCHES THE USER SPECIFICATION(S)
	 JRST	TMDLP		;FILE DOESN'T MATCH, LOOK FOR ANOTHER ONE

;COMPUTE CHECKSUM IF REQUESTED (WELL, WHY NOT?)

	SKIPG	S.CHK		;/CHECKSUM?
	JRST	TMDLP4		;NO
	MOVE	T1,FSIZ		;YES, GET WORD COUNT OF FILE
	PUSHJ	P,GETCOR	;GET AN "I/O" BUFFER FOR THE DATA FILE
	MOVE	P3,T1		;SAVE ADDRESS OF BUFFER (.JBFF)
	MOVN	T4,FSIZ		;NEGATIVE FILE LENGTH
	HRLZ	T4,T4		;IN THE LEFT HALF
	HRRI	T4,-1(P3)	;IOWD TO TMPCOR DATA FILE BUFFER
	HLLZ	T3,FNAM		;SET NAME OF THE TMPCOR FILE DESIRED
	MOVE	T2,[.TCRRF,,T3]	;TMPCOR ARG POINTER TO
	TMPCOR	T2,		;READ TMPCOR DATA FILE
	 JRST	E$$NTD		;ERROR??? SHOULDN'T HAPPEN
	HRLI	T1,(POINT 36,)	;CONCOCT A 36-BIT BYTE POINTER
	MOVEM	T1,BFHD+.BFPTR	;SET DATA RETRIEVER
	MOVE	T1,FSIZ		;GET "BYTE" COUNT
	MOVEM	T1,BFHD+.BFCTR	;SET DATA COUNT FIELD
	TLO	F,L.FKEF	;SET FAKE "EOF" AT END OF CURRENT BUFFER
	MOVEM	P3,.JBFF	;DEALLOCATE THE TMPCOR DATA FILE BUFFER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

TMDLP4:	SKIPLE	S.TMPC		;/TMPCOR SWITCH (OLD TMPCOR LISTING FORMAT)?
	JRST	TMDLP5		;YES
	SETOM	FFPRV		;FORCE BIZARRE PROTECTION
	PUSHJ	P,ANALYZ	;GO HANDLE A "DATA FILE" LISTING
	 JFCL			;HOHUM
	JRST	TMDLP		;BACK FOR MORE FILES

TMDLP5:	MOVEI	M,[ASCIZ /TMPCOR directory
/]				;GET HEADER LINE
	AOSG	NXFCNT		;IS THIS THE FIRST FILE?
	PUSHJ	P,LSTR		;YES, PREFIX THE LISTING OUTPUT
	SKIPLE	S.SUM		;SEE IF /SUM
	JRST	TMDLP6		;YES--SKIP OUTPUT
	MOVE	T2,FNAM		;GET NAME
	MOVEI	T3,4		;OUTPUT 4 CHARS
	PUSHJ	P,LSIXC		; (3 FOR NAME AND ONE SPACE)
TMDLP6:	MOVE	T1,FSIZ		;GET FILE LENGTH
	ADDM	T1,NOBLKS	;COUNT IN TOTAL BLOCKS (REALLY WORDS)
	SKIPLE	S.SUM		;SEE IF /SUM
	JRST	TMDLP		;YES--LOOP ON
	PUSHJ	P,LDEC4		;OUTPUT LENGTH
	SKIPG	S.CHK		;/CHECKSUM?
	JRST	TMDLP8		;NO
	PUSHJ	P,LSPC2		;YES, SPACE OVER
	SETZM	CHKSUM		;INITIALIZE CHECKSUM
	PUSHJ	P,NEXDCW	;CALCULATE
	PUSHJ	P,LCHECK	;AND LIST THE CHECKSUM TOO
TMDLP8:	PUSHJ	P,LCRLF		;END THE LINE
	JRST	TMDLP		;AND LOOP BACK

TMDON:	MOVEM	P2,.JBFF	;DEALLOCATE THE DIRECTORY BUFFER
	PUSHJ	P,DIRET		;OUTPUT ANY TOTAL AND/OR SUMMARY
	JRST	.POPJ1##	;RETURN HAPPILY


;ERRORS

	N$FAIL	(NTD,TMPCOR not supported in this monitor)
	SUBTTL	DIRECTORY LISTING - FIND FORMAT

FNDIR:

;NOW HANDLE /FNDDAT (IF ANY)

	SKIPN	F.BLK+.FXDEV	;DO WE HAVE A FILE SPEC (A LA /FNDDAT:FILE)?
	SKIPE	F.BLK+.FXNAM	; ( . . .)
	JRST	FNDIR1		;YES, USE IT
	SKIPN	F.BLK+.FXEXT	; ( . . .)
	SKIPE	F.BLK+.FXDIR	; ( . . .)
	JRST	FNDIR1		;YES, USE IT
	SETO	T2,		;NON-WILD MASK
	MOVSI	T1,'SYS'	;DEFAULT SCAN BLOCK - DEVICE SYS:
	DMOVEM	T1,F.BLK+.FXDEV	;SET IN FILE SPEC BLOCK
	MOVE	T1,['FNDDAT']	;DEFAULT FILENAME
	DMOVEM	T1,F.BLK+.FXNAM	;SET IN FILE SPEC BLOCK
	MOVE	T1,['FDF',,-1]	;DEFAULT EXTENSION (NO WILDCARDS)
	MOVEM	T1,F.BLK+.FXEXT	;SET IN FILE SPEC BLOCK

FNDIR1:	SETO	T2,		;FULL NON-WILD MASK
	MOVSI	T1,'DSK'	;DEFAULT DEVICE
	SKIPN	F.BLK+.FXDEV	;USER GIVE A DEVICE?
	DMOVEM	T1,F.BLK+.FXDEV	;NO, HE HAS ONE NOW
	MOVE	T1,['FNDDAT']	;DEFAULT NAME
	SKIPN	F.BLK+.FXNAM	;USER GIVE A FILE NAME?
	DMOVEM	T1,F.BLK+.FXNAM	;NO, HE HAS ONE NOW
	HRLOI	T1,'FDF'	;DEFAULT EXTENSION
	SKIPN	F.BLK+.FXEXT	;USER SUPPLY AN EXTENSION?
	MOVEM	T2,F.BLK+.FXEXT	;NO, USE OUR DEFAULT
				;WE UNCONDITIONALLY OVER-RIDE THE EXTENSION
				;ANYWAY, BUT IF USER TYPES .* WE STILL WANT
				;TO ISSUE ERROR MESSAGE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

FNDIR4:	MOVE	T1,[6,,[VERWRD		;PROTOCOL VERSION
		I.NXRD,,I.NXZR		;POINTER TO FIRST,,LAST FSB
		FOBLK+.FOIOS,,LBLOCK	;OPEN,,LOOKUP BLOCK ADDRESS
		.FXLEN,,LN$RIB+1	;LENGTH OF FSB,,LOOKUP
		FW.IFX + I		;IMMEDIATE FILE EXIT
		WLDEOD ]]		;END OF DIRECTORY
	PUSHJ	P,.LKWLD##	;SETUP WILD (.CHKTA) PARAMETERS
	 AOJA	T1,FNDIR5	;EXPECTED RETURN
	N$FAIL (LFS,LKWLD skip-returned to FNDIR - internal error)

FNDIR5:	JUMPE	T1,FNDIR8	;IF T1 = -1 THEN ALL DONE
	AOJE	T1,FNDIR6	;IF T1 = -2 THEN WE HAVE FILES TO DO
	N$FAIL	(LFU,LKWLD returned unknown reason to FNDIR - internal error)

FNDIR6:	MOVE	P4,T2		;POSITION ADDRESS OF RETURNED MATCHING FSB
	SOS	.CTFLS##	;BACKOFF WILD'S "FILES SEEN" FLAG
	SOS	.CTFLF##	;BACKOFF WILD'S "FILES FOUND" FLAG
	PUSHJ	P,FNDIN		;INITIALIZE INPUT FIND FILES
	SETZ	J,		;START AT THE BEGINING
	PUSHJ	P,FNLOP		;LOOK FOR FILES THAT MATCH
	JRST	FNDIR4		;BACK FOR MORE FILE SPECS

;HERE WHEN ALL DONE

FNDIR8:	PUSH	P,[-1]		;SETUP STACK FOR DIRED/DIRDON
	JRST	DIREDF		;HANDLE ANY END OF DIRECTORY STUFF
;LOOP OVER POINTER FILE LOOKING FOR A FILENAME/TYPE MATCH (WITHOUT WHICH
;WE KNOW IT IS USELESS TO CALL .CHKTA).
;
;CALL WITH P4 CONTAINING THE ADDRESS OF THE "MASTER" FILE SPEC BLOCK TO
;BE USED FOR POTENTIAL FILE MATCHES

FNLOP:	PUSHJ	P,PFGET		;WORD 00 - FILENAME
	MOVE	P1,T1		;SAVE IT FOR LOOP
	PUSHJ	P,PFGET		;WORD 01 - FILETYPE
	HLLZ	P2,T1		;SAVE IT FOR LOOP
	TLZE	F,L.FEOF	;REACHED END OF FILE ANYWHERE?
	POPJ	P,		;YES, CAN DO NO MORE HERE
	AOS	.CTFLS##	;NOTE A FILE HAS BEEN SEEN

;NOW SEE IF THE CURRENT FILE HAS ANY CHANCE OF MATCHING

FNLOP6:	XOR	P1,.FXNAM(P4)	;GET DIFFERENCE IN NAME
	XOR	P2,.FXEXT(P4)	;AND TYPE FIELDS
	TDNN	P1,.FXNMM(P4)	;FILE NAME DIFFER IN NON-WILD BITS?
	TLNE	P2,(P2)		;FILE TYPE DIFFER IN NON-WILD BITS?
	AOJA	J,FNLOP		;YES, CAN'T POSSIBLY MATCH

;FILENAME AND TYPE MIGHT MATCH, MUST CALL .CHKTA TO VERIFY TIMES ETC.

	PUSHJ	P,FNDOR		;GO DO THE GRUNDGE WORK
	 JFCL			;HOHUM
	AOJA	J,FNLOP		;LOOK FOR MORE FILES
;SETUP ONE FILE BLOCK FROM THE FIND DATA FILE INPUT

FNDOR:	MOVE	T1,J		;ENTRY NUMBER IN DATA FILES
	IMULI	T1,20		;DATA FILE IS 16 DECIMAL WORDS PER ENTRY
	IDIVI	T1,200		;DSK BLOCK IS 128 DECIMAL WORDS PER UUO
	CAME	T1,DGBLK	;HAVE WE ALREADY USETI'ED HERE?
	JRST	FNDOR1		;NO, NEED AN IN UUO
	SUB	T2,DGWRD	;YES, SEE HOW MUCH FURTHER INTO BLOCK
	JRST	FNDOR2		;AND POSITION THERE

FNDOR1:	USETI	DG,1(T1)	;POSITION MONITOR FOR NEXT IN
	SUBI	T1,1		;(DFGET WILL AOS ON THE FORCED IN)
	MOVEM	T1,DGBLK	;REMEMBER WHERE WE ARE IN DATA FILE
	SETZM	DGWRD		;START OF A NEW BLOCK
	SETZM	B.DG+.BFCTR	;MAKE SURE WE DO AN IN UUO
	PUSHJ	P,DFGET		;GET A WORD (FORCE IN UUO, REPLETE WITH ERROR
				; HANDLING AND ALL THOSE NICETIES)
	JUMPE	T2,FNDOR4	;IF POSITIONED, ENTER FILE READING CODE
	SUBI	T2,1		;ALLOW FOR WORD JUST READ
FNDOR2:	ADDM	T2,DGWRD	;POSITION WITHIN BLOCK
	ADDM	T2,B.DG+.BFPTR	;POINT TO PROPER WORD WITHIN DATA BLOCK
	MOVN	T2,T2		;(NO SUB TO MEMORY)
	ADDM	T2,B.DG+.BFCTR	;ADVANCE COUNTER ACCORDINGLY

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;EXTRACT AND BUILD A FILE BLOCK FROM THE DATA FILE

	PUSHJ	P,DFGET		;WORD 00 - IGNORED (NODE NAME, RESERVED)
FNDOR4:	PUSHJ	P,DFGET		;WORD 01 - DEVICE/STRUCTURE
	MOVEM	T1,FOBLK+.FODEV	;SET FOR ANALYZ
	MOVEI	T4,F.PTH	;PATH BLOCK
	MOVEM	T4,UFDPPN	;SET FOR ANALYZ
	HRLI	T4,-6		;SET TO BUILD DIRECTORY, FIVE SFD'S
				; (.FXLND NOTWITHSTANDING)
FNDOR6:	PUSHJ	P,DFGET		;WORD 02/07 - DIRECTORY
	MOVEM	T1,.PTPPN(T4)	;STORE AWAY IN PATH BLOCK
	AOBJN	T4,FNDOR6	;LOOP FOR UFD AND FIVE SFD'S
	PUSHJ	P,DFGET		;WORD 10 - FILE NAME
	MOVEM	T1,FNAM		;STORE FOR ANALYZ
	PUSHJ	P,DFGET		;WORD 11 - EXTENSION,,PROTECTION
	HLLZM	T1,FEXT		;STORE EXTENSION FOR ANALYZ
	HRLZM	T1,FPRV		;SET PROTECTION AND I/O MODE FOR ANALZY
	PUSHJ	P,DFGET		;WORD 12 - FILE LENGTH
	MOVEM	T1,FSIZ		;SET IN FILE BLOCK
	PUSHJ	P,DFGET		;WORD 13 - CREATION DATE/TIME
	PUSHJ	P,.CNTDT##	;SPLIT IT UP INTO DATE AND TIME
	DPB	T2,[POINTR FCRE,RB.CRD]  ;STORE MOST OF CREATION DATE
	LDB	T2,[POINT 3,T2,23]  ;POSITION AND
	DPB	T2,[POINTR FCRX,RB.CRX]  ;STORE REST OF CREATION DATE
	IDIVI	T1,^D60*^D1000	;CONVERT MILLISECONDS TO MINUTES
	DPB	T1,[POINTR FCRE,RB.CRT] ;STORE CREATION TIME
	PUSHJ	P,DFGET		;WORD 14 - ACCESS DATE/TIME
	PUSHJ	P,.CNTDT##	;CONVERT TO DATE AND TIME
	DPB	T2,[POINTR FACD,RB.ACD]  ;STORE ACCESS DATE
				; (NO ACCESS TIME AVAILABLE)
	PUSHJ	P,DFGET		;WORD 15 - VERSION
	MOVEM	T1,FVER		;STORE IN FILE BLOCK
	PUSHJ	P,DFGET		;WORD 16 - IGNORED
	PUSHJ	P,DFGET		;WORD 17 - CHECKSUM
	MOVEM	T1,CHKSUM	;STORE FOR ANALYZ

	AOS	.CTFLF##	;ASSUME FILE IS FOUND (.CHKTA WILL DECREMENT
				; THIS IF IT REJECTS THE FILE)
	PUSHJ	P,.CHKTA##	;SEE IF THIS FILE MATCHES
	 POPJ	P,		;NO - FILE REJECTED
	PUSHJ	P,ANALYZ	;PRINT DIRECTORY LISTING
	 JFCL			;HOHUM
	JRST	.POPJ1##	;FILE PRINTED
	SUBTTL	ROUTINE FOR DISK AND MAGTAPE DIRECTORY LINE

;SUBROUTINE TO ANALYZE AND PRINT FROM AN EXTENDED LOOKUP
;BLOCK AND READ THE FILE IF NECESSARY
;	SKIPS IF MATCHES, NON-SKIP IF TOO OLD OR TOO YOUNG

ANALYZ:	AOS	(P)		;WIN--GIVE OK RETURN
	PUSHJ	P,.SAVE1	;SAVE P1
	MOVEI	P1,0		;NO SPECIAL OFFSET
	SKIPLE	S.FIND		;/FIND?
	JRST	GOTSTR		;YES, ALREADY HAVE CHECKSUM AND STRUCTURE
	SETZM	CHKSUM		;CLEAR CHECKSUM ACCUMULATOR
	SKIPLE	S.FBLD		;/FNDBLD?
	JRST	GOTSTR		;YES, SKIP THIS JUNK THEN
	SKIPLE	S.UNIT		;SEE IF USER REQUESTED UNITS
	SKIPN	T1,FDEV		;YES--SEE IF FILSER TOLD US
	JRST	GOTSTR		;NO--DON'T CHANGE
	SKIPN	S.UNIT		;YES--SEE IF /NOUNITS
	SKIPE	.WLDFL##	;AND NO STR WILDCARD
	JRST	NEWSTR		;NO--OK
	MOVEM	T1,DCHBLK	;YES--SETUP FOR DSKCHR
	SETZM	DCHBLK+.DCSNM	;CLEAR ANSWER
	MOVE	T1,[.DCSNM+1,,DCHBLK] ;POINT TO BLOCK
	DSKCHR	T1,		;ASK MONITOR STR NAME
	  JRST	GOTSTR		;NICE TRY
	SKIPE	T1,DCHBLK+.DCSNM;GET STR NAME
NEWSTR:	MOVEM	T1,FSTR		;YES--UPDATE INFO TO PRINT
GOTSTR:	PUSHJ	P,SSTRDR	;SET STATUS AND TYPE SUMMARY
	AOS	SNFILF		;COUNT FILE FOUND
	SKIPG	S.SUM		;SEE IF /SUM
	TRNN	F,R.FAST	;NO SEE IF /F
	JRST	GETLEN		;NO--ANALYZE
	SKIPLE	S.FIND		;/FIND?
	JRST	GETLEN		;YES, SETUP LENGTHS
	SKIPGE	S.ACCS		;ACCESS REQUIRED?
	JRST	VERNON		;NO--NO ANALYSIS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

GETLEN:	MOVE	T1,FSIZ		;GET LENGTH
	SKIPE	FALC		;SEE IF FILE ALLOCATED
	SKIPG	S.ALC		;YES--SEE IF USER PREFERS THAT
	JRST	NOTALC		;NO--USE COMPUTED LENGTH
	MOVE	T1,FALC		;YES--PICK UP ALLOCATED LENGTH
	ASH	T1,7		;CONVERT TO WORD COUNT
NOTALC:	SKIPG	S.DTL		;IF /DETAIL, DON'T CLOBBER INFO
	MOVEM	T1,FSIZ		;STORE AWAY FOR PRINTING
	MOVE	T2,T1		;SAVE WORD COUNT
	ADDI	T1,177		;AND GENERATE THE
	LSH	T1,-7		;CORRESPONDING BLOCK COUNT
	SKIPG	S.SUM		;SEE IF /SUM
	TRNN	F,R.FAST	;IF NOT, DON'T ACCUMULATE IF /F
	CAIA			;ACCUMULATE TOTALS
	JRST	NOTAL2		;DON'T ACCUMULATE TOTALS
	ADDM	T1,SNBLKS	;ACCUMULATE BLOCK COUNT
	ADDM	T2,SNWRDS	;AS WELL AS WORD COUNT
NOTAL2:	SKIPLE	S.FIND		;/FIND?
	JRST	FILEND		;YES, NO /ACCESS, ALREADY HAVE VERSION
	CAMG	T1,S.ACCS	;SEE IF SHORT ENOUGH TO ACCESS
	TRO	F,R.ACCS	;YES--SET FLAG
	SKIPG	S.FBLD		;/FNDBLD?
	TRNN	F,R.FAST	;In fast mode?
	JRST	VERGET		;No, go ahead and grunge
	SKIPG	S.SUM		;Summing?
	JRST	VERNON		;No, avoid all this work

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

VERGET:	SETZM	FRVER		;CLEAR RIB VERSION FOR /DET
	SKIPE	T1,FVER		;SEE IF FILE HAS A VERSION ALREADY
	SKIPLE	S.DTL		;YES--SEE IF /DETAIL
	JRST	.+2		;NO VERSION OR /DET
	JRST	VERNON		;YES--SKIP READING
	MOVEM	T1,FRVER	;SAVE RIB VERSION FOR /DETAIL
	HLRZ	T1,FEXT		;SEE IF VERSION SEARCH USEFUL
	CAIN	T1,'EXE'	;
	JRST	VEREXE 		;YES--HANDLE .EXE
	CAIE	T1,'HGH'
	CAIN	T1,'SHR'
	JRST	VERHGH		;YES--HIGH SEGMENT VARIETY
	CAIE	T1,'SAV'
	CAIN	T1,'LOW'
	JRST	VERLOW		;YES--LOW SEGMENT VARIETY
	CAIE	T1,'SVE'
	JRST	VERNON		;NO--FORGET THE IDEA

VERLOW:	PUSHJ	P,NEXDTW	;GET NEXT IOWD POINTER
	  JRST	VERNOF		;GIVE UP IF EOF
	JUMPE	T1,VERNOF	;GIVE UP IF JUNK
	SKIPA	T2,T1		;SAVE IT
VERLO1:	AOBJP	T2,VERLOW	;IF ALL USED UP, LOOP BACK FOR ANOTHER
	PUSHJ	P,NEXDTW	;GET A DATA WORD
	  JRST	VERNOF		;GIVE UP IF EOF
	HRRZ	T3,T2		;LOOK AT CURRENT ADDRESS
	CAIGE	T3,.JBVER-1	;  (NOTE-T3 IS ADDR-1)
	JRST	VERLO1		;NOT THERE YET SO LOOP BACK FOR MORE
	CAIN	T3,.JBVER-1	;MAKE SURE NOT TOO FAR
	JRST	VERGOT		;A WINNER--GO SAVE IT
	JRST	VERNON		;AND PROCEED

VERHGH:	MOVEI	T2,.JBHVR	;GUESS HOW FAR TO READ
VERHG1:	PUSHJ	P,NEXDTW	;GET NEXT WORD
	  JRST	VERNOF		;GIVE UP IF EOF
	SOJGE	T2,VERHG1	;COUNT AND LOOP UNTIL THERE
	JRST	VERGOT		;GO FINISH WITH RESULT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

VEREXE:	MOVEI	T3,0		;CLEAR PROGRESS COUNT
VERE.1:	PUSHJ	P,NEXDTW	;GET BLOCK TYPE OF HEADER
	  JRST	VERNOF		;NONE IF EOF
	JUMPE	T1,VERNON	;IF BLOCK HEADER=0, SKIP READING FURTHER
	AOS	T3		;COUNT WORD
	HLRZ	T2,T1		;GET BLOCK TYPE
	CAIN	T2,1776		;SEE IF EXE DIRECTORY
	JRST	VERE.3		;YES--GO LOOKUP PAGE 0
	CAIL	T2,1776		;IF NOT VALID TYPE,
	JRST	VERNON		; EXIT WITHOUT VERSION
	HRRZ	T2,T1		;OK--GET BLOCK SIZE
VERE.2:	SOJLE	T1,VERE.1	;(ALLOW FOR FIRST WORD)
	PUSHJ	P,NEXDTW	;SKIP THIS BLOCK
	  JRST	VERNOF		;GIVE UP IF EOF
	AOS	T3		;COUNT PROGRESS
	JRST	VERE.2		;LOOP
VERE.3:	HRRZ	T4,T1		;DIRECTORY--GET SIZE
	LSH	T4,-1		;GET COUNT OF BIWORDS
VERE.4:	SOJL	T4,VERNON	;GIVE UP IF NOT IN DIRECTORY
	PUSHJ	P,NEXDTW	;GET FIRST WORD OF PAIR
	  JRST	VERNOF		;GIVE UP IF END
	MOVE	T2,T1		;SAVE FOR A MINUTE
	PUSHJ	P,NEXDTW	;GET SECOND WORD OF PAIR
	  JRST	VERNOF		;GIVE UP
	ADDI	T3,2		;COUNT PROGRESS
	TRNE	T1,-1		;SEE IF PAGE 0
	JRST	VERE.4		;NO--LOOP OVER DIRECTORY
	HRRZ	T4,T2		;GET POSITION IN FILE
	LSH	T4,^D9		;CONVERT TO WORDS
	SUB	T4,T3		;ALLOW FOR CURRENT POSITION
	JUMPLE	T4,VERNON	;ERROR IF BEHIND US
	ADDI	T4,.JBVER	;SET TO VERSION LOCATION
VERE.5:	PUSHJ	P,NEXDTW	;ADVANCE TO WORD
	  JRST	VERNOF		;GIVE UP IF END
	SOJGE	T4,VERE.5	;(@ VERE.5 + 2L) READ TO .JBVER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

VERGOT:	SKIPE	T1		;SEE IF WE GOT SOMETHING
	MOVEM	T1,FVER		;GOT IT! SO SAVE IT
VERNON:	SKIPG	S.CHK		;CHECKSUM NEEDED?
	JRST	VERNOA		;NO, CHECK FOR /ACCESS

VERCHK:	PUSHJ	P,NEXDCW	;YES - READ REST OF BLOCK
	  JRST	VERNOF		;[464] DONE IF EOF
	JRST	VERCHK		;KEEP GOING TO EOF

VERNOA:	TRNE	F,R.ACCS	;/ACCESS?
	PUSHJ	P,NEXDTW	;YES, MUST READ FILE THEN
	 JFCL			;(ONE IN UUO IS SUFFICIENT)

VERNOF:	TLNN	F,L.SVST!L.BKSS!L.FRSS  ;[464] SEE IF MAG TAPE
	JRST	FILCLS		;[464] NO, CLOSE OFF DATA FILE THEN
VERNOM:	PUSHJ	P,NEXDTW	;[464] READ A FILE DATA WORD
	 JRST	FILEND		;[464] AT EOF, TIME TO LIST FILE
	SETZM	BFHD+.BFCTR	;[464] TOSS REST OF RECORD
	JRST	VERNOM		;[464] GO 'TILL EOF

FILCLS:	TRZN	F,R.ACCS	;SEE IF ACCESS NEEDED
	JRST	FILNOA		;NO--CLOSE WITHOUT IT
	CLOSE	DC,CL.DAT	;CLOSE AND INDICATE ACCESSED
	JRST	FLIST		;AND CONTINUE BELOW
FILNOA:	CLOSE	DC,CL.ACS!CL.DAT;DON'T UPDATE ACCESS DATES
FILEND:

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN IT IS TIME TO OUTPUT ONE LINE OF THE DIRECTORY

FLIST:	SKIPLE	S.FBLD		;/FNDBLD?
	PUSHJ	P,DOFND		;WRITE FILE INTO FIND FILES
	SKIPN	S.DIRE		;/NODIRECT?
	POPJ	P,		;YES, DONE WITH THIS FILE
	TRNN	F,R.NDSK	;IF NOT A DISK (E.G., DECTAPE)
	SKIPG	S.DTL		;A DISK, /DETAIL?
	CAIA			;NOT A DISK, OR NOT /DETAIL
	JRST	DLIST		;DISK/DETAIL, GO ISSUE DETAILED LISTING
	SKIPLE	S.SUM		;SEE IF SUMMARY MODE
	TRNE	F,R.FAST	;YES--CHECK /F
	JRST	.+2		;YES--GIVE OUTPUT
	POPJ	P,		;NO--SKIP LISTING
	TLZN	F,L.SBTT	;DID WE JUST OUTPUT TOTALS LINE?
	JRST	FLIST2		;NO
	TLZ	F,L.CRLF	;YES WE DID
	PUSHJ	P,LCRLF		;SO GIVE A BLANK LINE FOR NEATNESS
FLIST2:	SKIPLE	S.IND		;[443] /INDIRECT ?
	JRST	FLNAM		;NO SKIP WIDTH TEST
	MOVE	T1,NOCHRS	;GET NUMBER OF CHARACTERS ON THE LINE
	ADDI	T1,7		;ADD A POSSIBLE TAB.
	TRZ	T1,7		;AND ROUND IT OFF
	ADD	T1,S.LENT	;ADD THE LENGTH OF AN ENTRY.
	TRNE	F,R.FAST	;[476] /FAST MODE?
	JRST	FLIST5		;[476] YES, VERSION AND SPOOL NEVER PRINT
	SKIPE	S.PRVE		;[443] PRINTING VERSIONS???
	SKIPN	FVER		;[443] YES, PRINT VERSIONS, BUT IS THERE ANY
	SKIPA			;[443] NO, NO VERSIONS & THERE IS NONE
	ADDI	T1,^D16		;[443] YES, THERE ARE VERSIONS, SO PRINT THEM
	SKIPE	FSPL		;[443] ANY SPOOLED NAMES????
	ADDI	T1,^D10		;[443] YES THERE IS, SO ALLOW 10(dec) FOR IT
FLIST5:	CAMLE	T1,S.WDTH	;[476] IF LESS THAN THEN WE CAN GO AHEAD
	PUSHJ	P,LCRLF		;ELSE PRINT THE LINE UP TO NOW.
FLNAM:	PUSHJ	P,LSTFNM	;LIST FILE NAME
	PUSHJ	P,LTBEXT	;SPACE OVER
FLEXT:	HLLZ	T2,FEXT		;OUTPUT EXTENSION
	SKIPG	S.IND		;/INDIRECT SPECIFIED?
	JRST	FLEXT2		;NO, NORMAL DIRECTORY LISTING
	PUSHJ	P,LSIXN		;YES, LIST EXTENSION, NO BLANKS
	JRST	FLSDIR		;AND GO DIRECTLY TO DIRECTORY OUTPUT
FLEXT2:	TRNN	F,R.FAST	;SEE IF /F MODE
	JRST	FLEXT3		;NO--GO DO SLOW FORMAT
	MOVEI	T3,3		;IN CASE DOING /SORT
	PUSHJ	P,LSIXC		;LIST IN 3 COLUMNS
	SKIPLE	S.CHK		;SEE IF /CHECKSUM
	PUSHJ	P,LSPC2		;YES--SPACE OVER TO IT
	JRST	FLCHEK		;AND END LINE
FLEXT3:	CAMN	T2,['UFD   ']	;SEE IF .UFD
	SKIPGE	FNAM		;AND NUMERIC
	JRST	FLEXT4		;NO--PROCEED
	MOVE	T1,FSIZ		;YES--SKIP EXT
	ADDI	T1,177		;ROUND UP TO BLOCK BOUNDRY
	LSH	T1,-7		;AND TRUNCATE TO BLOCK SIZE
	PUSHJ	P,LDEC4		;LIST LENGTH
	JRST	FLEXT8		;AND PROCEED

FLEXT4:	MOVEI	T3,3		;AS THREE CHARACTERS
	PUSHJ	P,LSIXC
	PUSHJ	P,LSPC		;POSITION FOR LENGTH
	MOVE	T1,FSIZ		;GET FILE LENGTH
	TRNE	F,R.WORD	;/WORDS?
	JRST	FLEXT7		;YES - PRINT DIRECTLY
	ADDI	T1,177		;NO - ROUND UP TO NEXT BLOCK
	LSH	T1,-7		;CONVERT TO BLOCKS
	PUSHJ	P,LDEC5		;SPACE 5 PLACES ONLY
	JRST	FLEXT8		;CONTINUE

FLEXT7:	PUSHJ	P,LDEC9		;DO THE SPACING TO 9 PLACES
				;AND FALL INTO FLEXT8

FLEXT8:	MOVEI	M,[ASCIZ /  </]
	PUSHJ	P,LSTR
	SKIPN	T1,FFPRV	;SEE IF FORCED KNOWN PRIV
	LDB	T1,[POINTR (FPRV,RB.PRV)]
	JUMPL	T1,[MOVEI M,[ASCIZ /***/]
		    PUSHJ P,LSTR;LIST "UNKNOWN"
		    JRST  .+2]	;AND PROCEED
	PUSHJ	P,LOCT3Z
	MOVEI	M,[ASCIZ />   /]
	PUSHJ	P,LSTR
FLCHEK:	SKIPG	S.CHK		;SEE IF CHECKSUM
	JRST	FCHKN		;NO--SKIP OUTPUT
	PUSHJ	P,LCHECK	;LIST CHECKSUM
	PUSHJ	P,LSPC2		;AND SPACE OVER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

FCHKN:	TRNN	F,R.SLOW	;SEE IF IN SLOW MODE
	JRST	FCRED		;NO--SKIP ACCESS DATE
	LDB	T4,[POINTR (FACD,RB.ACD)]	;
	PUSHJ	P,LDATE		;OUTPUT ACCESS DATE
	PUSHJ	P,LTAB
	LDB	T4,[POINTR (FCRE,RB.CRT)]	;
	PUSHJ	P,LTIMEB	;OUTPUT CREATION TIME
	PUSHJ	P,LTAB
FCRED:	TRNE	F,R.FAST	;SEE IF /FAST
	JRST	FLSDIR		;YES--SKIP ON
	LDB	T4,[POINTR (FCRE,RB.CRD)]	;
	LDB	T3,[POINTR (FCRX,RB.CRX)]	;GET EXTENSION
	DPB	T3,[POINT 3,T4,23]	;ADD INTO RESULT
	PUSHJ	P,LDATE		;OUTPUT CREATION DATE
	TRNN	F,R.SLOW	;SEE IF IN SLOW MODE
	JRST	FLVER		;NO--SKIP FILE MODE
	PUSHJ	P,LSPC2
	LDB	T1,[POINTR (FMOD,RB.MOD)]	;
	PUSHJ	P,LOCT2		;OUTPUT FILE MODE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

FLVER:	SKIPN	S.PRVE		;/NOPRVERSION?
	JRST	FLACCT		;YES, SKIP ONWARDS
	MOVE	T4,FVER		;OUTPUT FILE VERSION
	TLNN	F,L.FRMT	;FORCE OUTPUT IF FORMATTING
	SKIPLE	S.PRVE		;OR IF /PRVERSION
	JRST	FLVER2		;(ONE OF THE ABOVE)
	JUMPN	T4,FLVER2	;IF NON-ZERO VERSION THEN PRINT IT
	TRNN	F,R.SLOW	;IF SLOW (LONG) PRINTING
	SKIPLE	S.FIND		;OR IF /FIND OUTPUT
	PUSHJ	P,LTAB		;PRESERVE COLUMN-NESS OF OUTPUT
	JRST	FLACCT		;GO CHECK ACCOUNT STRING
FLVER2:	PUSHJ	P,LTAB
	MOVE	P1,NOCHRS	;GET POSITION
	ADDI	P1,7		;ALLOW FOR DELAYED TABBING
	TRZ	P1,7		;TAB OVER
	MOVNS	P1		;PREPARE TO SUBTRACT
	PUSHJ	P,LVER
	ADD	P1,NOCHRS	;GET DISTANCE MOVED BY VERSION
	TLNN	F,L.FRMT	;IF NICE OUTPUT FORMAT
	SKIPLE	S.PRVE		;OR IF /PRVERSION
	SKIPA			;(ONE OF THE ABOVE)
	JRST	FLACCT		;NO - SKIP FORMATTING STUFF
	CAIG	P1,7		;AND LESS THAN ONE TAB
	PUSHJ	P,LTAB		;YES--MOVE ANOTHER TAB
	SKIPG 	S.SORT		;/SORT'ING ?
	 JRST	FLS335		;[446] NO - GO AFFECT TAB PLACEMENT
FLS446:	PUSHJ	P,LSPC		;[446] MOVE (AT LEAST) ONE SPACE
	MOVE 	P1,NOCHRS	;[446] GET COLUMN COUNT
	TRC	P1,7		;[446] WE ONLY CARE ABOUT CHARS AFTER LAST TAB
	TRNE	P1,7		;[446] IS IT 7?
	 JRST	FLS446		;[446] NO - GO PLACE ANOTHER SPACE
	JRST	FLACCT		;YES - MOVE ON

FLS335:	PUSHJ	P,LSPC		;MOVE (AT LEAST) ONE SPACE
	MOVE	P1,NOCHRS	;GET COLUMN (CHARACTER) COUNT
	TRNE	P1,4		;1.5 TAB COLUMNS YET?
	 JRST	FL335A		;YES - NO MORE SPACING
	TRNE	P1,3		;1.5 TAB COLUMNS OVER?????
	 JRST	FLS335		;NOT YET - KEEP SPACING
FL335A:	TRO	F,R.STAB	;AND FLAG SUPPRESS NEXT TAB
				;AS ALREADY PROPERLY POSITIONED.

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

FLACCT:	SKIPG	S.ACCT		;SEE IF /ACCOUNT
	JRST	FNVER		;NO
	PUSHJ	P,LTAB		;POSITION
	MOVEI	M,FACT
	PUSHJ	P,LSTR
	TLNN	F,L.FRMT	;ARE WE FORMATTING OUTPUT?
	JRST	FNVER		;NO
	MOVEI	P1,^D103	;BRING OUT TO COLUMN 103
FLACC1:	CAMG	P1,NOCHRS	;[445] ARE WE THERE YET?
	JRST	FNVER
	PUSHJ	P,LSPC
	JRST	FLACC1
FNVER:	SKIPG	S.AUT		;SEE IF /AUTHOR
	JRST	FLSDIR		;NO--JUST GO DO DIRECTORY
	SKIPE	T2,UFDPPN	;GET FILE'S OWNER
	TLNE	T2,-1		;SEE IF SFD
	SKIPA			;NO
	MOVE	T2,.PTPPN(T2)	;YES--GET OWNER
	SKIPE	T1,FAUT		;SEE IF AUTHOR
	XOR	T1,T2		;YES--COMPARE TO OWNER
	TLNN	F,L.FRMT	;SEE IF NICE OUTPUT FORMAT
	JUMPE	T1,FLSDIR	;NO--SEE IF SAME AS OWNER
	PUSHJ	P,LTAB		;TAB OVER
	PUSHJ	P,LAUT		;YES--GO LIST AUTHOR
FLSDIR:	TRZ	F,R.STAB	;ONLY SUPRESS TAB IF IN AUTHOR
	SKIPN	S.SORT		;UNLESS /SORT
	SKIPLE	S.FLSD		;FIRST-LINE STR/DIR LISTING?
	PUSHJ	P,LSTRDR	;YES - OUTPUT STR AND DIRECT.
	TRNN	F,R.FAST	;SEE IF /F
	SKIPN	T2,FSPL		;NO--SEE IF SPOOLED NAME
	JRST	FDONE		;NO--SKIP OUTPUT
	PUSHJ	P,LTAB		;YES--SPACE OVER
	PUSHJ	P,LSIXN		;AND TYPE SPOOLED NAME
FDONE:	MOVE	T1,NOCHRS	;SEE IF DONE WITH THIS LINE
	CAMG	T1,MXWDTH	;SEE IF OVER REQUEST
	PJRST	LTAB		;NO--GO ISSUE TAB
	PJRST	LCRLF

;ROUTINE TO ISSUE DOT OR SPACE BEFORE EXTENSION

LTBEXT:	TRNE	F,R.FAST	;SEE IF /F
	SKIPE	S.WDTH		;YES--SEE IF NOT /WIDTH
	PJRST	LTAB		;NO--ISSUE TAB
	SKIPE	S.SORT		;SEE IF /SORT
	PJRST	LTAB		;YES, THEN NO .
LDOT:	MOVEI	C,"."		;[464] YES--USE DOT (IT'S FASTER)
	PJRST	LCHR		; AND RETURN
;HERE TO OUTPUT A DETAILED DIRECTORY LISTING

	DEFINE	MSG(A),<
	MOVEI	M,[ASCIZ \
A: \]
	PUSHJ	P,LSTR
	>

	DEFINE	MSGT(A),<
	MOVEI	M,[ASCIZ \
A\]
	PUSHJ	P,LSTR
	>

DLIST:	PUSHJ	P,.SAVE4##	;SAVE ALL JUST IN CASE
	TLZN	F,L.SBTT	;DID WE JUST ISSUE SUBTOTALS LINE?
	JRST	DLIST2		;NO
	TLZ	F,L.CRLF	;YES WE DID
	PUSHJ	P,LCRLF		;SO GIVE A BLANK LINE FOR NEATNESS
DLIST2:	SKIPE	T2,FDEV		;GET UNIT
	SKIPN	S.UNIT		;IF /NOUNITS
	SKIPE	T2,FSTR		;  OR IF UNIT NOT AVAILABLE, USE STR
	PUSHJ	P,LSIXCL	;LIST IN SIXBIT WITH COLON
	HLRZ	T1,FEXT		;GET EXTENSION
	CAIN	T1,'UFD'	;SEE IF UFD
	SKIPGE	T4,FNAM		;AND NOT ALPHA
	JRST	DLNAME		;NO--LIST AS ALPHA
	PUSHJ	P,LXWD		;LIST AS XWD
	JRST	DLEXT		;GO HANDLE EXTENSION
DLNAME:	MOVE	T2,FNAM		;GET NAME
	PUSHJ	P,LSIXN		;LIST IN SIXBIT
DLEXT:	MOVEI	C,"."		;LIST
	PUSHJ	P,LCHR		;PUNCTUATION
	HLLZ	T2,FEXT		;GET EXTENSION
	PUSHJ	P,LSIXN		;LIST IT
	MOVEI	P1,0		;CLEAR OFFSET POINTER
	PUSHJ	P,FLBDIR	;LIST DIRECTORY WITH []

	HRRZ	T4,FACD		;GET ACCESS DATE
	ANDX	T4,RB.ACD	;MASK DOWN
	JUMPE	T4,DLCREA
	MSG	<Access date>
	PUSHJ	P,LDATE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLCREA:	MOVE	T4,FCRE		;GET CREATION
	ANDX	T4,RB.CRD!RB.CRT; TIME AND DATE
	ROT	T4,-<WID(RB.CRD)>  ;DATE AT HIGH END
	LDB	T3,[POINTR (FCRX,RB.CRX)]	; GET DATE EXTENSION
	LSHC	T3,WID(RB.CRD)	;GET DATE TOGETHER
	SKIPN	T3		;
	JUMPE	T4,DLPROT
	MSG	<Creation time, date>
	PUSH	P,T3		;SAVE DATE
	LSH	T4,-<WID(RB.CRD)>  ;POSITION TIME
	PUSHJ	P,LTIME
	PUSHJ	P,LSPC		;MAKE SOME ROOM
	POP	P,T4		;RESTORE DATE
	PUSHJ	P,LDATE
DLPROT:	SKIPN	T1,FFPRV	;SEE IF FORCING
	LDB	T1,[POINTR (FPRV,RB.PRV)]
	JUMPL	T1,DLMODE	;SKIP IF NO PROTECTION
	MSG	<Access protection>
	PUSHJ	P,LOCT3Z
DLMODE:	MSG	<Mode>
	LDB	T1,[POINTR (FMOD,RB.MOD)]
	PUSHJ	P,LOCT
	MOVE	T1,FSTS		;RETRIEVE .RBSTS FLAGS
	TXNN	T1,RP.DIR	;IS THIS A DATA OR DIRECTORY FILE?
	PUSHJ	P,DLTYP		;DATA FILE, TYPE OUT .RBTYP/ETC.
	MOVE	T1,FSIZ		;GET FILE LENGTH
	SKIPE	RIBLEN		;SEE IF EXTENDED LOOKUP
	JRST	DLSIZE		;YES--GO LIST LENGTH
	HLRE	T1,T1		;NO--GET LEVEL-C STYLE
	SKIPLE	T1		;SEE IF IN BLOCKS
	ASH	T1,7		;YES--MAKE INTO WORDS
	MOVM	T1,T1		;GET NUMBER OF WORDS
DLSIZE:	JUMPE	T1,DLVERS
	MSG	<Words written>
	PUSHJ	P,LDECP

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLVERS:	SKIPN	T4,FVER		;GET VERSION
	JRST	DLVERR
	MSG	<Version>
	PUSHJ	P,LVER
DLVERR:	SKIPE	T4,FRVER	;SEE IF RIB VERSION DIFFERENT
	CAMN	T4,FVER		; FROM FILE VERSION
	JRST	DLCHEK		;NO--PROCEED
	MSG	<RIB version>
	PUSHJ	P,LVER		;OUTPUT RIB VERSION NUMBER
DLCHEK:	SKIPG	S.CHK		;SEE IF /CHECKSUM
	JRST	DLSPOL		;NO--SKIP ON
	MSG	<Computed checksum>
	PUSHJ	P,LCHECK
DLSPOL:	SKIPN	T2,FSPL		;GET SPOOLED FILE NAME
	JRST	DLESTL
	MSG	<Spooled name in ENTER>
	PUSHJ	P,LSIXN
DLESTL:	SKIPN	T1,FEST		;GET ESTIMATED LENGTH
	JRST	DLALLB
	MSG	<Estimated length>
	PUSHJ	P,LDECP
DLALLB:	SKIPN	T1,FALC		;GET ALLOCATED LENGTH
	JRST	DLALLP
	MSG	<Blocks allocated>
	PUSHJ	P,LDECP
DLALLP:	SKIPN	T1,FPOS		;GET POSITION ALLOCATED
	JRST	DLUFWR
	MSG	<Position of last allocation>
	PUSHJ	P,LDECP

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLUFWR:	SKIPN	T1,FUFW		;GET UNITS FILE WAS WRITTEN ON
	JRST	DLNCAR
	MSGT	<Written>	;[502]
	LDB	T1,[POINTR (FUFW,RB.UNI)]	;GET UNITS
	JUMPE	T1,DLUFW3	;ARE THERE ANY?
	MOVEI	M,[ASCIZ / on unit(s) /]	;[502] YES
	PUSHJ	P,LSTR
	LDB	T1,[POINTR (FUFW,RB.UNI)]	;MAKE SURE WE HAVE THE UNITS
	MOVEI	T2,0		;CLEAR ALL BITS
	MOVEI	T3,1		;SET UP FIRST BIT TO BE TESTED
	MOVSI	T4,400000
DLUFW1:	TDZE	T1,T3		;IS THIS BIT SET?
	TDO	T2,T4		;YES, RECORD IT
	LSH	T3,1		;LOOK AT NEXT BITS
	LSH	T4,-1
	JUMPN	T1,DLUFW1	;HAVE WE REVERSED ALL THE BITS?
	MOVE	P2,T2		;YES, NOW SAVE UNITS
	SETO	P4,		;CONTAINS UNIT NUMBER
DLUFW2:	JFFO	P2,.+1		;GET FIRST UNIT NUMBER
	ADDI	P4,1(P3)	;SAVE THE UNIT NUMBER
	MOVE	T1,P4		;SET UP FOR PRINTING
	PUSHJ	P,LOCT
	LSH	P2,1(P3)	;GET RID OF THE BIT
	JUMPE	P2,DLUFW3	;ARE WE DONE?
	PUSHJ	P,LCOMMA	;NO, PRINT COMMA-SPACE
	PUSHJ	P,LSPC
	JRST	DLUFW2		;GO GET THE NEXT UNIT NUMBER
DLUFW3:	MOVEI	M,[ASCIZ / on controller /]	;[502] YES
	PUSHJ	P,LSTR
	LDB	T1,[POINTR (FUFW,RB.CON)]	;MAKE SURE WE HAVE IT
	PUSHJ	P,LOCT
DLUFW4:	LDB	T1,[POINTR (FUFW,RB.APR)]	;GET APR SERIAL NUMBER
	JUMPE	T1,DLNCAR	;ARE WE FINISHED?
	MOVEI	M,[ASCIZ / on CPU /]	;NO
	PUSHJ	P,LSTR
	LDB	T1,[POINTR (FUFW,RB.APR)]
	PUSHJ	P,LDEC
DLNCAR:	SKIPN	T1,FNCA		;GET CUST ARG
	JRST	DLMTAP
	MSG	<Nonprivileged customer arg>
	PUSHJ	P,LOCT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLMTAP:	SKIPN	T2,FMTA		;GET DISK BACKUP TAPE
	JRST	DLSTAT
	MSG	<Backup tape>
	PUSHJ	P,LSIXN

DLSTAT:	MOVE	T1,FSTS		;GET STATUS BITS
	HLRZ	T2,FEXT		;SEE WHAT KIND OF FILE
	CAIE	T2,'UFD'	;IF KNOWN DIRECTORY,
	CAIN	T2,'SFD'	; ..
	TXC	T1,<RP.LOG!RP.DIR!RP.ABC>  ;CORRECT STANDARD SETTINGS
	JUMPE	T1,DLERRB
	MOVE	T1,FSTS		;GET BACK STATUS
	MSG	<Status bits>
	PUSHJ	P,LOCT
DLERRB:	MOVE	T1,FELB		;GET ERROR BLOCK
	IOR	T1,FEUN		;INCLUDE ERROR UNIT AND COUNT
	JUMPE	T1,DLQUTF
	MSG	<Error logical block>
	MOVE	T1,FELB		;GET ERROR BLOCK
	TSZ	T1,[770000]	;IGNORE VERSION AND ERROR BITS
	PUSHJ	P,LDECP		;PRINT ERROR BLOCK
	MSG	<Monitor Version>
	HLRZ	T1,FELB		;GET VERSION, ERROR BITS

	LSH	T1,^D-15	;GET VERSION ALONE
	PUSHJ	P,LOCT		;PRINT MONITOR VERSION
	MSG	<Error Bits>
	HLRZ	T1,FELB		;GET VERSION, ERROR BITS
	LSH	T1,^D-12	;GET ERROR BITS
	TRZ	T1,70		;. . .
	PUSHJ	P,LOCT		;PRINT ERROR BITS
	MSG	<Error unit>
	HLRZ	T1,FEUN		;GET ERROR UNIT
	PUSHJ	P,LDECP
	MSG	<Number of bad blocks>
	HRRZ	T1,FEUN		;GET ERROR LENGTH IN BLOCKS
	PUSHJ	P,LDECP

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLQUTF:	MOVE	T1,FSTS		;.RBSTS FLAGS
	TXNN	T1,RP.DIR	;DATA OR DIRECTORY FILE?
	JRST	DLAUTF		;DATA FILE, NO .RBQTA/ETC.
	MOVE	T1,FQTF		;GET QUOTAS
	IOR	T1,FQTO
	IOR	T1,FQTR
	IOR	T1,FUSD		;AND BLOCKS USED
	HLRZ	T2,FEXT		;AND EXTENSION
	CAIE	T2,'UFD'	;IF NOT UFD
	JUMPE	T1,DLAUTH	;AND ZERO, SKIP ON
	MSG	<Logged in quota>
	MOVE	T1,FQTF		;GET FCFS QUOTA
	PUSHJ	P,LDECP
	MSG	<Logged out quota>
	MOVE	T1,FQTO		;GET LOGGED OUT QUOTA
	PUSHJ	P,LDECP
	SKIPN	T1,FQTR		;GET RESERVED BLOCKS
	JRST	DLUSED
	MSG	<Reserved quota>
	PUSHJ	P,LDECP
DLUSED:	MSG	<Blocks used>
	MOVE	T1,FUSD
	PUSHJ	P,LDECP

DLAUTH:	HLRZ	T1,FEXT		;SEE IF
	CAIE	T1,'UFD'	; DIRECTORY
	JRST	DLAUTF		;NO--PROCEED
	MOVE	T1,FNAM		;YES--AUTHOR IS NORMALLY UFD NAME
	JRST	DLAUTC		;SO GO DO IT
DLAUTF:	SKIPN	T1,UFDPPN	;GET OWNER OF FILE
	MOVE	T1,.MYPPN##	;IF NONE, USE SELF
	TLNN	T1,-1		;SEE IF SFD POINTER
	MOVE	T1,.PTPPN(T1)	;YES--GET UFD
DLAUTC:	SKIPE	T4,FAUT		;GET AUTHOR
	CAMN	T4,T1		;SEE IF SAME AS OWNER
	JRST	DLNXTS		;YES--PROCEED BELOW
	MSG	<Author>
	JUMPL	T4,DLAUAL	;IF ALPHA, GO BELOW
	PUSHJ	P,LXWD
	JRST	DLNXTS
DLAUAL:	MOVE	T2,T4
	PUSHJ	P,LSIXN

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLNXTS:	SKIPN	T2,FNXT		;GET NEXT STR
	JRST	DLPIDT
	MSG	<Next structure>
	PUSHJ	P,LSIXN
DLPIDT:	SKIPN	T1,FIDT		;GET BACKUP INCREMENTAL DATE/TIME
	JRST	DLPCAR
	MSG	<"BACKUP" incremental date, time>
	PUSHJ	P,.CNTDT##	;CONVERT TO EASY FORMAT
	PUSHJ	P,LDATIM	;LIST DATE/TIME
DLPCAR:	SKIPN	T1,FPCA		;GET PRIV CUST ARG
	JRST	DLUFDB
	MSG	<Privileged customer arg>
	PUSHJ	P,LOCT
DLUFDB:	SKIPN	T1,FUFD		;GET DIRECTORY POINTER
	JRST	DLFLR
	MSG	<Data block in directory>
	PUSHJ	P,LDECP

DLFLR:	SKIPN	T1,FFLR		;GET RELATIVE BLOCK IN FILE
	JRST	DLXRA		;NONE--SKIP ON
	MSG	<Relative block in file>
	PUSHJ	P,LDECP
DLXRA:	SKIPN	T1,FXRA		;GET POINTER TO NEXT RIB
	JRST	DLTIM		;NONE--DO REST
	MSG	<Pointer to next RIB>
	PUSHJ	P,LOCT		;LIST IN OCTAL
DLTIM:	SKIPN	T1,FTIM		;GET INTERNAL CREATION TIME
	JRST	DLRBLK		;NONE--PROCEED
	MSG	<Internal creation date, time>
	PUSHJ	P,.CNTDT##	;CONVERT TO EASY FORMAT
	PUSHJ	P,LDATIM	;LIST DATE/TIME

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DLRBLK:	SKIPN	T1,FRIBLK	;SEE IF BLOCK NUMBER KNOWN
	JRST	DLLADT		;NO--PROCEED
	MSG	<RIB block number>
	PUSHJ	P,LDECP		;YES--PRINT IN DECIMAL
DLLADT:	SKIPN	T1,FLAD		;GET LAST ACCOUNTING DATE/TIME
	JRST	DLDEDT		;THERE IS NONE
	MSG	<Last accounting date,time>
	PUSHJ	P,.CNTDT##	;CONVERT TO EASY FORMAT
	PUSHJ	P,LDATIM	;LIST IT
DLDEDT:	SKIPN	T1,FDED		;GET THE DIRECTORY EXPIRATION DATE
	JRST	DLACCT		;THERE IS NONE
	MSG	<Directory expiration date,time>
	CAMN	T1,[.INFIN]	;+ INFINITY?
	JRST	[MOVEI	M,[ASCIZ\ Eternity\]  ;LABEL EXCEPTIONAL DATE/TIME
		PUSHJ	P,LSTR		;LIST MNEMONIC (SORTA) STRING
		JRST	DLACCT]		;AND BLUNDER EVER ONWARD
	PUSHJ	P,.CNTDT##	;CONVERT TO EASY FORMAT
	PUSHJ	P,LDATIM	;LIST IT
DLACCT:	SKIPN	T1,FACT		;IS THERE AN ACCOUNT STRING?
	JRST	DLXTRA		;NO
	MSG	<Account>
	MOVEI	M,FACT
	PUSHJ	P,LSTR

;HERE WHEN ALL DONE, PRINT IN OCTAL ANY MORE THAT EXIST

DLXTRA:	MOVEI	P1,.RBXTR	;POINT TO FIRST UNDEFINED AREA
	HRLI	P1,.RBXTR-LN$RIB;AND COUNT OF ARGS
DLXTRL:	SKIPN	LBLOCK(P1)	;GET NEXT WORD
	JRST	DLXTRC
	MOVEI	M,[ASCIZ /
Unknown arg #/]
	PUSHJ	P,LSTR
	MOVEI	T1,(P1)		;GET POSITION
	PUSHJ	P,LOCT
	MOVEI	M,[ASCIZ /: /]
	PUSHJ	P,LSTR
	MOVE	T1,LBLOCK(P1)
	PUSHJ	P,LOCT
DLXTRC:	AOBJN	P1,DLXTRL	;LOOP UNTIL DONE

	PUSHJ	P,LCRLF		;END LINE
	TLZ	F,L.CRLF	;KLEAR KROCK FLAG
	PJRST	LCRLF		;ISSUE BLANK LINE AND RETURN
;HELPER TO LIST THE MORE-COMPLEX .RBTYP/BSZ/RSZ/FFB FIELDS

DLTYP:	SKIPGE	T4,FTYP		;GET .RBTYP FIELD
		.CREF	RB.DEC	;CREF REFERENCE TO "DEC" FLAG
	JRST	DLTY00		;"DEC" FORMAT, LOTS OF FIELDS TO TAKE APART
	IOR	T4,FBSZ		;ACCUMULATE .RBBSZ,
	IOR	T4,FRSZ		; .RBRSZ,
	IOR	T4,FFFB		; AND .RBFFB FIELDS
	JUMPE	T4,.POPJ##	;IGNORE THEM IF THEY ARE ALL BLANK.

;HERE FOR NON-STANDARD (NON-DIGITAL-DEFINED) USAGE OF .RBTYP/ETC.

	MSGT	<File type/formatting is non-standard>
	MSG	<    .RBTYP>
	MOVE	T4,FTYP		;.RBTYP CONTENTS
	PUSHJ	P,L6XWD		;LIST IN XWD FORMAT
	MSG	<    .RBBSZ>
	MOVE	T4,FBSZ		;.RBBSZ CONTENTS
	PUSHJ	P,L6XWD		;LIST IN XWD FORMAT
	MSG	<    .RBRSZ>
	MOVE	T4,FRSZ		;.RBRSZ CONTENTS
	PUSHJ	P,L6XWD		;LIST IN XWD FORMAT
	MSG	<    .RBFFB>
	MOVE	T4,FFFB		;.RBFFB CONTENTS
	PJRST	L6XWD		;LIST IN XWD FORMAT

;HERE FOR RECOGNIZED FILE FORMATTING (RB.DEC SET IN .RBTYP WORD)

DLTY00:	MSGT	<File type/formatting is DECsystem-10 standard>
	TXZ	T4,RB.DEC!RB.CRY!RB.DTY!RB.DTO!RB.DCC  ;REDUCE TO JUST FLAGS
	JUMPE	T4,DLTY20	;SKIP IF NO FLAGS
	TXZN	T4,RB.RMS	;RMS-10?
	JRST	DLTY03		;NO
	MSGT	<File is RMS-10 formatted>
DLTY03:	TXZN	T4,RB.MCY	;MACY-11?
	JRST	DLTY04		;NO
	MSGT	<File is MACY11 formatted>
DLTY04:	TXZN	T4,RB.CTG	;CONTIGUOUS ALLOCATION IMPORTANT?
	JRST	DLTY05		;NO
	MSGT	<Allocation is contiguous>
DLTY05:	TXZN	T4,RB.NSB	;NO-SPAN-BLOCKS?
	JRST	DLTY06		;NO
	MSGT	<Records do not span physical blocks>
DLTY06:	JUMPE	T4,DLTY20	;ANYTHING LEFT OVER?
	MSG	<File type/formatting flags of unknown meaning>
	PUSHJ	P,L6XWD		;TYPE OUT UNKNOWN STUFF IN XWD FORMAT

DLTY20:	LDB	T1,[POINTR FTYP,RB.CRY]  ;SEE IF ENCRYPTED
	JUMPE	T1,DLTY22	;NO
	MSGT	<File is encrypted with algorithm >
	PUSHJ	P,LDECP		;LIST ALGORITHM IN DECIMAL

DLTY22:	MSG	<Data type>
	LDB	T2,[POINTR FTYP,RB.DTY]  ;EXTRACT FILE DATA TYPE
	MOVEI	T4,DLTT22	;DATA TYPE TABLE
	PUSHJ	P,DLTYT		;LIST FILE DATA TYPE

DLTY24:	LDB	T2,[POINTR FTYP,RB.DCC]  ;DATA "CARRIAGE CONTROL"
	JUMPE	T2,DLTY26	;SKIP IF NONE
	MSG	<Carriage control>
	MOVEI	T4,DLTT24	;CARRIAGE-CONTROL TABLE
	PUSHJ	P,DLTYT		;LIST CARRIAGE CONTROL

DLTY26:	LDB	T2,[POINTR FTYP,RB.DTO]  ;APPLICATION/OTS TYPE
	JUMPE	T2,DLTY30	;SKIP IF NONE
	MSG	<File "OTS" or application>
	MOVEI	T4,DLTT26	;OTS TABLE
	PUSHJ	P,DLTYT		;LIST "OTS" TYPE

DLTY30:	LDB	T1,[POINTR FBSZ,RB.BSZ]  ;LOGICAL DATA BYTE SIZE
	JUMPE	T1,DLTY31	;COMPLAIN IF NONE SET
	MSG	<Logical data byte size>
	PUSHJ	P,LDECP		;LIST DECIMAL BYTE SIZE
	JRST	DLTY32		;CHECK FOR FRAME SIZE
DLTY31:	MSGT	<No file data byte size is specified>

DLTY32:	LDB	T1,[POINTR FBSZ,RB.FSZ]  ;PHYSICAL DATA FRAME SIZE
	JUMPE	T1,DLTY40	;SKIP IF NONE
	MSG	<Physical data frame size>
	PUSHJ	P,LDECP		;LIST DECIMAL FRAME SIZE

DLTY40:	LDB	T2,[POINTR FBSZ,RB.RFM]  ;RECORD FORMAT
	JUMPE	T2,DLTY42	;SKIP IF NONE
	MSG	<Record format>
	MOVEI	T4,DLTT40	;RECORD FORMAT TABLE
	PUSHJ	P,DLTYT		;LIST RECORD FORMAT

DLTY42:	LDB	T1,[POINTR FBSZ,RB.HSZ]  ;FIXED-HEADER SIZE
	JUMPE	T1,DLTY44	;SKIP IF NONE
	MSG	<Fized-length-header size>
	PUSHJ	P,LDECP		;LIST HEADER-LENGTH IN DECIMAL

DLTY44:	LDB	T2,[POINTR FBSZ,RB.RFO]  ;RECORD ORGANIZATION
	JUMPN	T2,DLTY45	;IF NONZERO THEN DEFINITELY PRINT IT
	LDB	T1,[POINTR FBSZ,RB.RFM]  ;RECORD FORMAT
	JUMPE	T2,DLTY46	;SKIP IF NONE
DLTY45:	MSG	<Record organization>
	MOVEI	T4,DLTT44	;ORG TABLE
	PUSHJ	P,DLTYT		;LIST RECORD ORGANIZATION

DLTY46:	LDB	T1,[POINTR FRSZ,RB.RSZ]  ;RECORD SIZE
	JUMPE	T1,DLTY48	;SKIP IF NONE
	MSG	<Record size (in bytes)>
	PUSHJ	P,LDECP		;LIST IN DECIMAL

DLTY48:	LDB	T1,[POINTR FRSZ,RB.BLS]  ;BLOCK SIZE
	JUMPE	T1,DLTY50	;SKIP IF NONE
	MSG	<Block size (in bytes)>
	PUSHJ	P,LDECP		;LIST IN DECIMAL

DLTY50:	LDB	T1,[POINTR FFFB,RB.FFB]  ;FIRST FREE BYTE
	JUMPE	T1,DLTY55	;SKIP IF NONE
	MSG	<First free byte in last written block>
	PUSHJ	P,LDECP		;LIST IN DECIMAL

DLTY55:	LDB	T1,[POINTR FFFB,RB.ACW]  ;APPLICATIONS-SPECIFIC VALUE
	JUMPE	T1,DLTY99	;SKIP IF NONE
	MSG	<Applications-specific value>
	PUSHJ	P,LOCT6Z	;LIST IN OCTAL

DLTY99:	POPJ	P,		;ALL DONE
;HELPERS FOR DLTYP

DLTYT:	PUSHJ	P,.CFIND##	;FIND A MATCHING STRING
	 PUSHJ	P,DLTYT8	;LIST UNKNOWN VALUE
	MOVE	M,T1		;ADDRESS OF STRING
	PJRST	LSTR		;LIST THE IDENTIFYING STRING

DLTYT8:	MOVE	T1,T2		;POSITION UNKNOWN VALUE
	PUSHJ	P,LOCT		;AND TYPE IT IN OCTAL
	MOVEI	T1,[ASCIZ\ (Unknown)\]  ;A MATCHING STRING
	POPJ	P,		;RETURN AND TYPE OUT UNKNOWN
;STRING TABLES

	DEFINE	XT(VAL,STR),<XWD [ASCIZ\STR\],VAL>

;FILE DATA TYPE

DLTT22:	XT	.RBDUN,<Undefined (none specified)>
	XT	.RBDAS,<ASCII>
	XT	.RBDBI,<Image/Binary>
	0


;FILE DATA CARRIAGE CONTROL

DLTT24:	XT	.RBCUN,<Undefined (none specified)>
	XT	.RBCFO,<FORTRAN>
	XT	.RBCAS,<ANSI "space">
	0


;FILE 'OTS' OR APPLICATION

DLTT26:	XT	.RBOUN,<Undefined (none specified)>
	XT	.RBOCO,<COBOL>
	XT	.RBOFO,<FORTRAN>
	XT	.RBOMS,<MAIL (MS)>
	0


;RECORD FORMAT

DLTT40:	XT	.RBRUN,<Undefined (no record structure)>
	XT	.RBRFX,<Fixed-length records>
	XT	.RBRVR,<Variable-length records>
	XT	.RBRVF,<Variable-length records with fixed-header>
	XT	.RBRSP,<Spanned records (ANSI tapes)>
	0


;RECORD ORGANIZATION

DLTT44:	XT	.RBRSQ,<Sequential>
	XT	.RBRRL,<Relative>
	XT	.RBRID,<Indexed>
	XT	.RBRHS,<Hashed>
	0
IFN FT$MTA,<	;MAGTAPES

;BLKOVR -- READ BLOCK OF OVERHEAD WORDS
;CALL:	T1/ AOBJN TO READ
;	PUSHJ	P,BLKOVR
;	RETURN +1 AT END OF RECORD
;	RETURN +2 IF READ OK
;COUNTS WORDS IN T2
;USES T1-4

BLKOVR:	SKIPL	T3,T1		;PUT COUNT IN SAFE PLACE
	JRST	.POPJ1##	;GOOD RETURN IF NONE TO TRANSFER
BLKO.1:	PUSHJ	P,NEXOVR	;GET NEXT WORD
	  POPJ	P,		;RETURN IF EOF
	MOVEM	T1,(T3)		;STORE AWAY
	AOBJN	T3,BLKO.1	;LOOP
	JRST	.POPJ1##	;GOOD RETURN


;NEXDCW -- READ REST OF BLOCK COMPUTING CHECKSUM
;NEXDTW -- READ ONE WORD COMPUTING CHECKSUM
;NEXOVW -- DITTO, BUT DON'T INCLUDE IN CHECKSUM
;NEXOVR -- DITTO, BUT STOP AT END OF RECORD
;CALL:	PUSHJ	P,NEXDTW/NEXOVW/NEXOVR
;RETURN CPOPJ IF END OF FILE
;SKIP RETURN WITH DATUM IN T1
; NEXOVR COUNTS WORDS IN T2
;USES M, C

NEXOVR:	SKIPN	BFHD+.BFCTR	;SEE IF SOMETHING HERE
	POPJ	P,		;NO--RETURN
	PUSHJ	P,NEXOVW	;YES--GET IT
	  POPJ	P,		;EOF!
	AOS	T2		;COUNT WORD
	JRST	.POPJ1##	;OK RETURN
>;END IFN FT$MTA

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

NEXOVW:	TRO	F,R.MTOH	;INDICATE OVERHEAD WORD
NEXDTW:	TLNE	F,L.FKEF	;SEE IF FAKE EOF SET
	POPJ	P,		;YES--GIVE IT AGAIN
	TLZE	F,L.SVDW	;SEE IF SAVED WORD
	JRST	[MOVE	T1,MTSVWD
		 JRST	NEXDT3]
IFN FT$MTR,<	;OLD BACKUP/RESTORE
	TLNE	F,L.BKSS	;SEE IF OLD BACKUP/RESTORE SAVE SET
	JRST	NEXDT1		;YES--GO HANDLE IT
>;END IFN FT$MTR
	SKIPN	BFHD+.BFCTR	;NO--SEE IF READY TO READ NEXT RECORD
	TLNN	F,L.SVST!L.FRSS	;AND IN SAVE SET MODE
	JRST	NEXDT2		;NO--JUST PROCEED
IFN FT$MTB,<	;BACKUP/FRS
	TLNE	F,L.FRSS	;SEE IF BACKUP/FRS
	JRST	NEXDF1		;YES--GO HANDLE
>;END IFN FT$MTB
IFN FT$MTF,<	;FAILSAFE
	PUSHJ	P,NEXDT		;FAILSAFE--READ THE NEXT WORD
	  POPJ	P,		;EOF--ALL DONE
	TLNN	T1,-1		;SEE IF MORE DATA
	JRST	NEXDT2		;YES--GO READ DATA WORD
	MOVEM	T1,MTSVHD	;NO--SAVE HEADER
	TLO	F,L.FKEF	;AND SET FAKE EOF
	POPJ	P,		;RETURN EOF
>;END IFN FT$MTF

;HERE FOR BACKUP/FRS SAVE SETS

IFN FT$MTB,<	;BACKUP/FRS
NEXDF1:	SKIPGE	B$GFLG		;SEE IF END OF FILE
		..==GF$EOF	;(FOR CREF)
	TLOA	F,L.FKEF	;YES--SET EOF
	PUSHJ	P,NEXDT		;NO--GET START OF RECORD
	  POPJ	P,		;RETURN IF EOF
	PUSHJ	P,FRSLAH	;HANDLE BACKUP/FRS LOOK-AHEAD
	MOVEM	T1,MTSVWD	;SAVE WORD JUST IN CASE
	TLNE	T1,777770	;MAKE SURE FRS OR BACKUP
	JRST	NEXDF9		;NO--SET ERROR
	TLNE	T1,-1		;SEE IF FRS
	TLO	T1,-1		;YES--SET WHOLE HALF
	XOR	T1,B$GTYP	;COMPARE WITH PREVIOUS
	JUMPL	T1,NEXDF9	;IF DIFFERENT, ERROR
>;END IFN FT$MTB

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTB,<	;BACKUP/FRS

	MOVE	T1,MTSVWD	;RESTORE WORD
IFN FT$MTS,<	;FRS
	TLNE	T1,-1		;IF FRS,
	JRST	NEXDF2		;JUMP BELOW IF FRS
>;END IFN FT$MTS
	CAIE	T1,T$FIL	;MAKE SURE FILE
	JRST	NEXDV		;NO--CHECK FOR END OF VOLUME
NEXDFG:	PUSHJ	P,NEXDT		;GET RECORD NUMBER
	  POPJ	P,		;EOF!
	MOVEM	T1,B$GBNM	;STORE RECORD NUMBER
	PUSHJ	P,NEXDT		;GET TAPE NUMBER
	  POPJ	P,		;EOF!
	CAME	T1,B$GRTN	;MUST BE THE SAME
	JRST	NEXDF9		;NO--ERROR
	PUSHJ	P,NEXDT		;GET FLAGS
	  POPJ	P,		;EOF!
	MOVEM	T1,B$GFLG	;STORE
	PUSHJ	P,NEXDT		;GET CHECKSUM
	  POPJ	P,		;EOF!
	MOVEM	T1,B$GCHK	;STORE
	PUSHJ	P,NEXDT		;GET SIZE
	  POPJ	P,		;EOF!
	JUMPL	T1,NEXDF9	;ERROR IF NEGATIVE
	CAMLE	T1,MTFFTB	;SEE IF TOO BIG
	JRST	NEXDF9		;YES--ERROR
	MOVEM	T1,B$GSIZ	;STORE
	PUSHJ	P,NEXDT		;GET SKIP REGION
	  POPJ	P,		;EOF!
	JUMPL	T1,NEXDF9	;ERROR IF NEGATIVE
	MOVEM	T1,B$GLND	;STORE
	ADDI	T1,31		;COUNT OF REST OF HEADER
	JRST	NEXDF5		;GO SKIP HEADER AND JUNK
>;END IFN FT$MTB
IFN FT$MTS,<	;FRS

;HERE IF FRS--READ BLOCK HEADER
NEXDF2:	HRLZM	T1,B$GFLG	;UPDATE FLAGS
	HLRZS	T1		;GET TYPE
	CAIE	T1,4		;SEE IF FILE
	JRST	NEXDF9		;NO--ERROR
	PUSH	P,[5]		;SAVE COUNT TO SKIP FORWARD
NEXDF3:	PUSHJ	P,NEXDT		;GET HEADER
	  JRST	[POP  P,(P)	;CLEAN UP STACK
		 POPJ P,]	;RETURN EOF
	SOSLE	(P)		;COUNT DOWN
	JRST	NEXDF3		;REPEAT
	POP	P,(P)		;CLEAN UP STACK
	PUSHJ	P,NEXDT		;GET STARTING BLOCK
	  POPJ	P,		;EOF!
	MOVEM	T1,B$FRBN	;SAVE
	LSH	T1,7		;CONVERT TO WORDS
	MOVEM	T1,B$FRDW	;SAVE
	PUSHJ	P,NEXDT		;GET WORD TO SKIP
	  POPJ	P,		;EOF!
	PUSHJ	P,NEXDT		;GET DATA BLOCK IN RECORD
	  POPJ	P,		;EOF!
	SKIPL	T1		;CHECK FOR
	CAILE	T1,20		; REASONABLENESS
	JRST	NEXDF9		;NO--JUNK
	MOVEM	T1,B$FNDB	;SAVE
	PUSHJ	P,NEXDT		;GET WORDS IN LAST BLOCK
	  POPJ	P,		;EOF!
	SKIPL	T1		;CHECK FOR
	CAILE	T1,200		; REASONABLENESS
	JRST	NEXDF9		;NO--JUNK
	MOVEM	T1,B$FNDW	;SAVE
	SKIPN	T1,B$FNDB	;GET NUMBER OF BLOCKS
	SKIPGE	B$GFLG		;UNLESS EOF
	SKIPA			;YES
	MOVEI	T1,5		;(BUG IN OLD VERSION OF FRS)
	IMULI	T1,200		;CONVERT TO WORDS
	ADD	T1,B$FNDW	;GET NUMBER OF WORDS IN LAST
	CAIL	T1,200		;ALLOW FOR NO DATA
	SUBI	T1,200		;ALLOW FOR DOUBLE COUNT
	MOVEM	T1,B$GSIZ	;SAVE AS DATA SIZE
	MOVEI	T1,12		;INDICATE REST OF HEADER
>;END IFN FT$MTS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

IFN FT$MTB,<	;BACKUP/FRS
;HERE TO SKIP REST OF FRS/BACKUP BLOCK HEADER
NEXDF5:	PUSH	P,T1		;SAVE DISTANCE
NEXDF6:	PUSHJ	P,NEXDT		;GET MORE HEADER
	   JRST	[POP  P,(P)	;CLEAN UP STACK
		 POPJ P,]	;RETURN EOF
	SOSLE	(P)		;COUNT DOWN
	JRST	NEXDF6		;LOOP OVER HEADER
	POP	P,(P)		;RESTORE STACK
	MOVE	T1,B$GSIZ	;GET LENGTH OF DATA AREA
	MOVEM	T1,BFHD+.BFCTR	;STORE AS REAL STUFF TO READ
	JRST	NEXDTW		;GO GET SOME DATA

NEXDF9:	TLO	F,L.FKEF!L.SVDW	;INDICATE ERROR
	POPJ	P,		;RETURN
>;END IFN FT$MTB
;HERE TO CHECK AND MOUNT NEXT VOLUME IF DESIRED

IFN	FT$MTB,<		;BACKUP ONLY

NEXDV:	SKIPLE	S.MVOL		;ONLY IF /MVOLUME
	CAIE	T1,T$EOV	;IS THIS BACKUP END OF VOLUME?
	JRST	NEXDF9		;NO - JUST END OF FILE
	SETZM	BFHD+.BFCTR	;READ NEXT RECORD
	PUSHJ	P,NEXDT		;. . .
	CAIA			;TAPE MARK EXPECTED
	JRST	NEXDV8		;AND DATA ISN'T
	TLO	F,L.BPOP	;ASK MTFEOV TO "POPJ"
	PUSHJ	P,MTFEO0	;ASK FOR NEXT TAPE
	 JRST	NEXDV9		;USER SAID "EXIT"
NEXDV2:	SETZM	BFHD+.BFCTR	;MAKE SURE NO DATA
	PUSHJ	P,NEXDT		;FIRST WORD NEW TAPE
	 JRST	NEXDV9		;NO FIRST WORD
	CAIE	T1,T$CSS	;BACKUP CONTINUE SAVE SET?
	 JRST	NEXDV8		;NO, FORGET IT
	TLO	F,L.BPOP	;ASK MTFCSS TO POPJ
	PUSHJ	P,MTFRSP	;LIST SAVE SET HEADER
	 JRST	[TLO	F,L.BPOP	;ASK MTFEOV TO POPJ
		PUSHJ	P,MTFEO1	;WRONG TAPE, ASK AGAIN
		JRST	NEXDV9		;USER SAID "EXIT"
		JRST	NEXDV2]		;TRY AGAIN
	PUSHJ	P,NEXDT		;FIRST WORD NEXT RECORD
	JRST	NEXDV9		;EOF
	CAIE	T1,T$DIR	;DIRECTORY RECORD?
	JRST	[CAIN	T1,T$FIL	;[466] NO, FILE RECORD?
		JRST	NEXDV4		;YES
		JRST	NEXDV8]		;NO, GARBAGE FORMAT
	SETZM	BFHD+.BFCTR	;EAT DIRECTORY RECORD
	PUSHJ	P,NEXDT		;THIRD RECORD
	JRST	NEXDV9		;EOF
	CAIE	T1,T$FIL	;NOW, THIS SHOULD BE FILE RECORD
	JRST	NEXDV8		;IT'S NOT, BUMMER
NEXDV4:	MOVEM	T1,B$GTYP	;MAKE SURE B$GTYP CORRECT
	JRST	NEXDFG		;CONTINUE WITH FILE DATA


;ERRORS

NEXDV8:	MOVEM	T1,MTSVWD	;RE-READ THIS WORD
	TLO	F,L.SVDW	;ON NEXT CALL TO NEXD??
NEXDV9:	TLO	F,L.FKEF	;FORCE EOF
	POPJ	P,		;AND TAKE EOF RETURN
> ;END IFN FT$MTB
IFN FT$MTR,<	;OLD BACKUP/RESTORE

;HERE FOR OLD BACKUP/RESTORE SAVE SETS

NEXDT1:	SOSLE	MTSVCT		;DECREMENT COUNT
	JRST	NEXDT2		;STILL IN THIS HEADER
	PUSHJ	P,NEXDT		;GET NEXT HEADER
	  POPJ	P,		;RETURN IF EOF
	MOVEM	T1,MTSVWD	;SAVE WORD IN CASE
	TRZ	T1,777000	;CLEAR BACK POINTER
	HRRZM	T1,MTSVCT	;SET COUNT
	HLRZS	T1		;GET CONTROL HEADER
	CAIE	T1,400000	;IS IT DATA?
	JRST	[TLO F,L.FKEF!L.SVDW	;SET FLAGS
		 JRST NEXDT8]		;GIVE EOF RETURN
	PUSHJ	P,NEXDT		;THROW AWAY CHECKSUM
	  POPJ	P,		;EOF
	JRST	NEXDT2		;GO DO NORMAL READ NOW
>;END IFN FT$MTR

NEXDT2:	PUSHJ	P,NEXDT		;READ FILE
	  JRST	NEXDT8		;RETURN IF EOF
NEXDT3:	SKIPLE	S.CHK		;IS CHECKSUMMING REQUESTED?
	TRZE	F,R.MTOH	;SEE IF MAG TAPE OVERHEAD
	JRST	.POPJ1##	;DON'T CHECKSUM IT
NEXDT4:	EXCH	T1,CHKSUM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,CHKSUM	;ADD THIS WORD
	EXCH	T1,CHKSUM	;STORE AWAY
	EXCH	T1,SCHKSM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,SCHKSM	;ADD THIS WORD
	EXCH	T1,SCHKSM	;STORE AWAY
	EXCH	T1,TCHKSM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,TCHKSM	;ADD THIS WORD
	EXCH	T1,TCHKSM	;STORE AWAY
	JRST	.POPJ1##	;AND SKIP RETURN

NEXDT8:	SETZM	MTSVCT		;CLEAR COUNTER
	POPJ	P,		;RETURN
;NEXDCW  --  READ CHECKSUMMED WORD/BLOCK
;CALL AS NEXDTW
;
;THIS ROUTINE READS THE REST OF THE BLOCK OF DATA, CHECKSUMMING
;AS IT GOES. THIS ROUTINE CUTS THE CHECKSUMMING OVERHEAD FROM 27
;INSTRUCTIONS/WORD TO 14/WORD, (TO 6/WORD IF /FNDBLD/NODIRECT)
;PLUS IN UUO AND (IF APPLICABLE) ANY MAGTAPE RECORD PROCESSING, ETC.
;
;USES T1, T2.

NEXDCW:	IFN	FT$MTR,<TLNN F,L.BKSS>  ;NEXDTW IF OLD BACKUP/RESTORE
	SKIPG	T2,BFHD+.BFCTR	;ANY WORDS LEFT IN BUFFER?
	JRST	NEXDTW		;NO, DO IN, MAGTAPE RECORD HANDLING
	SKIPN	S.DIRE		;/NODIRECT?
	JRST	NEXDC6		;YES, THEN ONLY NEED 7 INSTR/WORD
	JRST	NEXDC3		;NO, NEED ALL THREE RUNNING CHECKSUMS

;HERE TO MAINTAIN ALL THREE RUNNING CHECKSUMS (E.G. NOT /FNDBLD/NODIRECT)

NEXDC2:	ILDB	T1,BFHD+.BFPTR	;GET NEXT WORD TO BE CHECKSUMMED
	EXCH	T1,CHKSUM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,CHKSUM	;ADD THIS WORD
	EXCH	T1,CHKSUM	;STORE AWAY
	EXCH	T1,SCHKSM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,SCHKSM	;ADD THIS WORD
	EXCH	T1,SCHKSM	;STORE AWAY
	EXCH	T1,TCHKSM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,TCHKSM	;ADD THIS WORD
	EXCH	T1,TCHKSM	;STORE AWAY
NEXDC3:	SOJGE	T2,NEXDC2	;LOOP FOR REST OF BLOCK
	SETZM	BFHD+.BFCTR	;THIS BUFFER NOW EXHAUSTED
	PJRST	NEXDTW		;START UP A NEW BUFFER

;HERE ON /CHECKSUM/NODIRECT (E.G., /FNDBLD/NODIRECT), GO EVEN FASTER

NEXDC5:	ILDB	T1,BFHD+.BFPTR	;GET NEXT WORD TO BE CHECKSUMMED
	EXCH	T1,CHKSUM	;GET CHECKSUM SO FAR
	ROT	T1,1		;ROTATE
	ADD	T1,CHKSUM	;ADD THIS WORD
	EXCH	T1,CHKSUM	;STORE AWAY
NEXDC6:	SOJGE	T2,NEXDC5	;LOOP FOR REST OF BUFFER
	SETZM	BFHD+.BFCTR	;THIS BUFFER NOW EXHAUSTED
	PJRST	NEXDTW		;START UP A NEW BUFFER
IFN FT$MTB,<	;BACKUP/FRS

;FRSLAH -- ROUTINE TO HANDLE FRS/BACKUP LOOK-AHEAD TO CORRECT ERRORS
;CALL:	1/ FIRST WORD OF A RECORD
;	PUSHJ	P,FRSLAH
;	RETURNS 1/FIRST WORD OF FIRST GOOD RECORD
;USES NO AC'S

FRSLAH:	PUSH	P,T1		;SAVE T1
	PUSH	P,T2		;[465] AND T2 TOO
FRSLA1:	MOVE	T1,@BFHD+.BFADR	;[465] GET POINTER TO NEXT BUFFER
	SKIPL	.BFHDR-1(T1)	;MAKE SURE IT IS FULL
	JRST	[WAIT	DC,		;[465] LET THE TAPE CATCH UP
		SKIPL	.BFHDR-1(T1)	;[465] GOT THE NEXT BUFFER NOW?
		JRST	FRSLA9		;[465] NO, JUST GIVE UP THEN
		JRST	.+1]		;[465] YES, CHECK FOR REPEATER
	SKIPL	B$GTYP		;IS IT FRS OR BACKUP
	SKIPA	T2,.BFCNT+G$FLAG(T1) ;BACKUP--GET FLAGS
	HRLZ	T2,.BFCNT(T1)	;FRS--GET FLAGS
	TXNE	T2,GF$RPT	;[465] IS IT A REPEAT
	JRST	FRSLA5		;[465] DEFINITELY A REPEATER
	SKIPGE	B$GTYP		;[465] BACKUP OR FRS?
	JRST	FRSLA9		;[465] FRS, ASSUME OK
	MOVE	T2,.BFCNT+G$SEQN(T1)  ;[465] BACKUP, GET NEXT RECORD NUMBER
	MOVE	T1,BFHD+.BFADR	;[465] POINT BACK TO CURRENT BUFFER
	CAME	T2,.BFCNT+G$SEQN(T1)  ;[465] RECORD NUMBER REPEATED?
	JRST	FRSLA9		;[465] NO, THIS BUFFER/RECORD IS OK

FRSLA5:	PUSHJ	P,FRSSBR	;[465] TELL USER OF WOES
	SETZM	BFHD+.BFCTR	;[465] DISCARD CURRENT (REPEATED) RECORD
	PUSHJ	P,NEXDT		;GET NEXT
	  TLO	F,L.FKEF	;EOF!
	MOVEM	T1,-1(P)	;[465] SET NEW "FIRST" WORD
	JRST	FRSLA1		;[465] AND TRY AGAIN

FRSLA9:	POP	P,T2		;[465] RESTORE TRASHED AC
	POP	P,T1		;RESTORE FIRST WORD
	POPJ	P,		;RETURN


;[465] TELL USER OF REPEATER RECORDS BEING SKIPPED (IF HE CARES)

FRSSBR:	SKIPG	S.SBRM		;[465] USER CARE (/SBRMSG)?
	POPJ	P,		;[465] NO, DON'T MESS UP HER LISTING
	PUSHJ	P,.PSH4T##	;[465] YES, PROTECT THE TEAS
	N$WRNX	(SBR,<Skipping for BACKUP/FRS repeater record>)  ;[465]
	MOVE	T1,BFHD+.BFADR	;[465] ADDRESS OF [TO BE PITCHED] BUFFER
	MOVE	T1,.BFCNT+G$SEQN(T1)  ;[465] GET THE [REPEATED] RECORD NUMBER
	PUSHJ	P,LDEC		;[465] AND LIST IT TOO
X$$SBR:	PUSHJ	P,.TCRLF##	;[465] CAP OFF WITH A <CR><LF>
	PUSHJ	P,.POP4T##	;[465] GET THE TEAS BACK
	POPJ	P,		;[465] ADVANCE TO NEXT RECORD
>;END IFN FT$MTB
;NEXDT -- ROUTINE TO READ ONE WORD FROM THE BUFFER
;NON-SKIP RETURN IF EOF
;SKIP RETURN WITH WORD IN T1

NEXDT:	SOSGE	BFHD+.BFCTR	;SEE IF ANY LEFT
	JRST	NEXDTR		;NO--GO DO A READ
	ILDB	T1,BFHD+.BFPTR	;YES--GET IT
	JRST	.POPJ1##	;SKIP RETURN

NEXDTR:	AOSN	MTAEOF		;START OF A NEW FILE ??
	PUSHJ	P,MTLBIN	;YES, GET LABEL PARMS
	IN	DC,		;READ NEXT BLOCK
	  JRST	NEXDT		;GO ANALYZE

;ERROR OR END OF FILE, CHECK IT OUT

	PUSHJ	P,.PSH4T##	;SAVE ALL TEMPS
	GETSTS	DC,T1		;GET CURRENT I/O STATUS
	TXNE	T1,IO.EOF	;END OF FILE?
	JRST	NEXDTF		;YES, TAKE EOF RETURN
	PUSH	P,T1		;SAVE ERROR STATUS
	N$WRNX	(IDE,<Error reading>)

IFN FT$MTA,<	;MAGTAPE
	SKIPE	T1,MTNAME	;SEE IF MAG-TAPE NAME
	PUSHJ	P,[PUSHJ P,.TSIXN##	;YES--TYPE IT
		MOVEI	T1,[ASCIZ /: file /]
		PJRST	.TSTRG##]	;MORE MESSAGE
>;END IFN FT$MTA

	MOVEI	T1,FOBLK+.FOIOS	;POINT TO OPEN BLOCK
	MOVEI	T2,LBLOCK	;POINT TO LOOKUP BLOCK
	PUSHJ	P,.TOLEB##	;ISSUE FILE SPEC
	MOVEI	T1,[ASCIZ\; \]	;A NICE SEPARATOR
	PUSHJ	P,.TSTRG##	;SEPARATE FILE FROM I/O STATUS
	MOVE	T1,0(P)		;RETRIEVE A COPY OF THE I/O STATUS
	HRLI	T1,DC		;AND ITS CHANNEL
	PUSHJ	P,IOERM		;TYPE ERROR STATUS
	AOSN	T1		;T1 SAY TO ABORT?
	SETOM	ABORTI		;YES, ABORT INPUT
X$$IDE:	PUSHJ	P,.TCRLF##	;END LINE
	POP	P,T1		;RETRIEVE I/O/ERROR STATUS
	TRZ	T1,IO.ERR	;CLEAR OUT ERROR BITS
	SETSTS	DC,(T1)		;SET CLEARED STATUS
	PUSHJ	P,.POP4T##	;RESTORE TEMPS
	SKIPL	ABORTI		;ANYTHING REALLY WRONG?
	JRST	NEXDT		;NO, JUST READ WHAT WAS RETURNED TO US
	POPJ	P,		;YES, ABORT I/O HERE

;HERE ON EOF

NEXDTF:	PUSHJ	P,.POP4T##	;RESTORE THE T'S
	SETOM	MTAEOF		;INDICATE NEW FILE
	POPJ	P,		;AND TAKE EOF RETURN
;IOERM  --  ISSUE GENERAL I/O CHANNEL/STATUS ERROR MESSAGE
;CALL IS:
;
;	MOVE	T1,<STS>
;	PUSHJ	P,IOERM
;	RETURN
;
;WHERE <STS> IS THE OFFENDING I/O STATUS.
;
;ON RETURN I/O CHANNEL IS UNAFFECTED, AND T1 HAS -1 IF NO FURTHER
;I/O SHOULD BE ATTEMPTED (PULSAR/AD NAUSEUM HAS STOMPED ON THE I/O).

IOERM:	PUSHJ	P,.SAVE1##	;WANT A PRESERVED AC HERE
	MOVE	P1,T1		;HANG ON TO STATUS
	MOVEI	T1,[ASCIZ\I/O status = \]
	PUSHJ	P,.TSTRG##	;PREFIX STATUS MESSAGE
	HRRZ	T1,P1		;RETRIEVE STATUS AGAIN
	PUSHJ	P,.TOCTW##	;LIST OCTAL I/O STATUS
	MOVE	T1,P1		;RETRIEVE STATUS YET AGAIN
	TXCN	T1,IO.ERR	;ANY ERROR BITS SET?
	JRST	IOERM9		;NO?
	TXCN	T1,IO.ERR	;EXTENDED ERROR STATUS?
	JRST	IOERX		;YES, LIST I/O REASON
	MOVEI	T1,[ASCIZ\ (\]	;START EXPLANATORY TEXT
	PUSHJ	P,.TSTRG##	; . . .
	MOVEI	T1,[ASCIZ\Improper mode\]  ;WRITE-LOCK, ETC.
	TXZE	P1,IO.IMP	;"IMPROPER MODE" ERROR?
	PUSHJ	P,IOERM5	;YES, LIST EXPLANATION
	MOVEI	T1,[ASCIZ\Hard device error\]  ;DEVICE (NOT DATA)
	TXZE	P1,IO.DER	;DEVICE AT FAULT (POWER, ETC.)?
	PUSHJ	P,IOERM5	;YES, LIST EXPLANATION
	MOVEI	T1,[ASCIZ\Hard data error\]  ;DATA PARITY ERROR
	TXZE	P1,IO.DTE	;DATA INCORRECT?
	PUSHJ	P,IOERM5	;YES, LIST EXPLANATION
	MOVEI	T1,[ASCIZ\Block too large\]  ;DATA RECORD TOO BIG
	TXZE	P1,IO.BKT	;DATA RECORD BIGGER THAN BUFFER?
	PUSHJ	P,IOERM5	;YES, LIST EXPLANATION
	MOVEI	T1,")"		;END OF EXPLANATORY TEXT
	PJRST	.TCHAR##	;CAP OFF ERROR STATUS TEXT

;SUBSIDIARY OF IOERM, FOR TYPING MESSAGE, OPTIONAL SEPARATING COMMA

IOERM5:	PUSHJ	P,.TSTRG##	;TYPE OUT ASCII TEXT
	MOVEI	T1,[ASCIZ\, \]	;PRETTY ITEM SEPERATOR
	TXNE	P1,IO.ERR	;MORE EXPLANATIONS COMING UP?
	PJRST	.TSTRG##	;YES
	POPJ	P,		;NO

;HERE WHEN NO APPARENT REASON

IOERM9:	MOVEI	T1,[ASCIZ\ (no apparent error)\]
	PJRST	.TSTRG##	;CAP OFF OUR OUTPUT
;HERE TO LIST EXTENDED DEVICE I/O ERROR STATUS

IOERX:	HLRZ	T3,P1		;CHANNEL WITH ERROR
	MOVEI	T2,.DFRES	;READ I/O ERROR FUNCTION
	MOVE	T1,[2,,T2]	;DEVOP. ARG POINTER TO
	DEVOP.	T1,		;READ EXTENDED I/O ERROR STATUS
	 SETZ	T1,		;NONE?
	CAIL	T1,0		;MUST BE POSITIVE
	CAILE	T1,IOERXX	;AND KNOWN TO US
	 SETZ	T1,		;UNKNOWN ERROR STATUS
	PUSH	P,T1		;SAVE THE CODE FOR A BIT
	HRRZ	T1,IOERXT(T1)	;[447] GET EXPLANATORY TEXT
	PUSHJ	P,.TSTRG##	;AND GIVE IT TO USER
	POP	P,T1		;RESTORE THE EXTENDED ERROR CODE
	HLLE	T1,IOERXT(T1)	;[447] RETURN "FATALNESS" IN T1
	POPJ	P,		;RETURN TO CALLER

IOERXT:	00,,	[ASCIZ\ ((00) - Unknown error status)\]
	00,,	[ASCIZ\ (IOPLE% (01) - Page limit exceeded)\]
	00,,	[ASCIZ\ (IOVFE% (02) - VFU format error)\]
	-1,,	[ASCIZ\ (IOLTE% (03) - Label type error)\]
	-1,,	[ASCIZ\ (IOHLE% (04) - Header label error)\]
	-1,,	[ASCIZ\ (IOTLE% (05) - Trailer label error)\]
	-1,,	[ASCIZ\ (IOVLE% (06) - Volume label error)\]
	00,,	[ASCIZ\ (IODER% (07) - Hard device error)\]
	00,,	[ASCIZ\ (IOPAR% (10) - Data parity error)\]
	00,,	[ASCIZ\ (IOWLE% (11) - Device is write-locked)\]
	-1,,	[ASCIZ\ (IOIPO% (12) - Illegal positioning operation\]
	00,,	[ASCIZ\ (IOBOT% (13) - Begining of tape)\]
	-1,,	[ASCIZ\ (IOIOP% (14) - Illegal operation)\]
	-1,,	[ASCIZ\ (IOFNF% (15) - Labelled file not found)\]
	-1,,	[ASCIZ\ (IOCAN% (16) - Operator cancelled volume switch)\]
	-1,,	[ASCIZ\ (IOTMV% (17) - Too many volumes in volume set)\]
	00,,	[ASCIZ\ (IONND% (20) - Network communications broken)\]
	00,,	[ASCIZ\ (IOUNC% (21) - Undefined character interrupt)\]
	00,,	[ASCIZ\ (IORPE% (22) - RAM parity error)\]
	-1,,	[ASCIZ\ (IOLRA% (23) - Labeler request aborted by RESET)\]
	-1,,	[ASCIZ\ (IOVPF% (24) - Volume protection failure)\]
	-1,,	[ASCIZ\ (IOFPF% (25) - File protection failure)\]
	-1,,	[ASCIZ\ (IOUEF% (26) - Unexpired file)\]

	IOERXX==.-IOERXT	;LARGEST KNOWN TO US ERROR CODE
REPEAT	0,<

;CHKNXF -- CHECK FOR PREVIOUS SPEC. WAS NON-EXISTENT EVERY PLACE
;PRESERVES T1-4

CHKNXF:	CAMN	I,LASI		;SEE IF STILL SAME REQUEST
	POPJ	P,		;YES--DON'T WORRY YET
	MOVEM	I,LASI		;SAVE LAST REQUEST
	SKIPN	NXFCNT		;SEE IF ANY FILE FOUND
	SKIPN	NXFI		;NO--SEE IF ERROR FOUND
	JRST	CHKNXY		;NO--JUST CLEAN UP AND RETURN
	PUSH	P,T1		;PRESERVE T1-4
	PUSH	P,T2	
	PUSH	P,T3
	PUSH	P,T4
	EXCH	I,NXFI		;GET OLD I
	MOVEI	T1,H.ZERX-H.ZER1;POINT TO OLD COPY AREA
	MOVE	T2,.FXDEV(I)	;GET ORIGINAL DEVICE REQUESTED
	MOVEM	T2,FSTR(T1)	;SAVE AWAY FOR LATER
	HLLZS	FEXT(T1)	;CLEAR ERROR CODE
	SKIPN	NXUCNT		;SEE IF UFD FOUND
	JRST	[MOVEI T2,1	;NO--SET UFD NOT FOUND
		 SKIPE NXSCNT	;SEE IF SFD MISSING
		 MOVEI T2,23	;YES--SET THAT CODE
		 HRRM  T2,FEXT(T1)  ;AND STORE THE
		 JRST  .+1]	;  CODE AWAY
	PUSHJ	P,E.DFLS	;ISSUE ERROR
	MOVE	I,NXFI		;RESTORE I
	POP	P,T4		;RESTORE T1-4
	POP	P,T3
	POP	P,T2
	POP	P,T1

CHKNXY:	SETZM	NXFI		;CLEAR ERROR FLAG
	SETZM	NXFCNT		;CLEAR FOUND COUNT
	SETZM	NXSCNT		;CLEAR NX SFD COUNT
	POPJ	P,		;RETURN
;STILL IN REPEAT 0

;SUBROUTINE IF LOOKUP ERROR

;		BEFORE COUNTING THE ERROR.	LCR.	15-FEB-77.

E.DFLL:	PUSHJ	P,.CHKTA##	;GO CHECK CONCATENATION REQUIREMENTS.
	 JRST	[SOS	NXFCNT		;WE DON'T NEED THIS FILE. DON'T COUNT
		 POPJ	P,]		;ERROR, JUST RETURN TO MAINLINE.
	HRRZ	T1,FEXT		;GET ERROR CODE
	CAIN	T1,ERPRT%	;SEE IF PROTECTION ERROR
	JRST	[MOVX	T2,FX.PRT	;YES--SEE IF /OKPROT
		TDNN	T2,.FXMOD(I)	; ..
		JRST	.+1		;NO--PROCEED
		MOVEI	T1,LBLOCK	;YES--USE
		MOVEI	T2,LN$RIB	; E.LKEN
		MOVEI	T3,(I)		; TO GET WILD
		PJRST	E.LKEN##]	; ERROR COUNTS
	CAIE	T1,ERSNF%	;SEE IF NX SFD
	CAIG	T1,ERIPP%	;NO--SEE IF NX FILE OR NX UFD
	SKIPG	.WLDFL##	;YES--SEE IF STR WILDCARDING
	JRST	E.DFLC		;NO--ISSUE MESSAGE NOW ANYWAY
	SKIPN	T1		;SEE IF UFD PRESENT
	AOS	NXUCNT		;NON-X FILE
	CAIN	T1,ERSNF%	;SEE IF SFD
	AOS	NXSCNT		;YES--COUNT IT
	MOVEM	I,NXFI		;YES--SAVE I AS FLAG FOR LATER
				;THIS IS NEEDED BECAUSE WE WISH TO
				; GIVE NX FILE MESSAGE ONLY IF IT DOES
				; NOT EXIST ON ANY STR IN THE LIST
	MOVE	T1,[H.ZER1,,H.ZERX]
	BLT	T1,H.ZERY-1	;COPY TO ALTERNATE AREA
	SKIPE	T1,UFDPPN	;SEE IF SFD TO COPY
	TLNE	T1,-1		;  ..
	POPJ	P,		;NO--RETURN
	HRLZ	T1,T1		;YES--COPY TO ALTERNATE
	HRRI	T1,H.ZERY	;  AREA
	BLT	T1,H.ZERY+2+.FXLND  ; ..
	POPJ	P,		;GO AROUND THE LOOP

E.DFLC:	MOVEI	T1,0		;POINT TO REGULAR AREA
	PUSHJ	P,E.DFLS	;ISSUE ERROR MESSAGE
	AOS	SNFILR		;COUNT LOOKUP ERROR
	AOS	NXFCNT		;COUNT FILE FOUND
	POPJ	P,		;AND GO AROUND LOOP
;STILL IN REPEAT 0

;E.DFLS -- SUBROUTINE TO PRINT ERROR IN FILE LINE
;T1 MUST BE SET TO 0 FOR REGULAR AREA
;USES T1, T2, T3, T4, M, C

E.DFLS:	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVE	P1,T1		;SAVE POINTER THERE
	TRO	F,R.TYPE	;DUPLICATE TO TTY:
	PUSHJ	P,SSTRDR	;OUTPUT DIR AND DEV
	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	N$WRNX	(LKE,)
	HRRZ	T1,FEXT(P1)	;GET ERROR CODE
	MOVE	T3,FPRV(P1)	;GET LOOKUP ANSWER (PROT. CODE)
	PUSHJ	P,.LKERR##	;LIST ERROR CODE
	MOVEI	T1,[ASCIZ / file    /]
	PUSHJ	P,.TSTRG##	;OUTPUT HEADING
	PUSHJ	P,LSTFNX	;LIST FILE NAME
	MOVEI	C,"."		;SEPARATE WITH
	PUSHJ	P,LCHR		; A DOT
	HLLZ	T2,FEXT(P1)	;GET EXTENSION
	PUSHJ	P,LSIXT		;LIST IT
	MOVEI	T1,.CHTAB	;PICK UP TAB
	PUSHJ	P,.TTCHR	; AND TYPE IT
	SKIPN	S.WDTH		;SEE IF /WIDTH
	PUSHJ	P,LSTRDX	;LIST STR/DIR
X$$LKE:	TRZ	F,R.TYPE	;CLEAR FLAG
	PJRST	.TCRLF##	;END LINE

> ;END OF REPEAT 0
;LSTFNM -- LIST FILE NAME IN APPROPRIATE MODE
;USES T1, T2, T3, T4

LSTFNM:	PUSHJ	P,.SAVE1	;SAVE P1
	MOVEI	P1,0		;SET TO NO OFFSET
LSTFNX:	HLRZ	T1,FEXT(P1)	;LOOK AT EXTENSION
	CAIN	T1,'UFD'	;TO SEE IF IT IS A UFD
	SKIPGE	FNAM(P1)	;YES--SEE IF ALPHA
	JRST	.+2		;YES--USE SIXBIT ANYWAY
	JRST	FLUFD		;NO--SPECIAL PRINT
	MOVE	T2,FNAM(P1)	;OUTPUT FILE NAME
	PJRST	LSIX		;LIST IN SIXBIT

FLUFD:	HLRZ	T1,FNAM(P1)	;GET PROJECT
	SKIPLE	S.CMP		;IF /COMPARE
	SETOM	S.FUFD		;FORCE THE PRINTING OF THE UFD.
	PUSHJ	P,LOCT6B	;ISSUE RIGHT ADJUSTED
	SETZM	S.FUFD		;RESET THE PRINTTING WHEN DONE
	MOVEI	C,","		;ISSUE COMMA
	PUSHJ	P,LCHR		; ..
	HRRZ	T1,FNAM(P1)	;GET PROGRAMMER
	PJRST	LOCT		;ISSUE LEFT ADJUSTED
;SSTRDR -- SET FLAGS TO LIST STR AND OR DIRECTORY
;CALL:	PUSHJ	P,SSTRDR
;	WITH I AND P1 SETUP
;USES T1-4

SSTRDR:	MOVE	T1,FSTR(P1)	;SEE IF SAME FILE STRUCTURE
;RDH	CAMN	T1,[SIXBIT /DSK/]
;RDH	SKIPE	LASSTR		;IS IT THE FIRST ONE?
;RDH	JRST	.+2		;NO--PRINT IT
;RDH	MOVEI	T1,0		;IF FIRST DSK, NEVER PRINT
	MOVEM	T1,LSTSTR	;SAVE FOR PRINTING
	EXCH	T1,LASSTR	;UPDATE MEMORY
	CAMN	T1,LASSTR	;SEE IF DIFFERENT
	SETZM	LSTSTR		;SAME--FLAG TO NOT PRINT

	MOVEI	T3,(I)		;POINT TO DIRECTORIES
	HRLI	T3,-.FXLND	;SET COUNT
SSTRD1:	SKIPN	.FXDIR(T3)	;SEE IF NULL DIRECTORY
	SKIPE	T2,.FXDIM(T3)	;YES--USE WILDCARD STRAIGHT
	SETCM	T2,.FXDIM(T3)
	JUMPN	T2,SSTRD2	;IF WILD--PROCEED
	AOS	T3		;ADVANCE EXTRA SHOT
	SKIPN	.FXDIR-1(T3)	;SEE IF AT END
	SKIPE	.FXDIM-1(T3)	; ..
	AOBJN	T3,SSTRD1	;LOOP UNTIL DONE

;HERE WITH T2=0 IF NOT WILD DIRECTORY, .NE. 0 IF WILD
;COPY THIS DIRECTORY TO OLD ONE WATCHING FOR CHANGES

SSTRD2:	MOVE	T1,UFDPPN(P1)	;SEE IF SAME DIRECTORY
	MOVEM	T1,LSTDIR	;SAVE FOR LISTING
	EXCH	T1,LASDIR	;UPDATE MEMORY
	PUSH	P,T2
	MOVE	T2,T1		;SETUP POINTER TO OLD AREA
	MOVE	T3,UFDPPN(P1)	;  AND TO NEW AREA
	TLNE	T3,-1		;SEE IF NEW HAS PATH
	JRST	SSTRD4		;NO--PROCEED
	TLNE	T2,-1		;IF OLD DIDN'T,
	SETOM	T1		; THEN DEFINITELY DON'T MATCH

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVEI	T2,LASPTH	;POINT TO LAST PATH
	HRLI	T3,-.FXLND	;SET LOOP COUNTER
SSTRD3:	MOVE	T4,.PTPPN(T3)	;GET NEW DIRECTORY
	CAME	T4,.PTPPN(T2)	;SEE IF SAME AS OLD ONE
	SETOM	T1		;NO--SET DIFFERENT FLAG
	MOVEM	T4,.PTPPN(T2)	;STORE FOR OLD MEMORY
	AOS	T2		;ADVANCE OLD POINTER
	SKIPE	T4		;SEE IF END OF PATH YET
	AOBJN	T3,SSTRD3	;NO--LOOP UNTIL DONE
	CAME	T1,[-1]		;SEE IF DIFFERENT
	MOVE	T1,LASDIR	;SAME--FAKE OUT CHECK BELOW

;HERE WITH T1=OLD DIRECTORY (OR -1 IF KNOWN DIFFERENT)

SSTRD4:	CAMN	T1,LASDIR	;NO--SEE IF CHANGED
	SETZM	LSTDIR		;NO--CLEAR LISTING FLAG

	TRNE	F,R.FAST	;SEE IF /F
	SKIPLE	S.SUM		;YES--SEE IF /SUM
	JRST	.+2		;/F/SUM OR NOT /F
	JRST	SSTRD6		;/F AND NOT /SUM--NO SUBTOTALS
	SKIPN	LSTSTR		;SEE IF SEVERAL STRS
	SKIPE	LSTDIR		;OR SEVERAL DIRS
	PUSHJ	P,SUBTOT	;YES--ISSUE SUBTOTALS
	MOVE	T1,LASSTR	;GET LAST STRUCTURE
	MOVEM	T1,SUBSTR	;SAVE FOR SUBTOTALS
	SKIPE	T1,LASDIR	;GET LAST DIRECTORY
	TLNE	T1,-1		;SEE IF PATH POINTER
	JRST	SSTRD5		;NO--JUST STORE WORD
	HRLZS	T1		;SET AS FROM POINTER
	HRRI	T1,SUBPTH	;SET TO POINTER
	BLT	T1,SUBEND	;COPY PATH
	MOVEI	T1,SUBPTH	;SET POINTER TO SUBTOTAL PATH
SSTRD5:	MOVEM	T1,SUBDIR	;SAVE SUBTOTAL DIRECTORY

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

SSTRD6:	POP	P,T2		;RESTORE WILD FLAG (.NE. 0 IF WILD)
	SKIPN	S.SORT		;SEE IF SORTING
	JRST	SSTRD7		;NO--PROCEED
	SETOM	LSTSTR		;YES--SET TO LIST
	SETOM	LSTDIR		;LIST DIRECTORY
	SKIPGE	T1,.WLDFL##	;SEE IF WILD STR
	SETCM	T1,T1		;  OR WILD FILE AND STR
	CAIE	T1,1		; ..
	SETZM	LSTSTR		;NO--CLEAR LIST
	SKIPN	T2		;CHECK WILD DIRECT
	SETZM	LSTDIR		;NO--CLEAR LIST DIRECT
SSTRD7:	SKIPLE	S.IND		;IF /INDIRECT
	JRST	[SKIPN S.PRDE	;IF /NOPRDEVICE
		  POPJ	P,	;THEN DON'T OUTPUT DEVICE NAME
		 SKIPE T2,FSTR	; IF STRUCTURE KNOWN,
		 PUSHJ P,LSIXCL	; OUTPUT IT ALWAYS
		 POPJ  P,]	;AND RETURN
	SKIPN	S.SORT		;UNLESS /SORT,
	SKIPG	S.HDSD		;HEADER STR/DIR LISTING?
	JRST	SSTRD8		;NO--PROCEED
	SKIPN	LSTSTR		;YES--SEE IF CHANGE OF STR
	SKIPE	LSTDIR		; OR OF DIRECTORY
	JRST	.+2		;YES--PRINT THEM
	JRST	SSTRD8		;NO--SKIP OUTPUT
	PUSHJ	P,.TNEWL	;FORCE NEW LINE
	TLZN	F,L.SBTT	;JUST OUTPUT A SUB-TITLE?
	JRST	.+3		;NO
	TLZ	F,L.CRLF	;YES, ZAP BLANK-LINE SUPPRESSOR
	PUSHJ	P,LCRLF		;AND GIVE A BLANK LINE
	PUSHJ	P,SSTRD8	;CHECK FOR PRDEV/PRDIR SWS.
	PUSHJ	P,LSTRDX	;PRINT STR AND DIRECTORY
	PUSHJ	P,.TNEWL	;SPACE OVER AND RETURN

SSTRD8:	SKIPL	T1,S.PRDE	;SEE IF /PRDEVICE
	MOVEM	T1,LSTSTR	;YES--USE THAT
	SKIPL	T1,S.PRDI	;SEE IF /PRDIRECTORY
	MOVEM	T1,LSTDIR	;YES--USE THAT
	POPJ	P,		;RETURN
;LSTRDR -- LIST STRUCTURE AND DIRECTORY IF APPROPRIATE
;CALL:	PUSHJ	P,LSTRDR
;RETURNS
;USES T1, T2, T3, T4, C, M

LSTRDR:	SKIPLE	S.IND		;IF /INDIRECT,
	 JRST	[SKIPN	S.PRDI	;DOES HE WANT DIRECTORY?
		 POPJ	P,	;NO - JUST RETURN NOW
		 JRST	FLBDIR] ;YES - PRINT DIRECTORY SANS <TAB>
	PUSHJ	P,.SAVE1	;SAVE P1
	MOVEI	P1,0		;SET TO NO OFFSET
LSTRDX:	SKIPN	LSTSTR		;SEE IF APPROPRIATE TO LIST
	JRST	FNSTR		;NO--PROCEED
	SKIPE	T1,NOCHRS	;SEE IF INTO LINE
	JRST	[CAIG  T1,7	;SEE IF AT LEAST COL 8 YET
		 PUSHJ P,LTAB	;NO--MOVE OVER
		 PUSHJ P,LTAB	;YES--POSITION
		 JRST  .+1]	;PROCEED
	SKIPE	T2,FSTR(P1)
	PUSHJ	P,LSIXCL	;DO SO IN SIXBIT WITH COLON
FNSTR:	SKIPN	LSTDIR		;SEE IF TIME TO LIST
	POPJ	P,		;NO--PROCEED
FLDIR:	SKIPE	NOCHRS		;SEE IF INTO LINE
	PUSHJ	P,LTAB

;FLBDIR -- SUBROUTINE TO LIST DIRECTORY INSIDE []

FLBDIR:	SKIPN	T4,UFDPPN(P1)	;IF UFD,
	POPJ	P,		;(NO--RETURN)
	TLNN	T4,-1		;[454] PPN OR PATH POINTER?
	SKIPE	.PTPPN(T4)	;[454] PATH POINTER, ANYTHING THERE?
	CAIA			;[454] VALID DIRECTORY, TYPE IT OUT
	POPJ	P,		;[454] NULL DIRECTORY, DON'T LIST "[0]"
	MOVEI	C,"["
	PUSHJ	P,LCHR
	PUSHJ	P,LDIRB
	MOVEI	C,"]"
	PJRST	LCHR		;AND RETURN
;HERE AT END OF A NON-DISK DIRECTORY

DIREND:	PUSHJ	P,DIRE		;OUTPUT SUMMARY AND TOTAL LINE
	TRZ	F,R.WORD!R.NDSK	;CLEAR WORD MODE AND NOT DISK
	MOVE	I,.WILAS	;GET END OF SET
	MOVEM	I,I.NXRD	;SET FOR MASTER LOOP
	POPJ	P,		;RETURN
	SUBTTL	MISCELLANEOUS DIRECTORY SUBROUTINES

;ENDSUB -- ROUTINE TO CLEAN UP SUBTOTALS AT END

ENDSUB:	SKIPLE	NUMSUB		;SEE IF SUBTOTALS ALREADY
	PJRST	SUBTOT		;YES--DO SOME MORE
	PJRST	SUBLOP		;NO--JUST CLEAN END OF WORK


;SUBTOT -- ROUTINE TO ISSUE SUBTOTALS
;USES T1-4

SUBTOT:	SKIPN	S.SUM		;SEE IF /NOSUM
	POPJ	P,		;YES--NEVER GIVE IT
	PUSHJ	P,.SAVE1	;SAVE P1
	SKIPE	NOCHRS		;SEE IF AT START OF LINE
	PUSHJ	P,LCRLF		;NO--END THIS LINE
	MOVEI	P1,SUBT-TOT	;POINT TO SUBTOTALS
	SKIPLE	FLFSUM		;SEE IF FORCED SUMMARY
	JRST	SUBTDO		;YES--GO DO SUBTOTAL
	MOVEI	T1,1		;SET ONE
	CAML	T1,SNFILF	;IF MORE THAN ONE FILE
	CAMGE	T1,SNFILR	;OR MORE THAN ONE ERROR
SUBTDO:	PUSHJ	P,TOTALS	;GO ISSUE SUBTOTALS

;HERE FROM END OF DISK TO MOVE SUBT. TO TOT.

SUBLOP:	SKIPN	SNFILF		;SEE IF ANY FILE FOUND
	SKIPE	SNFILR		;OR ANY ERRORS
	AOS	NUMDIR		;COUNT DIRECTORY FOUND
	PUSH	P,TCHKSM	;PRESERVE TOTAL CHECKSUM
	MOVSI	T1,-<SUBT-TOT>	;SET COUNT TO COPY
SUBTL:	MOVE	T2,SUBT(T1)	;GET SUBTOTAL
	ADDM	T2,TOT(T1)	;ADD INTO TOTAL
	SETZM	SUBT(T1)	;CLEAR SUBTOTAL
	AOBJN	T1,SUBTL	;LOOP UNTIL DONE
	POP	P,TCHKSM	;RESTORE TOTAL CHECKSUM
	SETZM	SUBSTR		;CLEAR STRUCTURE FROM TOTAL
	POPJ	P,		;RETURN
;DIRE  -- OUTPUT EMPTY OR TOTAL LINE
;DIRET -- OUTPUT TOTAL LINE
;CALL:	PUSHJ	P,DIRE/DIRET
;USES T1-4

DIRE:	PUSHJ	P,ENDSUB	;FINISH LAST SUBTOTAL
	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	T1,[ASCIZ /Directory empty/]
	SKIPE	NOFIL
	MOVEI	T1,[ASCIZ /Directory has no such files/]
	SKIPN	NOFILF
	JRST	DIREL		;GO PRINT MESSAGE
DIRET:	PUSHJ	P,ENDSUB	;FINISH LAST SUBTOTAL
	PUSHJ	P,.TNEWL	;FORCE NEW LINE
	SKIPLE	FLFSUM		;SEE IF FORCED SUMMARY
	JRST	DIRETP		;YES--GO DO IT
	TRNE	F,R.NDSK	;NO--SEE IF NOT DISK FORMAT
	JRST	DIRELX		;RIGHT--NO SUMMARY
	MOVE	T1,NOFILR	;GET NUMBER OF LOOKUP ERRORS
	MOVE	T1,NOFILF	;SEE HOW MANY FILES FOUND
	CAILE	T1,1		;IF LE 1, NO SUMMARY NEEDED
	SKIPN	NOBLKS		;SEE IF BLOCKS ACCUMULATED
	JRST	DIRELX		;NO--JUST PRINT BLANK LINE AND RETURN
DIRETP:	SKIPN	S.SUM		;SEE IF /NOSUM
	POPJ	P,		;YES--NEVER DO IT
	SOSG	NUMSUB		;SEE IF SUBTOTALS
	PUSHJ	P,LCRLF		;NO--SEPARATE SUMMARY BY BLANK LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	PUSHJ	P,.CLOSU##	;CLEAR ^O SUPPRESSION
	PUSHJ	P,.SAVE1	;SAVE P1
	MOVEI	P1,0		;POINT TO TOTALS
	MOVEI	T1,[ASCIZ /  Grand total of /]
	SKIPGE	T2,NUMSUB	;GET NUMBER OF SUBTOTALS
	JRST	TOTALS		;IF NONE, DO TOTAL
	JUMPN	T2,TOTALO	;IF SEVERAL, DO GRAND TOTAL
	MOVE	T2,NUMDIR	;IF ONE, GET NUMBER OF DIRECTORIES
	CAIG	T2,1		;IF MORE THAN ONE, DO GRAND TOTAL
	JRST	DIRELX		;NO--JUST EXIT
	JRST	TOTALO		;YES--GIVE GRAND TOTAL

;TOTALS -- ROUTINE TO ISSUE EITHER SUB OR GRAND TOTALS
;CALL:	MOVEI	P1,0 FOR GRAND OR SUBT-TOT FOR SUBS
;USES T1-4

TOTALS:	MOVEI	T1,[ASCIZ /  Total of /]
TOTALO:	SKIPN	NOFILF(P1)	;SEE IF ANY FILES
	SKIPE	NOFILR(P1)	; OR ERRORS
	SKIPA			;YES--OUTPUT LINE
	POPJ	P,		;NO--SKIP TOTAL LINE
	TLO	F,L.SBTT	;SUB/TOTALS LINE PRINTED
	PUSHJ	P,.TSTRG	;PRINT HEADING
	AOS	NUMSUB		;COUNT SUBTOTAL
	SKIPN	NOFILF(P1)	;SEE IF ANY FILES
	JRST	[SKIPN NOFILR(P1)	;NO--SEE IF ANY ERRORS
		 JRST  DIRETF		;NO--SAY 0 FILES
		 JRST  DIRETL]		;YES--TELL ALL
	TRNE	F,R.FAST	;SEE IF /F
	SKIPLE	S.SUM		; AND NOT /SUM
	SKIPA			;NO--DO THE OUTPUT
	JRST	DIRETF		;YES--SKIP "N BLOCKS"
	TRNE	F,R.WORD	;WORDS OR BLOCKS DESIRED?
	SKIPA	T1,NOWRDS(P1)	;WORDS
	MOVE	T1,NOBLKS(P1)	;BLOCKS
	PUSH	P,T1		;SAVE FOR MOMENT
	PUSHJ	P,.TDECW##	;PRINT NUMBER OF BLOCKS
	MOVEI	T1,[ASCIZ / block/]
	TRNE	F,R.WORD	;SEE IF WORD MODE
	MOVEI	T1,[ASCIZ / word/]
	PUSHJ	P,.TSTRG##	;PRINT WORD OR BLOCK
	POP	P,T2		;GET BACK WORD/BLOCK COUNT
	MOVEI	T1,"s"		;MAKE PLURAL IF NEEDED
	CAIE	T2,1		; ..
	PUSHJ	P,.TCHAR##	;YES

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	MOVEI	T1,[ASCIZ / in /]	;AND REST OF MESSAGE
	PUSHJ	P,.TSTRG##	; ..
DIRETF:	MOVE	T1,NOFILF(P1)	;GET NUMBER OF FILES
	PUSHJ	P,.TDECW##	;  FOUND AND PRINTED
	MOVEI	T1,[ASCIZ / file/]
	PUSHJ	P,.TSTRG##	;OUTPUT LINE
	MOVE	T2,NOFILF(P1)	;GET NUMBER FOUND
	MOVEI	T1,"s"		;GET PLURAL
	CAIE	T2,1		;SEE IF NOT ONE
	PUSHJ	P,.TCHAR##	;YES--TYPE PLURAL
	SKIPG	S.FIND		;IF /FIND THEN CHECKSUMS VALID ONLY FOR
				;THE INDIVIDUAL FILES . . .
	SKIPG	S.CHK		;SEE IF /CHECKSUM
	JRST	DIRETC		;NO--PROCEED
	MOVE	T1,TCHKSM(P1)	;GET AGGRAGATE CHECKSUM
	MOVEM	T1,CHKSUM	;SET FOR PRINTOUT
	SETZM	TCHKSM(P1)	;CLEAR FOR NEXT TIME
	MOVEI	M,[ASCIZ / Checksum = /]
	PUSHJ	P,LSTR
	PUSHJ	P,LCHECK	;LIST CHECKSUM
DIRETC:	SKIPN	NOFILR(P1)	;SEE IF ANY ERRORS
	JRST	DIRELE		;NO--THAT'S ALL
	MOVEI	T1,[ASCIZ / and /]
	PUSHJ	P,.TSTRG##	;YES--ISSUE CONNECTIVE
DIRETL:	MOVE	T1,NOFILR(P1)	;GET NUMBER OF ERRORS
	PUSHJ	P,.TDECW##	;TYPE THE COUNTER
	MOVEI	T1,[ASCIZ / LOOKUP error/]
	PUSHJ	P,.TSTRG##	;TYPE LABEL
	MOVE	T2,NOFILR(P1)	;GET COUNT
	MOVEI	T1,"s"		;GET PLURAL
	CAIE	T2,1		;SEE IF NOT ONE
	PUSHJ	P,.TCHAR##	;TYPE PLURAL
	JRST	DIRELE		;AND GO FINISH
DIREL:	PUSHJ	P,.TSTRG##
DIRELE:	MOVE	T1,NUMDIR	;SEE HOW MANY DIRECTORIES
	CAILE	T1,1		;SEE IF MORE THAN ONE
	JUMPE	P1,DIRELF	;YES--JUMP IF GRAND TOTAL
	SKIPN	SUBSTR		;SEE IF DEVICE KNOWN
	JRST	DIRELF		;NO--SKIP THIS LINE
	MOVEI	T1,[ASCIZ / on /]
	PUSHJ	P,.TSTRG##
	MOVE	T1,SUBSTR	;GET STRUCTURE
	PUSHJ	P,.TSIXN##	;LIST IT
	MOVEI	T1,[ASCIZ /: /]
	PUSHJ	P,.TSTRG##	;LIST SEPARATION
	MOVEI	T1,SUBDIR	;POINT TO DIRECTORY
	PUSHJ	P,.TDIRB##	;PRINT IT
DIRELF:	PUSHJ	P,.TCRLF##
DIRELX:	SKIPG	S.SUM		;UNLESS /SUMMARY,
	PUSHJ	P,LCRLF		; GIVE A BLANK LINE
	POPJ	P,		;RETURN
DM	FND,.FXLEN,0,0

DEFINE	SWTCHS,<
SP ACCESS,S.ACCS,.SWDEC##,ACC,FS.NFS!FS.LRG
SN ACCOUNT,S.ACCT,FS.NFS
SS *ALLOCATED,S.ALC,1,FS.NFS
SN AUTHOR,S.AUT,FS.NFS
SP *BLOCKINGFACTOR,S.BFCT,.SWDEC##,FCT,FS.NFS
;SS *BLOCKS,S.WORD,0,FS.NFS
SN CHECKSUM,S.CHK,FS.NFS
SN COMPARE,S.CMP,FS.NFS
SN DETAIL,S.DTL,FS.NFS
SN DIRECT,S.DIRE,FS.NFS
SN DTA,S.DTA,FS.NFS
SN EOTS,S.EOT,FS.NFS
SN ERLOG,S.ERLO,FS.NFS
SS *FAST,<POINTR (FLAGS,R.FAST!R.SLOW)>,R.FAST/R.FAST,FS.NFS
SP FILES,S.FILE,.SWDEC##,FIL,FS.NFS
SN FIND,S.FIND,FS.NFS
SN FLSDIR,S.FLSD,FS.NFS
SN FNDBLD,S.FBLD,FS.NFS
SP FNDDAT,F.BLK,.SWFIL##,FND,FS.NFS!FS.VRQ
SN HDSDIR,S.HDSD,FS.NFS
SN *INDIRECT,S.IND,FS.NFS
SS *LIST,S.DODV,1,FS.NFS
SN MARKS,S.MARK,FS.NFS
SN MVOLUM,S.MVOL,FS.NFS
SS *NORMAL,<POINTR (FLAGS,R.FAST!R.SLOW)>,0,FS.NFS
SN PRDEVICE,S.PRDE,FS.NFS
SN PRDIRECTORY,S.PRDI,FS.NFS
SN PRVERSION,S.PRVE,FS.NFS
SN RETRY,S.RETR,FS.NFS
SN REWINDS,S.REWS,FS.NFS
SN SBRMSG,S.SBRM,FS.NFS
SS *SLOW,<POINTR (FLAGS,R.FAST!R.SLOW)>,R.SLOW/R.FAST,FS.NFS
SN SORT,S.SORT,FS.NFS
SN SUMMARY,S.SUM,FS.NFS
SN TITLES,S.TITL,FS.NFS
SN TMPCOR,S.TMPC,FS.NFS
SN UNITS,S.UNIT,FS.NFS
SP *WIDTH,S.WDTH,.SWDEC##,WID,FS.NFS
SN WORDS,S.WORD,FS.NFS
SS WRITTEN,S.ALC,0,FS.NFS
>
	DOSCAN	(DRSWT)
	SUBTTL	SUBROUTINES FOR LISTING OUTPUT

;ERROR -- ROUTINE TO ISSUE ERROR MESSAGE WITH JUST TEXT
;ERRORC -- ROUTINE TO ISSUE ERROR MESSAGE WITH MORE STUFF
;WARN -- ROUTINE TO ISSUE WARNING MESSAGE

ERROR:	HRLI	T2,(1B0)	;SET FLAG TO NOT RETURN
ERRORC:	TLOA	T2,"?"		;SET FATAL ERROR CODE
WARN:	HRLI	T2,"%"		;SET WARNING CODE
	HRLI	T1,'DRT'	;SET DIRECT'S PREFIX
	PUSHJ	P,.ERMSG##	;ISSUE MESSAGE
	JUMPGE	T1,.POPJ##	;RETURN UNLESS ERROR ENTRY

;LFERX -- ROUTINE TO CLEAN UP AFTER FATAL ERROR
;THE ROUTINES IN SCAN CANNOT BE USED AFTER ANOTHER PUSHJ

LFERX:	PUSHJ	P,.TCRLF##	;ISSUE FINAL <CRLF>
	RELEAS	LC,		;BIND OFF LISTING
	RESET			;CLEAR I/O AND CORE ASSIGNMENTS
	JRST	MAINLP		;AND TRY AGAIN
;TITLER -- PLACE PAGE TITLE IF USER REQUESTED ONE
;CALLED AT START OF FIRST PAGE AND END OF EACH PAGE BUT LAST
;CALL:	PUSHJ	P,TITLER

TITLER:	PUSHJ	P,SAVTYP	;CLEAR R.TYPE AND SAVE OLD VALUE
	PUSH	P,M		;PRESERVE POINTER
	PUSH	P,C		;PRESERVE CHARACTER
	SKIPG	S.TITL		;SEE IF TITLES ON
	JRST	TITLEY		;NO--RETURN
	MOVEI	M,LN$LPP+2	;RESET LINES THIS PAGE COUNT
	MOVEM	M,LNPP		; ..
	TRON	F,R.LSOM	;SEE IF FIRST CALL
	JRST	TITLEH		;YES--SKIP BIND-OFF OF PREVIOUS PAGE
	MOVEI	C,.CHFFD	;EJECT TO NEW PAGE
	PUSHJ	P,LCHR		; ..

;HERE WHEN IT IS DESIRED TO OUTPUT A PAGE HEADER

TITLEH:	PUSH	P,T1		;SAVE T1-P1
	PUSH	P,T2
	PUSH	P,T3
	PUSH	P,T4
	PUSH	P,P1
	MOVEI	M,[ASCIZ /	Directory listing	/]
	PUSHJ	P,LSTR		;SEND START OF LINE 1
	DATE	T4,		;GET CURRENT DATE
	PUSHJ	P,LDATE		;PRINT IT
	PUSHJ	P,LTAB		;SPACE OVER
	MSTIME	T4,		;GET CURRENT TIME
	IDIVI	T4,^D60000	;CONVERT TO MINUTES
	PUSH	P,P1		;SAVE REMAINDER
	PUSHJ	P,LTIME		;PRINT TIME (HH:MM)
	POP	P,T1		;RESTORE REMAINDER
	IDIVI	T1,^D1000	;CONVERT TO SECONDS
	PUSHJ	P,LTIMES	;PRINT SECONDS (:SS)
	MOVEI	M,[ASCIZ /	Page /]
	PUSHJ	P,LSTR		;SPACE OVER TO PAGE NUMBER
	AOS	T1,PAGCNT	;GET NEXT PAGE NUMBER
	PUSHJ	P,LDEC2		;LIST IT
	TRNE	F,R.NDSK	;SEE IF NOT A DISK
	JRST	TITLEX		;RIGHT--SKIP SUBTITLE
	PUSHJ	P,LCRLF		;END OF LINE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN FIRST LINE HAS BEEN PRINTED, DO THE REST

	MOVEI	M,[ASCIZ /Name Extension/]
	PUSHJ	P,LSTR
	TRNE	F,R.FAST
	JRST	TITLEX
	TRNE	F,R.WORDS	;[451] /WORDS SPECIFIED?
	PUSHJ	P,LSPC4		;[451] YES, ALLOW FOR WIDER COLUMN
	MOVEI	M,[ASCIZ / Len  Prot  /]
	PUSHJ	P,LSTR
	MOVEI	M,[ASCIZ /Checksum/]
	SKIPLE	S.CHK
	PUSHJ	P,LSTR
	MOVEI	M,[ASCIZ /  Creation/]
	TRNE	F,R.SLOW
	MOVEI	M,[ASCIZ /   Access      ---Creation---   Mode/]
	PUSHJ	P,LSTR
	MOVEI	M,[ASCIZ /	   Version/]
	SKIPE	S.PRVE		;SKIP IF /NOPRVERSION
	PUSHJ	P,LSTR		;<TAB><SP><SP><SP>VERSION
	MOVEI	M,[ASCIZ/			Account String/]
	SKIPLE	S.ACCT
	PUSHJ	P,LSTR
	MOVEI	M,[ASCIZ/	Author/]
	SKIPLE	S.AUT		;NEED AN AUTHOR FIELD?
	PUSHJ	P,LSTR		;<TAB>AUTHOR
	MOVEI	M,[ASCIZ/	Device/] ;NO
	SKIPN	S.PRDE		;IF /NOPRDEVICE
	JRST	TITLE5		;THEN NO DEVICE FIELD EVER
	SKIPG	S.PRDE		;IF /PRDEVICE
	SKIPLE	S.FLSD		;OR /FLSDIR
	PUSHJ	P,LSTR		;<TAB>DEVICE
TITLE5:	MOVEI	M,[ASCIZ/	Directory/]
	SKIPN	S.PRDI		;IF /NOPRDIRECTORY
	JRST	TITLE6		;THEN NO DIRECTORY FIELD EVER
	SKIPG	S.PRDI		;IF /PRDIRECTORY
	SKIPLE	S.FLSD		;OR /FLSDIR
	PUSHJ	P,LSTR		;<TAB> [DIRECTORY]
TITLE6:				;SPOOLNAME HERE IF FIGURE OUT
				;WHAT TO DO WITH IT . . .

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
TITLEX:	POP	P,P1		;RESTORE THE ACS
	POP	P,T4
	POP	P,T3
	POP	P,T2
	POP	P,T1
	PUSHJ	P,LCRLF		;ISSUE END OF LINE
	TLZ	F,L.CRLF	;TURN OFF CRLF SUPPRESS FLAG
	PUSHJ	P,LCRLF		;AND A BLANK LINE

TITLEY:	SKIPGE	LNPP		;SEE IF FIRST TIME
	JRST	[HRLOI C,377777	;YES--SET COUNTER HIGH
		 MOVEM C,LNPP	;YES--CLEAR FLAG
		 SKIPG S.SUM	;UNLESS /SUMMARY,
		 PUSHJ P,LCRLF	;YES--SKIP ONE LINE
		 JRST  .+1]	; AND CONTINUE
	POP	P,C		;RESTORE CHARACTER
	POP	P,M		;RESTORE POINTER
	POPJ	P,		;RETURN
;LDIRB -- LIST DIRECTORY IN SFD FORMAT
;CALL:	MOVE	T4,CONTENTS OF UFDPPN
;	PUSHJ	P,LDIRB
;USES T1, T2, T3, T4, C

LDIRB:	JUMPE	T4,.POPJ##	;GIVE UP IF BLANK
	JUMPL	T4,[MOVE  T2,T4 ;IF SIXBIT, TYPE IT
		    PJRST LSIXN]
	TLNE	T4,-1		;SEE IF SFD POINTER
	JRST	[PUSH P,[[0]-3]	;NO--JUST DO UFD
		 JRST LDIRBU]

	PUSH	P,T4		;SAVE ARGUMENT
	MOVE	T4,2(T4)	;GET UFD IN PATH LIST
LDIRBU:	JUMPL	T4,[MOVE  T2,T4 ;IF SIXBIT, TYPE IT
		MOVEI	T3,6	;SET FOR 6 CHARS
		SKIPLE	S.SORT
		PUSHJ	P,LSIXC ; IF /SORT, DO 6 CHARS
		SKIPG	S.SORT
		PUSHJ	P,LSIXN
		JRST	LDIRBR]
	SKIPG	S.SORT		;IF NOT /SORT
	JRST	LDIRBN		; PROCEED BELOW
	HLRZ	T1,T4		;IF /SORT,
	PUSHJ	P,LOCT6Z	; DO FIXED FORMAT
	MOVEI	C,","		;SEPARATE HALVES
	PUSHJ	P,LCHR		; WITH A COMMA
	HRRZ	T1,T4		;THEN DO
	PUSHJ	P,LOCT6Z	; RIGHT HALF
	JRST	LDIRBR		;CONTINUE BELOW
LDIRBN:	PUSHJ	P,LXWD		;TYPE UFD
LDIRBR:	POP	P,T4		;RESTORE ARGUMENT
	HRLI	T4,-.FXLND+1	;SET MAX LIST LENGTH
LDIRB1:	SKIPN	T2,3(T4)	;GET NEXT SFD IN PATH
	POPJ	P,		;IF NONE, RETURN
	MOVEI	C,","		;YES--TYPE COMMA
	PUSHJ	P,LCHR		; ..
	MOVEI	T3,6		;SET FIXED LENGTH
	SKIPLE	S.SORT		;IF /SORT
	PUSHJ	P,LSIXC		; DO FIXED
	SKIPG	S.SORT		;ELSE,
	PUSHJ	P,LSIXN		;  AND SFD
	AOBJN	T4,LDIRB1	;LOOP UNTIL DONE
	POPJ	P,		;RETURN
;LVER -- LIST WORD IN VERSION NUMBER FORMAT
;CALL:	MOVE	T4,WORD
;	PUSHJ	P,LVER
;USES T1, T2, T3, T4, C

LVER:	LDB	T1,[POINT 9,T4,11]  ;GET MAJOR VERSION
	SKIPE	T1		;IF NON-ZERO,
	PUSHJ	P,LOCT		;  PRINT IN OCTAL
	LDB	T1,[POINT 6,T4,17]  ;GET MINOR VERSION
	JUMPE	T1,LVER2	;IF NON-ZERO,
	SOS	T1		;OFFSET
	IDIVI	T1,^D26		;  PRINT IN ALPHA
	JUMPE	T1,LVER1	;  ONE OR TWO
	MOVEI	C,"A"-1(T1)	;  CHARACTERS
	PUSHJ	P,LCHR		;  ..
LVER1:	MOVEI	C,"A"(T2)	;  ..
	PUSHJ	P,LCHR		;  ..
LVER2:	HRRZ	T1,T4		;GET EDIT NUMBER
	JUMPE	T1,LVER3	;IF NON-ZERO,
	MOVEI	C,"("		;  PRINT (
	PUSHJ	P,LCHR		;  ..
	PUSHJ	P,LOCT		;  IN OCTAL
	MOVEI	C,")"		;  AND )
	PUSHJ	P,LCHR		;  ..
LVER3:	LDB	T1,[POINT 3,T4,2]
	JUMPE	T1,.POPJ##	;IF CUST. NUMBER NON-ZERO,
	MOVEI	C,"-"		;  PRINT -
	PUSHJ	P,LCHR		;  ..
	PJRST	LOCT		;  AND NUMBER
;LAUT -- LIST THE AUTHOR FIELD
;CALL:	PUSHJ	P,LAUT
;USES T1-4,C

LAUT:	SKIPN	T2,FAUT		;SEE IF ANYTHING THERE
	PJRST	LTAB		;NO--JUST ISSUE TAB
	PJUMPL	T2,LSIXT	;IF SIXBIT, ISSUE AS SUCH
	HLRZ	T1,T2		;ELSE GET PROJECT
	SKIPG	S.SORT		;SEE IF /SORT
	PUSHJ	P,LOCT6B	;NO
	SKIPLE	S.SORT		;ELSE
	PUSHJ	P,LOCT6Z	;YES
	MOVEI	C,","		;SEPARATOR
	PUSHJ	P,LCHR		;TO FILE
	HRRZ	T1,FAUT		;GET PROGRAMMER
	SKIPG	S.SORT		;SEE IF /SORT
	PJRST	LOCT		;NO
	PJRST	LOCT6Z		;YES


;LCHECK -- ROUTINE TO LIST THE ACCUMULATED CHECKSUM
;CALL:	PUSHJ	P,LCHECK
;USES T1, T2, T3, C

LCHECK:	HLRZ	T1,CHKSUM	;YES--COMBINE HALVES
	HRRZ	T2,CHKSUM	;GET RH
	SETZM	CHKSUM		;CLEAR CHECKSUM FOR NEXT FILE
	ADD	T2,T1		;ADD
	HLRZ	T1,T2		;GET CARRY
	ADDI	T1,(T2)		;COMBINE
	PJRST	LOCT6Z		;LIST AS 6 DIGIT OCTAL AND RETURN



;GCHECK -- ROUTINE TO GET THE ACCUMULATED CHECKSUM
;CALL:	PUSHJ	P,GCHECK
;USES T1, T2, T3

GCHECK:	HLRZ	T1,CHKSUM	;COMBINE HALVES
	HRRZ	T2,CHKSUM	;GET RH
	ADD	T2,T1		;ADD
	HLRZ	T1,T2		;GET CARRY
	ADDI	T1,(T2)		;COMBINE
	ANDI	T1,-1		;REDUCE TO 6 DIGITS
	POPJ	P,		;RETURN
;LXWD -- LIST WORD IN XWD FORMAT (N,N)
;CALL:	MOVE	T4,WORD
;	PUSHJ	P,LXWD
;USES T1, T2, T3, C

LXWD:	HLRZ	T1,T4		;GET LEFT HALF
	JUMPE	T1,LXWD1	;SKIP FIRST PART IF 0
	PUSHJ	P,LOCT		;OUTPUT LH IN OCTAL
	MOVEI	C,","		;SEND SEPARATOR
	PUSHJ	P,LCHR
LXWD1:	HRRZ	T1,T4		;DO RIGHT HALF
	PJRST	LOCT		;IN OCTAL AND RETURN

L6XWD:	HLRZ	T1,T4		;GET LEFT HALF
	PUSHJ	P,LOCT6Z	;OUTPUT LH IN OCTAL
	MOVEI	C,","		;SEND SEPARATOR
	PUSHJ	P,LCHR
	HRRZ	T1,T4		;DO RIGHT HALF
	PJRST	LOCT6Z		;IN OCTAL AND RETURN



;LOCT6Z -- LIST 6 OCTAL DIGITS WITH LEADING ZEROS
;LOCTZ -- LIST N OCTAL DIGITS WITH LEADING ZEROS
;CALL:	(MOVE	T2,MASK OF LARGEST NUMBER  IF LOCTZ)
;	MOVE	T1,NUMBER
;	PUSHJ	P,LOCT6Z/LOCTZ
;USES T1, T2, T3, C

LOCT6Z:	MOVEI	T2,-1		;PRESET FOR 6 DIGITS

LOCTZ:	LSH	T2,-3		;COUNT DOWN MASK
	SKIPE	T2		;SEE IF ALL DONE
	CAMLE	T1,T2		;SEE IF DONE YET
	PJRST	LOCT		;REST ARE NON-ZERO
	PUSHJ	P,LZER		;NO--TYPE A ZERO
	JRST	LOCTZ		;AND GO AROUND AGAIN


;LOCT6B -- SAME ONLY LEADING BLANKS
;LOCTB -- SAME ONLY BLANKS

LOCT6B:	MOVEI	T2,-1		;SET FOR 6 DIGITS

LOCTB:	LSH	T2,-3		;COUNT DOWN MASK
	SKIPE	T2		;SEE IF ALL DONE
	CAMLE	T1,T2		;SEE IF DONE YET
	PJRST	LOCT		;REST ARE NON-ZERO
	PUSHJ	P,LSPC		;NO--TYPE A SPACE
	JRST	LOCTB		;AND GO AROUND AGAIN
;LDATE -- OUTPUT DATE IN FORM DD-MMM-YY
;CALL:	MOVE	T4,DATE IN SYSTEM FORMAT
;	PUSHJ	P,LDATE
;USES T1, T2, T3, T4, M, C

LDATE:	PUSHJ	P,.SAVE1	;SAVE P1
	SKIPE	S.SORT		;SEE IF /SORT
	JRST	LDATEN		;YES--USE SORTABLE FORMAT
	JUMPE	T4,LDATEZ	;JUMP IF NO DATE
	IDIVI	T4,^D31		;GET DAY
	MOVEI	T1,1(P1)
	PUSHJ	P,LDEC2
	IDIVI	T4,^D12		;GET MONTH
	MOVE	T1,[ASCII /-Jan--Feb--Mar--Apr--May--Jun--Jul--Aug--Sep--Oct--Nov--Dec-/](P1)
	MOVEI	T2,0
	MOVEI	M,T1
	PUSHJ	P,LSTR
	MOVEI	T1,^D64(T4)	;GET YEAR
	IDIVI	T1,^D100	;GET YEAR IN CENTURY
	MOVE	T1,T2		;GET REMAINDER
	PJRST	LDEC2Z		;OUTPUT YEAR AND RETURN

LDATEZ:	MOVEI	M,[ASCIZ /(undated)/]
	PJRST	LSTR

;HERE WHEN /SORT TO USE ANSI FORMAT:  YYYYMMDD

LDATEN:	PUSHJ	P,LSPC		;SPACE ONE TO USE SAME WIDTH
	IDIVI	T4,^D31		;GET DAYS
	MOVE	T2,P1		;SAVE FOR LATER
	IDIVI	T4,^D12		;GET MONTHS VS. YEARS
	MOVEI	T1,^D1964(T4)	;START WITH YEARS A.D.
	IMULI	T1,^D100	;MAKE ROOM FOR MONTHS
	ADDI	T1,1(P1)	;INCLUDE MONTHS (1=JAN)
	IMULI	T1,^D100	;MAKE ROOM FOR DAYS
	ADDI	T1,1(T2)	;INCLUDE DAYS
	PJRST	LDEC		;OUTPUT THIS MESS

;LDATIM -- OUTPUT DATE AND TIME IN FORM DD-MMM-YY HH:MM:SS
;CALL:	MOVE	T1,TIME RETURNED BY .CNTDT##
;	MOVE	T4,DATE RETURNED BY .CNTDT##
;	PUSHJ	P,LDATIM
;USES T1, T2, T3, T4, M, C

LDATIM:	PUSH	P,T1		;SAVE TIME
	MOVE	T4,T2		;POSITION DATE
	PUSHJ	P,LDATE		;LIST DATE
	PUSHJ	P,LSPC		;SPACE OVER
	POP	P,T4		;RESTORE TIME
	IDIVI	T4,^D60000	;GET MINS
	PUSHJ	P,LTIME		;LIST HH:MM
	MOVE	T1,P1		;GET MILLI-SECS
	IDIVI	T1,^D1000	;CONVERT TO SECS
	PJRST	LTIMES		;LIST :SS
;LOCT3Z -- LIST OCTAL 3 DIGITS (LEADING ZEROS)
;LOCT2Z -- DITTO 2 DIGITS
;CALL:	MOVEI	T1,NUMBER
;	PUSHJ	P,LOCT3Z/2Z
;USES T1, T2, T3, C

LOCT3Z:	CAIGE	T1,100		;TEST FOR FIRST ZERO
	PUSHJ	P,LZER		;YES--DO IT
LOCT2Z:	CAIGE	T1,10		;SEE IF NEXT
	PUSHJ	P,LZER		;YES--DO IT
	PJRST	LOCT		;THEN FINISH NUMBER


;LDECP -- LIST DECIMAL (POSSIBLY NEGATIVE) FOLLOWED BY .
;CALL:	MOVE	T1,NUMBER
;	PUSHJ	P,LDECP
;USES T1, T2, T3, C

LDECP:	JUMPGE	T1,LDECPP	;JUMP IF NOT NEGATIVE
	MOVEI	C,"-"		;TYPE MINUS
	PUSHJ	P,LCHR		; SIGN
	MOVMS	T1		;AND MAKE POSITIVE
LDECPP:	PUSHJ	P,LDEC		;LIST DECIMAL NUMBER
	MOVEI	C,"."		;LIST .
	PJRST	LCHR		;TO INDICATE DECIMAL NUMBER


;LOCT2 -- LIST OCTAL AT LEAST TWO DIGITS
;CALL:	MOVEI	T1,NUMBER
;	PUSHJ	P,LOCT2
;USES T1, T2, T3, C

LOCT2:	CAIGE	T1,10		;SEE IF LARGE ENOUGH
	PUSHJ	P,LSPC		;NO--SEND A SPACE
	PJRST	LOCT		;SEND IN OCTAL
;LTIME -- OUTPUT TIME IN FORM HH:MM
;LTIMEB-- OUTPUT TIME OR BLANKS IF 00:00
;LTIMES-- OUTPUT JUST ":DD" FOR SECONDS CALL
;LSECS -- OUTPUT TIME IN FORM HH:MM:SS
;LMSECS-- DITTO WITH INPUT IN MILLISEC.
;CALL:	(MOVE	T4,TIME IN MINUTES    FOR LTIME/LTIMEB)
;	(MOVE	T1,SECONDS            FOR LTIMES)
;	(MOVE	T4,TIME IN SECONDS    FOR LSECS)
;	(MOVE	T1,TIME IN MSEC       FOR LMSECS)
;	PUSHJ	P,LTIME
;USES T1, T2, T3, T4, C

LSECS:	SKIPA	T1,T4		;MOVE ARGUMENT
LMSECS:	IDIVI	T1,^D1000	;CONVERT TO SECONDS
	IDIVI	T1,^D60		;GET HH:MM PART
	PUSH	P,T2		;SAVE SECONDS
	MOVE	T4,T1		;POSITION HH:MM
	PUSHJ	P,LTIME		;ISSUE HH:MM
	POP	P,T1		;RESTORE SECONDS
	PJRST	LTIMES		;ISSUE :SS AND RETURN

LTIMEB:	JUMPE	T4,LSPC5	;IF 0, PRINT BLANKS

LTIME:	PUSHJ	P,.SAVE1	;SAVE P1
	IDIVI	T4,^D60		;GET HOURS
	MOVE	T1,T4
	PUSHJ	P,LDEC2		;LIST HOURS
	MOVE	T1,P1		;LIST MINUTES

LTIMES:	PUSHJ	P,LCOLON
				;FALL INTO LDEC2Z

;LDEC2Z -- LIST DECIMAL AT LEAST 2 DIGITS WITH LEADING ZERO
;CALL:	MOVEI	T1,NUMBER
;	PUSHJ	P,LDEC2Z
;USES T1, T2, T3, C

LDEC2Z:	CAIGE	T1,^D10		;TEST TO SEE IF NEEDED
	PUSHJ	P,LZER		;YES--SEND ZERO
	PJRST	LDEC		;GO FINISH WORK
;LDEC9 -- LIST DECIMAL AT LEAST NINE DIGITS
;LDEC8 -- LIST DECIMAL AT LEAST EIGHT DIGITS
;LDEC7 -- LIST DECIMAL AT LEAST SEVEN DIGITS
;LDEC6 -- LIST DECIMAL AT LEAST SIX DIGITS
;LDEC5 -- LIST DECIMAL AT LEAST FIVE DIGITS
;LDEC4 -- LIST DECIMAL AT LEAST FOUR DIGITS
;LDEC3 -- LIST DECIMAL AT LEAST THREE DIGITS
;LDEC2 -- LIST DECIMAL AT LEAST TWO DIGITS
;CALL:	MOVEI	T1,NUMBER
;	PUSHJ	P,LDEC2
;USES T1, T2, T3, C

LDEC9:	CAMGE	T1,[^D100000000];WILL IT FIT IN 9 DIGITS?
	PUSHJ	P,LSPC		;NO, EMIT A SPACE FILLER THEN
LDEC8:	CAMGE	T1,[^D10000000]	;SEE IF GREATER THAN 8 DIGITS
	PUSHJ	P,LSPC		;No. type a space then.
LDEC7:	CAMGE	T1,[^D1000000]	;See if greater than 7 digits.
	PUSHJ	P,LSPC		;No. type a space then.
LDEC6:	CAIGE	T1,^D100000	;See if greater than 6 digits.
	PUSHJ	P,LSPC		;No. type a space then.
LDEC5:	CAIGE	T1,^D10000	;See if greater than 5 digits.
	PUSHJ	P,LSPC		;No. type a space then.
LDEC4:	CAIGE	T1,^D1000	;SEE IF NEEDED
	PUSHJ	P,LSPC
LDEC3:	CAIGE	T1,^D100
	PUSHJ	P,LSPC
LDEC2:	CAIGE	T1,^D10
	PUSHJ	P,LSPC		;YES
	PJRST	LDEC		;GO LIST IN DECIMAL
;LDEC -- LIST DECIMAL NUMBER
;LOCT -- LIST OCTAL NUMBER
;LRDX -- LIST VIA PRESET RADIX
;CALL:	MOVEI	T1,NUMBER
;      (MOVEI	T3,RADIX    LRDX ONLY)
;	PUSHJ	P,LDEC/LOCT/LRDX
;USES T1, T2, T3, C

LOCT:	JUMPGE	T1,LOCTC	;IF POS, EASY TO DO
	MOVE	T2,T1		;NO--USE OTHER WAY
	MOVEI	T3,^D12		;SET DIGIT COUNT
LOCTL:	MOVEI	T1,0		;CLEAR RESULT
	LSHC	T1,3		;GET NEXT DIGIT
	MOVEI	C,"0"(T1)	;CONVERT TO ASCII
	PUSHJ	P,LCHR		;OUTPUT IT
	SOJG	T3,LOCTL	;AND LOOP UNTIL DONE
	POPJ	P,		;RETURN

LDEC:	SKIPA	T3,[^D10]	;INITIALIZE FOR DECIMAL RADIX
LOCTC:	MOVEI	T3,10		;INITIALIZE FOR OCTAL RADIX
LRDX:	IDIV	T1,T3		;DIVIDE BY RADIX
	HRLM	T2,(P)		;SAVE REMAINDER
	SKIPE	T1		;SEE IF ANYTHING LEFT
	PUSHJ	P,LRDX		;YES--LOOP BACK WITH PD LIST
	HLRZ	C,(P)		;GET BACK A DIGIT
	ADDI	C,"0"		;CONVERT TO ASCII
	PJRST	LCHR		;GO LIST IT
;LCRLF - LIST END OF LINE
;CALL:	PUSHJ	P,LCRLF
;USES M, C

LCRLF:	TLNE	F,L.CRLF	;HAVE WE DONE A CRLF?
	JRST	[TRZ	F,R.SPLN	;THIS SATISFIES EOL FOR R.SPLN
		POPJ	P,]		;RETURN EMPTY HANDED
	MOVEI	M,[ASCIZ /
/]
				;FALL INTO LSTR

;LSTR - LIST ASCII STRING
;CALL:	MOVEI	M,STRING (END WITH 0 BYTE)
;	PUSHJ	P,LSTR
;USES M, C

LSTR:	TLOA	M,(POINT 7,)	;CONVERT TO BYTE POINTER
LSTR1:	PUSHJ	P,LCHR		;OUTPUT CHARACTER
	ILDB	C,M		;GET NEXT CHARACTER
	JUMPN	C,LSTR1		;LOOP UNLESS NULL
	POPJ	P,		;RETURN


;LSIXT -- LIST SIXBIT WORD FOLLOWED BY TAB
;CALL:	MOVE	T2,WORD
;	PUSHJ	P,LSIXT
;USES T1, T2, C

LSIXT:	PUSHJ	P,LSIX		;OUTPUT WORD
	PJRST	LTAB		;GO OUTPUT TAB AND RETURN


;LSIXCL -- LIST SIXBIT WORD FOLLOWED BY COLON
;CALL:	MOVE	T2,WORD
;	PUSHJ	P,LSIXCL
;USES T1, T2, C

LSIXCL:	PUSHJ	P,LSIX		;ISSUE IN SIXBIT
LCOLON:	MOVEI	C,":"		;GET COLON
	PJRST	LCHR		;ISSUE AND RETURN
;LSIX  -- LIST SIXBIT WORD (AT LEAST ONE SPACE)
;LSIXN -- SAME EXCEPT 0 GIVES NO SPACES
;CALL:	MOVE	T2,WORD
;	PUSHJ	P,LSIX/LSIXN
;USES T1, T2, C

LSIX:	MOVEI	T1,0		;CLEAR NEXT CHARACTER
	LSHC	T1,6		;FETCH NEXT CHAR
	PUSHJ	P,LCHRS		;LIST IT IN SIXBIT

LSIXN:	JUMPN	T2,LSIX		;LOOP UNTIL ONLY BLANKS LEFT
	POPJ	P,		;RETURN


;LSIXC -- LIST SIXBIT WORD FIXED NUMBER OF CHARACTERS
;CALL:	MOVE	T2,WORD
;	MOVEI	T3,NUM CHARS TO PRINT
;	PUSHJ	P,LSIXC
;USES T1, T2, T3, C

LSIXC:	MOVEI	T1,0		;CLEAR NEXT CHAR
	LSHC	T1,6		;GET NEXT CHAR
	PUSHJ	P,LCHRS		;LIST IT IN SIXBIT
	SOJG	T3,LSIXC	;LOOP UNTIL DONE
	POPJ	P,		;RETURN


;LSPC2 -- LIST TWO SPACES
;LSPC4 -- LIST FOUR SPACES
;LSPC5 -- LIST FIVE SPACES
;CALL:	PUSHJ	P,LSPC2
;USES C

LSPC5:	PUSHJ	P,LSPC		;SPACE ONE
LSPC4:	PUSHJ	P,LSPC		;SPACE ONE MORE
LSPC3:	PUSHJ	P,LSPC		;SPACE ANOTHER ONE
LSPC2:	PUSHJ	P,LSPC		;DO ONE
	PJRST	LSPC		;DO ANOTHER AND RETURN


;LCOMMA -- LIST A COMMA
;CALL:	PUSHJ	P,LCOMMA
;USES C

LCOMMA:	MOVEI	C,","		;GET CHARACTER
	PJRST	LCHR1		;GO LIST IT


;LZER -- LIST A ZERO
;CALL:	PUSHJ	P,LZER
;USES C

LZER:	MOVEI	C,"0"		;GET CHARACTER
	PJRST	LCHR1		;GO LIST IT
;LTAB -- LIST TAB
;LSPC -- LIST SPACE
;LCHR -- LIST CHARACTER
;LCHRS -- LIST CHARACTER IN SIXBIT
;CALL:	(MOVEI	C,CHARACTER    IF LCHR)
;	(MOVEI	T1,CHARACTER   IF LCHRS)
;	PUSHJ	P,LTAB/LSPC/LCHR
;USES C EXCEPT LCHR USES NO AC'S

LCHRS:	MOVEI	C," "-' '(T1)	;CONVERT TO ASCII AND MOVE TO C
LCHR:	CAIE	C,.CHTAB	;SEE IF A TAB
	JRST	LCHR1		;NO--GO SEND IT

LTAB:	TRZN	F,R.STAB	;KILL TAB IF SO REQUESTED
	TRON	F,R.LTAB	;SET/TEST TAB
	POPJ	P,		;RETURN IF NOT TWO IN A ROW

LTAB1:	SKIPA	C,[.CHTAB]	;GET THE TAB
LSPC:	MOVEI	C," "		;GET THE SPACE

LCHR1:	SKIPGE	LNPP		;SEE IF AT END OF PAGE
	PUSHJ	P,TITLER	;YES--GO ISSUE PAGE HEADER
	CAIN	C,.CHCRT	;SEE IF CARRIAGE RETURN
	TRZ	F,R.LTAB	;YES--CLEAR TAB MEMORY
	CAIN	C,.CHLFD	;SEE IF END OF LINE
	JRST	[SOS  LNPP	;YES--DECREMENT LINES PER PAGE
		 TLO  F,L.CRLF	;SET ON CRLF SEEN FLAG.
		 TRZE F,R.SPLN	;STOP SUPPRESSING LINE
		 JRST LCHR4	;FINISH LAST SUPPRESSION
		 JRST .+1]	;AND PROCEED
	SKIPLE	S.CMP		;IF /COMPARE,
	JRST	[SKIPN	S.FUFD	;AND PRINTING A "UFD".
		 SKIPE NOCHRS	; AND AT START OF LINE
		 JRST  .+1	;NO--PROCEED
		 CAIE  C,"%"	;YES--IF WARNING
		 CAIN  C,"?"	; OR ERROR
		 TRO   F,R.SPLN	; SUPPRESS
		 CAIE  C,.CHCRT ;IF BLANK LINE, OR
		 CAIN  C," "	;IF BLANK,
		 TRO   F,R.SPLN	; SUPPRESS
		 JRST  .+1]	;AND PROCEED
	TRNE	F,R.SPLN	;IF SUPPRESSING,
	JRST	LCHR4		; HANDLE EXIT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	TRZE	F,R.LTAB	;CLEAR TAB MEMORY
	JRST	LCHR5		;IF SET, GO ISSUE ONE
	CAIE	C,.CHCRT	;IS IT A CR?
	CAIN	C,.CHLFD	;OR A LINE FEED?
	SKIPA			;YES. DON'T TURN OFF THE FLAG.
	TLZ	F,L.CRLF	;ELSE. RESET IT.
	AOS	NOCHRS		;ADVANCE CHARACTER POSITION COUNTER
	CAIE	C,.CHTAB	;SEE IF TAB
	JRST	LCHR3		;NO--PROCEED BELOW
	PUSH	P,T1		;YES--SAVE AN AC
	MOVE	T1,NOCHRS	;GET CHARACTER COUNTER
	ADDI	T1,7		;ROUND UP
	TRZ	T1,7		;ROUND OFF
	SUB	T1,NOCHRS	;FIND EXCESS
	ADDM	T1,NOCHRS	;UPDATE CHARACTER COUNTER
	SKIPE	T1		;IF NO FILLING
	SKIPN	S.SORT		; OR NOT /SORT
	JRST	LCHR2		; DON'T FILL IN SPACES
	MOVEI	C," "		;GET A SPACE
	PUSHJ	P,LCHR3		;OUTPUT IT
	SOJG	T1,.-1		;LOOP FOR ENOUGH SPACE
	MOVEI	C,.CHTAB	;RESTORE THE TAB
LCHR2:	POP	P,T1		;RESTORE AC

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

LCHR3:	SKIPN	S.DIRE		;/NODIRECT?
	JRST	LCHR4		;YES, NO LISTING OUTPUT
	CAIL	C,.CHLFD	;SEE IF VERTICAL MOTION
	CAILE	C,.CHFFD	; ..
	JRST	.+2		;NO
	SETZM	NOCHRS		;YES--CLEAR POSITION
	SOSG	B.LC+.BFCTR	;SEE IF ROOM IN THE BUFFER
	PUSHJ	P,LCHRW		;NO--GO WRITE THIS BUFFER
	IDPB	C,B.LC+.BFPTR	;YES--SEND CHARACTER
	SKIPN	NOCHRS		;SEE IF END OF LINE
	PUSHJ	P,LCHRWL	;YES--OUTPUT BUFFER IF APPROPRIATE
LCHR4:	TRNN	F,R.TYPE	;SEE IF NEED TO DUPLICATE
	POPJ	P,		;NO--RETURN
	PUSH	P,T1		;PRESERVE TEMP
	MOVE	T1,C		;GET CHARACTER
	PUSHJ	P,.TTCHR	;YES--TYPE IT (IF NOT SAME)
	POP	P,T1		;RESTORE TEMP
	POPJ	P,		;RETURN


LCHR5:	PUSH	P,C		;SAVE REQUESTED CHARACTER
	PUSHJ	P,LTAB1		;SEND A TAB
	POP	P,C		;RESTORE CHARACTER
	JRST	LCHR1		;PROCEED


LCHRWL:	TRNE	F,R.OUTL	;SEE IF OUTPUT APPROPRIATE FOR EACH END OF LINE
LCHRW:	OUT	LC,		;OUTPUT BUFFER
	  POPJ	P,		;OK--RETURN
LCHRWR:	PUSH	P,T1		;ERROR--SAVE SOME ACS
	PUSH	P,T2		; ..
	PUSH	P,T3		; ..
	PUSH	P,F		;SAVE F
	TRZ	F,R.OUTO!R.OUTD	;CLEAR OUTPUT FLAGS
	N$WRNX	(LOE,Listing device output error,)
	GETSTS	LC,T1		;GET ERROR STATUS
	PUSH	P,T1		;SAVE THE STATUS
	HRLI	T1,LC		;SUPPLY THE CHANNEL TOO
	PUSHJ	P,IOERM		;ISSUE REST OF ERROR STATUS
	POP	P,T1		;GET BACK THE STATUS
	TXZ	T1,IO.EOF!IO.ERR;CLEAR OFFENSIVE BITS
	SETSTS	LC,(T1)		;AND TELL MONITOR TO CLEAR ERROR STATUS
X$$LOE:	PUSHJ	P,.TCRLF##	;AND END LINE
	POP	P,F		;RESTORE THE ACS
	POP	P,T3		; ..
	POP	P,T2		; ..
	POP	P,T1		; ..
	POPJ	P,		;RETURN
	SUBTTL	MISCELLANEOUS I/O ROUTINES

;FNDIN  --  SUBROUTINE TO OPEN THE FIND INPUT FILES
;USES T1 - T4

FNDIN:	MOVEI	T1,F.BLK	;/FNDDAT SCAN BLOCK
	MOVEI	T2,F.OPN	;OPEN BLOCK
	MOVE	T3,[F.LEN,,F.LKP]  ;FILE LOOKUP BLOCK
	MOVEI	T4,F.PTH	;DIRECTORY PATH BLOCK
	PUSHJ	P,.STOPB##	;SETUP OPEN AND LOOKUP BLOCKS
	  JRST	[N$FAIL (FWI,/FNDDAT wildcards illegal)]
	MOVX	T1,.IOBIN	;FIND FILES ARE BINARY
	IORM	T1,F.OPN	;SET I/O MODE
	MOVEI	T1,B.DG		;DATA FILE INPUT BUFFER RING HEADER
	MOVEM	T1,F.OPN+.OPBUF	;SET IN OPEN BLOCK
	OPEN	DG,F.OPN	;OPEN FIND FILE INPUT DEVICE
	  JRST	E.OPF		;OPEN FAILURE
	MOVEI	T1,F.LEN-1	;LENGTH OF LOOKUP BLOCKS
	MOVEM	T1,F.LKP+.RBCNT	;SET IN LOOKUP BLOCK
	MOVE	T4,F.LKP+.RBPPN	;PRESERVE PATH ACCROSS LOOKUP
	MOVSI	T1,'FDF'	;DATA FILE TYPE
	MOVEM	T1,F.LKP+.RBEXT	;SET IN LOOKUP BLOCK
	LOOKUP	DG,F.LKP	;DO FILE LOOKUP
	  JRST	E.LKF		;LOOKUP FAILURE

;NOW GET THE POINTER FILE

	MOVEI	T1,B.PG		;POINTER FILE INPUT BUFFER RING HEADER
	MOVEM	T1,F.OPN+.OPBUF	;SET IN OPEN BLOCK
	OPEN	PG,F.OPN	;OPEN POINTER FILE DEVICE
	  JRST	E.OPF		;OPEN FAILURE HERE?
	MOVEM	T4,F.LKP+.RBPPN	;USE SAME PATH AS DATA FILE
	MOVSI	T1,'FPF'	;POINTER FILE EXTENSION
	MOVEM	T1,F.LKP+.RBEXT	;SET IN LOOKUP BLOCK
	LOOKUP	PG,F.LKP	;LOOKUP POINTER FILE
	  JRST	E.LKF		;LOOKUP FAILED HERE?

	INBUF	DG,1		;WANT ONLY ONE BUFFER FOR USETI
	INBUF	PG,		;BUT LOTS ARE OK FOR POINTER FILE

	SETZM	DGWRD		;INITIALLY ON WORD 0
	SETOM	DGBLK		;OF BLOCK 0 (I.E., BLOCK 1)
	TLZ	F,L.FEOF	;CLEAR END OF FILE FLAG
	POPJ	P,		;FIND INPUT DATA FILES READY TO BE READ
E.OPF:	MOVE	P3,F.BLK+.FXDEV	;GET FIND DEVICE
	N$FAIN	(OPF,Find File input OPEN failure for device )

E.LKF:	MOVEI	T1,'LKF'	;FIND LOOKUP ERROR PREFIX
	SETZ	T2,		;NO TEXT HERE
	PUSHJ	P,ERRORC	;TYPE OUT ERROR PREFIX
	TXNN	T1,JWW.FL	;WANT FIRST LINE INFO?
	JRST	LFERX		;NO, ABORT NOW
	HRRZ	T1,F.LKP+.RBEXT	;YES, GET LOOKUP ERROR CODE
	PUSHJ	P,.LKERR##	;TYPE OUT ERROR CODE
	MOVEI	T1,[ASCIZ/ Find input file /]
	PUSHJ	P,.TSTRG##	;TYPE OUT MORE ENGLISH TEXT
	MOVEI	T1,F.OPN	;ADDRESS OF OPEN BLOCK
	MOVEI	T2,F.LKP	;ADDRESS OF LOOKUP BLOCK
	PUSHJ	P,.TOLEB##	;TYPE OUT THE FILE SPEC
	JRST	LFERX		;CAP OFF THE ERROR
;OUTIN -- SUBROUTINE TO OPEN THE OUTPUT LISTING FILE
;USES T1-4

OUTIN:	MOVE	T1,[O.LZER,,O.BLK]  ;POINT TO OUTPUT SPEC
	MOVEI	T2,O.LC		;POINT TO OUTPUT OPEN BLOCK
	MOVE	T3,[LE.LC-1,,E.LC]  ;POINT TO OUTPUT ENTER BLOCK
	PUSHJ	P,.STOPN##	;SETUP BLOCKS
	  JRST	E.OWI		;ERROR IF WILD-CARDS
	MOVSI	T1,B.LC		;GET BUFFER HEADERS
	MOVEM	T1,O.LC+.OPBUF	;STORE IN OPEN BLOCK
	MOVE	T4,E.LC+.RBPPN	;SAVE OUTPUT PATH

	SKIPN	S.DIRE		;/NODIRECT?
	JRST	OUTIN4		;YES, CHECK FOR FNDBLD
	OPEN	LC,O.LC		;OPEN DEVICE
	  JRST	E.OPO
	MOVE	T1,O.BLK+.FXNAM	;ENTER IF NEEDED
	JUMPE	T1,OUTIN2
	MOVEI	T1,0		;LONG OFFSET
	TLNN	F,L.LENT	;IF SHORT ENTER,
	MOVEI	T1,2		; SET SHORT OFFSET
	ENTER	LC,E.LC(T1)	;ENTER FILE
	  JRST	E.OPE

OUTIN2:	OUTBUF	LC,0		;SETUP STANDARD BUFFERS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

OUTIN4:	SKIPG	S.FBLD		;/FNDBLD?
	JRST	OUTIN8		;NO, SKIP THIS STUFF
	MOVEI	T1,.IOBIN	;/FNDBLD FILES ARE BINARY
	MOVEM	T1,O.LC		;SO SET IN OPEN BLOCK
	MOVSI	T1,B.DF		;DATA FILE BUFFER HEADER
	MOVEM	T1,O.LC+.OPBUF	;SET IN OPEN BLOCK
	OPEN	DF,O.LC		;OPEN DATA FILE CHANNEL
	  JRST	E.OPO		;OPEN FAILURE
	MOVEM	T4,E.LC+.RBPPN	;USE SAME CREATION PATH
	MOVSI	T1,'FDF'	;FIND DATA FILE EXTENSION
	HLLM	T1,E.LC+.RBEXT	;SET IN ENTER BLOCK
	ENTER	DF,E.LC		;ENTER THE FILE
	  JRST	E.OPE		;ENTER FAILURE
	OUTBUF	DF,0		;SET UP BUFFER RING

	MOVSI	T1,B.PF		;POINTER FILE BUFFER HEADER
	MOVEM	T1,O.LC+.OPBUF	;SET IN OPEN BLOCK
	OPEN	PF,O.LC		;OPEN POINTER FILE CHANNEL
	  JRST	E.OPO		;OPEN FAILURE
	MOVEM	T4,E.LC+.RBPPN	;USE SAME CREATION PATH
	MOVSI	T1,'FPF'	;FIND POINTER FILE EXTENSION
	HLLM	T1,E.LC+.RBEXT	;SET IN ENTER BLOCK
	ENTER	PF,E.LC		;ENTER POINTER FILE
	  JRST	E.OPE		;ENTER FAILURE
	OUTBUF	PF,0		;SETUP BUFFER RING

OUTIN8:	TRO	F,R.OUTD	;INDICATE OUTPUT INITIALIZED
	POPJ	P,		;RETURN
E.OWI:	TRZ	F,R.OUTD!R.OUTO!R.OUTL	;CLEAR LISTING FLAGS
	N$FAIL	(OWI,Output wildcard illegal)

E.OPO:
IFN FT$LPW,<			;
	MOVE	T1,O.BLK+.FXDEV	;SEE WHAT TYPE
	DEVCHR	T1,		;  OF DEVICE
	TXNN	T1,DV.LPT	;IS IT LINE PRINTER
	JRST	E.OPO1		;NO--FAIL
	TRON	F,R.LPTB	;YES--SECOND TIME?
	OUTSTR	[ASCIZ /LPT busy--waiting
/]
	MOVEI	T1,5		;SLEEP 5 SECONDS AND TRY AGAIN
	SLEEP	T1,		; ..
	JRST	OUTIN1		; ..
E.OPO1:
>;END IFN FT$LPW
	TRZ	F,R.OUTD!R.OUTO!R.OUTL  ;CLEAR LISTING FLAGS
	MOVE	P3,O.BLK+.FXDEV
	N$FAIN	(OPO,Output OPEN failed on device)
E.OPE:	TRZ	F,R.OUTD!R.OUTO!R.OUTL  ;CLEAR LISTING FLAGS
	MOVE	P3,O.BLK+.FXNAM
	N$FAIN	(OPE,Output ENTER failed on file)
;.TNEWL -- FORCE LISTING OUTPUT TO START OF LINE
;CALL:	PUSHJ	P,.TNEWL
;RETURNS AT BEGINNING OF LINE
;PRESERVES ALL ACS

.TNEWL::TRNE	F,R.OUTD	;SEE IF OUTPUT
	SKIPN	NOCHRS		;YES--SEE IF AT START OF LINE
	POPJ	P,		;YES--RETURN
	PJRST	LCRLF		;NO--OUTPUT END OF LINE


;TCHR -- TYPE CHARACTER ON TTY
;CALL:	MOVEI	T1,CHARACTER
;	PUSHJ	P,TCHR
;PRESERVES ALL ACS

TCHR:	PUSHJ	P,SAVTYP	;SAVE R.TYPE AND CLEAR IT
	MOVE	C,T1		;(TEMP)
	TRNN	F,R.OUTD	;SEE IF OUTPUT
	JRST	TTCHR1		;NOT OPEN--FORCE TO TTY
	PUSHJ	P,LCHR		;YES--LIST CHARACTER
.TTCHR:	TRNN	F,R.OUTO	;SEE IF LISTING ON CONSOLE
TTCHR1:	OUTCHR	T1		;NO--TYPE IT ALSO
	POPJ	P,		;RETURN


;SAVTYP -- ROUTINE TO SAVE R.TYPE ON THE STACK AND CLEAR IT
;	THIS AVOIDS TYPING TITLES AND DOUBLE LISTINGS
;CALL:	PUSHJ	P,SAVTYP
;RETURNS CPOPJ.  SETS STACK TO RESTORE R.TYPE WHEN CALLER
;	RETURNS (CPOPJ OR CPOPJ1)
;PRESERVES ALL ACS

SAVTYP:	EXCH	T1,(P)		;GET CALLING PC
	MOVEM	T1,1(P)		;STASH AWAY FOR THE NEXT CALL
	MOVE	T1,(P)		;RESTORE T1
	SETZM	(P)		;FLAG R.TYPE=0
	TRZE	F,R.TYPE	;CLEAR R.TYPE
	SETOM	(P)		;FLAG THAT IT WAS ON
	PUSHJ	P,@1(P)		;CALL BACK TO CALLER
	  JRST	.+2		;HANDLE NON-SKIP
	AOS	-1(P)		;HANDLE SKIP
	SKIPE	(P)		;TEST MEMORY OF FLAG
	TRO	F,R.TYPE	;RESTORE R.TYPE
	POP	P,(P)		;DISCARD MEMORY
	POPJ	P,		;RETURN TO CALLER'S CALLER
	SUBTTL	SUBROUTINES FOR FIND FILE(S) OUTPUT

;DOFND  --  WRITE FILE INTO FIND FILES
;CALL FROM ANALYZ WITH F--- AREA SET UP WITH FILE INFO.
;
;THERE ARE TWO FIND FILES, THE POINTER FILE AND THE DATA FILE.
;
;THE POINTER FILE HAS ONLY FILENAME/EXTENSIONS AND IS USED TO
;SEE WHERE TO GO WITHIN DATA FILE FOR FILE INFORMATION. FORMAT IS:
;
;	0/	FILE NAME IN SIXBIT
;	1/	EXTENSION IN SIXBIT,,0
;
;THE DATA FILE HAS ALL THE PERTINENT INFORMATION ABOUT THE ACTUAL
;FILE. FORMAT IS:
;
;	00/	NODE NAME IN SIXBIT (RESERVED FOR FUTURE)
;	01/	DEVICE/STRUCTURE NAME IN SIXBIT
;	02/	UFD
;	03/	SFD 1
;	04/	SFD 2
;	05/	SFD 3
;	06/	SFD 4
;	07/	SFD 5
;	10/	FILE NAME
;	11/	EXTENSION,,PROTECTION & I/O MODE (LH OF .RBPRV)
;	12/	WORD COUNT
;	13/	CREATION TIME
;	14/	ACCESS TIME
;	15/	VERSION
;	16/	0 (RESERVED FOR FUTURE)
;	17/	CHECKSUM

DOFND:	MOVEI	T1,0		;NODE NAME (RESERVED)
	PUSHJ	P,DFPUT		;WORD 0
	MOVE	T1,FSTR		;FILE STRUCTURE
	PUSHJ	P,DFPUT		;WORD 1
	SKIPN	T1,UFDPPN	;[454] UFD/PATH POINTER
	JRST	DOFND1		;[454] BLANK, WRITE OUT 0'S
	TLNN	T1,-1		;UFD OR PATH POINTER?
	JRST	DOFND2		;PATH POINTER
DOFND1:	PUSHJ	P,DFPUT		;[454] WORD 2
	MOVEI	T1,0		;NO SFD'S
	PUSHJ	P,DFPUT		;WORD 3
	PUSHJ	P,DFPUT		;WORD 4
	PUSHJ	P,DFPUT		;WORD 5
	PUSHJ	P,DFPUT		;WORD 6
	PUSHJ	P,DFPUT		;WORD 7
	JRST	DOFND4		;FINISH RECORD
DOFND2:	MOVEI	T2,.PTPPN(T1)	;ADDRESS OF UFD/SFD'S (6 WORDS MAX)
	HRLI	T2,-6		;UFD + 5 SFD'S
DOFND3:	SKIPN	T1,(T2)		;GET UFD/SFD
	SOJ	T2,		;0 TERMINATES LIST
	PUSHJ	P,DFPUT		;WORDS 2 - 7
	AOBJN	T2,DOFND3	;LOOP FOR WHOLE PATH

DOFND4:	MOVE	T1,FNAM		;FILE NAME
	PUSHJ	P,DFPUT		;WORD 10
	PUSHJ	P,PFPUT		;POINTER FILE WORD 0
	MOVE	T1,FFPRV	;SPECIAL PROTECTION CODE
	LSH	T1,^D9		;POSITION PROTECTION
	SKIPN	FFPRV		;SPECIAL PROTECTION CODE?
	HLRZ	T1,FPRV		;NO, GET FROM FILE BLOCK
	SKIPGE	FFPRV		;IS PROTECTION UNKNOWN?
	SETZ	T1,		;YES
	HLL	T1,FEXT		;EXTENSION,,PROTECTION+I/O MODE
	PUSHJ	P,DFPUT		;WORD 11
	ANDCMI	T1,-1		;EXTENSION,,0
	PUSHJ	P,PFPUT		;POINTER FILE WORD 1
	MOVE	T1,FSIZ		;FILE SIZE (WORDS)
	PUSHJ	P,DFPUT		;WORD 12
	LDB	T1,[POINTR FCRE,RB.CRT]  ;CREATION TIME
	IMULI	T1,^D60*^D1000	;(.CNVDT WANTS MILLISECONDS)
	LDB	T2,[POINTR FCRE,RB.CRD]  ;CREATION DATE
	LDB	T4,[POINTR FCRX,RB.CRX]  ;CREATION DATE EXTENSION
	DPB	T4,[POINT 3,T2,23]  ;REST OF CREATION DATE
	PUSHJ	P,.CNVDT##	;CONVERT TO UNIVERSAL DATE/TIME
	PUSHJ	P,DFPUT		;WORD 13
	MOVEI	T1,0		;ACCESS TIME UNKNOWN
	LDB	T2,[POINTR FACD,RB.ACD]  ;ACCESS DATE
	PUSHJ	P,.CNVDT##	;CONVERT TO UNIVERSAL DATE/TIME
	PUSHJ	P,DFPUT		;WORD 14
	MOVE	T1,FVER		;VERSION WORD
	PUSHJ	P,DFPUT		;WORD 15
	SETZ	T1,		;0
	PUSHJ	P,DFPUT		;WORD 16
	PUSHJ	P,GCHECK	;GET FILE CHECKSUM
	PJRST	DFPUT		;WORD 17 AND END OF RECORD
;DFPUT  --  WRITE ONE WORD INTO DATA FILE
;CALL WITH T1/DATA WORD
;RETURN CPOPJ0

DFPUT:	SOSGE	B.DF+.BFCTR	;ROOM?
	JRST	DFPUT2		;NO
	IDPB	T1,B.DF+.BFPTR	;YES
	POPJ	P,		;RETURN

DFPUT2:	OUT	DF,		;GET NEXT BUFFER
	JRST	DFPUT		;AND STUFF WORD IN
DFERR:	GETSTS	DF,P3		;I/O ERROR, I/O STATUS
	HRLI	P3,DF		;AND ASSOCIATED CHANNEL
	N$FAIO	(DOE,Find Data File output error,)


;PFPUT  --  WRITE ONE WORD INTO POINTER FILE
;CALL WITH T1/DATA WORD
;RETURN CPOPJ0

PFPUT:	SOSGE	B.PF+.BFCTR	;ROOM?
	JRST	PFPUT2		;NO
	IDPB	T1,B.PF+.BFPTR	;YES
	POPJ	P,		;RETURN

PFPUT2:	OUT	PF,		;GET NEXT BUFFER
	JRST	PFPUT		;AND STUFF WORD IN
PFERR:	GETSTS	PF,P3		;I/O ERROR, I/O STATUS
	HRLI	P3,PF		;AND I/O CHANNEL
	N$FAIO	(POE,Find Pointer File output error,)
;DFGET  --  READ ONE WORD FROM DATA FILE
;RETURNS NEXT DATA WORD IN T1

DFGET:	SOSGE	B.DG+.BFCTR	;ANY WORDS LEFT?
	JRST	DFGET2		;NO, GO TO NEXT BUFFER
	ILDB	T1,B.DG+.BFPTR	;READ NEXT WORD
	AOS	DGWRD		;REMEMBER HOW FAR INTO BLOCK WE HAVE READ
	POPJ	P,		;RETURN

DFGET2:	AOS	DGBLK		;REMEMBER HOW MANY BLOCK WE HAVE READ
	IN	DG,		;READ NEXT BUFFER
	JRST	DFGET		;AND RETURN THE FIRST WORD
	STATO	DG,IO.EOF	;REACH END OF FILE?
	JRST	DFGET4		;NO, I/O ERROR
	TLO	F,L.FEOF	;YES, NOTE EOF REACHED
	SETZ	T1,		;RETURN ZILCH
	POPJ	P,		;RETURN IT NOW

DFGET4:	PUSHJ	P,.PSH4T##	;SAVE THE T ACS
	GETSTS	DG,T1		;GET THE I/O ERROR STATUS
	PUSH	P,T1		;SAVE A COPY
	N$WRNX	(DFI,Find Data File input error,)
	MOVE	T1,0(P)		;FETCH A COPY OF THE STATUS
	HRLI	T1,DG		;SET THE I/O CHANNEL TOO
	PUSHJ	P,IOERM		;ISSUE I/O STATUS
X$$DFI:	PUSHJ	P,.TCRLF##	;CAP OFF ERROR MESSAGE
	POP	P,T1		;RESTORE I/O STATUS
	TXZ	T1,IO.ERR	;CLEAR OUT ERROR BITS
	SETSTS	DG,(T1)		;AND TELL MONITOR TO CONTINUE WITH I/O
	PUSHJ	P,.POP4T##	;RESTORE TEMP ACS
	JRST	DFGET		;AND PROCESS WHAT DATA WE GOT
;PFGET  --  READ ONE WORD FROM POINTER FILE
;RETURNS NEXT POINTER WORD IN T1

PFGET:	SOSGE	B.PG+.BFCTR	;ANY WORDS LEFT?
	JRST	PFGET2		;NO, GO TO NEXT BUFFER
	ILDB	T1,B.PG+.BFPTR	;READ NEXT WORD
	POPJ	P,		;RETURN

PFGET2:	IN	PG,		;READ NEXT BUFFER
	JRST	PFGET		;AND RETURN THE FIRST WORD
	STATO	PG,IO.EOF	;REACH END OF FILE?
	JRST	PFGET4		;NO, I/O ERROR
	TLO	F,L.FEOF	;YES, NOTE EOF REACHED
	SETZ	T1,		;RETURN ZILCH
	POPJ	P,		;RETURN IT NOW

PFGET4:	PUSHJ	P,.PSH4T##	;SAVE THE T ACS
	GETSTS	PG,T1		;READ I/O STATUS
	PUSH	P,T1		;SAVE A COPY
	N$WRNX	(PFI,Find Pointer File input error,)
	MOVE	T1,0(P)		;RETRIEVE A COPY OF I/O STATUS
	HRLI	T1,PG		;AND I/O CHANNEL IN QUESTION
	PUSHJ	P,IOERM		;ISSUE I/O STATUS MESSAGE
X$$PFI:	PUSHJ	P,.TCRLF##	;CAP OFF ERROR MESSAGE
	POP	P,T1		;RESTORE I/O STATUS
	TXZ	T1,IO.ERR	;CLEAR OUT ERROR BITS
	SETSTS	PG,(T1)		;AND TELL MONITOR TO CONTINUE WITH I/O
	PUSHJ	P,.POP4T##	;RESTORE TEMP ACS
	JRST	PFGET		;AND PROCESS WHAT DATA WE GOT
;MAKBUF -- ROUTINE TO MAKE A BUFFER RING
;CALL:	HRLI	T1,NUMBER OF BUFFERS
;	HRRI	T1,SIZE OF EACH (***EXCLUDES*** OVERHEAD CONTROL WORDS)
;	MOVEI	T2,LOCATION OF BUFFER HEADER
;	PUSHJ	P,MAKBUF
;RETURNS UNLESS NOT ENOUGH CORE

MAKBUF:	PUSHJ	P,.SAVE2##	;SAVE P1 AND P2
	HRRI	T1,3(T1)	;ALLOW FOR BUFFER CONTROL WORDS
	HLRZ	P1,T1		;GET BUFFER COUNT
	MOVEI	T3,(T1)		;GET BUFFER SIZE
	TLZ	T1,-1		;CLEAR JUNK
	IMUL	T1,P1		;GET TOTAL SPACE
	PUSHJ	P,GETCOR	;GET CORE AT .JBFF
	MOVE	P2,T1		;SAVE OLD .JBFF
	AOS	T1		;POINT TO LINK WORD
	MOVE	T4,T1		;AND MAKE A COPY
	HRLI	T4,-2(T3)	;PUT SIZE IN POINTERS

MAKBF1:	ADD	T4,T3		;ADVANCE TO NEXT BUFFER
	MOVEM	T4,(T1)		;STORE POINTER IN PREVIOUS BUFFER
	MOVE	T1,T4		;STEP TO NEXT BUFFER
	SOJG	P1,MAKBF1	;LOOP UNTIL DONE
	SUB	T1,T3		;BACKUP TO LAST POINTER
	HRRI	T4,1(P2)	;GET FIRST BUFFER LINK WORD ADDRESS
	MOVEM	T4,(T1)		;STORE POINTER TO FIRST BUFFER
	HRLI	T4,(1B0)	;SET USE BIT
	MOVEM	T4,(T2)		;STORE IN HEADER
	POPJ	P,		;RETURN
;GETCOR -- ROUTINE TO GET SOME CORE AT .JBFF
;WILL EXPAND LOW SEG IF NECESSARY
;CALL:	MOVEI	T1,AMOUNT NEEDED
;	PUSHJ	P,GETCOR
;RETURN WITH T1=START OF AREA (OLD .JBFF)

GETCOR:	PUSH	P,T2		;SAVE TEMP
	MOVE	T2,T1		;GET ARG
	MOVE	T1,.JBFF	;SAVE OLD .JBFF
	ADDM	T2,.JBFF	;ADVANCE .JBFF

GTCOR1:	MOVE	T2,.JBFF	;GET AMOUNT NEEDED
	CAMG	T2,.JBREL	;SEE IF MORE THAN WE HAVE
	JRST	GTCOR2		;NO--OK TO RETURN
	CORE	T2,		;TELL MONITOR
	  JRST	E.NEC		;ERROR--TELL USER
	JRST	GTCOR1		;LOOP TO VERIFY IT'S OK

GTCOR2:	POP	P,T2		;RESTORE TEMP
	POPJ	P,		;RETURN

E.NEC:	MOVE	P3,.JBFF	;GET VALUE NEEDED
	N$FAID	(NEC,Not enough core--need)
	SUBTTL	STORAGE

	XLIST		;LITERALS
	LIT
	LIST

	RELOC

OFFSET:	BLOCK	1		;STARTING ADDRESS OFFSET
ZCOR:!			;START OF AREA TO ZERO ON INITIAL LOAD

PDLST:	BLOCK	LN$PDL+1	;PUSH DOWN LIST
SAVCOR:	BLOCK	1		;LENGTH OF CORE ORIGINALLY
ORGFF:	BLOCK	1		;ORIGINAL .JBFF
H.ZER:!			;START OF AREA FOR OUTPUT PARAMETERS
O.LC:	BLOCK	3		;LISTING OPEN BLOCK
E.LC:	BLOCK	1+.RBEST	;LISTING ENTER BLOCK
	LE.LC==.-E.LC
B.LC:	BLOCK	3		;DIRECTORY FILE OUTPUT BUFFER RING HEADER
B.DF:	BLOCK	3		;DATA FILE OUTPUT BUFFER RING HEADER
B.PF:	BLOCK	3		;POINTER FILE OUTPUT BUFFER RING HEADER
B.DG:	BLOCK	3		;DATA FILE INPUT BUFFER RING HEADER
DGBLK:	BLOCK	1		;LOGICAL DATA BLOCK WITHIN DATA FILE
DGWRD:	BLOCK	1		;WORD WITHIN BLOCK WITHIN DATA FILE
B.PG:	BLOCK	3		;POINTER FILE INPUT BUFFER RING HEADER
F.OPN:	BLOCK	3		;FIND INPUT OPEN BLOCK
F.LKP:	BLOCK	.RBEST+1	;FIND INPUT FILE LOOKUP BLOCK
	F.LEN==.-F.LKP
F.PTH:	BLOCK	.PTMAX		;FIND INPUT PATH BLOCK

LNPP:	BLOCK	1		;LINES LEFT TO GO ON PAGE
PAGCNT:	BLOCK	1		;PAGE COUNTER
SVJBFF:	BLOCK	1		;INPUT SIDE .JBFF

LWIFIR:	BLOCK	1		;LAST .WIFIR
FRCLOK:	BLOCK	1		;.NE. 0 THEN LOOKUP REQUIRED FOR THIS FILE


H.ZER1:!		;START OF AREA FOR ONE OUTPUT
DCHBLK:	BLOCK	.DCSNM+1	;DSKCHR BLOCK

FOBLK:	BLOCK	.FOMAX		;FILOP. BLOCK
	FSTR==FOBLK+.FODEV	;ADDRESS OF "FILE STRUCTURE"

LBLOCK:	BLOCK	LN$RIB		;EXTENDED LOOKUP BLOCK

FRVER:	BLOCK	1		;RIB VERSION IF DIFF. FROM FILE
FFPRV:	BLOCK	1		;FILE PRIVILEGE
FRIBLK:	BLOCK	1		;RIB BLOCK NUMBER

MTNAME:	BLOCK	1		;DEVICE NAME OF MAG-TAPE
MTXDEV:	BLOCK	2		;SAVED ORIGINAL DEVICE SPEC BI-WORD
ABORTI:	BLOCK	1		;SETOM'ED IF SHOULD ABORT INPUT
AMWCNT:	BLOCK	1		;[462] COUNT OF SILLY FILES THIS SAVE SET
BFHD:	BLOCK	3		;BUFFER HEADERS FOR INPUT

H.ZERX:	BLOCK	.-H.ZER1	;REGION FOR PREVIOUS FILE
H.ZERY:
	BLOCK	.PTMAX		;  ..
MTPATH:	BLOCK	.PTMAX		;FOR PATH ON TAPES
MTSVFF:	BLOCK	1		;.JBFF AT FIRST MTOPEN
MTFBSZ:	BLOCK	1		;TAPE BLOCKSIZE (PLUS 3 OVERHEAD WORDS)
MTFFTB:	BLOCK	1		;BACKUP TAPE BLOCK SIZE COMPUTED FROM
				; /BLOCKINGFACTOR SWITCH ARGUMENT

H.MZER:!		;START OF AREA FOR ONE MT SAVE SET
MTSVHD:	BLOCK	1		;LAST WORD READ FOR FAILSAFE MODE
MTSVVR:	BLOCK	1		;VERSION,,TAPE NUMBER
MTSVWD:	BLOCK	1		;SAVE HEADERS DURING BACKUP TAPES
MTSVCT:	BLOCK	1		;COUNTER FOR BACKUP DATA READS
LASI:	BLOCK	1		;LAST FILE FOUND
LASDIR:	BLOCK	1		;LAST DIRECTORY LISTED
LASSTR:	BLOCK	1		;LAST STRUCTURE LISTED
LASPTH:	BLOCK	.PTMAX		;ROOM FOR PREVIOUS PATH
THSPTH:	BLOCK	.PTMAX		;ROOM FOR CURRENT PATH
SUBDIR:	BLOCK	1		;SUBTOTAL DIRECTORY
SUBSTR:	BLOCK	1		;SUBTOTAL STRUCTURE
SUBPTH:	BLOCK	.PTMAX		;SUBTOTAL PATH
SUBEND==.-1
NOFIL:	BLOCK	1		;NUMBER OF FILES IN UFDS SCANNED
TOT:!			;GRAND TOTALS
NOFILF:	BLOCK	1		;NUMBER OF FILES ACTUALLY USED
NOFILR:	BLOCK	1		;NUMBER OF LOOKUP ERRORS
NOBLKS:	BLOCK	1		;NUMBER BLOCKS IN FILES PRINTED
NOWRDS:	BLOCK	1		;NUMBER WORDS IN FILES PRINTED
TCHKSM:	BLOCK	1		;GRAND CHECKSUM
SUBT:!			;SUB TOTALS
SNFILF:	BLOCK	1		; (MUST PARALLEL AND IMMED. FOLLOW TOT)
SNFILR:	BLOCK	1
SNBLKS:	BLOCK	1
SNWRDS:	BLOCK	1		;WORD COUNT
SCHKSM:	BLOCK	1

NUMDIR:	BLOCK	1		;NUMBER OF DIRECTORIES
NUMSUB:	BLOCK	1		;NUMBER OF SUBTOTALS
CHKSUM:	BLOCK	1		;CHECKSUM ACCUMULATOR
NOCHRS:	BLOCK	1		;CURRENT HORIZONTAL POSITION
LSTSTR:	BLOCK	1		;STR TO LIST IF NEEDED
LSTDIR:	BLOCK	1		;DIRECTORY TO LIST IF NEEDED
NXUCNT:	BLOCK	1		;COUNT OF UFDS FOUND
NXSCNT:	BLOCK	1		;COUNT OF SFDS MISSED
NXFCNT:	BLOCK	1		;COUNT OF FILES FOUND
NXFI:	BLOCK	1		;I OF LAST NON-EX FILE
H.EMZR==.-1
KCHKSM:	BLOCK	1		;TEMP CHKSUM
MTFLCT:	BLOCK	1		;COUNT DOWN ON MT FROM /FILE:N
DSLOET:	BLOCK	1		;[475] ERROR OUTPUT INTERCEPT FLAG/ADDR
;BACKUP/FRS FORMAT HEADER STORAGE AREAS

B$GTYP:	BLOCK	1		;RH=TYPE, LH=-1 IF FRS
B$GBNM:	BLOCK	1		;BLOCK NUMBER
B$GRTN:	BLOCK	1		;RELATIVE TAPE NUMBER
B$GFLG:	BLOCK	1		;FLAGS
B$GCHK:	BLOCK	1		;CHECKSUM
B$GSIZ:	BLOCK	1		;DATA SIZE
B$GLND:	BLOCK	1		;OVERHEAD WORDS
	BLOCK	5		;(FUTURE) WASTE SPACE

;LABEL HEADER

B$LBL:!
B$LCDT:	BLOCK	1		;CREATION DATE/TIME
B$LFRM:	BLOCK	1		;FORMAT STYLE
B$LFVR:	BLOCK	1		;FRS/BACKUP VERSION NUMBER
B$LMTY:	BLOCK	1		;MONITOR TYPE
B$LSVR:	BLOCK	1		;SYSTEM VERSION
B$LAPR:	BLOCK	1		;APR S/N WRITTEN ON
B$LDEV:	BLOCK	1		;DEVICE WRITTEN ON
B$LMTC:	BLOCK	1		;MTCHR.
B$LREL:	BLOCK	1		;REEL
B$LDDT:	BLOCK	1		;DESTROY DATE/TIME
	BLOCK	^D10		;WASTE SPACE
B$LTIM:	BLOCK	1		;TIME
B$LDAT:	BLOCK	1		;DATE
B$LDSD:	BLOCK	1		;DESTROY DATE
B$LCMT:	BLOCK	16		;COMMENT
	BLOCK	1		;PROTECT ASCIZ
;START/END OF SAVE SET

B$SSS:!
B$SCDT:	BLOCK	1		;SAVE DATE/TIME
B$SFMT:	BLOCK	1		;TAPE FORMAT
B$SVER:	BLOCK	1		;BACKUP/FRS VERSION
B$SMTY:	BLOCK	1		;MONITOR TYPE
B$SSVR:	BLOCK	1		;SYSTEM VERSION
B$SAPR:	BLOCK	1		;SAVE APR S/N
B$SDEV:	BLOCK	1		;DEVICE SAVED ON
B$SMTC:	BLOCK	1		;SAVE MTCHR.
B$SREL:	BLOCK	1		;REELID
B$SLBT:	BLOCK	1		;LABEL TYPE
B$SFCT:	BLOCK	1		;BLOCKING FACTOR
	BLOCK	^D9		;WASTE SPACE
B$SSNM:	BLOCK	5		;SYSTEM NAME
B$STIM:	BLOCK	1		;SAVE TIME
B$SDAT:	BLOCK	1		;SAVE DATE
B$SMOD:	BLOCK	1		;MODE
B$STRK:	BLOCK	1		;TRACKS
B$SNAM:	BLOCK	1		;SAVE SET NAME
B$SCMT:	BLOCK	4		;COMMENT
	BLOCK	1		;PROTECT ASCIZ

;DIRECTORY RECORD

B$DIR:!
B$UPCH:	BLOCK	1		;PATH CHECKSUM
B$ULVL:	BLOCK	1		;DIRECTORY LEVEL (0=UFD)
B$USTA:	BLOCK	^D12		;DIRECTORY NAME
	BLOCK	6		;WASTE SPACE
B$USTR:	BLOCK	1		;STRUCTURE OF DIRECTORY

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FILE RECORD

B$FIL:!
B$FPCH:	BLOCK	1		;PATH CHECKSUM
B$FRDW:	BLOCK	1		;RELATIVE DATA WORD
B$FPTH:	BLOCK	^D12		;REDUNDANT PATH
	BLOCK	6		;WASTE SPACE
B$FSTR:	BLOCK	1		;STRUCTURE
B$FNAM:	BLOCK	1		;NAME
B$FEXT:	BLOCK	1		;EXTENSION
B$FUFD:	BLOCK	1		;UFD
B$FRBN:	BLOCK	1		;RELATIVE BLOCK NUMBER
B$FCHK:	BLOCK	1		;CHECKSUM
B$FNDB:	BLOCK	1		;NUMBER OF DATA BLOCKS
B$FNDW:	BLOCK	1		;NUMBER OF DATA WORDS
B$FLVL:	BLOCK	1		;FILE DIRECTORY LEVEL

;END OF VOLUME

B$EOV:	BLOCK	^D20		;WASTE SPACE

;COMMENT

B$CMT:	BLOCK	^D20		;COMMENT
	BLOCK	1		;PROTECT ASCIZ

;VARIOUS "DATA" REGION BLOCKS

B$BNAM:	BLOCK	^D30		;FILE PATH
B$BATT:	BLOCK	^D50		;FILE ATTRIBUTES
B$BSYS:	BLOCK	^D6		;SYSTEM NAME
B$BSSN:	BLOCK	^D7		;SAVE SET NAME

;MULTI-VOLUME HOLD WORDS FOR VERIFICATION

B$HRTN:	BLOCK	1		;VERIFICATION OF B$GRTN
B$HSSN:	BLOCK	7		;VERIFICATION OF B$BSSN

H.EZER==.-1
S.MIN:!			;START OF AREA FOR COMMAND ACCUMULATION
S.ACCS:	BLOCK	1		;VALUE OF /ACCESS SWITCH
S.ACCT:	BLOCK	1		;/ACCOUNT SWITCH
S.ALC:	BLOCK	1		;/ALLOCAT SWITCH
S.AUT:	BLOCK	1		;/AUTHOR SWITCH
S.BFCT:	BLOCK	1		;/BLOCKINGFACTOR SWITCH
S.CHK:	BLOCK	1		;/CHECKSUM SWITCH
S.CMP:	BLOCK	1		;/COMPARE SWITCH
S.DODV:	BLOCK	1		;CODE FOR DEFAULT OUTPUT DEVICE
S.DTL:	BLOCK	1		;/DETAIL SWITCH
S.DIRE:	BLOCK	1		;/DIRECT SWITCH
S.DTA:	BLOCK	1		;/DTA SWITCH (.GT. 0 LIST IN SHORT DTA FORMAT)
S.EOT:	BLOCK	1		;/EOT SWITCH
S.ERLO:	BLOCK	1		;/ERLOG SWITCH
S.FILE:	BLOCK	1		;/FILES:N SWITCH
S.FIND:	BLOCK	1		;/FIND SWITCH
S.FLSD:	BLOCK	1		;/FLSDIR SWITCH
S.FBLD:	BLOCK	1		;/FNDBLD SWITCH
S.HDSD:	BLOCK	1		;/HDSDIR SWITCH
S.IND:	BLOCK	1		;/INDIRECT SWITCH
S.MARK:	BLOCK	1		;/MARKS SWITCH
S.MVOL:	BLOCK	1		;/MVOLUME SWITCH
S.PRDE:	BLOCK	1		;/PRDEVICE SWITCH
S.PRDI:	BLOCK	1		;/PRDIRECTORY SWITCH
S.PRVE:	BLOCK	1		;/PRVERSION SWITCH
S.RETR:	BLOCK	1		;/RETRY SWITCH
S.REWS:	BLOCK	1		;/REWINDS SWITCH
S.SBRM:	BLOCK	1		;[465] /SBR MESSAGE(S) DESIRED
S.SORT:	BLOCK	1		;/SORT SWITCH
S.SUM:	BLOCK	1		;/SUMMARY SWITCH
S.TITL:	BLOCK	1		;-1,1=TITLE, 0=2=NO TITLE
S.TMPC:	BLOCK	1		;/TMPCOR (.GT. 0 LIST IN SHORT TMPCOR FORMAT)
S.UNIT:	BLOCK	1		;/UNITS SWITCH
S.WDTH:	BLOCK	1		;VALUE OF /WIDTH SWITCH
S.WORD:	BLOCK	1		;/[NO]WORD SWITCH
S.LENT:	BLOCK	1		;USED TO HOLD THE MAXIMUN LENGTH OF AN ENTRY.
FLFSUM:	BLOCK	1		;FORCE SUMMARY IF 1
S.EMIN==.-1

S.ZER:!
S.FUFD:	BLOCK	1		;USED WITH /COMPARE TO FORCE
				;THE PRINTING OF UFD DIRECTORIES
				;EG: DIRECTORY [1,1]/COMPARE
O.ZER:!				;START OF OUTPUT SPEC STORAGE
O.BLK:	BLOCK	.FXLEN		;OUTPUT FILE SPEC BLOCK
O.LZER==.-O.ZER

;THE FIND (/FNDDAT) INPUT SCAN BLOCK

F.BLK:	BLOCK	.FXLEN		;FIND FILE SPEC BLOCK

I.INZR:	BLOCK	1		;POINTER TO START OF INPUT SPEC
I.NXZR:	BLOCK	1		;POINTER TO NEXT INPUT SPEC STORAGE
I.NXRD:	BLOCK	1		;POINTER TO NEXT INPUT SPEC TO DO
FLAGS:	BLOCK	1		;COPY OF F DURING SCAN
FLAGSM:	BLOCK	1		;DITTO--MASKS
MXWDTH:	BLOCK	1		;MAX WIDTH IF /W


	BLOCK	2		;ROOM FOR BUFFER HEADERS
DIRB:	BLOCK	LN$BLK		;DIRECTORY BLOCK FOR DECTAPE/ETC.

IFN FT$MTL,<
M.MTLB:	BLOCK	.TPLEN		;LABEL PARAMETERS AREA
MTAEOF:	BLOCK	1		;NEW FILE FLAG
>;END INF FT$MTL

S.EZER==.-1
EZCOR==.-1		;END OF AREA TO ZERO
	END	DIRECT