Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93e-bb - 7,6/ap018/swiwld.x18
There is 1 other file named swiwld.x18 in the archive. Click here to see a list.
	TITLE	.WILD	SWIL local wildcard file operations
	SUBTTL	P.CONKLIN/PFC/JNG/MD/RKH/LLN/LCR/KPY/RDH	30-MAY-80

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

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000			;NICE PURE CODE


	COMMENT	\

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

\
	SUBTTL	Version and Revision history

MAJVER==13	;MAJOR VERSION LEVEL
MINVER==0	;MAINTENANCE VERSION LEVEL
CSTVER==0	;CUSTOMER LEVEL
EDTVER==1036	;EDIT LEVEL

%%WILD==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>
%%SWIL==:%%SWIL	;SHOW (AND SYNCHRONIZE) SWIL VERSION



;%1 -- 6/71 WITH 5.03 MONITOR (NAMED LOKWLD)

;A)  SHIFT INDEX TO P1 WHICH IS PRESERVED.  UPDATE USER'S
;	INDEX VIA ARGUMENT.
;B)  UPDATE TO USE THE REVISED TYPEOUT ROUTINES IN SCAN.
;C)  CHANGE CALL TO BE A BLOCK POINTED TO FROM T1.
;D)  USE CHANNEL 0 FOR ALL DIRECTORY READING.  HANDLE SFDS.  DIRECTORY
;	READING IS NOW IN DUMP MODE.
;E)  USE ARGUMENT CHANNEL FOR DATA READS.
;F)  USE C.MAC (AND SCNMAC.MAC) FOR ALL BITS AND BYTES INCLUDING THE
;	FILE SPEC AREA.
;G)  HANDLE [,] [P,] [,P] AND [-] NOTATIONS.
;H)  HANDLE + FOR UFDS (DEFICIENCY OF VERSION 1).
;I)  USE PATH. WHERE POSSIBLE FOR SYS:, ETC.
;J)  HANDLE STR, CONTROLLER CLASS, AND CONTROLLER ABBREVIATIONS.
;K)  FLAG FOR CALLER BOTH STRS AND WILD (.WLDFL=-2).
;L)  DO NOT OPEN DATA CHANNEL.
;M)  RETURN LOOKUP BLOCK IN CORE INSTEAD OF ACS.
;N)  ADD ROUTINE (.CHKTM) TO CHECK /BEFORE AND /SINCE SWITCHES.
;O)  DELAY DIRECTORY LOOKUP ERRORS TO END IN CASE SOME OTHER
;	STRUCTURE GETS IT OK.
;P)  MAKE OPEN FAILURE FATAL.  INCLUDE ASSIGNED JOB NUMBER IF KNOWN.
;Q)  ADD SEARCH LIST EMPTY (24) TO STANDARD LOOKUP ERRORS.
;R)  CHKACC DIRECTORIES
;S)  HANDLE SPECIAL DEVICES SUCH AS HLP:, ALL:, SXS:, ETC.

;%2(76) -- 5/72 WITH DIRECT %2.

;77	CORRECT BUG WHEN READING BLOCKS OF THE DIRECTORY.  EXAMINED
;	ONLY 63 FILES PER BLOCK INSTEAD OF 64.

;%3(77) -- 6/72

;100	USE .FX SYMBOLS FROM SCNMAC %3(50)
;101	USE .FXDFX TO FLAG MFD FIXUPS. HANDLE SYS:.UFD
;102	ALLOW REENTRY AFTER NON-DISK DEVICE.
;103	ALLOW FX.ADD OR .FXTRO FOR OR FUNCTION.
;104	ADD DEFENSIVE HALT IN CASE LH(DIRECTORY)=0.  (SPR 10-7182)
;105	REPLACE INTERNS BY :: FLAG.
;106	USE REAL EXTENSION IN LOOKUP ERROR MESSAGE
;107	ADD DTA HANDLING
;110	CORRECT SUBSCRIPTS IN E.DFL ROUTINE
;111	SET /DEN/PAR SWITCHES FOR MTA
;112	CONSIDER /BEFORE AND /SINCE =-1 TO BE ABSENT
;113	[*,NOT *,...] WILL NOT MATCH FOR USER PROJECT GT 7
;		AND TARGET PROJECT LE 7
;114	HANDLE [1,1].UFD CORRECTLY.  THIS ELIMINATES THE OLD NOTATION
;		OF #X0000YY.UFD[1,1]
;115	FIX BUG IN CHKACC LOGIC OF MFD.
;116	FIX BUG IN SYS: INTRODUCED BY 107.
;117	ADD ENTRY .CHKTA FOR DIRECT
;120	INCLUDE "." IN MODULE NAME.
;121	ADD SYMBOLS .WILDZ AND .WILDL FOR START AND LENGTH OF
;	LOW CORE AREA
;122	HANDLE NO MFD MESSAGE GRACEFULLY.

;%4(122) -- 12/72 WITH DIRECT %3

;123	ADD ERROR MESSAGE "NO FILE NAME SPECIFIED".
;124	ADD ROUTINE .SCWLD FOR SECONDARY WILDCARD (E.G., OUTPUT)
;125	SIMPLIFY CHECKS FOR END OF DIRECTORY LIST
;126	CHANGE HALT TO JRST AT WILDK
;127	ADD E.LKEN AND .TFILB AS GENERAL SCAN-STYLE TYPEOUTS
;130	CREATE MODULE\WILDDM
;131	DEFAULT OUTPUT PROTECTION IF TO SAME OWNER AS
;	INPUT FILE IS XYY WHERE X IS SYSTEM FILE PROT AND YY
;	IS COPIED FROM THE INPUT FILE
;132	SUPPORT DATE75
;133	SUPPORT /OKPROT AND /ERPROT.  DEFAULT IS /ERPROT
;	UNLESS WILD UFD.
;134	FIX BUG IN E.LKEN (EDIT 127)
;135	HANDLE NUL: CORRECTLY
;136	(10-10819) REMOVE BUG IN DECTAPE DIRECTORY READ
;137	GET RIGHT DIRECTORY WHEN UFD READ PROTECT. ERROR
;140	PREFIX ALL ERROR MESSAGES WITH WLDXXX
;141	(10-11421) CHECK /STR/PHY ON DIRECTORY MATCHING
;142	CORRECTLY STORE POINTER TO INPUT SPEC FOR CALLER

;%5(142) DEC, 73

;143	CORRECT BUG IN MULTIPLE DIRECTORY WILD-CARD LOGIC
;144	CORRECT SKIP INSTRUCTION ERROR IN DTA DIRECTORY LOGIC
;145	DON'T DELETE ACCESS TABLES IF WE ARE THE OWNER
;146	ADD ENTRY POINTS .INSTR, .NXSTR
;147	CONVERT TO USE C, SCNMAC AS UNIVERSALS
;150	SUPPORT /MESSAGE FROM .GTWCH
;151	MOVE .PTWRD TO .SCAN
;152	SUPPORT /MESSAGE FROM SCAN
;153	(10-12368) HANDLE UFD NAME CORRECTLY AS A FILE
;154	FIX /STRS ON NON-WILD TO GET RIGHT MESSAGE AND DIRECTORY
;155	IF /OKNONE AND NOT WILD, NO ERROR
;156	(10-12368) SUPPORT /SINC/BEFOR ON DTA
;157	ADD OPTION TO .LKWLD TO INDICATE END OF DIRECTORY
;160	ADD OPTION TO .LKWLD TO SCAN DIRECTORIES BEFORE SFD
;161	SUPPORT /ABEFORE/ASINCE/ERSUPERSEDE/LENGTH/ESTIMATE/VERSION
;162	(QAR 1882) FIX 153
;163	MORE 161
;164	MORE 153
;165	MORE 135

;%6(165) JUNE, 1974

;300	SUPPORT OF 'OR', ETC., (ADD FT$COR)
;301	DEFAULT TO /OKPROTECT IF ANY WILDCARDS
;302	ADD ERROR TWC IF TWO MANY WILD-CARDS ON INPUT
;303	IGNORE SINGLE ACCESS F/S IF NOT OWNED BY THIS JOB
;304	WARN WLDAFP IF ALL FILES PROTECTED
;305	WARN WLDAFR IF ALL FILES REJECT CONDITIONS
;306	(10-13,944) FIX TYPO IN MESSAGE
;307	(QAR 2760) ADD WLDSDP
;310	(QAR 2836) BUG IN 304
;311	ADD WLDSFP

;%7(311) SEPTEMBER, 1974

;312	(10-14727) FIX CHKTST TO WORK WITH FORCED DIRECTORY AND SFD
;313	(10-14841) FIXES TO CODE FOR SECONDARY LOOPUP BLOCKS
;314	(10-14839) SAVE PROTECT FOR LOOKUP ERROR PRINTOUT
;315	(SER S55-076) CORRECT BUG TO FIND FILES IF DEFAULT PATH IS AN
;	SFD AND REFERENCE IS ERSATZ
;316	(QAR 3672) HANDLE FIVE DEEP SFDS
;317	DO NOT CLEAR DIRECTORY IF STRUCTURE NOT MOUNTED
;320	ADD EXTERNAL SYMBOL .FRCPP FOR FRCPPN.
;321	ADD NEW ENTRY POINT FOR .INSTR WHICH CAUSES FRCPPN TO BE SET.
;322	MAKE .NXSTR AND .INIST ENTRY POINTS.
;323	DON'T DISCARD SFDS WHEN ERSATZ DEVICE AND FILE IS WILD
;324	(SPR-17317) USE 'SYS' AS 'NEW,SYS' IF /NEW ENABLED
;	AND ERSATZ DEVICE SYS IS REQUESTED.
;325	(SPR 10-17642) ALLOW 'NOT' GUIDE WORD TO WORK WITH PPNS

;%7A(325)	JANUARY, 1976

;326	ALLOW THE USE OF ERSATZ DEVICES WHEN PATH SET TO AN SFD.
;	18-MAY-76	LCR.

;327	MAKE NEW: GIVE CORRECT RESULTS [1,5] ONLY
;	07-JUN-76	LCR.
;

;330	HANDLE '+' NOTATION. BROKEN BY EDIT [325].
;	07-JUN-76	LCR.

;331	Synchronize the saving of the LOOKUP error code and the
;	PROTECTION code with the POP's.
;	Areas affected:E$$LKE:
;	L.C.R.	05-Oct-76.

;332	SPR # 10-21940	L.C.R.	21-Feb-77.
;	Clean up EDIT #327
;	Areas affected:	STR1:

;333	Provide a symbol equal to the version number for
;	version checking by programs like QUEUE.  LLN, SPR #
;	10-22263, 24-Mar-77

;334	SPR # 10-22140	LCR.	08-JUN-77.
;	Set on the flag indicating "SEARCHING SYS" when using the construct
;	SYSA: or SYSB: so that both [1,5] and [1,4] is searched for these
;	variations.
;	Areas affected: INSTR:

;335	Remove edits 326 and 323.  This prevents %non-existent
;	directory errors for certain combinations of directories and
;	search lists, but restricts the problem solved by 323.
;	LLN, SPR # 10-25314, 12-Jun-78.

;336	REMOVE 2 REDUNDANT LINES FROM EDIT 334 BEFORE INSTR2:
;	SPR 10-26341 BY BBE 8/7/78

;337	FIX BUG IN EDIT 154, DIR FOO[1,1] YIELDS
;	%WLDNSF NO SUCH FILES AS DSK:FOO.*[FOO]
;	SPR 10-26446 BY KPY 10/5/78
;	FIX BUG IN EDIT 331, P1 NOT PRESERVED
;	SPR 10-27435, VLR 15-FEB-79.

;1000	RDH	01-Jan-84
;	Incorporate into SWIL %12(1000), sync edit level at 1000.

;1006	RDH
;	Run in non-zero PC sections.

;1017	RDH	8-Aug-85
;	A wildcarded directory spec of the form [,,X*] would match files
;	from the spec [,,*], due to the removal of an important
;	instruction at WILDF. A wildcarded directory spec of the form
;	[,,*,X*] would match files from the spec [,] (but not [,,*],
;	a "year one" WILD bug).

;1021	RDH	14-Aug-85
;	ASSIGNed pathological name with logical name doesn't expand
;	correctly (e.g., .PATH X:=[1,2],[3,4], .ASSIGN X Y, .DIRECT Y:)

;1022	LEO	09-Sep-85
;	Do Copyrights.

;1025	DRB	22-Nov-85
;	Add an entry to close off all our directory channels (.LKABO).

;1026	RDH	25-Dec-85
;	Rename .LKZAP=.LKABO (see .IOZAP in SWIFIL).

;1027	RDH	25-Dec-85
;	Fix up typeout of .UFD-like specs in E$FILE.

;1030	RDH	25-Dec-85
;	Don't type "No such files" on non-network operations.

;1032	RDH	26-Dec-85
;	MCO 12262 stomped on DIRECT/WILD's handling of DTAs.

;1035	RDH	28-Dec-85
;	Fixup typeout of "Directory-is-empty" message.

;1036	RDH	31-Dec-85
;	Allow output non-wild with no input field, don't give WLDTMC errors.

;;	END OF REVISION HISTORY
;       	TABLE OF CONTENTS FOR WILD
;
;
;                          SECTION                            PAGE
;    1. REVISION HISTORY......................................   5
;    2. MISC. DEFINITIONS.....................................   7
;    3. INITIALIZE AND PRESET CALL............................   8
;    4. LOOKUP ONE FILE.......................................   9
;    5. SECONDARY WILD-CARD LOGIC.............................  25
;    6. DIRECTORY SUBROUTINES.................................  35
;    7. STRUCTURE SUBROUTINES.................................  49
;    8. USEFUL SUBROUTINES....................................  54
FLPLN==.FOMAX		;LENGTH OF FILOP. BLOCK
LKPLN==.RBMAX		;LENGTH OF LOOKUP BLOCK
	SUBTTL	MISC. DEFINITIONS

;ACCUMULATORS


T1=1	;SCRATCH
T2=2
T3=3
T4=4

P1=5	;INDEX TO COMMAND SCANNER DATA BASE
P2=6	;PRESERVED ACS
P3=7
P4=10	;

P=17	;PUSH DOWN LIST

;CHANNELS

WC==0	;CHANNEL FOR DIRECTORY READING

;RANDOM

ND	PLN$MX,4	;MAXIMUM NESTING OF PATHOLOGICAL DEVICES
ND	STR$MX,^D17	;MAXIMUM NUMBER OF DISK STRUCTURES

	WST$LN==<<PLN$MX*2>+10>	;LENGTH OF WSTR STATE/STACK
	PLN$LN==<<PLN$MX*2>+2>	;LENGTH OF PATHOLOGICAL NAME STACK
	KCN$LN==<STR$MX>	;LENGTH OF WSTR STRUCTURE STACK

ND	VERWRD,<12,,%%FXVE>	;SCAN PROTOCOL VERSION WORD

DVCNUL==DV.DRI!DV.DSK!DV.CDR!DV.LPT!DV.TTA!DV.TTY!DV.DIS!DV.PTP!DV.PTR!DV.DTA
;TEMP

DEFINE	ERROR(PRE,TXT,ADR,RTN,CNT<.POPJ##>),<
	JRST	[OUTSTR	[ASCIZ\? TXT\]
		PUSHJ	P,.TCRLF##
		JRST	CNT]
> ;END OF DEFINE ERROR


OPDEF	IFIW	[1B0]		;'TILL UUOSYM/MACTEN/ETC GETS IT
.NODDT	IFIW			;PRESERVE SETZ
	SUBTTL	PRIMARY WILDCARDING LOGIC

	ENTRY	.LKWLD

;THIS SUBROUTINE WORKS ON THE DATA BASE LEFT BY THE COMMAND SCANER.
;A LIST OF PARAMETER AREAS DEFINES THE FILES REQUESTED AND THE VARIOUS
;SYSTEM STRUCTURES AND DIRECTORIES ARE SEARCHED.

;ONLY ONE PRINCIPLE ENTRY POINT IS DEFINED--GET THE FIRST OR NEXT FILE.
;CALL:	MOVE	T1,[LENGTH,,BLOCK]
;	PUSHJ	P,.LKWLD
; RETURN CPOPJ IF NO MORE FILES WITH T1=-1 (OR DEVCHR IF DISK ONLY)
;SKIP RETURN WITH OPEN BLOCK AND LOOKUP BLOCK PRESET
;	INDEX LOCATION WILL POINT TO CURRENT SCANER FILE SPEC
;		WITH T1=THE DEVCHR OF THE NEXT DEVICE
;		WITH T2=-1 IF DISK, 0 IF DTA, 1 OTHERS OR NUL:
;
;BLOCK+0:	PROTOCOL VERSION WORD
;      1: LH =	LOCATION CONTAINING FIRST WORD OF FIRST SCANER FILE SPEC
;	  RH =	0 OR LOCATION CONTAINING FIRST WORD OF LAST SPEC
;      2: LH =	LOCATION OF OPEN BLOCK (3 WORDS LONG)
;	  RH =	LOCATION OF LOOKUP BLOCK
;      3: LH =	LENGTH OF FILE SPEC FROM SCANER
;	  RH =	LENGTH OF LOOKUP BLOCK
;      4: LH =	WILD CONTROL FLAGS
;		FW.ADO	HANDLE ALL DEVICES (ELSE, JUST DISK)
;		FW.DBS	SCAN DIRECTORY BEFORE DOING ITS SFD'S
;		FW.IFX	IMMEDIATE FILE EXIT (USER WILL PROVIDE FILES TO .CHKTM)
;			.LKWLD WILL RETURN CPOPJ, T1/-2, T2/ADR OF FSB
;		FW.FBD	RETURN DIRECTORY AS DATA FILE BEFORE DIRECTORY
;		FW.FAD	RETURN DIRECTORY AS DATA FILE AFTER DIRECTORY
;	  RH =	LOCATION OF POINTER TO FILE SPEC (INITIALLY 0)
;      5: RH =	LOCATION OF ROUTINE TO NOTIFY AT END OF DIRECTORY
;      6: RH =	ADDRESS OF DEFAULT EXTENSION (RESERVED)
;      7: RH =	ADDRESS OF "ON-BEHALF-OF" PPN (RESERVED)
;SECONDARY ENTRY POINTS:
;
;	PUSHJ	P,E.DFO
;		REPORTS OPEN ERROR FOR DATA FILE
;	PUSHJ	P,E.DFL
;		REPORTS LOOKUP ERROR 
;		ERROR INFO IN LOOKUP BLOCK
;		ON RETURN, T1=-1 IF SHOULD IGNORE THE ERROR (E.G., /OKPROT)
;	PUSHJ	P,E.DFF
;		REPORTS FILOP. OPEN/LOOKUP ERROR, ERROR CODE IN T1
;		ON RETURN, T1=-1 IF SHOULD IGNORE THE ERROR (E.G., /OKPROT)
;	PUSHJ	P,.LKERR
;		REPORTS LOOKUP ERROR MESSAGE (NO FILE)
;		(CODE IN T1)
;		(PROT. IN 0-8 OF T3)
;	PUSHJ	P,.CHKTM
;		CHECKS FILE [SWITCH] CONSTRAINTS SUCH AS /BEFORE/SINCE/ETC.
;		ALSO VERIFIES FILE AGAINST FILE EXPRESSION ('OR', ETC.)
;		***MUST*** BE CALLED AFTER .LKWLD
;		ASSUMES PARAMETERS SETUP VIA CALL TO .LKWLD.

;GLOBAL VARIABLES OF INTEREST
;
;.WLDFL	=FLAG (-1 IF WILD, +1 IF STR WILD, -2 IF BOTH)
;.WIFIR	=LOCATION OF START OF CONCATENATED SET
;.WILAS	=LOCATION OF END ...  (X+Y)
;.WXPRC	=NON-ZERO IF WANT CHKTST TO CHECK ALL FIELDS
;B.DC	=LOCATION OF BUFFER HEADER
;.WLDBF =BUFFER WITH CURRENT DIRECTORY BLOCK
;.WILDZ	=START OF WILD LOW SEG
;.WILDL	=LENGTH OF WILD LOW SEG
.LKWLD::PUSHJ	P,.SAVE4##	;WANT SOME ACS TO PLAY WITH
	PUSHJ	P,LKWAG		;SETUP USER ARGUMENTS
E..IWA:	 ERROR	IWA,<Illegal .LKWLD arguments>

LOOK:	SKIPE	@AGPNTR		;GET LAST STATE/ADDRESS
	JRST	LOOKI7		;CONTINUE WITH PROCESSING

;INITIALIZE FOR A POSSIBLE WILD FILE SEARCH

LOOKI:	MOVX	T1,%CNVER	;GETTAB ARG POINTER TO
	GETTAB	T1,		;READ MONITOR VERSION
	 SETZ	T1,		;DUH???
	CAIL	T1,70000	;AT LEAST 7.00 (EXTENDED I/O CHANNELS)?
	SETOM	ASCFLG		;YES
	CAIL	T1,70101	;AT LEAST 7.01+ (FO.UOC)?
	SETOM	UOCFLG		;YES
	MOVSI	T1,(1B0)	;FUNNY STUPID BIT
	MOVEM	T1,AGFOPF	;REMEMBER TO USE IT
	MOVE	P1,AGPFSB	;GET START OF FIRST SPEC
	JRST	LOOKN2		;AND START DOING OUR THING

LOOKI7:	MOVE	T1,AGFLAG	;USER PROCESSING FLAGS
	TXNN	T1,FW.IFX	;USER PROVIDING HIS OWN FILE SERVICE?
	SKIPE	.WLDNE		;SOMEONE WANT US TO QUIT THIS SPEC?
	JRST	LOOKN		;YES, JUST ACCUMLATE NEXT SET OF FILE SPECS
	SKIPE	NOTDSK		;IF ALREADY SETUP, CONTINUE
	JRST	LOOKD		;(NON-DISK) CONTINUE WITH NEXT DEVICE
	SKIPE	.WLDFL		;(DISK) DOING ANYTHING FANCY?
	JRST	WILDN		;YES, CONTINUE WITH NEXT FILE
	SKIPE	AGEODN		;NO. USER GIVE END-OF-DIRECTORY ROUTINE?
	PUSHJ	P,@AGEODN	;YES, CALL IT ON G.P.'S (WHAT IT USED TO DO)
	JRST	LOOKD		;CONTINUE WITH NEXT "DEVICE CUM SEARCH LIST"
;FINISHED WITH CURRENT FILE SPEC SET, ADVANCE TO NEXT SET

LOOKN:	MOVE	P1,.WILAS	;GET END OF CURRENT SPEC SET
	ADD	P1,AGLENP	;ADVANCE PARAMETER
LOOKN2:	HRRZM	P1,@AGPNTR	;STORE CURRENT POINTER FOR USER
	CAMG	P1,AGLIMS	;SEE IF AT END YET
	JRST	LOOKN7		;NO--GO DO OUR BIT
	SETO	T1,		;YES--FLAG ALL DONE
	POPJ	P,	

;HERE WHEN AN INPUT REQUEST HAS BEEN SPECIFIED AND SETUP IN P1

LOOKN7:	SETZM	FWAZER		;CLEAR TEMPORARIES
	MOVE	T1,[FWAZER,,FWAZER+1]	; ..
	BLT	T1,LWAZER	; ..
	MOVEM	P1,.WIFIR	;SAVE STARTING BLOCK

;LOOP TO DISCOVER A SET OF CONCATENATED FILE SPECIFICATIONS
;THE USER HAS CONCATENATED THEM TO CAUSE A SINGLE PASS WILD SEARCH.

LOOK00:	MOVS	T1,P1		;CONCOCT
	HRRI	T1,X.BLK	;A BLT POINTER TO
	BLT	T1,X.BLK+.FXLEN-1  ;MAKE A SCRATCH COPY OF USER'S SPEC BLOCK
	SETZM	.WXPRC		;SO FAR, NOT A CONCATENATED FILE EXPRESSION

;LOOP LOOKING FOR THE END OF THE CONCATENATED SPECS

LOOK02:	LDB	T1,[POINTR .FXMOD(P1),FX.TRM]  ;GET THIS "OPERATOR"
	SKIPN	T2,LOOK1T(T1)	;MORE FILE EXPRESSION COMING?
	JRST	LOOK50		;NO, MARK END OF THIS SET
	MOVE	T4,P1		;ADDRESS OF CURRENT SIMPLE SPEC
	ADD	T4,AGLENP	;ADDRESS OF NEXT SPEC IN SET
	CAMLE	T4,AGLIMS	;PAST THE LAST ONE SUPPLIED BY CALLER?
	JRST	LOOK50		;YES, THEN THAT TERMINATES THE SET TOO
	EXCH	T4,P1		;P1:=NEW LAST SPEC IN EXPRESSION
	AOSG	.WXPRC		;WE'VE GOT A CONCATENATED FILE EXPRESSION NOW
	SETOM	.WXPRC		;AND CHKTST NEEDS TO DO A LOT OF WORK
	SOJE	T2,LOOK02	;IF "NEGATIVE" EFFECT JUST ACCUMULATE THE SPEC

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN AN "ADDITIVE" FILE EXPRESSION IS ENCOUNTERED ('OR')
;
;THERE ARE SEVERAL NON-OBVIOUS RESULTS OF THE "ADDITIVE" PROCESSING
;DONE BY WILD:
;
;1)	THE ORDER IN WHICH FILES ARE FOUND AND RETURNED TO THE CALLER IS
;	NOT OBVIOUSLY DETERMINISTIC (THE RESULT OF "SYS: 'OR' DSK:" IS
;	A LIST OF DISK STRUCTURES RETURNED BY SYSSTR, WHICH IS IN TURN
;	DEPENDENT OF WHAT UNITS AND WHEN THE VARIOUS DISK STRUCTURES
;	WERE MOUNTED, AND HAS NOTHING TO DO WITH EITHER THE SYSTEM OR
;	THE JOB SEARCH LIST).
;
;2)	JUNK DEVICES (E.G., MPX) ARE TOTALLY LOST, AS IS NUL:
;
;3)	"USER-IMPLEMENTED" DEVICES (E.G., DIRECT AND TMP:) ARE LOST.
;
;4)	.LKWLD MAY RETURN A HUMONGOUS NUMBER OF "FILES" FOR A VERY
;	SIMPLE FILE EXPRESSION ("TTY123: 'OR' TTY456:" WILL RETURN EVERY
;	PHYSICAL TTY IN THE SYSTEM). IT IS UP TO .CHKTM (AND RELATIVES)
;	TO SORT OUT WHICH FILES ARE JUNK, AND REJECT SAME. TRY IT WITH
;	DIRECT SOME TIME, IT CAN BE RATHER AMUSING IF YOU LIKE TO BURN
;	CPU CYCLES.

LOOK10:	DMOVE	T1,.FXDEV(P1)	;GET NEXT DEVICE SPECIFICATION
	JUMPE	T1,LOOK17	;IF NO DEVICE, JUST MERGE THE NEW SPEC IN
	CAMN	T1,X.BLK+.FXDEV	;DIFFERENT FROM ACCUMULATION SO FAR?
	CAME	T2,X.BLK+.FXDEM	;AND THE MASK TOO?
	JRST	LOOK20		;DEVICE SPECIFICATIONS DIFFERENT
	MOVE	T1,.FXMOD(P1)	;GET NEW MODS
	XOR	T1,X.BLK+.FXMOD	;CONTRAST WITH ACCUMULATION SO FAR
	TXNE	T1,FX.PHY	;/PHYSICAL DIFFERENT?
	JRST	LOOK20		;YES, DEVICES NOT [NECESSARILY] THE SAME

;DEVICE SPECIFICATIONS THE SAME, CHECK OUT THE DIRECTORY SPECS TOO

	SKIPN	.FXDIR(P1)	;GOT ANYTHING NEW TO SAY?
	JRST	LOOK17		;NO, JUST MERGE THE NEW SPEC IN
	MOVSI	T4,-<2*.FXLND>	;TOTAL OF DIRECTORY SPECIFICATIONS
	MOVEI	T3,.FXDIR-1(P1)	;INDEXER FOR USER'S FSB
LOOK12:	ADDI	T3,1		;ADVANCE TO NEXT INPUT WORD OR MASK
	MOVE	T1,X.BLK+.FXDIR(T4)  ;GET ACCUMULATED FIELD SO FAR
	CAMN	T1,(T3)		;ANY DIFFERENCE?
	AOBJN	T4,LOOK12	;NO, KEEP HOPING
	JUMPL	T4,LOOK20	;IF DIFFERENT (MOAN) GO DO IT THE HARD WAY

;SIMPLE CASE ("A.B 'OR' C.D"), JUST ACCUMULATE THE NEW SPECIFICATIONS

LOOK17:	PUSHJ	P,LKWCF		;TRIVIAL DIFFERENCES, JUST COMBINE THE FSB'S
	 JFCL			;CAN'T HAPPEN
	JRST	LOOK02		;AND KEEP "PARSING"
;HERE WHEN A DIFFERENCE IN THE 'OR' SPECS IS NOTED IN THE NODE, DEVICE,
;OR DIRECTORY SPECS. LOTS OF CPU CYCLES ARE NEEDED.

LOOK20:	PUSH	P,P1		;SAVE INPUT FILE SPEC BLOCK
	SKIPGE	.WXPRC		;FIRST TIME HERE?
	JRST	LOOK30		;NO, JUST KEEP "OR"ING IN THE DIFFERENCES

;FIRST TIME, BACKTRACK TO THE FIRST SPEC

	MOVE	T1,.WIFIR	;SPEC THAT STARTED THIS ALL OFF
	PUSHJ	P,.WSTRI	;INIT FOR LOOPING THROUGH THE SPEC
	 JFCL			;CAN'T HAPPEN
	MOVEI	P1,Y.BLK	;OUR OWN INTERNAL BLOCK
	MOVE	T1,P1		;POSITION FOR WSTRN TO
	PUSHJ	P,.WSTRN	;GET THE FIRST DEVICE/ETC.
	 JRST	LOOK30		;DUH?
	MOVE	T4,[Y.BLK+.FXNOD,,X.BLK+.FXNOD]  ;BLT POINTER TO
	BLT	T4,X.BLK+<2*.FXLND>-1  ;"SET" THE FIRST DEVICE/ETC.
				; (LEAVE THE NAME ALONE SINCE PREVIOUS AND
				;  MORE INNOCOUS 'OR'S MIGHT HAVE ALREADY
				;  BEEN LKWCF'ED INTO X.BLK)
LOOK25:	MOVE	T1,P1		;ADDRESS OF TEMP BLOCK
	PUSHJ	P,.WSTRN	;GET THE NEXT INCARNATION
	 JRST	LOOK30		;ALL DONE
	PUSHJ	P,LKWCF		;"OR" IN THIS LATEST SET
	 JFCL			;CAN'T HAPPEN
	JRST	LOOK25		;LOOP BACK FOR THE REST

;NOW MERGE IN THE NEW FILE SPEC BLOCK

LOOK30:	MOVE	T1,0(P)		;ADDRESS OF NEXT FILE SPEC BLOCK
	PUSHJ	P,.WSTRI	;SET UP TO EXPAND IT
	 JFCL			;CAN'T HAPPEN
	MOVEI	P1,Y.BLK	;OUR OWN INTERNAL BLOCK
LOOK35:	MOVE	T1,P1		;ADDRESS OF TEMP BLOCK
	PUSHJ	P,.WSTRN	;GET NEXT DEVICE/ETC.
	 JRST	LOOK38		;ALL DONE
	PUSHJ	P,LKWCF		;"OR" IN THIS SET
	 JFCL			;CAN'T HAPPEN
	JRST	LOOK35		;BACK FOR THE REST

LOOK38:	POP	P,P1		;RESTORE P1 = ADDRESS OF CURRENT INPUT FSB
	SETOM	.WXPRC		;CHKTST WILL NEED LOTS**N OF CPU CYCLES
	JRST	LOOK02		;BACK TO FINISH THE INPUT FILE EXPRESSION
;THE OPERATOR TABLE
;
;	0	END OF FILE EXPRESSION
;	1	NEGATIVE EFFECT ONLY
;	2	ADDITIVE CONSTRAINTS

LOOK1T:	EXP	0		;.FXTRZ	","	END OF EXPRESSION
	EXP	1		;.FXTRA 'AND'	NEGATIVE CONSTRAINTS
	EXP	2		;.FXTRO 'OR'	ADDITIVE CONSTRAINTS
	EXP	1		;.FXTRN 'NOT'	NEGATIVE CONSTRAINTS
	EXP	0		;.FXTRC "+"	END OF EXPRESSION
	EXP	0		;		UNDEFINED
	EXP	1		;.FXTRB 'BEGIN'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTRE 'END'	NEGATIVE CONSTRAINTS
	EXP	0		;		UNDEFINED
	EXP	1		;.FXTIA	'IFAND'	NEGATIVE CONSTRAINTS
	EXP	0		;		UNDEFINED
	EXP	1		;.FXTIN	'IFNOT'	NEGATIVE CONSTRAINTS
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	1		;.FXTIS	'IFSAM'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTID	'IFDIF'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTIO	'IFOLD'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTIY	'IFNEW'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTIL	'IFSMA'	NEGATIVE CONSTRAINTS
	EXP	1		;.FXTIB	'IFBIG'	NEGATIVE CONSTRAINTS
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
	EXP	0		;		UNDEFINED
;HERE WHEN CONCATENATED REQUESTS HAVE BEEN SELECTED TO DETERMINE
; WHAT TYPE OF SEARCHING TO DO ACROSS STRS

LOOK50:	MOVEM	P1,.WILAS	;MARK END OF FILE EXPRESSION SET
LOOKS:	MOVSI	T2,X.BLK+.FXNOD	;POINT TO ARGUMENT AREA
	HRRI	T2,W.BLK+.FXNOD	;POINT TO INTERNAL AREA
	BLT	T2,W.BLK+.FXLEN-1  ;COPY FOR ANY ERROR MESSAGES

;NOW SEE WHAT TO DO

	MOVE	T1,X.BLK+.FXFLD	;GET FIELDS SUPPLIED
	MOVEI	P1,X.BLK	;***TEMP CHECK OUT WILD BITS
	PUSHJ	P,FX.W		;***TEMP CHECK OUT WILD BITS
	TXNE	T1,FX.WND!FX.WDV!FX.WDR!FX.WNM!FX.WEX  ;ANY WILDCARDS?
	SETOM	.WLDFL		;YES, FLAG "EXPLICIT" WILDCARDS
	MOVE	T2,X.BLK+.FXMOD	;GET SPEC MODIFIERS
	TXNN	T2,FX.STR	;/STRS ("IMPLICIT" WILDCARDS)?
	SOSA	.WLDFL		;NO
	SKIPL	.WLDFL		;YES, IN ADDITION TO NORMAL WILDCARDS?
	AOSA	T1,.WLDFL	;(/NOSTRS) OR (/STRS NO WILDCARDS)
	SOS	T1,.WLDFL	;/STRS AND WILDCARDS

	MOVE	T2,AGFLAG	;PICK UP FLAGS
	TXNN	T2,FW.IFX	;IMMEDIATE FILE EXIT?
	JRST	LOOKW		;NO, GO STARTUP POSSIBLY-WILDCARDED SEARCH

;USER HAS REQUESTED AN "IMMEDIATE FILE EXIT", SO DO NOT ATTEMPT ANY ACTUAL
;FILE FINDING OPERATIONS. RETURN IMMEDIATLY, PASSING THE USER THE COMBINED
;FILE SPEC BLOCK GENERATED FROM THE INPUT FILE EXPRESSION. PRESUMABLY THE
;USER WILL SOMEHOW SUPPLY HIS/HER OWN FILE ROUTINE (E.G., BACKUP READING
;FILES FROM TAPE, OR DIRECT/FIND) AND CALL .CHKTM DIRECTLY.

	SETOM	NOTDSK		;SET A SEMI-KROCKY FLAG
	AOS	.CTDVS		;COUNT A DEVICE SELECTED
	AOS	.CTFLS		;AND A FILE SELECTED
	AOS	.CTFLF		;AND ASSUME FILE FOUND
	SETZM	SRCH		;WITHOUT ANY FANCY MULTIPLE DEVICE LOGIC
	SETOM	.WXPRC		;ALWAYS FORCE FULL FILE SPEC IN CHKTST
	MOVNI	T1,2		;RETURN -2 TO CALLER
	MOVEI	T2,X.BLK	;RETURN COMBINED FILE SPEC BLOCK ADDRESS
	POPJ	P,		;LET THE USER TAKE IT FROM HERE
;HERE FOR SOME SORT OF POSSIBLY-WILDCARDED ACTION

LOOKW:	MOVEI	T1,X.BLK	;ADDRESS OF FILE SPEC BLOCK
	PUSHJ	P,.WSTRI	;INITIALIZE FOR DEVICE LOOP
	 JFCL			;CAN'T GET HERE
	SETOM	.CTNDF		;WIERD HANDSHAKING WITH LOOKED
	

;LOOP OVER EACH NODE/DEVICE/STRUCTURE

LOOKD:	SETZM	NOTDSK		;OPTIMISTICALLY ASSUME A DISK IS COMING
	SETZM	FLDTA		; . . .
	MOVEI	P1,Y.BLK	;YET ANOTHER INTERNAL BLOCK
	MOVE	T1,P1		;POSITION IT FOR WSTRN TO FIND
	PUSHJ	P,.WSTRN	;GET NEXT NODE/DEVICE/STRUCTURE/PATH/ETC.
	 JRST	LOOKED		;NO MORE DEVICES HERE
	SKIPE	T4,Y.BLK+.FXNOD	;GOT A NODE PASSED BACK AT US?
	CAMN	T4,.MYNOD##	;YES, REQUESTING LOCAL OR REMOTE SERVICE?
	JRST	LOOKL		;LOCAL - THAT'S US!!

;REMOTE NODE FILE SERVICE REQUESTED - TIME TO TALK TO A FAL

	AOS	.CTNDS		;COUNT A NODE SELECTED
	AOSG	.CTNDF		;AND PRESUMABLY FOUND
	AOS	.CTNDF		;AND REALLY TRULY FOUND
	MOVEI	T1,Y.BLK	;ADDRESS OF CURRENT SELECTION
	PUSHJ	P,.LKWLN##	;DISPATCH TO NETWORK SERVICE
	 JRST	LOOKD		;OOPS - CAN'T TALK TO THE NODE
	JRST	.POPJ1		;SUCCESSFUL FILE "LOOKUP"
				; THE CALLER IS RESPONSIBLE FOR FIGURING
				; OUT THIS MESS!
;LOCAL FILE SERVICE

LOOKL:	AOS	.CTNDS		;COUNT A NODE (US) SELECTED
	AOSG	.CTNDF		;AND DEFINITELY FOUND
	AOS	.CTNDF		;AND REALLY TRULY FOUND
	TXNE	T2,DV.DSK	;A NICE NORMAL DISK?
	JRST	LOOKL4		;YES
	SKIPGE	AGFLAG		;NO, USER WANT OTHER DEVICES TOO?
	JRST	LOOKL2		;YES

;ERROR - INPUT DEVICE NOT A DISK

	MOVE	T1,T2		;POSITION DEVCHR
	SETOM	NOTDSK		;FLAG NOT A DISK
	POPJ	P,		;ERROR RETURN

;NOT A DISK, BUT USER WANTS IT ANYWAY

LOOKL2:	TXNE	T2,DV.DTA	;A DECTAPE?
	SETOM	FLDTA		;YES
	TXNN	T2,DV.DTA	;A DECTAPE?
	SETOM	NOTDSK		;NEITHER DISK NOR DECTAPE

;LOCAL INPUT DEVICE SELECTED AND ACCEPTABLE

LOOKL4:	MOVEI	T3,.FXDIR	;BI-WORD INDEXER
	MOVSI	T4,-.FXLND	;PARALLEL TABLE COUNTER/INDEXER
LOOKL5:	DMOVE	T1,Y.BLK(T3)	;GET A DIRECTORY LEVEL
	MOVEM	T1,DIRNAM(T4)	;PUT INTO NAME TABLE
	MOVEM	T2,DIRMSK(T4)	;AND PARALLEL MASK TABLE
	ADDI	T3,2		;ADVANCE BI-WORD INDEXER
	AOBJN	T4,LOOKL5	;AND LOOP FOR ENTIRE DIRECTORY
	JRST	STR7		;GO DO IT
;HERE AT END OF A REQUEST TO SEE IF ANYTHING WAS FOUND
;IF NOT, AN APPROPRIATE ERROR MESSAGE WILL BE TYPED

LOOKED:;SKIPN	.CTDVS		;ANY DEVICES FOUND?
;	JRST	E$$NXD		;NO
LOOKEN:	MOVX	T1,FX.NOM	;SEE IF WE CARE IF ANY MATCHED
	TDNE	T1,X.BLK+.FXMOD	; ..
	JRST	LOOKN		;NO--NO WARNINGS AT ALL		[311]
	HRLZI	T1,X.BLK	;COPY ORIGINAL REQUEST
	HRRI	T1,W.BLK	;  INTO ANSWER AREA
	BLT	T1,W.BLK+.FXLEN-1  ;  FOR TYPE OUT
	SKIPE	.CTFLF		;SEE IF ANYTHING FOUND
	JRST	[SKIPE	.CTNDP		;ANY NODES SELECTED BUT INACCESSIBLE?
		JRST	E$$SNP		;YES--WARN USER
		SKIPN	.CTFLP		;SEE IF ANY FILES OR
		SKIPE	.CTDRP		; DIRECTORIES PROTECTED
		JRST	E$$SFP		;YES--WARN USER	
		JRST	LOOKN]		;NO--JUST EXIT NORMALLY
	SKIPE	.CTFLR		;SEE IF REJECTIONS
	JRST	E$$AFR		;YES--INDICATE THAT
	SKIPE	.CTDRP		;SEE IF DIRECTORY PROT FAILURE
	JRST	E$$SDP		;YES--ISSUE ERROR
	SKIPE	.CTFLP		;SEE IF PROTECT. FAILURES
	JRST	E$$AFP		;YES--ISSUE ERROR
	SKIPE	.CTFLS		;SEE IF ANY FILES EXAMINED
	JRST	E$$NSF		;YES--JUST NO SUCH FILES
	SKIPE	.CTDRS		;NO--SEE IF ANY DIRECTORIES MATCHED
	JRST	E.DEM		;YES--DIRECTORY EMPTY
	SKIPE	T2,LASERR	;SEE IF ANY ERRORS LEFT LYING AROUND
	JRST	DLYERR		;YES--GO GIVE THEM AS EXPLANATION
	SKIPE	.CTDVS		;SEE IF ANY DEVICES (STRUCTURES) FOUND
	JRST	E$$NSD		;YES--JUST NO SUCH DIRECTORY
	SKIPE	.CTNDF		;SEE IF ANY NODES SUCCESSFULLY FOUND
	JRST	E$$SLE		;YES--SEARCH LIST EMPTY
	SKIPE	.CTNDP		;NO--WHY?
	JRST	E$$ANP		;ALL SELECTED NODES "PROTECTED"
	SKIPE	.CTNDS		;DID WE SEE ANY NODES AT ALL??
	JRST	E$$ANI		;YES, ALL SELECTED NODES INACCESSIBLE
	JRST	E$$NSN		;NO SUCH NODE(S)
;HERE TO START ONE DEVICE (FILE STRUCTURE)

STR7:	AOS	.CTDVS		;COUNT DEVICE (STRUCTURE) SELECTED
	PUSHJ	P,SETOPN	;SETUP AN OPEN BLOCK
	MOVE	T4,DVCH		;GET DEVICE CHARS
	TXNN	T4,DV.MTA	;SEE IF MAG TAPE
	JRST	NOTMTA		;NO--PROCEED
	MOVX	T4,FX.PAR	;GET BIT FOR TEST
	TDNE	T4,.FXMOD(P1)	;SEE IF /PAR:EVEN
	TXO	T1,IO.PAR	;YES--SET INTO OPEN
	LDB	T4,[POINTR (.FXMOD(P1),FX.DEN)] ;GET /DEN
	DPB	T4,[POINTR (T1,IO.DEN)] ;SET INTO OPEN
NOTMTA:	LDB	T4,[POINTR .FXCTL(P1),FX.IOM]  ;GET I/O MODE (IF ANY)
	DPB	T4,[POINTR T1,IO.MOD]  ;AND SET IN OPEN BLOCK
	MOVE	T4,AGOPEN	;POINT TO USER AREA
	MOVEM	T1,(T4)		;STORE PHYSICAL BIT, ETC.
	MOVEM	T2,1(T4)	;STORE DEVICE NAME
	MOVEI	T3,B.DC		;POINT TO BUFFER HEADER FOR INPUT
	MOVEM	T3,2(T4)	;STORE FOR USER
	SKIPE	NOTDSK		;IF NOT A DIRECTORY-TYPE DEVICE
	JRST	UFD6		;RIGHT--GO GIVE ANSWERS

;NOTE THAT EVEN IF THERE ARE NO WILDCARDS SPECIFIED AND /NOSTRS, CONTROL
;STILL GOES TO WILDSN, WHICH (AFTER SOME RATHER INTRICATE DICING WITH
;COHORTS WILDJ AND WILDM) WILL EVENTUALLY END UP IN UFD6!!! AND NO, A
;"SKIPE .WLDFL" IN FRONT OF THE "SKIPE NOTDSK" IS NOT A GOOD IDEA, THE
;DETAILS OF WHICH I LEAVE AS A BONUS EXERCISE FOR THE READER.

	SETZB	T4,DEPTH	;CLEAR DEPTH OF NEST
	JRST	WILDSN		;GO START A NEW UFD
;BACK HERE TO GET NEXT FILE IN THIS DIRECTORY

WILDN:	MOVEI	P1,Y.BLK	;RESET INTERNAL SPEC POINTER
;***	MOVE	P1,.WIFIR	;RESET SPEC POINTER
	MOVE	T4,DEPTH	;SET INDEX TO TABLES
	SETZB	T3,DIRBU(T4)	;CLEAR DIRECTORY AT THIS LEVEL
	LSH	T4,1		;GET DOUBLE WORD POINTER
	SETZM	W.BLK+.FXDIR(T4);CLEAR ERROR MESSAGE STORAGE
	SETZM	W.BLK+.FXDIM(T4);  AND ITS MASK
	LSH	T4,-1		;REPOSITION COUNTER
	SKIPG	BUFUSI(T4)	;SEE IF WILD AT THIS LEVEL
	JRST	WILDE		;NO--PRETEND EOF THIS DIRECTORY
	SKIPE	DIRFLG		;SEE IF DIRECTORY BEING REPEATED
	JRST	WILDP		;YES--READ DIRECTORY AS A DIRECTORY NOW
	SOSGE	BUFCNT(T4)	;COUNT DOWN FILES IN THIS BLOCK
	JRST	WILDR		;NONE LEFT--GO READ NEXT BLOCK
	MOVEI	T3,2		;OK--ADVANCE TWO WORDS
	SKIPE	FLDTA		;SEE IF DECTAPE
	MOVEI	T3,1		;YES--ADVANCE ONE WORD
WILDP:	ADDB	T3,BUFPOS(T4)	;NOTE NEW POSITION
	SKIPE	FLDTA		;SEE IF DECTAPE
	ADDI	T3,^D84		;POSITION TO FILE NAME
	SKIPN	T1,.WLDBF-2(T3)	;GET FILE NAME
	JRST	WILDN		;NULL--LOOP FOR NEXT FILE
	SKIPE	FLDTA		;SEE IF DECTAPE
	ADDI	T3,^D21		;POINT TO EXTENSION
	HLRZ	T2,.WLDBF-1(T3)	;GET EXTENSION
	SKIPE	FLDTA		;SEE IF DECTAPE
	JRST	WILDF		;YES--NO DIRECTORY JUNK
	CAIN	T2,'SFD'	;SEE IF SUB-FILE DIRECTORY
	JUMPN	T4,WILDS	;YES--GO HANDLE
	SKIPGE	FNDSFD(T4)	;IF REPEATING FOR SFD'S		[160]
	JRST	WILDN		; IGNORE ALL OTHER FILES	[160]
	CAIN	T2,'UFD'	;SEE IF DIRECTORY
	JUMPE	T4,WILDU	;YES--GO HANDLE
WILDF:	CAIL	T4,.FXLND	;[1017] IF ALREADY AT MAX NESTING DEPTH
	JRST	WILDC		;[1017] THEN THIS IS A CANDIDATE FILE
	SETZ	T3,		;[1017] CLEAR "DEEPER-DOWN-NON-WILDNESS" FLAG
	IOR	T3,DIRMSK(T4)	;[1017] BUILD MASK OF "DEEPER-DOWN-NON-WILDNESS"
	CAIGE	T4,.FXLND	;[1017] ANY DEEPER LEVELS LEFT?
	AOJA	T4,.-2		;[1017] YES, CHECK THEM TOO
	JUMPN	T3,WILDN	;[1017] JUMP IF NO FILE LEGAL

;THERE IS NO MORE-DEEPLY-NESTED SUBDIRECTORY WHICH IS NOT FULLY WILDCARDED,
;ERGO THIS FILE IS A CANDIDATE TO BE RETURNED TO THE USER.

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN FOUND A POSSIBLE FILE--SEE IF IT MATCHES

WILDC:	AOS	.CTFLS		;[1017] COUNT FILE AS SEEN
	MOVE	T3,T1		;GET THIS FILE
	XOR	T3,.FXNAM(P1)	;COMPARE
	HRLZ	T4,T2		;GET THIS EXT
	XOR	T4,.FXEXT(P1)	;COMPARE,,FETCH MASK
	TDNN	T3,.FXNMM(P1)	;CHECK NAME
	TLNE	T4,(T4)		;CHECK EXT
	JRST	WILDN		;FAIL--TRY ANOTHER FILE
	JRST	UFD7		;WIN--GO GIVE ANSWER TO USER



;HERE WHEN SFD SEEN IN SCANNING THE DIRECTORIES

WILDS:	SKIPL	FNDSFD(T4)	;UNLESS SFD SECOND PASS,	[160]
	SKIPE	DIRFLG		;SEE IF DIRECTORY REPEATED
	JRST	WILDU		;YES--HANDLE AS DIRECTORY NOW
	MOVX	T3,FW.DBS	;SEE IF USER WANTS SFD LATER	[160]
	TDNE	T3,AGFLAG	; (IT'S SLOWER)			[160]
	JRST	WILDSD		;YES, DEFER THE DIRECTORY FILE
	SETOM	DIRFLG		;NOT YET--SET FLAG
	JRST	WILDSF		;AND HANDLE AS FILE FIRST - MAYBE

;HERE TO HANDLE DEFERRED DIRECTORY FILE - EXPAND THE SFD'S ONLY AFTER
;THE CURRENT DIRECTORY LEVEL IS DONE

WILDSD:	SKIPN	DIRNAM(T4)	;IS THERE A DEEPER LEVEL SPEC?
	SKIPE	DIRMSK(T4)	; . . .
	AOS	FNDSFD(T4)	;YES, COUNT DEFERRED DIRECTORIES

;SEE IF USER WANTS DIRECTORIES AS DATA FILES BEFORE DIRECTORIES

WILDSF:	JRST	WILDF		;RETURN DIRECTORY AS DATA FILE
;HERE WHEN A DIRECTORY (.SFD OR .UFD) SEEN WHILE READING A DIRECTORY,
;THE .SFD/.UFD HAS ALREADY BEEN RETURNED (AS NECESSARY) AS A RANDOM DATA
;FILE, IT IS NOW TIME TO EXPAND THE .SFD/.UFD AS A NEW DIRECTORY

WILDU:	SETZM	DIRFLG		;CLEAR DIRECTORY FLAG
	JRST	WILDK		;JOIN COMMON CODE

;HERE VIA EXPLICIT NON-WILD DIRECTORY PATH SPECIFICATION

WILDJ:	SETOM	BUFUSI(T4)	;SET NO WILD FLAG FOR THIS DIRECTORY LEVEL
	MOVE	T1,DIRNAM(T4)	;AND GET THIS NON-WILD DIRECTORY NAME
WILDK:	SKIPN	DIRNAM(T4)	;DO WE CARE ABOUT DEEPER DIRECTORIES?
	JRST	WILDN		;NO, IGNORE THIS "DIRECTORYNESS"
	MOVEM	T1,DIRBU(T4)	;YES, TIME TO NEST DOWN A DIRECTORY LEVEL
	LSH	T4,1		;DOUBLE POINTER
	MOVEM	T1,W.BLK+.FXDIR(T4)  ;STORE FOR POSSIBLE ERROR MESSAGE
	SETOM	W.BLK+.FXDIM(T4);SET MASK ON FULL
	LSH	T4,-1		;RESTORE INDEX
	XOR	T1,DIRNAM(T4)	;COMPARE TO REQUEST
	TDNE	T1,DIRMSK(T4)	;SEE IF MATCH
	JRST	WILDN		;NO--GO TRY AGAIN
;XXX	JUMPN	T3,WILDM	;SEE IF UFD
;XXX	SKIPE	T1,.FXDIM(T4)	;YES--SEE IF [*,NOT*]
;XXX	TLNE	T1,-1		; ..
;XXX	JRST	WILDM		;NO--OK TO PROCEED
;XXX	MOVE	T1,.MYPPN##	;YES--GET OUR NUMBER
;XXX	MOVE	T2,W.BLK+.FXDIR	;AND TARGET NUMBER
;XXX	TLNE	T1,777770	;SEE IF WE ARE GT PROJ 7
;XXX	TLNE	T2,777770	;AND TARGET IS LE PROJ 7
;XXX	JRST	WILDM		;NO--PROCEED
;XXX	JRST	WILDN		;YES--SKIP MATCH SINCE THIS
				; IS TO A SYSTEM FILE FROM USER

WILDM:	AOS	T4,DEPTH	;LOOKS GOOD--ADVANCE DEPTH OF SEARCH
	CAIG	T4,.FXLND	;SEE IF TOO DEEP
	JRST	WILDSN		;NO--PROCEED
	SOS	DEPTH		;YES--BACK UP
	JRST	WILDN		;AND TRY AGAIN
;HERE WHEN NEW DIRECTORY SELECTED

WILDSN:	CAIL	T4,.FXLND	;MAXIMUM DEPTH YET?
	JRST	WILDSG		;YES, CAN GO NO DEEPER
	SETCM	T2,DIRMSK(T4)	;GET WILDCARD MASK
	JUMPE	T2,WILDJ	;IF NOT WILD HERE, NEST A LEVEL
	SKIPE	DIRNAM(T4)	;I DON'T UNDERSTAND THIS
	JRST	WILDD		; CODE'S RAISON D'ETRE
WILDSG:	AOS	.CTDRS		;YES--COUNT DIRECTORY AS SEEN
	AOS	.CTDRF		; AND SUCCESSFULLY FOUND (LOOKUP'ED)
	SKIPL	.WLDFL		;SEE IF WILD FILE NAME
	JRST	UFD6		;NO--GIVE TO CALLER
WILDD:	SETZM	BUFUSI(T4)	;CLEAR USETI POINTER

;HERE WHEN TIME TO READ NEXT BLOCK OF A DIRECTORY

WILDR:	MOVEI	T1,100		;SET FOR 100
	SKIPE	FLDTA		;SEE IF DECTAPE
	MOVEI	T1,^D22		;YES--ONLY 22 FILES
	MOVEM	T1,BUFCNT(T4)	;  FILES IN A BLOCK
	SETZM	BUFPOS(T4)	;CLEAR POSITION IN BLOCK

;ENTER HERE TO RE-READ THE CURRENT BLOCK (AS WHEN POPPING UP A DIRECTORY LEVEL)

WILDRR:	PUSHJ	P,SETOPN	;SETUP OPEN BLOCK
	HRRI	T1,.IODMP	;READ IN DUMP MODE
	SKIPN	FLDTA		;SEE IF DECTAPE
	JRST	WILDRD		;NO--CHECK DIRECTORY
	SKIPE	BUFUSI(T4)	;SEE IF FIRST TIME HERE
	JRST	WILDE		;NO--GO HANDLE AS EOF
	TXO	T1,IO.NSD!IO.SSD;DTA: - SET SEMI-STANDARD MODE	[136]
	OPEN	WC,T1		;OPEN WILD CHANNEL
	  JRST	E.UFO		;ERROR--GO ISSUE MESSAGE
	MOVEI	T1,^D100	;SET FOR DECTAPE POSITION
	MOVEM	T1,BUFUSI(T4)	;FLAG FOR NEXT TIME
	USETI	WC,(T1)		;POSITION FILE
	MOVE	T1,[-200,,.WLDBF-1]
	MOVEI	T2,0		;SETUP DUMP LIST
	IN	WC,T1		;READ BUFFER
	  JRST	WILDRK		;OK
	STATZ	WC,IO.ERR	;SEE IF ANY ERRORS
	  PUSHJ	P,E.UFE		;YES--GO TELL USER
	STATO	WC,IO.EOF	;SEE IF END OF FILE
	  JRST	WILDRK		;NO--PROCEED WITH THIS BLOCK
	RELEAS	WC,		;MAKE SURE TO LEGGO OF THE DECTAPE
	JRST	WILDE		;DUH?

;HERE WHEN DECTAPE BLOCK READ

WILDRK:	RELEAS	WC,		;DON'T CONFUSE POOR OLE UUOCON
	JRST	WILDN		;AND GO READ FOR FILES
WILDRD:	DMOVEM	T1,FLPBL+.FOIOS	;SET DEVICE BLOCK WITHIN FILOP. BLOCK
	SETZM	FLPBL+.FOBRH	;DUMP MODE SO NO BUFFER RING HEADERS
	SKIPL	FNDSFD(T4)	;DOING SFD-EXPANSION PASS 2?
	SKIPE	BUFUSI(T4)	;NO, FIRST TIME HERE FOR THIS DIRECTORY?
	SKIPN	BUFCHN(T4)	;NO, CHANNEL ALREADY OPEN?
	CAIA			;MUST [RE]OPEN DIRECTORY FILE
	JRST	WILDRI		;JUST READ NEXT BLOCK
	SETZM	DIRBU-1		;ALWAYS CLEAR SWITCHES (AND MFD)
	MOVE	T3,DIRBU-1(T4)	;GET THIS DIRECTORY'S NAME
	MOVEM	T3,LKPBL+.RBNAM	;AND SET AS FILENAME TO BE READ
	SETZM	DIRBU-1(T4)	;CLEAR DIRECTORY IN PATH BLOCK
	CAIG	T4,1		;SEE IF UFD
	JRST	WILDRU		;YES--GO HANDLE IT
WILDRS:	MOVSI	T1,'SFD'	;SUB FILE DIRECTORY - SO INDICATE
	MOVEM	T1,LKPBL+.RBEXT	;IN THE LOOKUP BLOCK
	MOVEI	T2,DIRB		;POINT TO PATH
	MOVEI	T1,.PTSCN	;INDICATE NO
	MOVEM	T1,DIRBS	;  DIRECTORY SCANNING
	SKIPN	DIRBU+1		;SEE IF FIRST SFD
	MOVE	T2,DIRBU	;YES--GET UFD
	MOVEM	T2,LKPBL+.RBPPN	;SET DIRECTORY NAME PATH
	JRST	WILDRL		;GO LOOKUP DIRECTORY

WILDRU:	MOVSI	T1,'UFD'	;USER FILE DIRECTORY - SO INDICATE
	MOVEM	T1,LKPBL+.RBEXT	;IN THE LOOKUP BLOCK
	MOVE	T2,.PPMFD##	;SET MFD
	MOVEM	T2,LKPBL+.RBPPN	;AS THE PATH OF THE UFD
	SKIPN	T3		;SEE IF TOP LEVEL
	MOVEM	T2,LKPBL+.RBNAM	;YES--READ THE MFD ITSELF
	JRST	WILDRL		;GO LOOKUP DIRECTORY
;LOOKUP BLOCK SETUP (EXCEPT .RBCNT), FINISH FILOP. BLOCK, AND "DO IT"

WILDRL:	MOVEI	T1,3		;THREE-WORD EXTENDED LOOKUP
	MOVEM	T1,LKPBL+.RBCNT	;SET LENGTH OF LOOKUP BLOCK
	MOVEI	T1,LKPBL	;ADDRESS OF THE LOOKUP BLOCK
	MOVEM	T1,FLPBL+.FOLEB	;SET IN THE FILOP. BLOCK
	MOVE	T1,AGOBOP	;USE ON-BEHALF-OF-PPN (IF ANY)
	MOVEM	T1,FLPBL+.FOPPN	;AND SET IN THE FILOP. BLOCK
	MOVE	T1,BUFCHN(T4)	;GET DIRECTORY CHANNEL
	TXNN	T1,FO.CHN	;CHANNEL ALREADY ASSOCIATED HERE?
	SKIPN	ASCFLG		;NO, EXTENDED CHANNELS AVAILABLE?
	CAIA			;LEAVE ALONE
	TXO	T1,FO.ASC	;ASK MONITOR FOR NEW I/O CHANNEL
;RDH	TXNE	T1,FO.CHN	;TRYING TO USE "DORMANT" CHANNEL?
;RDH	TXO	T1,FO.UOC	;YES, USE ALREADY-OPENED-CHANNEL
	IOR	T1,AGFOPF	;SET ANY OTHER FLAGS
	HRRI	T1,.FORED	;SIMPLE READ FUNCTION
	MOVEM	T1,FLPBL+.FOFNC	;SET FILOP. FUNCTION WORD
	MOVE	T1,[FLPLN,,FLPBL]  ;FILOP. ARG POINTER TO
	FILOP.	T1,		;OPEN THE DIRECTORY FILE FOR READ
	  JRST	ERUFL		;ERROR--GO GIVE MESSAGE
	MOVE	T1,FLPBL+.FOFNC	;PICK UP THE FUNCTION/CHANNEL WORD
	AND	T1,[FO.CHN]	;REDUCE TO JUST THE CHANNEL NUMBER
	MOVEM	T1,BUFCHN(T4)	;AND SAVE THE CHANNEL
	SETZM	DIRBU-1		;CLEAR SWITCHES (AND MFD)
	CAIE	T4,0		;READING MFD?
	MOVEM	T3,DIRBU-1(T4)	;NO, RESTORE FULL DIRECTORY PATH BLOCK

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

WILDRI:	AOS	T3,BUFUSI(T4)	;ADVANCE BLOCK COUNT
	MOVE	T2,BUFCHN(T4)	;GET FILE CHANNEL
	HRRI	T2,.FOUSI	;USETI FUNCTION (ON CHANNEL 0)
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;POSITION TO APPROPRIATE DIRECTORY BLOCK
	  JFCL			;DUH???
	MOVEI	T3,[IOWD 200,.WLDBF	;DUMP-MODE COMMAND LIST
		EXP	0]		;DUMP-MODE COMMAND LIST
	MOVE	T2,BUFCHN(T4)	;GET FILE CHANNEL
	HRRI	T2,.FOINP	;INPUT FUNCTION (ON CHANNEL 0)
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;READ DIRECTORY FILE
	 JRST	WILDRE		;MAYBE ERROR? MAYBE EOF?
	SKIPN	BUFCHN(T4)	;IF NOT USING AN "EXTENDED" CHANNEL,
	PUSHJ	P,WILDRC	;THEN CLOSE/RELEASE CHANNEL 0
	JRST	WILDN		;GO PROCESS THE DIRECTORY BLOCK

WILDRE:	PUSH	P,T1		;SAVE ERROR STATUS
	TXNE	T1,IO.ERR	;SEE IF ANY ERRORS
	  PUSHJ	P,E.UFE		;YES--GO TELL USER
	POP	P,T1		;RESTORE EOF STATUS
	TXNN	T1,IO.EOF	;SEE IF END OF FILE
	  JRST	WILDRK		;NO--PROCEED WITH THIS BLOCK
	JRST	WILDE		;YES, TIME TO POP UP A DIRECTORY LEVEL



;HERE TO CLOSE AND RELEASE A DIRECTORY CHANNEL

WILDRC:	MOVEI	T3,CL.ACS	;CLOSE BUT DON'T UPDATE ACCESS DATES
	MOVE	T2,BUFCHN(T4)	;GET FILE CHANNEL
	HRRI	T2,.FOCLS	;CLOSE FUNCTION (ON CHANNEL 0)
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;CLOSE FILE CHANNEL
	 JFCL			;DUH?
	SKIPE	T2,BUFCHN(T4)	;GET FILE CHANNEL
	POPJ	P,		;EXTENDED CHANNEL, DON'T RELEASE IT
WILDRZ:	HRRI	T2,.FOREL	;RELEASE FUNCTION
	MOVE	T1,[1,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;RELEASE THE CHANNEL
	 JFCL			;DUH???
	SETZM	BUFCHN(T4)	;THIS DIRECTORY LEVEL HAS NO CHANNEL ANY MORE
	POPJ	P,		;CHANNEL CLEAR
;HERE AT END OF FILE IN A DIRECTORY

WILDE:	SKIPE	AGEODN		;SEE IF USER WANTS TO HEAR	[157]
	PUSHJ	P,@AGEODN	; AT EO DIRECTORY		[157]
	MOVE	P1,.WIFIR	;RESTORE INDEX			[157]
	MOVE	T4,DEPTH	;GET DEPTH AS INDEX		[160]
	SKIPE	T1,FNDSFD(T4)	;SEE IF NEED SECOND PASS FOR SFD [160]
	JRST	[SETZM	FNDSFD(T4)	;YES--INDICATE DONE		[160]
		JUMPL	T1,.+1		;IF END OF SECOND PASS, DONE	[160]
		SETOM	FNDSFD(T4)	;ELSE, FLAG FOR SECOND PASS	[160]
		JRST	WILDD]		;AND DO SECOND PASS		[160]
	PUSHJ	P,WILDRC	;CLOSE THE DIRECTORY CHANNEL
	SKIPE	T2,BUFCHN(T4)	;EXTENDED I/O CHANNEL?
	PUSHJ	P,WILDRZ	;YES, RELEASE IT TOO
	SOSGE	T4,DEPTH	;BACK OFF DEPTH
	JRST	WILDEX		;DONE WITH THIS STR, RELEASE DORMANT CHANNELS
	SETZM	DIRBU(T4)	;CLEAR DIRECTORY ENTRY
	SOSGE	T3,BUFUSI(T4)	;BACKUP BUFFER INDEX(TO FILE)
	JRST	WILDN		;NOT WILD--GO UP AGAIN
	SKIPN	FLDTA		;IF DECTAPE
	SKIPN	BUFCHN(T4)	;(NOT DECTAPE) DIRECTORY CHANNEL STILL OPEN?
	JRST	WILDRR		;DTA OR NOT OPEN, GO GET NEXT BLOCK
	JRST	WILDRI		;JUST RE-READ CURRENT BLOCK

WILDEX:	MOVSI	T4,-<.FXLND+1>	;MAXIMUM CHANNELS (INC MFD)
	SKIPE	T2,BUFCHN(T4)	;DORMANT CHANNEL HERE?
	PUSHJ	P,WILDRZ	;YES, STOMP ON IT
	AOBJN	T4,.-2		;LOOP FOR ALL POSSIBLE CHANNELS
	JRST	LOOKD		;TRY NEXT STR/PATH COMBO
;HERE WHEN FILE PRESUMED (NO WILD CARD)

UFD6:	MOVE	T1,.FXNAM(P1)	;GET USER'S NAME
	HLRZ	T2,.FXEXT(P1)	;AND EXTENSION
	AOS	.CTFLS		;COUNT FILE SEEN

;HERE WHEN A FILE IS FOUND
;SETUP ANSWER BLOCK FOR CALLING PROGRAM

UFD7:	AOS	.CTFLF		;COUNT FILE FOUND
	MOVEM	T1,W.BLK+.FXNAM	;SAVE FILE NAME
	HRLZM	T2,W.BLK+.FXEXT	;SAVE FILE EXTENSION
	MOVE	P3,AGLOOK	;ADDRESS OF CALLER'S FILE LOOKUP BLOCK
	SETZM	0(P3)		;CLEAR FIRST WORD OF LOOKUP BLOCK
	MOVSI	T3,0(P3)	;CONCOCT A
	HRRI	T3,1(P3)	; BLT POINTER
	MOVE	T4,AGLENL	;LENGTH OF LOOKUP BLOCK
	ADD	T4,P3		;T4:=FIRST WORD PAST LOOKUP BLOCK
	BLT	T3,-1(T4)	;CLEAR OUT THE LOOKUP BLOCK
	MOVE	T3,AGLENL	;LENGTH OF LOOKUP BLOCK
	SUBI	T3,1		;OFFSET VERSUS LENGTH
	MOVEM	T3,.RBCNT(P3)	;SET LENGTH OF LOOKUP BLOCK
	HRLZM	T2,.RBEXT(P3)	;SET FILE TYPE
	MOVEM	T1,.RBNAM(P3)	; AND FILE NAME IN THE LOOKUP BLOCK
	SKIPN	DIRBU+1		;SEE IF PATH NEEDED
	SKIPA	T1,DIRBU	;NO--GET UFD
	MOVEI	T1,DIRB		;YES--SETUP POINTER
	JUMPN	T1,UFD8		;IF DIRECTORY SETUP, PROCEED
	MOVX	T2,FX.DIR	;SEE IF USER SAID NO DIRECT.
	TDNE	T2,.FXMOD(P1)	; ...
	MOVE	T1,.PPMFD##	;NO--SO MUST BE MFD
UFD8:	MOVEM	T1,.RBPPN(P3)	;SET PPN/PATH POINTER
	SETCM	T2,FLDTA	;GET -1 IF DISK, 0 IF DECTAPE
	SKIPE	NOTDSK		;SEE IF NOT DIRECTORY DEVICE
	MOVEI	T2,1		;RIGHT--SET FLAG
	MOVE	T1,DVCH		;RESTORE DEVICE CHARS.
	CAIE	P1,Y.BLK	;CONSISTENCY CHECK
	ERROR	PNY,<P1 not pointing to Y.BLK at UFD8>
	MOVE	P1,.WIFIR	;GET START OF CURRENT SET
	MOVEM	P1,@AGPNTR	;RETURN THAT TO USER FOR NOW
				; (.CHKTM WILL SET IT RIGHT)
	JRST	CPOPJ1		;RETURN SUCCESSFULLY
	SUBTTL	PRIMARY WILDCARDING HELPERS

;LKWAG  --  READ USER ARGUMENTS (.LKWLD)

LKWAG:	HLRZ	T2,T1		;GET LENGTH OF BLOCK
	PUSHJ	P,.GTWRD##	;GET BLOCK+0
	PUSHJ	P,FXVERC##	;ENSURE PROPER INTERFACE PROTOCOL
	PUSHJ	P,.GTWRD##	;GET BLOCK+1
	TLNN	T3,-1		;ENSURE START ADDRESS GIVEN
	POPJ	P,		;NO, ERROR
	TRNE	T3,-1		;SEE IF END GIVEN
	HRR	T3,(T3)		;YES--GET END OF SPECS
	MOVS	T4,T3		;SWITCH TO START
	HRR	T4,(T4)		;GET START OF SPECS
	TLNN	T4,-1		;SEE IF END SPECIFIED
	HRL	T4,T4		;NO--USE START
	HRRZM	T4,AGPFSB	;SAVE ADDRESS OF FIRST FILE SPEC BLOCK
	HLRZM	T4,AGLIMS	;STORE END FOR TESTS
	PUSHJ	P,.GTWRD	;GET BLOCK+2
	TLNE	T3,-1		;ENSURE THAT BOTH AN OPEN
	TRNN	T3,-1		;AND A LOOKUP BLOCK ARE SUPPLIED
	POPJ	P,		;NOPE, ERROR, ABORT
	HLRZM	T3,AGOPEN	;SAVE OPEN BLOCK
	HRRZM	T3,AGLOOK	;SAVE LOOKUP BLOCK
	PUSHJ	P,.GTWRD	;GET BLOCK+3
	TRNN	T3,-1		;WAS A LENGTH SUPPLIED?
	HRRI	T3,.RBEXT	;NO, ASSUME MINIMUM
	HRRZM	T3,AGLENL	;SAVE LENGTH OF LOOKUP BLOCK
	TLNN	T3,-1		;WAS A LENGTH SUPPLIED?
	HRLI	T3,.FXLEN	;NO, ASSUME STANDARD
	HLRZM	T3,AGLENP	;SAVE LENGTH OF FILE SPEC BLOCK
	PUSHJ	P,.GTWRD	;GET BLOCK+4
	TRNN	T3,-1		;WAS A CURRENT/STATE POINTER PROVIDED?
	POPJ	P,		;NO, ERROR
	HRRZM	T3,AGPNTR	;SAVE LOCATION OF POINTER
	MOVEM	T3,AGFLAG	;STORE FLAGS
	PUSHJ	P,.GTWRD	;GET BLOCK+5			[157]
	HRRZM	T3,AGEODN	;SAVE FOR DIRECTORY READER	[157]
	PUSHJ	P,.GTWRD##	;GET BLOCK+6
	MOVEM	T3,AGDFEX	;DEFAULT EXTENSION LIST ADDRESS (FUTURE)
	PUSHJ	P,.GTWRD##	;GET BLOCK+7
	CAIE	T3,0		;USER SUPPLY AN ADDRESS?
	MOVE	T3,@T3		;YES, FETCH ON-BEHALF-OF-PPN (MAY BE 0)
	MOVEM	T3,AGOBOP	;ON-BEHALF-OF-PPN
	JRST	.POPJ1##	;SUCCESSFUL RETURN
;LKWCF - COMBINE THE FILE SPECS
;
;HERE WHEN A EXPRESSION INVOLVING MULTIPLE SPECIFICATIONS EACH OF WHICH
;CONTRIBUTE TO THE PRIMARY WILDCARD SELECTION IN AN ADDITIVE FASHION
;(E.G., "*.MAC 'OR' *.BAK").
;
;THE IDEA IS TO EFFECTIVELY "OR" TOGETHER THE OVERLAPPING WILDCARDEDNESS
;OF THE DISCRETE REQUESTS, BUILDING IN X.BLK THE SUPERSET OF ALL RELATED
;FILE EXPRESSION COMPONETS.
;
;USES T1, T2, T3, T4, P1, P2, P3

;AT FIRST GLANCE ONE WOULD THINK THIS TO BE EASILY DO-ABLE VIA A NICE,
;SHORT, MAYBE-EVEN TABLE-DRIVEN LOOP. AS IT HAPPENS, THERE ARE SO MANY
;SPECIAL CASES INVOLVED (PPN IS NOT SIXBIT, EXTENSION IS NOT BI-WORD
;FORMAT, DEVICE NEEDS FX.PHY CHECKED TOO) THAT I JUST DO THE OBVIOUS
;INLINE CODE . . . EVEN IF IT DOES ACTUALLY TAKE A LITTLE MORE SPACE

;CHECK THE NODE SPECIFICATION

LKWCF:	DMOVE	T1,X.BLK+.FXNOD	;GET ACCUMULATED NODE SPECIFICATION
	DMOVE	T3,.FXNOD(P1)	;GET NEXT POSSIBLE NODE SPECIFICATION
	CAIE	T3,0		;IGNORE IF NO NEW NODE
	PUSHJ	P,LKW6B		;MERGE THE TWO SPECS
	 JRST	LKWC12		;DON'T BOTHER
	DMOVEM	T1,X.BLK+.FXNOD	;SET NEW ACCUMULATION IN INTERNAL BLOCK
	MOVX	T3,FX.WND	;THE NODE-IS-WILD FLAG
	AOJE	T2,.+3		;ANY WILDCARDS GENERATED
	CAIE	T1,0		;IN A NON-BLANK NODE SPECIFICATION?
	IORM	T3,X.BLK+.FXFLD	;YES, NOTE THAT IN THE FIELDS WORD

;CHECK THE DEVICE SPECIFICATION

LKWC12:	MOVX	T1,FX.ADO	;THE ANY-DEVICE-OK FLAG
	AND	T1,.FXMOD(P1)	;IF IT IS SET IN THE NEW SPECIFICATION
	IORM	T1,X.BLK+.FXMOD	;THEN ACCUMULATE IT TOO
	DMOVE	T1,X.BLK+.FXDEV	;GET ACCUMULATED DEVICE SPECIFICATION
	DMOVE	T3,.FXDEV(P1)	;GET POSSIBLE NEW DEVICE SPECIFICATION
	CAIE	T3,0		;IGNORE IF NO NEW DEVICE
	PUSHJ	P,LKW6B		;MERGE THE WILDCARDS
	 JRST	LKWC20		;DON'T BOTHER
	DMOVEM	T1,X.BLK+.FXDEV	;SET NEW ACCUMULATED DEVICE SPECIFICATION
	MOVX	T3,FX.WDV	;THE WILDCARDS-IN-DEVICE FLAG
	AOJE	T2,.+3		;ANY WILDCARDS GENERATED
	CAIE	T1,0		;IN A NON-BLANK DEVICE SPECIFICATION?
	IORM	T3,X.BLK+.FXFLD	;YES, NOTE THAT IN THE FIELDS WORD

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHECK THE DIRECTORY SPECIFICATION

LKWC20:	SKIPE	.FXDIR(P1)	;IF NO NEW DIRECTORY SPEC GIVEN
	JRST	LKWC30		; JUST IGNORE
	HRLI	P1,(<1B0 (P2)>)	;SET TO INDEX OFF OF P2
	MOVE	P2,[-.FXLND,,.FXDIR]  ;AOBJN COUNTER/INDEXER
	MOVEI	P3,LKW3B	;START OFF WITH PPN FORMAT

;LOOP CHECKING EACH DIRECTORY LEVEL FOR DIFFERENCES

LKWC22:	DMOVE	T1,X.BLK(P2)	;GET ACCUMULATED DIRECTORY SPECIFICATION
	DMOVE	T3,@P1		;GET POSSIBLE NEW SPECIFICATION
	PUSHJ	P,(P3)		;MERGE THE TWO SPECIFICATIONS
	 JRST	LKWC24		;DON'T BOTHER WITH THIS LEVEL
	DMOVEM	T1,X.BLK(P2)	;SET NEW ACCUMULATED DIRECTORY SPECIFICATION
	MOVX	T3,FX.WDR	;THE WILDCARDS-IN-DIRECTORY FLAG
	AOJE	T2,.+3		;ANY WILDCARDS PRESENT
	CAIE	T1,0		;IN A NON-BLANK DIRECTORY SPECIFICATION?
	IORM	T3,X.BLK+.FXFLD	;YES, NOTE THAT IN THE FIELDS FLAGS
	MOVEI	P3,LKW6B	;ALL SFD'S ARE NAMES
LKWC24:	ADDI	P2,1		;HALF OF THE BI-WORD INDEX
	AOBJN	P2,LKWC22	;LOOP FOR ALL DIRECTORY LEVELS

LKWC29:	ANDI	P1,-1		;RESTORE JUST THE ADDRESS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHECK THE NAME SPECIFICATION

LKWC30:	DMOVE	T1,X.BLK+.FXNAM	;GET ACCUMULATED NAME SPECIFICATION
	DMOVE	T3,.FXNAM(P1)	;GET POSSIBLE NEW NAME SPECIFICATION
	PUSHJ	P,LKW6B		;MERGE THE TWO SPECIFICATIONS
	 JRST	LKWC33		;DON'T BOTHER
	DMOVEM	T1,X.BLK+.FXNAM	;SET IN INTERNAL BLOCK
	MOVX	T3,FX.WNM	;THE WILDCARDS-IN-NAME FLAG
	AOJE	T2,.+3		;ANY WILDCARDS PRESENT
	CAIE	T1,0		;IN A NON-BLANK FILE NAME SPECIFICATION?
	IORM	T3,X.BLK+.FXFLD	;YES, SET IN FIELDS WORD

;CHECK THE EXTENSION TOO

LKWC33:	HLLZ	T1,X.BLK+.FXEXT	;GET ACCUMULATED FILE TYPE SPECIFICATION
	HRLZ	T2,X.BLK+.FXEXT	;GET FILE TYPE WILDCARD MASK
	HLLZ	T3,.FXEXT(P1)	;GET POSSIBLE NEW FILE TYPE
	HRLZ	T4,.FXEXT(P1)	;GET POSSIBLE NEW WILDCARD MASK
	PUSHJ	P,LKW6B		;MERGE THE TWO SPECIFICATIONS
	 JRST	LKWC36		;DON'T BOTHER
	HLR	T1,T2		;RECOMBINE INTO ONE WORD
	MOVEM	T1,X.BLK+.FXEXT	;SET NEW ACCUMULATION
	MOVX	T3,FX.WEX	;THE WILDCARDS-IN-EXTENSION FLAG
	IORI	T2,-1		;IGNORE R.H.
	AOJE	T2,.+3		;ANY WILDCARDS PRESENT IN EXTENSION
	CAIE	T1,0		;IN A NON-BLANK FILE TYPE SPECIFICATION?
	IORM	T3,X.BLK+.FXFLD	;YES, SET IN FIELDS WORD

;CHECK THE GENERATION (?)

LKWC36:	JRST	.POPJ1##	;FILE SPECS "OR"ED TOGETHER
;LKW3B - RETURN "LOGICAL OR, WILDCARDED" OF TWO PPN SPECIFICATIONS
;CALL IS:
;
;	MOVX	T1,<PPN1>
;	MOVX	T2,<MSK1>
;	MOVX	T3,<PPN1>
;	MOVX	T4,<MSK1>
;	PUSHJ	P,LKW3B
;	 IGNORE
;	RETURN
;
;WHERE <PPN1> AND <PPN2> ARE THE 6-CHARACTER 3-BIT PPNS; AND <MSK1>
;AND <MSK2> ARE THE RELATED WILDCARD MASKS
;
;IF BOTH SPECIFICATIONS ARE BLANK (OR OTHERWISE IDENTICAL) THE
;NON-SKIP ("IGNORE") RETURN IS TAKEN.
;
;ON SKIP RETURN THE TWO SPECIFICATIONS HAVE BEEN "MERGED" AND THE
;RESULT IS IN T1/T2.

LKW3B:	CAIN	T1,0		;IF BOTH SPECS ARE BLANK
	JUMPE	T3,.POPJ##	;THEN NOTHING TO DO
	CAMN	T1,T3		;OR
	CAME	T2,T4		; IF BOTH SPECS ARE IDENTICAL
	CAIA			;(THEY AREN'T)
	POPJ	P,		;BOTH SPECS IDENTICAL, DO NOTHING

;AT LEAST ONE SPECIFICATION NON-BLANK, "MERGE" THEM

	PUSHJ	P,.SAVE2##	;NEED A COUPLA EXTRA ACS
	MOVSI	P1,700000	;START WITH LEFT-MOST CHARACTER

;LOOP CHECKING EACH CHARACTER POSITION

LKW3B1:	TDNE	T2,P1		;ANY WILDCARDS
	TDNN	T4,P1		; IN EITHER SPECIFICATION?
	JRST	LKW3B4		;YES, WILDCARDS WIN!
	MOVE	P2,T1		;NO. GET SCRATCH COPY OF FIRST NAME
	XOR	P2,T3		;CONTRAST WITH SECOND NAME
	AND	P2,P1		;IGNORE OTHER CHARACTER POSITIONS
	JUMPE	P2,LKW3B7	;IF IDENTICAL THEN PASS IT THROUGH

;EITHER WILD OR DIFFERENT CHARACTERS, MARK THIS POSITION FULL WILD

LKW3B4:	ANDCM	T2,P1		;MARK THIS CHARACTER POSITION WILD
	MOVE	P2,[333333,,333333]  ;ALL POSSIBLE WILD CHARACTER POSITIONS
	AND	P2,P1		;SELECT JUST ONE OF THEM
	ANDCM	T1,P1		;MAKE ROOM FOR IT IN THE RESULTANT NAME
	IOR	T1,P2		;AND MAKE THE NAME LOOK REASONABLE
LKW3B7:	LSH	P1,-6		;ADVANCE TO NEXT CHARACTER POSITION
	JUMPN	P1,LKW3B1	;AND CHECK IT OUT
	CAIN	T2,0		;RESULTANT NAME FULL WILD?
	MOVE	T1,[377777,,377777]  ;YES, CHOOSE A BETTER REPRESENTATION
	JRST	.POPJ1##	;RETURN MERGED SPECIFICATION
;LKW6B - RETURN "LOGICAL OR, WILDCARDED" OF TWO NAME SPECIFICATIONS
;CALL IS:
;
;	MOVX	T1,<NAM1>
;	MOVX	T2,<MSK1>
;	MOVX	T3,<NAM1>
;	MOVX	T4,<MSK1>
;	PUSHJ	P,LKW6B
;	 IGNORE
;	RETURN
;
;WHERE <NAM1> AND <NAM2> ARE THE 6-CHARACTER 6-BIT NAMES; AND <MSK1>
;AND <MSK2> ARE THE RELATED WILDCARD MASKS
;
;IF BOTH SPECIFICATIONS ARE BLANK (OR OTHERWISE IDENTICAL) THE
;NON-SKIP ("IGNORE") RETURN IS TAKEN.
;
;ON SKIP RETURN THE TWO SPECIFICATIONS HAVE BEEN "MERGED" AND THE
;RESULT IS IN T1/T2.

LKW6B:	CAIN	T1,0		;IF BOTH SPECS ARE BLANK
	JUMPE	T3,.POPJ##	;THEN NOTHING TO DO
	CAMN	T1,T3		;OR
	CAME	T2,T4		; IF BOTH SPECS ARE IDENTICAL
	CAIA			;(THEY AREN'T)
	POPJ	P,		;BOTH SPECS IDENTICAL, DO NOTHING

;AT LEAST ONE SPECIFICATION NON-BLANK, "MERGE" THEM

	PUSHJ	P,.SAVE2##	;NEED A COUPLA EXTRA ACS
	MOVSI	P1,770000	;START WITH LEFT-MOST CHARACTER

;LOOP CHECKING EACH CHARACTER POSITION

LKW6B1:	TDNE	T2,P1		;ANY WILDCARDS
	TDNN	T4,P1		; IN EITHER SPECIFICATION?
	JRST	LKW6B4		;YES, WILDCARDS WIN!
	MOVE	P2,T1		;NO. GET SCRATCH COPY OF FIRST NAME
	XOR	P2,T3		;CONTRAST WITH SECOND NAME
	AND	P2,P1		;IGNORE OTHER CHARACTER POSITIONS
	JUMPE	P2,LKW6B7	;IF IDENTICAL THEN PASS IT THROUGH

;EITHER WILD OR DIFFERENT CHARACTERS, MARK THIS POSITION FULL WILD

LKW6B4:	ANDCM	T2,P1		;MARK THIS CHARACTER POSITION WILD
	MOVE	P2,['??????']	;ALL POSSIBLE WILD CHARACTER POSITIONS
	AND	P2,P1		;SELECT JUST ONE OF THEM
	ANDCM	T1,P1		;MAKE ROOM FOR IT IN THE RESULTANT NAME
	IOR	T1,P2		;AND MAKE THE NAME LOOK REASONABLE
LKW6B7:	LSH	P1,-6		;ADVANCE TO NEXT CHARACTER POSITION
	JUMPN	P1,LKW6B1	;AND CHECK IT OUT
	CAIN	T2,0		;RESULTANT NAME FULL WILD?
	MOVSI	T1,'*  '	;YES, CHOOSE A BETTER REPRESENTATION
	JRST	.POPJ1##	;RETURN MERGED SPECIFICATION
	SUBTTL	PRIMARY WILDCARDING ERRORS

;ERROR:	THE DIRECTORY IS EMPTY

E.DEM:	SKIPE	UFDEF		;SEE IF WE FOUND AN ERROR YET
	JRST	LOOKN		;YES--DON'T REPORT IT AGAIN
	SKIPN	.CTDRF		;SEE IF ANY SUCCESSFULLY LOOKUP'ED
	JRST	E$$NXD		;NO--GO GIVE MESSAGE
E$$DEM:	SKIPA	T1,['DEM',,[ASCIZ \Directory is empty \]]
E$$NSD:	MOVE	T1,['NSD',,[ASCIZ \No such directory \]]
	PUSHJ	P,WLDWRN	;ISSUE WARNING
	  JRST	E$FIL9		;SKIP REST IF NOT /VERB:FIRST
	MOVE	T1,.WIFIR	;START OF USER FILE EXPRESSION
	MOVX	T2,FX.UND!FX.UDV!FX.UDR  ;TYPE OUT NODE/DEV/DIRECTORY ONLY
	HRR	T2,AGLENP	;BUT TYPE 'EM ALL OUT
	JRST	E$FIL7		;GO ISSUE FILE EXPRESSION AND RETURN


;ERROR: DECTAPE DIRECTORY PATH ILLEGAL

E$$DDI:	MOVE	T1,['DDI',,[ASCIZ\DECtape directory path illegal\]]
	PUSHJ	P,WLDWRN	;START UP THE MESSAGE
	 JRST	E$FIL9		;PREFIX ONLY
	PUSHJ	P,DIRERR	;LIST THE DIRECTORY
	JRST	E$FIL9		;CAP OFF THE ERROR


;ERROR:	NO FILE NAME SPECIFIED FOR DISK FILE

E$$NFS:	MOVE	T1,['NFS',,[ASCIZ /No file name specified /]]
	PUSHJ	P,WLDERR	;ISSUE ERROR
	  JRST	E$FIL9		;SKIP REST IF NOT /VERB:FIRST
	PUSHJ	P,FILOUT	;ISSUE FILE ERROR
;ERROR: DIRECTORY COULD NOT BE FOUND ON SOME STRUCTURE

DLYERR:	MOVE	T2,[ERIPP%	;MFD MISSING
		    ERSNF%	;SFD MISSING
		    ERFNF%]-1(T2)  ;OR FILE MISSING
	SKIPN	UFDEF		;SEE IF ERROR ALREADY GIVEN
	PUSHJ	P,LKEDR		;NO--GIVE THIS ONE
	JRST	LOOKN		;AND FINISH UP


;ERROR:	ALL MATCHING UFDS WERE NON-EXISTENT

E$$NXD:	MOVE	T1,['NXD',,[ASCIZ /Non-existent/]]
	PUSHJ	P,WLDWRN	;ISSUE WARNING
	  JRST	E$FIL9		;SKIP REST IF NOT /VERB:FIRST
	PUSHJ	P,UFDERR	;ISSUE DEVICE AND UFD CODE
	JRST	LOOKN		;AND START OVER
;ERROR:	NO FILE MATCHES THE USER'S REQUEST

E$$NSF:	SKIPA	T1,['NSF',,[ASCIZ \No such files as \]]
E$$AFR:	MOVE	T1,['AFR',,[ASCIZ \All files rejected by constraints \]]
E$FILE:	PUSHJ	P,WLDWRN	;ISSUE WARNING PREFIX
	  JRST	E$FIL9		;NOT /MESSAGE:FIRST
	MOVE	T1,.WIFIR	;START OF USER FILE EXPRESSION
	MOVX	T2,FX.UXX	;TYPE IT ALL OUT
	HRR	T2,AGLENP	;TYPE 'EM ALL OUT
	HLRZ	T3,.FXEXT(T1)	;GET USER'S FILE TYPE
	CAIE	T3,'UFD'	;USER SPECIFY A UFD?
	JRST	E$FIL7		;NO, JUST TYPE OUT THE SPEC
	MOVE	T3,.FXFLD(T1)	;YES, GET FIELDS FLAGS
	TXNE	T3,FX.UNM	;DID USER SPECIFY A NAME
	TXNN	T3,FX.UDR	;AS WELL AS A DIRECTORY?
	JRST	[TXNE	T3,FX.UDR	;NO, USER SPECIFY A DIRECTORY?
		SKIPA	T3,.FSDIR(T1)	;GET USER-SPECIFIED DIRECTORY
		MOVE	T3,.FSNAM(T1)	;GET USER-SPECIFIED NAME
		MOVEM	T3,W.BLK+.FSDIR	;SAVE IN SCRATCH BLOCK
		TXZ	T2,FX.UNM	;DON'T TYPE OUT FILE NAME
		HRRI	T2,0		;DON'T TYPE CONCATENATED STUFF
		MOVEI	T1,W.BLK	;TYPE OUT FROM OUR SCRATCH BLOCK
		JRST	E$FIL7]		;TYPE OUT NICELY

E$FIL7:	PUSHJ	P,.TOFSB##	;LIST THE OFFENDING FILE SPEC/CONSTRAINTS
E$FIL9:	PUSHJ	P,.TCRLF##	;ISSUE NEW LINE
	JRST	LOOKN		;PROCEDE WITH NEXT FILE EXPRESSION SET

E$$AFP:	SKIPA	T1,['AFP',,[ASCIZ \All files protected \]]
E$$SFP:	MOVE	T1,['SFP',,[ASCIZ \Some files protected \]]
	JRST	E$FILE		;GO ISSUE WARNING

E$$SLE:	SKIPA	T1,['SLE',,[ASCIZ \Search list empty \]]
E$$SDP:	MOVE	T1,['SDP',,[ASCIZ \Some directories protected \]]
	JRST	E$FILE		;GO ISSUE MESSAGE

E$$NSN:	SKIPA	T1,['NSN',,[ASCIZ \No such nodes \]]
E$$ANI:	MOVE	T1,['ANI',,[ASCIZ \All nodes inaccessible \]]
	JRST	E$FILE		;GO ISSUE COMPLAINTS

E$$SNP:	SKIPA	T1,['SNP',,[ASCIZ \Some nodes inaccessible \]]
E$$ANP:	MOVE	T1,['ANP',,[ASCIZ \All nodes protected \]]
	JRST	E$FILE		;GO ISSUE COMPLAINTS
	SUBTTL	PRIMARY WILDCARDING FILE EXPRESSION LOGIC

;CHKTM  --  VERIFY SELECTED FILE SATISFIES FILE EXPRESSION/CONSTRAINTS
;CALL IS:
;
;	PUSHJ	P,.CHKTM/.CHKTA
;	 REJECTED
;	OK
;
;CHKTM AND CHKTA BOTH ASSUME THE CALLER IS RETURNING THE FILE SELECTED
;BY .LKWLD, AND THAT AS SUCH THE AG???? POINTERS ARE VALID (ADDRESS OF
;FILE OPEN AND LOOKUP BLOCKS, ETC.).
;
;.CHKTF ACCEPTS IN T1 THE SAME ARGUMENT POINTER AS .LKWLD, AND WILL SETUP
;THE AG???? AREA ACCORDINGLY (USER HAD BETTER BE CAREFUL NOT TO INTERMIX
;.LKWLD AND .CHKTF CALLS - THE RESULTS ARE UNPREDICTABLE)
;
;IF THE SELECTED FILE (AS SETUP IN THE OPEN/LOOKUP/PATH BLOCKS) MATCHES
;THE SELECTED FILE EXPRESSION SET (THIS INCLUDES BOTH FILE EXPRESSION
;OPERATIONS SUCH AS 'OR' AS WELL AS FILE CONSTRAINTS SUCH AS /BEFORE)
;THEN THE SKIP ("OK") RETURN IS TAKEN, OTHERWISE THE NON-SKIP ("REJECTED")
;RETURN IS TAKEN INDICATING THE CALLER SHOULD IGNORE THIS FILE AND
;ADVANCE TO THE NEXT FILE.
;
;USES T1-4

.CHKTM::SKIPE	NOTDSK		;SEE IF NONDIRECTORY
	SKIPE	FLDTA		; AND NOT DECTAPE		[156]
	JRST	.CHKTA		;OK--GO DO
	JRST	CPOPJ1		;YES--ASSUME OK

.CHKTF::PUSHJ	P,LKWAG		;READ IN USER-SUPPLIED INFO
	 JRST	E..IWA		;GO BITCH ABOUT THIS
.CHKTA::MOVE	T4,.WIFIR	;GET FIRST SPEC BLOCK ADDRESS
	CAME	T4,.WILAS	;MORE THAN ONE SPEC BLOCK?
	SKIPE	.WXPRC		;YES, CONCATENATED EXPRESSION FLAG SET TOO?
	JRST	CHKTX0		;OK
	SETOM	.WXPRC		;NOTE CONCATENATED FILE EXPRESSION
	OUTSTR	[ASCIZ\% .WXPRC not set with concatenated file expression
\]				;WARN CALLER OF MISBEHAVIOUR

CHKTX0:	PUSHJ	P,.SAVE1##	;WANT A PRESERVED SCRATCH AC
	SETZM	CHKRCT		;NO FILES REJECTED YET
	SETOM	CHKTCT		;HAVEN'T CALLED CHKTST YET
	SKIPE	.WXPRC		;WILL CHKTST NEED TO CALL WSXXX ROUTINES?
	PUSHJ	P,.SAVWS	;YES, PRESERVE CURRENT STATE THEN

;LOOP OVER EACH SPEC IN THE CONCATENATED SET LOOKING FOR MATCH

	MOVE	P1,.WIFIR	;START AT START			[300]
	JRST	CHKTML		;ENTER CHECK LOOP
;HERE WHEN HOPING FOR A WINNING SPEC (LOSING, WITH 'OR' NEXT)

CHKTMO:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT
	  JRST	CPOPJ1		;IF DONE, ASSUME WIN BIG
CHKTML:	PUSHJ	P,CHKTST	;TEST NEXT SPEC FOR MATCH
	  JRST	CHKLOS		;NO--BAD MATCH
	MOVEM	P1,@AGPNTR	;UPDATE CURRENT SPEC POINTER FOR USER
	JRST	CHKWIN		;WINNING SO FAR . . .


;HERE WHEN WINNING SO FAR, THEN 'AND' ENCOUNTERED

CHKTMA:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT
	  JRST	CPOPJ1		;IF DONE, ASSUME WIN BIG
	PUSHJ	P,CHKTST	;SEE IF THIS SPEC WINS TOO
	  JRST	CHKLOS		;LOST, NEED ANOTHER 'OR'
	JRST	CHKWIN		;WON, DONE UNLESS 'AND' ETC.


;HERE WHEN WINNING SO FAR, THEN 'BEGIN' ENCOUNTERED

CHKTMB:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;IF DONE, ASSUME WIN BIG
	MOVE	T1,.CTFLF	;GET FILES WON SO FAR
	CAILE	T1,1		;IS THIS THE [POTENTIAL] FIRST FILE?
	JRST	CHKWIN		;NO, THEN IGNORE THE 'BEGIN' SPEC
	PUSHJ	P,CHKTST	;YES, DOES IT MATCH?
	  JRST	CHKLOS		;NO, SKIP ONWARDS
	JRST	CHKWIN		;YES, BEGIN WITH THIS FILE


;HERE WHEN WINNING SO FAR, THEN 'END' ENCOUNTERED

CHKTME:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;IF DONE, ASSUME WIN BIG
	MOVE	T1,.CTFLF	;GET FILES WON SO FAR
	CAIG	T1,1		;HAVE ANY FILES WON YET?
	JRST	CHKWIN		;NO, THEN THIS ONE MIGHT
	PUSHJ	P,CHKTST	;YES, IS THIS THE END OF IT ALL?
	  JRST	CHKWIN		;NO, THIS FILE WINS
	SETOM	.WLDNE		;YES, FLAG NO MORE FILES FROM THIS SPEC SET
	JRST	CHKTMF		;AND REJECT THIS FILE
;HERE WHEN WINNING SO FAR, THEN 'NOT' ENCOUNTERED

CHKTMN:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;NOT THERE!--ASSUME BIG WIN
	PUSHJ	P,CHKTST	;TEST FOR MATCH
	  JRST	CHKWIN		;NO--PROCEED TO NEXT BASED ON SEPARATOR
	JRST	CHKLOS		;FILE OK, WE LOSE, SKIP TO NEXT 'OR'


;HERE WHEN WINNING SO FAR, THEN 'IFAND' ENCOUNTERED

CHKIFA:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;RAN OUT, ASSUME WIN
	PUSHJ	P,CHKLOK	;OPEN SECONDARY FILE
	  JRST	CHKLOS		;NO THERE, LOSE
	JRST	CHKWIN		;SECONDARY FILE MATCHED! WIN!


;HERE WHEN WINNING SO FAR, THEN 'IFNOT' ENCOUNTERED

CHKIFN:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;RAN OUT, ASSUME WIN
	PUSHJ	P,CHKLOK	;OPEN SECONDARY FILE
	  JRST	CHKWIN		;NOT MATCHED, WIN
	JRST	CHKLOR		;SECONDARY FILE MATCHED, REJECT THIS FILE
;HERE WHEN WINNING SO FAR, THEN 'IFSAME' ENCOUNTERED

CHKISA:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;RAN OUT, ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT SECONDARY FILE
	  JRST	CHKLOR		;DOESN'T EXIST, SO IT CAN'T BE THE SAME
	JSP	T4,CHKJC	;CHECK LOGICAL DATA CREATION TIMES
	  JRST	CHKLOR		;OLDER, LOSE
	  CAIA			;SAME, WIN
	  JRST	CHKLOR		;NEWER, LOSE
	JSP	T4,CHKJS	;CHECK FILE SIZE
	  JRST	CHKLOR		;SMALLER, LOSE
	  CAIA			;SAME, WIN
	  JRST	CHKLOR		;BIGGER, LOSE
	JSP	T4,CHKJM	;CHECK FILE I/O DATA MODE
	  JRST	CHKLOR		;DIFFERENT, LOSE
	  JRST	CHKWIN		;FILES ARE THE SAME, WIN


;HERE WHEN WINNING SO FAR, THEN 'IFDIFFERENT' ENOUNTERED

CHKIDF:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;RAN OUT, ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT SECONDARY FILE
	  JRST	CHKWIN		;DOESN'T EXIST, ABOUT AS DIFFERENT AS CAN BE
	JSP	T4,CHKJC	;CHECK DATA CREATION DATE
	  JRST	CHKWIN		;OLDER, DIFFERENT, WINS
	  CAIA			;SAME, CHECK FURTHER
	  JRST	CHKWIN		;NEWER, DIFFERENT, WINS
	JSP	T4,CHKJS	;CHECK FILE SIZE
	  JRST	CHKWIN		;SMALLER, DIFFERENT, WINS
	  CAIA			;CAME, CHECK FURTHER
	  JRST	CHKWIN		;BIGGER, DIFFERENT, WINS
	JSP	T4,CHKJM	;CHECK I/O DATA MODE
	  JRST	CHKWIN		;DIFFERENT, WINS
	  JRST	CHKLOR		;FILES ARE THE SAME, LOSE
;HERE WHEN WINNING SO FAR, THEN 'IFOLDER' ENCOUNTERED

CHKIOL:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT THE SECONDARY FILE
	  JRST	CHKLOR		;NO FILE, ASSUME LOSE
	JSP	T4,CHKJC	;COMPARE THE CREATION DATES
	  JRST	CHKWIN		;OLDER, WIN
	  JRST	CHKLOR		;SAME, LOSES
	  JRST	CHKLOR		;NEWER, LOSES


;HERE WHEN WINNING SO FAR, THEN 'IFNEWER' ENCOUNTERED

CHKINE:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT THE SECONDARY FILE
	  JRST	CHKLOR		;NO FILE, ASSUME LOSE
	JSP	T4,CHKJC	;COMPARE THE CREATION DATES
	  JRST	CHKLOR		;OLDER, LOSES
	  JRST	CHKLOR		;SAME, LOSES
	  JRST	CHKWIN		;NEWER, WINS


;HERE WHEN WINNING SO FAR, THEN 'IFSMALLER' ENCOUNTERED

CHKISM:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT THE SECONDARY FILE
	  JRST	CHKLOR		;NO FILE, ASSUME LOSE
	JSP	T4,CHKJS	;COMPARE THE FILE SIZES
	  JRST	CHKWIN		;SMALLER, WINS
	  JRST	CHKLOR		;SAME, LOSES
	  JRST	CHKLOR		;BIGGER, LOSES


;HERE WHEN WINNING SO FAR, THEN 'IFBIGGER' ENCOUNTERED

CHKIBG:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CPOPJ1		;ASSUME WIN
	PUSHJ	P,CHKLOK	;LOOK AT SECONDARY FILE
	  JRST	CHKLOR		;NO FILE, ASSUME LOSE
	JSP	T4,CHKJS	;COMPARE FILE SIZES
	  JRST	CHKLOR		;SMALLER, LOSE
	  JRST	CHKLOR		;SAME, LOSE
	  JRST	CHKWIN		;BIGGER, WIN
;HERE WHEN SKIPPING TO NEXT 'OR' BECAUSE LOOSING

CHKSKP:	PUSHJ	P,CHKTAD	;ADVANCE TO NEXT SPEC
	  JRST	CHKTMF		;IF DONE, LOOSE BIG
	JRST	CHKLOR		;IF SOMETHING, REDISPATCH


;HERE IF TOO OLD OR TOO YOUNG
;	BACK DOWN SUCCESS COUNTER

CHKTMF:	SOS	.CTFLF		;IN ANY CASE, FILE IS NOT SUCCESSFULLY FOUND
	SKIPE	CHKRCT		;DID FILE EVEN MATCH THE FILE EXPRESSION?
	AOS	.CTFLR		;YES, REJECTED AS OPPOSED TO "NOT FOUND"
				; (THIS ALLOWS USERS TO SUPPLY THEIR OWN
				;  "FILE SERVICE" (E.G., DIRECT/FIND) AND
				;  STILL GET MEANINGFUL MESSAGES FROM .LKWLD
				;  "NO SUCH FILE" VERSUS "ALL FILES REJECTED")
	POPJ	P,		;GIVE BAD NEWS TO CALLER



;CHKTAD -- ROUTINE TO ADVANCE WITHIN A CONCATENATED SPEC
;	MAINTAINS T4 AND AGPNTR

CHKTAD:	ADD	P1,AGLENP	;ADVANCE TO NEXT SPEC
	CAMG	P1,.WILAS	;SEE IF DONE
	AOS	(P)		;NO--SKIP RETURN
	POPJ	P,		;RETURN
;HERE WHEN WINNING SO FAR, DISPATCH ON ANY FURTHER FILE CONSTRAINTS

CHKWIN:	LDB	T1,[POINTR (.FXMOD(P1),FX.TRM)] ;GET TERMINATOR
	JRST	@.+1(T1)	;DISPATCH ON FILE EXPRESSION OPERATOR

CHKWTB:	IFIW	CPOPJ1		;.FXTRZ	","	END, WIN BIG
	IFIW	CHKTMA		;.FXTRA	'AND'	NEXT MUST ALSO WIN
	IFIW	CPOPJ1		;.FXTRO	'OR'	WIN BIG
	IFIW	CHKTMN		;.FXTRN	'NOT'	NEXT MUST NOT WIN
	IFIW	CPOPJ1		;.FXTRC	"+"	END, WIN BIG
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CHKTMB		;.FXTRB 'BEGIN'	WIN ONLY IF FIRST FILE
	IFIW	CHKTME		;.FXTRE 'END'	LOSE IF PAST FIRST FILE
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CHKIFA		;.FXTIA	'IFAND'	SECONDARY FILE MUST ALSO WIN
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CHKIFN		;.FXTIN	'IFNOT'	SECONDARY FILE MUST NOT WIN
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CHKISA		;.FXTIS	'IFSAM' IF SAME AS
	IFIW	CHKIDF		;.FXTID	'IFDIF'	IF DIFFERENT FROM
	IFIW	CHKIOL		;.FXTIO	'IFOLD'	IF OLDER THAN
	IFIW	CHKINE		;.FXTIW	'IFNEW'	IF NEWER THAN
	IFIW	CHKISM		;.FXTIL	'IFSMA'	IF SMALLER THAN
	IFIW	CHKIBG		;.FXTIB	'IFBIG'	IF BIGGER THAN
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
	IFIW	CPOPJ1		;		  --  UNDEFINED  --
;HERE WHEN LOST--MUST WAIT FOR NEXT 'OR' TO WIN

CHKLOR:	AOS	CHKRCT		;COUNT REJECTIONS BASED ON CONSTRAINTS
CHKLOS:	LDB	T1,[POINTR (.FXMOD(P1),FX.TRM)] ;GET TERMINATOR
	JRST	@.+1(T1)	;DISPATCH ON FILE EXPRESSION OPERATOR

CHKLTB:	IFIW	CHKTMF		;.FXTRZ	","	END, LOOSE BIG
	IFIW	CHKSKP		;.FXTRA	'AND'	SKIP ON
	IFIW	CHKTMO		;.FXTRO	'OR'	START MATCHING OVER
	IFIW	CHKSKP		;.FXTRA	'NOT'	SKIP ON
	IFIW	CHKTMF		;.FXTRC	"+"	END, LOOSE BIG
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKSKP		;.FXTRB 'BEGIN'	SKIP ON
	IFIW	CHKSKP		;.FXTRE 'END'	SKIP ON
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKSKP		;.FXTIA	'IFAND'	SKIP ON
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKSKP		;.FXTIN	'IFNOT'	SKIP ON
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;.FXTIS	'IFSAM'	SKIP ON
	IFIW	CHKTMF		;.FXTID	'IFDIF'	SKIP ON
	IFIW	CHKTMF		;.FXTIO	'IFOLD'	SKIP ON
	IFIW	CHKTMF		;.FXTIW	'IFNEW'	SKIP ON
	IFIW	CHKTMF		;.FXTIL	'IFSMA'	SKIP ON
	IFIW	CHKTMF		;.FXTIB	'IFBIG'	SKIP ON
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
	IFIW	CHKTMF		;		  --  UNDEFINED  --
;CHKTST -- CHECK TO SEE IF CURRENT SPEC MATCHES FILE
;CALL IS:
;
;	MOVX	P1,<FSB>
;	PUSHJ	P,CHKTST
;	 NO-MATCH
;	MATCH
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPEC BLOCK TO BE MATCHED.
;
;ASSUMES THAT AGOPEN AND AGLOOK CONTAIN THE ADDRESSES OF THE RESULTANT
;FILE OPEN AND LOOKUP BLOCKS (AS [USUALLY] SET BY .LKWLD).
;
;USES T1-4

CHKTST:	PUSHJ	P,.SAVE4##	;P'S USED LOCALLY
	MOVE	P2,AGOPEN	;ADDRESS OF FILE OPEN BLOCK
	MOVE	P3,AGLOOK	;ADDRESS OF THE FILE LOOKUP BLOCK
	SETZ	P4,		;NO NODE STUFF HERE YET
	AOSG	CHKTCT		;FIRST CALL IN THE SET?
	SKIPE	.WXPRC		;YES - CAN WE SKIP THE WSTR STUFF?
	JRST	CHKTS3		;MUST LOOP THROUGH WSTR (MAYBE)

;SINCE A FILE EXPRESSION WAS NOT TYPED (AND WILD SELECTED THE FILE) THE
;FILE IS GUARANTEED TO ALREADY MATCH THE FILE SPEC BLOCK!

CHKTS1:	PUSHJ	P,CHKSW		;JUST CHECK THE SWITCH CONSTRAINTS HERE
	 AOSA	CHKRCT		;COUNT A REJECTION BASED ON FILE CONSTRAINTS
	AOS	(P)		;FILE MATCHED, ACCEPT RETURN
	POPJ	P,		;RETURN APPROPRIATELY


;MUST VERIFY THE FILE SPECIFICATION AS WELL AS FILE SWITCHES

CHKTS3:	DMOVE	T1,.FXDEV(P1)	;GET DEVICE SPECIFICATION
	CAIE	T1,0		;IF A NON-WILD DEVICE WAS SPECIFIED
	AOJE	T2,CHKTS5	;THEN MUST LOOP THROUGH WSTR

;EITHER NO DEVICE WAS SPECIFIED, OR THE DEVICE IS WILDCARDED. IN EITHER
;CASE THE DEVICE CANNOT EXPAND INTO IMPLIED/DEFAULT FIELDS SO A SIMPLE
;DIRECT COMPARISON IS SUFFICIENT

CHKTS4:	PUSHJ	P,CHKFS		;SEE IF THE FILE SPECIFICATION MATCHES
	 POPJ	P,		;FILE SPECIFICATION DOESN'T MATCH
	PJRST	CHKTS1		;SEE IF THE SWITCHES MATCH ALSO
;MUST ITERATE THROUGH THE VARIOUS "SEARCH LISTS" IMPLIED BY THIS FILE SPEC

CHKTS5:	PUSH	P,P1		;PRESERVE A COPY OF THE ORIGINAL FSB
	MOVE	T1,P1		;ADDRESS OF CURRENT SPEC TO BE MATCHED
	PUSHJ	P,.WSTRI	;INIT WSTRN
	  JFCL			;CAN'T HAPPEN
	CAIA			;ENTER WSTRC LOOP

;LOOP ON EACH FILE "SEARCH LIST"

CHKTS6:	AOS	CHKRCT		;COUNT UP FILE REJECTIONS
CHKTS7:	MOVEI	T1,Z.BLK	;CHKXXX'S OWN INTERNAL BLOCK
	PUSHJ	P,.WSTRC	;GET A/NOTHER "SEARCH LIST"
	 JRST	CHKTS8		;ALL DONE, FILE DOESN'T MATCH
	MOVEI	P1,Z.BLK	;INTERNAL FILE SPEC BLOCK FOR THIS SEARCH LIST
	PUSHJ	P,CHKFS		;VERIFY FILE SPEC
	 JRST	CHKTS7		;REJECTED, KEEP TRYING
;	PUSHJ	P,CHKSW		;VERIFY FILE SWITCHES FROM WSTRN
;	 JRST	CHKTS6		;REJECTED, KEEP TRYING
	MOVE	P1,0(P)		;CALLER'S ORIGINAL FILE SPEC BLOCK
	PUSHJ	P,CHKSW		;VERIFY CALLER'S FILE SWITCHES
	 JRST	CHKTS6		;REJECTED, KEEP TRYING
	AOS	-1(P)		;MATCHED! RETURN SUCCESSFULLY
CHKTS8:	POP	P,P1		;ADJUST STACK
	POPJ	P,		;RETURN APPROPRIATELY
;CHKLOK -- CHECK TO SEE IF SECONDARY FILE EXISTS AND MATCHES
;CALL IS:
;
;	MOVX	P1,<FSB>
;	PUSHJ	P,CHKTST
;	 NO-MATCH
;	MATCH
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPEC BLOCK TO BE MATCHED.
;
;ASSUMES THAT AGOPEN AND AGLOOK CONTAIN THE ADDRESSES OF THE RESULTANT
;FILE OPEN AND LOOKUP BLOCKS (AS [USUALLY] SET BY .LKWLD).
;
;USES T1-4

CHKLOK:	PUSHJ	P,.SAVE4##	;WANT SOME ACS HERE
	MOVEM	P1,CHKSOF	;SET SECONDARY ("OUTPUT") FILE SPEC BLOCK ADR
	MOVE	T1,@AGPNTR	;GET PRIMARY ("INPUT") FILE SPEC BLOCK ADR
	MOVEM	T1,CHKSIF	;AND SET IT FOR SCWILD

;SET SETUP SCWILD ARG BLOCK

	MOVE	T1,[VERWRD]	;PROTOCOL WORD
	MOVEM	T1,CHKSCB+0	;SET IN ARG BLOCK
	MOVE	T1,[CHKSIF,,CHKSOF]  ;PRIMARY,,SECONDARY FSB ADDRESS OF ADDRESS
	MOVEM	T1,CHKSCB+1	;SET IN ARG BLOCK
	MOVS	T1,AGOPEN	;PRIMARY OPEN BLOCK
	HRRI	T1,CHKFOB+.FOIOS;SECONDARY OPEN BLOCK
	MOVEM	T1,CHKSCB+2	;SET IN ARG BLOCK
	MOVS	T1,AGLOOK	;PRIMARY LOOKUP BLOCK
	HRRI	T1,CHKLEB	;SECONDARY LOOKUP/ENTER BLOCK
	MOVEM	T1,CHKSCB+3	;SET IN ARG BLOCK
	MOVE	T1,[[0,,-1],,CHKLEL]  ;DEFAULT EXTENSION,,LENGTH OF LOOKUP BLOCK
	MOVEM	T1,CHKSCB+4	;SET IN ARG BLOCK
	MOVEI	T1,CHKPAT	;SECONDARY PATH BLOCK
	MOVEM	T1,CHKSCB+5	;SET IN ARG BLOCK
	MOVEI	T1,CHKSCF	;ADDRESS OF FLAGS
	MOVEM	T1,CHKSCB+6	;SET IN ARG BLOCK

;NOW GENERATE SECONDARY FILE OPEN/LOOKUP BLOCK

	MOVE	T1,[7,,CHKSCB]	;ARG BLOCK POINTER FOR SCWILD TO
	PUSHJ	P,.SCWLD	;GENERATE SECONDARY FILE
	 POPJ	P,		;FAILED?? ASSUME NO MATCH THEN

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FILE OPEN AND LOOKUP BLOCKS SETUP, TRY TO ACCESS THE FILE

	SETZM	CHKFOB+.FOBRH	;NO BUFFER RING HEADERS NEEDED
	SETZM	CHKFOB+.FONBF	;AND NO BUFFERS NEEDED EITHER
	MOVEI	T1,CHKLEB	;ADDRESS OF SECONDARY FILE LOOKUP BLOCK
	MOVEM	T1,CHKFOB+.FOLEB;SET IN SECONDARY FILE FILOP. BLOCK
	MOVE	T1,[.PTMAX,,CHKPAT]  ;RETURNED PATH BLOCK
	MOVEM	T1,CHKFOB+.FOPAT;ASK FOR IT ON G.P.'S
	MOVE	T1,AGOBOP	;USE ON-BEHALF-OF PPN (IF ANY)
	MOVEM	T1,CHKFOB+.FOPPN;TELL MONITOR ABOUT IT TOO
	MOVE	T1,[1B0+.FORED]	;READ FUNCTION ON TEMP CHANNEL (0)
	MOVEM	T1,CHKFOB+.FOFNC;SET FILOP. FUNCTION WORD
	MOVE	T1,[.FOMAX,,CHKFOB]  ;FILOP. ARG POINTER TO
	FILOP.	T1,		;TRY TO ACCESS SECONDARY FILE
	 JRST	[HRRM	T1,CHKLEB+.RBEXT;ENSURE ERROR CODE SET IN LOOKUP BLOCK
		PUSHJ	P,E.IFL		;HANDLE ANY ERROR MESSAGES NEEDED
		JRST	CHKLO9]		;AND REJECT THE FILE

;FILE EXISTS AND WE CAN AT LEAST ACCESS IT - CHECK AGAINST SWITCH CONSTRAINTS

	MOVE	P1,CHKSOF	;ADDRESS OF FILE SPEC BLOCK
	MOVEI	P2,CHKFOB+.FOIOS;ADDRESS OF FILE OPEN BLOCK
	MOVEI	P3,CHKLEB	;ADDRESS OF FILE LOOKUP BLOCK
	MOVEI	P4,0		;NO NODE STUFF
	MOVEI	T1,CHKLEL	;LENGTH OF OUR INTERNAL LOOKUP BLOCK
	PUSH	P,AGLENL	;SAVE USER'S LENGTH
	MOVEM	T1,AGLENL	;AND SET OURS TEMPORARILY
	PUSHJ	P,CHKSW		;VERIFY FILE AGAINST FILE SWITCH CONSTRAINTS
	 JRST	[POP	P,AGLENL	;RESTORE CORRECT USER PARAMETER
		JRST	CHKLO9]		;AND REJECT THIS FILE
	POP	P,AGLENL	;RESTORE CORRECT USER PARAMETER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO ACCEPT THE FILE

CHKLO8:	AOS	(P)		;SKIP RETURN TO INDICATE SUCCESS

;HERE TO REJECT THE FILE

CHKLO9:	MOVEI	T3,CL.DLL!CL.ACS;DON'T UPDATE ACCESS DATE
	MOVEI	T2,.FOCLS	;CLOSE FUNCTION ON TEMP CHANNEL (0)
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;CLOSE THE FILE QUIETLY
	 JFCL			;DUH???
	MOVEI	T2,.FOREL	;RELEASE FUNCTION ON TEMP CHANNEL (0)
	MOVE	T1,[1,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;RELEASE THE FILE QUIETLY
	 JFCL			;DUH???
	POPJ	P,		;RETURN AS APPROPRIATE



;RANDOM CHKLOK JUNK

	CHKLEL==.RBTIM+1	;LENGTH OF SECONDARY LOOKUP BLOCK

CHKSCF:	0			;USE DEFAULT /SCWILD AND /SCERROR
;CHKFS  --  VERIFY SELECTED PHYSICAL FILE AGAINST FILE SPECIFICATION
;CALL IS:
;
;	MOVX	P1,<FSB>
;	MOVX	P2,<OPN>
;	MOVX	P3,<LKP>
;	MOVX	P4,<NOD>
;	PUSHJ	P,CHKFS
;	 NO-MATCH
;	MATCH
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPECIFICATION BLOCK; <OPN>
;AND <LKP> ARE THE ADDRESSES OF THE RESULTANT PHYSICAL FILE OPEN AND
;LOOKUP BLOCKS; AND <NOD> IS THE NODE NAME OF THE RESULTANT PHYSICAL
;FILE.

CHKFS:	SKIPE	T1,P4		;IF NODE NAME TO BE CHECKED
	SKIPE	T1,.FXNOD(P1)	;GET NODE SPECIFICATION (IF ANY)
	XOR	T1,P4		;CONTRAST WITH RESULTANT "REAL" NODE
	SKIPE	T2,.FXDEV(P1)	;GET DEVICE SPECIFICATION (IF ANY)
	XOR	T2,.OPDEV(P2)	;CONTRAST WITH RESULTANT "REAL" DEVICE
	TDNN	T1,.FXNOM(P1)	;IF NODE DOESN'T MATCH, OR
	TDNE	T2,.FXDEM(P1)	;IF DEVICE DOESN'T MATCH
	POPJ	P,		;THEN REJECT THE CURRENT FILE

;NODE AND DEVICE ARE OK, CHECK THE FILE NAME AND TYPE

CHKFS3:	SKIPE	T1,.FXNAM(P1)	;GET FILE NAME SPECIFICATION
	XOR	T1,.RBNAM(P3)	;CONTRAST WITH ACTUAL "REAL" FILE NAME
	SKIPE	T2,.FXEXT(P1)	;UNLESS NO EXTENSION SPECIFIED,
	HLLZ	T2,.RBEXT(P3)	;GET EXTENSION
	XOR	T2,.FXEXT(P1)	;COMPARE TO MATCH
	TDNN	T1,.FXNMM(P1)	;IF FILE NAME DOESN'T MATCH,
	TLNE	T2,(T2)		;OR IF FILE TYPE DOESN'T MATCH
	POPJ	P,		;THEN REJECT THE CURRENT FILE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHECK THE FILE PATH NOW

CHKDR:	SKIPE	T2,.FXDIR(P1)	;GOT A DIRECTORY TO MATCH AGAINST?
	SKIPN	T1,.RBPPN(P3)	;GET DIRECTORY ENTRY
	JRST	CPOPJ1		;IF NONE, ASSUME MATCHES
	TLNN	T1,-1		;PPN OR PATH POINTER?
	MOVE	T1,.PTPPN(T1)	;PATH, FETCH PPN
	XOR	T1,T2		;CONTRAST "REAL" WITH SPECIFIED PPN
	TDNE	T1,.FXDIM(P1)	;IF PPN'S DON'T MATCH
	POPJ	P,		;THEN REJECT THE CURRENT FILE
CHKDR3:	MOVE	T1,.RBPPN(P3)	;FETCH ORIGINAL POINTER AGAIN
	TLNE	T1,-1		;PPN OR PATH?
	MOVEI	T1,DEFZRO	;PPN, DUMMY UP A PATH BLOCK
	HRLI	T1,-<.FXLND-1>	;LENGTH OF PATH (SFDS ONLY)
	MOVE	T2,P1		;SCRATCH COPY OF FILE SPEC BLOCK
CHKDR5:	MOVE	T3,.PTPPN+1(T1)	;NEXT SFD
	XOR	T3,.FXDIR+2(T2)	;CONTRAST WITH DIRECTORY SPECIFICATION
	SKIPN	.FXDIR+2(T2)	;USER SPECIFY ANYTHING AT THIS LEVEL?
	SKIPN	T3		;NO, PATH GO THIS FAR DOWN?
	TDNE	T3,.FXDIM+2(T2)	;PATH MATCH SPECIFICATION?
	POPJ	P,		;NO
	SKIPN	.PTPPN+1(T1)	;END OF DIRECTORY YET?
;	JRST	CHKSW		;YES, THEN IT MATCHES
;				; BUT WHAT ABOUT [1,2,A,B] & [1,2,*,*,X,*]??
	SUBI	T1,1		;CATCH [1,2,A] MATCHED AGAINST [1,2,*,B]
	ADDI	T2,2		;ADVANCE TO NEXT SPEC BIWORD
	AOBJN	T1,CHKDR5	;LOOP FOR REST OF DIRECTORY
	JRST	CPOPJ1		;WIN IF ALL MATCH
;CHKSW  --  VERIFY SELECTED PHYSICAL FILE AGAINST FILE [SWITCH] CONSTRAINTS
;CALL IS:
;
;	MOVX	P1,<FSB>
;	MOVX	P2,<OPN>
;	MOVX	P3,<LKP>
;	MOVX	P4,<NOD>
;	PUSHJ	P,CHKSW
;	 NO-MATCH
;	MATCH
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPECIFICATION BLOCK; <OPN>
;AND <LKP> ARE THE ADDRESSES OF THE RESULTANT PHYSICAL FILE OPEN AND
;LOOKUP BLOCKS; AND <NOD> IS THE NODE NAME OF THE RESULTANT PHYSICAL
;FILE.

CHKSW:	MOVE	T1,AGLENP	;GET BLOCK LENGTH
	SUBI	T1,.FXBOM	;T1:=LENGTH OF SWITCHES AREA
	JUMPLE	T1,.POPJ1##	;IF NO SWITCHES THEN CAN'T REJECT FILE HERE
	CAILE	T1,.FXEOM-.FXBOM;PAST WHAT WE KNOW ABOUT?
	MOVEI	T1,.FXEOM-.FXBOM;YES, LIMIT IT
	MOVN	T1,T1		;NEGATIVE LENGTH
	HRLZ	T1,T1		;IN THE LEFT HALF
	HRRI	T1,.FXBOM(P1)	;AOBJN POINTER TO SWITCH AREA
	SETO	T2,		;"NO-VALUE" VALUE
	CAMN	T2,(T1)		;SWITCH SPECIFIED?
	AOBJN	T1,.-1		;NO, CHECK THE REST
	JUMPGE	T1,.POPJ1##	;IF NO SWITCHES SPECIFIED, CAN'T REJECT FILE

;CHECK LOGICAL DATA CREATION DATE/TIMES

CHKSW2:	MOVE	T2,AGLENP	;LENGTH OF FILE SPEC BLOCK
	CAIGE	T2,.FXSNC+1	;IF /BEFORE AND /SINCE EXIST
	JRST	.POPJ1##	;(THEY DON'T)  ((THIS SHOULDN'T HAPPEN))
	LDB	T2,[POINTR .RBPRV(P3),RB.CRD]  ;LOW-ORDER CREATION DATE
	LDB	T3,[POINTR .RBEXT(P3),RB.CRX]  ;HIGH-ORDER CREATION DATE
	LSH	T3,WID(RB.CRD)	;POSITION HIGH-ORDER DATE BITS
	ADD	T2,T3		;MERGE TO FORM FULL 15-BIT CREATION DATE
	SKIPE	FLDTA		;IF DECTAPE,
	TDZA	T1,T1		; NO CREATION TIME
	LDB	T1,[POINTR (.RBPRV(P3),RB.CRT)]  ;GET CREATION TIME
	IMULI	T1,^D60000	;CONVERT TO MILLI-SEC.
	PUSHJ	P,.CNVDT##	;CONVERT TO INTERNAL FORMAT
	SKIPLE	.FXBFR(P1)	;SEE IF /BEFORE GIVEN
	CAMG	T1,.FXBFR(P1)	;YES--SEE IF TOO YOUNG
	CAMGE	T1,.FXSNC(P1)	;SEE IF TOO OLD
	POPJ	P,		;FILE FAILED LOGICAL CREATION CONSTRAINT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHECK LAST ACCESS DATE/TIMES

CHKSW3:	MOVE	T2,AGLENP	;LENGTH OF FILE SPEC BLOCK
	SKIPN	FLDTA		;IF DECTAPE
	CAIGE	T2,.FXASN+1	;OR IF /ABEFORE AND /ASINCE EXIST
	JRST	.POPJ1##	;THEY DON'T, FILE CAN'T BE REJECTED
	LDB	T2,[POINTR .RBEXT(P3),RB.ACD]  ;GET FILE ACCESS DATE
	MOVEI	T1,0		;CLEAR TIME			[161]
	PUSHJ	P,.CNVDT##	;CONVERT TO INTERNAL FORMAT	[161]
	SKIPLE	.FXABF(P1)	;SEE IF /ABEFORE GIVEN
	CAMG	T1,.FXABF(P1)	;YES--SEE IF TOO YOUNG
	CAMGE	T1,.FXASN(P1)	;SEE IF TOO OLD
	POPJ	P,		;FILE FAILED ACCESS DATE/TIME CONSTRAINT

;CHECK PHYSICAL MEDIA CREATION DATE/TIMES

CHKSW4:	MOVE	T2,AGLENP	;LENGTH OF FILE SPEC BLOCK
	CAIGE	T2,.FXPSN+1	;IF /PBEFORE AND /PSINCE EXIST
	POPJ	P,		;(THEY DON'T)
	MOVE	T1,AGLENL	;LENGTH OF USER LOOKUP BLOCK
	CAIGE	T1,.RBTIM	;IF THE LOOKUP BLOCK IS LONG ENOUGH
	JRST	CHKSW5		;LOOKUP TOO SHORT FOR PHYSICAL MEDIA CREATION
	MOVE	T1,.RBTIM(P3)	;GET PHYSICAL MEDIA CREATION DATE/TIME
	SKIPLE	.FXPBF(P1)	;SEE IF /PBEFORE GIVEN
	CAMG	T1,.FXPBF(P1)	;YES--SEE IF TOO YOUNG
	CAMGE	T1,.FXPSN(P1)	;SEE IF TOO OLD
	POPJ	P,		;FILE FAILED PHYSICAL MEDIA CREATION CONSTRAINT

;CHECK FILE SIZE CONSTRAINTS

CHKSW5:	MOVE	T2,AGLENP	;LENGTH OF FILE SPEC BLOCK
	SKIPL	T1,.RBSIZ(P3)	;IF FILE LENGTH SET,		[161]
	CAIG	T2,.FXFLM	; AND SCAN INCLUDES /LENGTH,	[161]
	JRST	CPOPJ1		;NO--ACCEPT AS OK		[161]
	SKIPL	.FXFLM(P1)	;SEE IF MAX SET			[161]
	CAMG	T1,.FXFLM(P1)	;YES--COMPARE			[161]
	CAMGE	T1,.FXFLI(P1)	;CHECK MIN			[161]
	POPJ	P,		;BAD--REJECT FILE		[161]
	JRST	CPOPJ1		;JUST RIGHT--GIVE OK RETURN
;CHKJA - CHECK RELATIVE FILE ACCESS DATE
;CALL IS:
;
;	JSP	T4,CHKJA
;	  OLDER
;	  SAME
;	  NEWER

CHKJA:	MOVE	T1,AGLOOK	;ADDRESS OF PRIMARY FILE LOOKUP BLOCK
	LDB	T1,[POINTR .RBEXT(T1),RB.ACD]  ;PRIMARY FILE ACCESS DATE
	LDB	T2,[POINTR .RBEXT+CHKLEB,RB.ACD]  ;SECONDARY ACCESS DATE
	SUB	T1,T2		;CONTRAST THE TWO DATES
	JUMPL	T1,0(T4)	;SKIP 0 IF OLDER
	JUMPE	T1,1(T4)	;SKIP 1 IF SAME
	JUMPG	T1,2(T4)	;SKIP 2 IF NEWER


;CHKJC - CHECK RELATIVE FILE CREATION DATE
;CALL IS:
;
;	JSP	T4,CHKJC
;	  OLDER
;	  SAME
;	  NEWER

CHKJC:	MOVE	T3,AGLOOK	;ADDRESS OF PRIMARY FILE LOOKUP BLOCK
	LDB	T1,[POINTR .RBEXT(T3),RB.CRX]  ;PRIMARY FILE HI-ORDER DATE
	LDB	T2,[POINTR .RBEXT+CHKLEB,RB.CRX]  ;SECONDARY HI-ORDER DATE
	CAMN	T1,T2		;MIGHT THEY BE THE SAME?
	JRST	CHKJC2		;YES, FURTHER INVESTIGATION REQUIRED
	CAMG	T1,T2		;OLDER OR NEWER?
	JRST	0(T4)		;SKIP 0 IF OLDER
	JRST	2(T4)		;SKIP 2 IF NEWER

CHKJC2:	LDB	T1,[POINTR .RBPRV(T3),RB.CRD]  ;PRIMARY FILE LO-ORDER DATE
	LDB	T2,[POINTR .RBPRV+CHKLEB,RB.CRD]  ;SECONDARY LO-ORDER DATE
	CAMN	T1,T2		;MIGHT THEY STILL BE THE SAME?
	JRST	CHKJC4		;YES, EVEN MORE CHECKING REQUIRED
	CAMG	T1,T2		;OLDER OR NEWER?
	JRST	0(T4)		;SKIP 0 IF OLDER
	JRST	2(T4)		;SKIP 2 IF NEWER

CHKJC4:	LDB	T1,[POINTR .RBPRV(T3),RB.CRT]  ;PRIMARY FILE CREATION TIME
	LDB	T2,[POINTR .RBPRV+CHKLEB,RB.CRT]  ;SECONDARY CREATION TIME
	SUB	T1,T2		;CONTRAST THE TIMES
	JUMPL	T1,0(T4)	;SKIP 0 IF OLDER
	JUMPE	T1,1(T4)	;SKIP 1 IF SAME
	JUMPG	T1,2(T4)	;SKIP 2 IF NEWER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHKJM - CHECK RELATIVE FILE MODE
;CALL IS:
;
;	JSP	T4,CHKJM
;	  DIFFERENT
;	  SAME

CHKJM:	MOVE	T1,AGLOOK	;ADDRESS OF PRIMARY FILE LOOKUP BLOCK
	MOVE	T1,.RBPRV(T1)	;PRIMARY FILE I/O MODE
	XOR	T1,.RBPRV+CHKLEB;CONTRAST WITH SECONDARY FILE I/O MODE
	TXNE	T1,RB.MOD	;ARE THE MODES DIFFERENT?
	JRST	0(T4)		;SKIP 0 IF DIFFERENT
	JRST	1(T4)		;SKIP 1 IF SAME


;CHKJP - CHECK RELATIVE FILE PHYSICAL MEDIA CREATION
;CALL IS:
;
;	JSP	T4,CHKJP
;	  OLDER
;	  SAME
;	  NEWER

CHKJP:	MOVE	T1,AGLENL	;SIZE OF PRIMARY FILE LOOKUP BLOCK
	MOVE	T2,AGLOOK	;ADDRESS OF PRIMARY FILE LOOKUP BLOCK
	CAIL	T1,.RBTIM	;BIG ENOUGH TO HAVE A MEDIA CREATION?
	SKIPN	T1,.RBTIM(T2)	;AND IS THERE A MEDIA CREATION?
	JRST	1(T4)		;CALL IT THE SAME
	SUB	T1,.RBTIM+CHKLEB;CONTRAST WITH SECONDARY MEDIA CREATION
	JUMPL	T1,0(T4)	;SKIP 0 IF OLDER
	JUMPE	T1,1(T4)	;SKIP 1 IF SAME
	JUMPG	T1,2(T4)	;SKIP 2 IF NEWER


;CHKJS - CHECK RELATIVE FILE SIZE
;CALL IS:
;
;	JSP	T4,CHKJS
;	  SMALLER
;	  SAME
;	  BIGGER

CHKJS:	MOVE	T1,AGLOOK	;ADDRESS OF PRIMARY FILE LOOKUP BLOCK
	MOVE	T1,.RBSIZ(T1)	;PRIMARY FILE SIZE
	SUB	T1,.RBSIZ+CHKLEB;CONTRAST WITH SECONDARY FILE SIZE
	JUMPL	T1,0(T4)	;SKIP 0 IF SMALLER
	JUMPE	T1,1(T4)	;SKIP 1 IF SAME
	JUMPG	T1,2(T4)	;SKIP 2 IF BIGGER
;E.IFL  --  PRINT CHECK FILE LOOKUP ERROR MESSAGE
;CALL IS:
;
;	MOVX	T1,<ERROR>
;	PUSHJ	P,E.IFL
;	RETURN
;
;WHERE <ERROR> IS THE FILOP. ERROR CODE.
;
;USES T1 - T4.

E.IFL:	PUSHJ	P,.SAVE4##	;WANT SOME GOOD ACS
	MOVE	P1,CHKSOF	;GET POINTER TO "OWNING" FILE SPEC BLOCK
	MOVEI	P2,CHKFOB+.FOIOS;ADDRESS OF FILE OPEN BLOCK
	MOVEI	P3,CHKLEB	;ADDRESS OF FILE LOOKUP BLOCK
	HRRM	T1,.RBEXT(P3)	;ENSURE ERROR CODE SET IN LOOKUP BLOCK
	HRRZ	T2,.RBEXT(P3)	;GET CODE
	MOVX	T1,FX.PRT	;SEE IF
	TDNE	T1,.FXMOD(P1)	;/OKPROTECTION?
	CAIE	T2,ERPRT%	; AND PROTECTION ERROR?
	JRST	EIFL3		;NOT AN IGNORABLE PROTECTION ERROR
	AOS	.CTFLP		;COUNT THIS AS PRIMARY FILE PROTECTION FAILURE
EIFL22:	SETO	T1,		;TELL CALLER TO IGNORE ERROR
	POPJ	P,		;RETURN

EIFL3:	MOVX	T1,FX.NOM	;SEE IF
	TDNN	T1,.FXMOM(P1)	;WAS EITHER /ERNONE OR /OKNONE GIVEN?
	JRST	EIFL35		;NO, DEFAULT /OKNONE
	TDNN	T1,.FXMOD(P1)	; /OKNONE
	JRST	EIFL5		;NO, ISSUE ERROR MESSAGE
EIFL35:	JUMPE	T2,EIFL22	;YES--IF NOT FOUND, SUPPRESS ERROR
	CAIE	T2,ERSNF%	;SEE IF NO .SFD
	CAIN	T2,ERIPP%	;SEE IF NO .UFD
	JRST	EIFL22		;YES, THEN ALSO QUALIFIES AS NOT FOUND
EIFL5:	SETZ	T4,		;SET WARNING
	PUSHJ	P,ELKE10	;ISSUE FORTH A LOOKUP ERROR MESSAGE
	SETZ	T1,		;INDICATE A REAL ERROR
	POPJ	P,		;AND RETURN TO CALLER
	SUBTTL	SECONDARY WILDCARDING LOGIC

	ENTRY	.SCWLD

;SCWLD  --  ENTRY POINT TO COMPUTE SECONDARY FILE GIVEN
; INPUT AND WILD-CARDS.
;
;CALL:	MOVE	T1,[LENGTH,,BLOCK]
;	PUSHJ	P,.SCWLD
;	  ERROR RETURN IF NOT POSSIBLE TO SETUP (MESSAGE ALREADY ISSUED)
;	SKIP RETURN WITH DEVICE CHARACTERISTICS IN T1
;		AND T2=-1 IF DISK OR SPOOLED, 0 IF DTA, 1 OTHERWISE OR NUL:
;		AND NODE NAME IN T3 (TILL SOMETHING BETTER COMES ALONG)
;
;BLOCK+1 THROUGH BLOCK+3 MANDATORY, LH=INPUT (PRIMARY), RH=OUTPUT (SECONDARY)
;BLOCK+0:	PROTOCOL VERSION WORD
;      1:	ADDRESS OF SCAN FORMAT FILE SPEC (AT LEAST 32 WORDS)
;      2:	OPEN BLOCK (3 WORDS)
;      3:	LOOKUP/ENTER BLOCK (EXTENDED FORMAT)
;      4: LH =	ADDRESS OF DEFAULT OUTPUT EXTENSION WITH RH=-1
;	  RH =	LENGTH OF ENTER BLOCK
;      5:	ADDRESS OF PATH BLOCK (IF BLANK, INTERNAL ONE WILL BE SUPPLIED)
;      6:	ADDRESS OF DEFAULT .FXCTL WORD
;
;AT RETURN, OUTPUT (SECONDARY) OPEN AND ENTER BLOCKS WILL BE SETUP

;SECONDARY ENTRY POINTS
;
;	PUSHJ	P,E.SCO
;		REPORTS OPEN ERROR
;	PUSHJ	P,E.SCL
;		REPORTS ENTER ERROR FROM ENTER BLOCK
;		ON RETURN T1=-1 IF SHOULD IGNORE ERROR (E.G., /OKPROT)
.SCWLD::HLRZ	T2,T1		;GET ARGUMENT COUNT
	SETZM	SCBZM		;CLEAR START OF TO-BE-ZEROED AREA
	MOVE	T4,[SCBZM,,SCBZM+1]  ;BLT POINTER TO
	BLT	T4,SCEZM-1	;CLEAR THE TO-BE-ZEROED AREA
	PUSHJ	P,.GTWRD##	;GET BLOCK+0
	PUSHJ	P,FXVERC##	;ENSURE PROPER PROTOCOL VERSION
	PUSHJ	P,.GTWRD##	;GET BLOCK+1
	MOVE	T4,(T3)		;GET ADDRESS OF OUTPUT SPEC
	MOVEM	T4,SCOSP	;SAVE FOR LATER
	HLRZS	T3		;POSITION FOR INPUT
	MOVE	T4,(T3)		;GET ADDRESS OF INPUT SPEC
	MOVEM	T4,SCISP	;SAVE FOR LATER
	PUSHJ	P,.GTWRD##	;GET BLOCK+2
	HLRZM	T3,SCIOPN	;SAVE INPUT OPEN
	HRRZM	T3,SCOOPN	;SAVE OUTPUT OPEN
	PUSHJ	P,.GTWRD##	;GET BLOCK+3
	HLRZM	T3,SCILKP	;SAVE INPUT LOOKUP BLOCK
	HRRZM	T3,SCOLKP	;SAVE OUTPUT LOOKUP BLOCK
	PUSHJ	P,.GTWRD##	;GET BLOCK+4
	HLRZM	T3,SCODFE	;SAVE ADDRESS OF DEFAULT EXTENSION
	HRRZM	T3,SCOLLK	;STORE LENGTH OF OUTPUT LOOKUP BLOCK
	PUSHJ	P,.GTWRD##	;GET BLOCK+5
	CAIN	T3,0		;WAS A PATH BLOCK SUPPLIED?
	MOVEI	T3,SCWPTH	;NO, USE OUR OWN THEN
	MOVEM	T3,SCOPTH	;SET ADDRESS OF OUTPUT PATH BLOCK
	PUSHJ	P,.GTWRD##	;GET BLOCK+6
	CAIE	T3,0		;ADDRESS OF DEFAULT .FXCTL SUPPLIED?
	MOVE	T3,(T3)		;YES, PICK UP DEFAULT .FXCTL
	MOVEM	T3,SCDCTL	;SET DEFAULT .FXCTL FIELDS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

SCWL00:	PUSHJ	P,.SAVE4##	;SAVE P1-P4

;HERE TO APPLY WILD-CARDS.  IDEA IS TO COPY CORRESPONDING INPUT WILD
; CARDS IN THE SAME ORDER OF FILE NAME, EXTENSION, DIRECTORY.

	MOVEI	T1,.FXNOD-2	;STARTING POINT FOR INPUT FILE FIELDS
	MOVEM	T1,SCNWD	;SAVE FOR FNDNBT ROUTINE
	MOVE	P2,SCOSP	;POINT TO OUTPUT SPEC
	MOVE	P4,SCISP	;POINT TO INPUT FILE SPEC BLOCK

;SELECT OUTPUT WILDCARD GENERATION METHOD (/SCWILD)

	LDB	T1,[POINTR .FXCTL(P2),FX.SCW]  ;/SCWILD TYPE
	CAIN	T1,0		;IF NOTHING EXPLICITLY STATED
	LDB	T1,[POINTR SCDCTL,FX.SCW]  ;THEN USE CALLER-SET DEFAULT (IF ANY)
	MOVE	T1,[0,,0	;UNSPECIFIED, DEFAULT /SCWILD:FIELD
		01,,00		;/SCWILD:ANY
		00,,00		;/SCWILD:FIELD
		00,,-1		;/SCWILD:DFIELD
		-1,,00		;/SCWILD:SAME
		-1,,-1		;/SCWILD:DSAME
		-1,,00		;  --  UNDEFINED  --
		-1,,00](T1)	;  --  UNDEFINED  --
	HLLEM	T1,SCWMM	;SET BASIC REPLACEMENT MODE (ANY/FIELD/SAME)
	HRLEM	T1,SCWMD	;SET DIRECTORY SHIFTING (/FIELD VS /DFIELD)

;SELECT OUTPUT WILDCARDING ERROR CONSTRAINTS (/SCERROR)

	LDB	T1,[POINTR .FXCTL(P2),FX.SCE]  ;/SCERROR TYPE
	CAIN	T1,0		;IF NOTHING EXPLICITLY PROVIDED
	LDB	T1,[POINTR SCDCTL,FX.SCE]  ;THEN USE CALLER-SET DEFAULT (IF ANY)
	MOVE	T1,[0		;UNSPECIFIED, DEFAULT /SCERROR:INSUFFICIENT
		-1		;/SCERROR:NEVER
		0		;/SCERROR:INSUFFICIENT
		1		;/SCERROR:DIFFERENT
		1		;  --  UNDEFINED  --
		1		;  --  UNDEFINED  --
		1		;  --  UNDEFINED  --
		1](T1)		;  --  UNDEFINED  --
	MOVEM	T1,SCWBE	;STORE ERROR CONSTRAINTS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SETUP OUTPUT NODE NAME (NOT REALLY IMPLEMENTED YET)

;	P1/	UNUSED
;	P2/	OUTPUT FILE SPEC BLOCK
;	P3/	UNUSED
;	P4/	INPUT FILE SPEC BLOCK

SCWL10:	SKIPN	T1,.FXNOD(P2)	;EXPLICIT OUTPUT NODE NAME?
	SKIPA	T1,.FXNOD(P4)	;NO, USE INPUT SIDE
	SKIPA	T2,.FXNOM(P2)	;YES, GET NODE NAME AND MASK AS SPECIFIED
	MOVE	T2,.FXNOM(P4)	;USE INPUT SIDE WILDCARDS TOO
	PUSHJ	P,INSWLS	;GENERATE OUTPUT NODE NAME
	 JRST	E$$IWC		;ILLEGAL WILD CARDS
	SKIPN	.FXNOD(P2)	;WAS THERE AN OUTPUT NODE REALLY SPECIFIED?
	SETZ	T1,		;NO, SO LEAVE OUTPUT NODE BLANK
	MOVEM	T1,SCNOD	;HANG ONTO THE NODE NAME FOR A WHILE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SETUP OUTPUT OPEN BLOCK

;	P1/	OUTPUT OPEN BLOCK
;	P2/	OUTPUT FILE SPEC BLOCK
;	P3/	INPUT OPEN BLOCK
;	P4/	INPUT FILE SPEC BLOCK

SCWL20:	MOVE	P1,SCOOPN	;POINT TO OUTPUT OPEN BLOCK
	MOVE	P3,SCIOPN	;POINT TO INPUT OPEN BLOCK
	SKIPN	T1,.FXDEV(P2)	;GET SPECIFIED OUTPUT DEVICE
	SKIPA	T1,.OPDEV(P3)	;NONE, USE LAST INPUT
	SKIPA	T2,.FXDEM(P2)	;GET SPECIFIED OUTPUT DEVICE MASK
	MOVE	T2,.FXDEM(P4)	;USE INPUT SIDE WILDCARDS TOO
	PUSHJ	P,INSWLS	;GENERATE OUTPUT DEVICE NAME
	 JRST	E$$IWC		;ILLEGAL WILDCARD CONSTRUCTION
	SKIPN	.FXDEV(P2)	;WAS AN OUTPUT DEVICE REALLY SPECIFIED?
	MOVSI	T1,'DSK'	;NO, THEN USE STANDARD DEVICE
	MOVEM	T1,.OPDEV(P1)	;STORE OUTPUT DEVICE NAME
	SETZB	T4,.OPBUF(P1)	;CLEAR BUFFER POINTERS
	MOVX	T2,FX.PHY	;CHECK FOR /PHYSICAL
	TDNE	T2,.FXMOD(P2)	; IN OUTPUT SPEC
	TXOA	T4,UU.PHS	;YES--SET FOR OPEN
	TDZA	T3,T3		;NO, LOGICAL
	MOVEI	T3,UU.PHY	;YES, PHYSICAL
	MOVE	T2,T1		;COPY OF DEVICE
	DEVCHR	T1,(T3)		;GET SELECTED DEVICE DEVCHR BITS
	DEVTYP	T2,(T3)		;ALSO GET DEVICE TYPE FOR ERROR/ETC.
	 SETZB	T1,T2		;CLEAR IF DEVICE UNAVAILABLE
	MOVEM	T1,SCCHR	;SAVE DEVCHR BITS FOR LATER ALSO
	MOVEM	T2,SCTYP	;SAVE FOR ERROR MESSAGES AND LATER
	TXNN	T1,DV.MTA	;SEE IF MAG TAPE
	JRST	SCWL22		;NO--PROCEED
	MOVX	T1,FX.PAR	;CHECK FOR /PARITY
	TDNE	T1,.FXMOD(P2)	; FOR :EVEN
	TXO	T4,IO.PAR	;YES--SET FOR OPEN
	LDB	T1,[POINTR .FXMOD(P2),FX.DEN]  ;GET /DENSITY
	DPB	T1,[POINTR T4,IO.DEN]  ;SET INTO OPEN BLOCK
SCWL22:	LDB	T1,[POINTR .FXCTL(P2),FX.IOM]  ;GET /IOMODE:MODE (IF ANY)
	DPB	T1,[POINTR T4,IO.MOD]  ;AND SET INTO THE LOOKUP BLOCK
	MOVEM	T4,.OPMOD(P1)	;STORE FIRST WORD OF OPEN BLOCK

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SETUP OUTPUT DIRECTORY

;	P1/	OUTPUT PATH BLOCK
;	P2/	OUTPUT FILE SPEC BLOCK
;	P3/	UNUSED
;	P4/	INPUT FILE SPEC BLOCK

SCWL30:	MOVE	P1,SCOPTH	;FETCH ADDRESS OF RESULTANT DIRECTORY PATH
	SETZM	(P1)		;CLEAR START OF PATH BLOCK
	MOVSI	T1,(P1)		;CONCOCT A
	HRRI	T1,1(P1)	; BLT POINTER TO
	BLT	T1,.PTMAX-1(P1)	;CLEAR THE WHOLE PATH BLOCK
	MOVE	T2,.FXFLD(P2)	;GET OUTPUT FIELDS FLAGS
	TXNN	T2,FX.DPN	;EXPLICIT REQUEST FOR NULL PATH ("[]")?
	SKIPN	.FXDIR(P2)	;OR NO PATH SPECIFICATION AT ALL?
	JRST	SCWL60		;YES, PROVIDE NO OUTPUT PATH
	TXNN	T2,FX.DPT	;EXPLICIT REQUEST FOR DEFAULT PATH?
	JRST	SCWL33		;NO, NORMAL SPECIFICATION TO BE FILLED
	MOVSI	T1,.MYPTH##+.PTPPN  ;ADDRESS OF JOB DEFAULT PATH
	HRRI	T1,.PTPPN(P1)	;ADDRESS OF PATH BLOCK
	BLT	T1,.PTMAX-1(P1)	;COPY AND SET JOB DEFAULT PATH
	JRST	SCWL60		;GO SET DIRECTORY

;HERE TO GENERATE OUTPUT PATH SPECIFICATION

SCWL33:	SKIPN	.FXDIR(P4)	;GOT AN INPUT PATH SPECIFICATION?
	SETOM	SCNWD3		;NO DIRECTORY
	MOVE	T1,.FXDIR(P2)	;GET USER SPECIFIED UFD
	MOVE	T2,.FXDIM(P2)	;GET UFD MASK
	TLNN	T1,-1		;SEE IF PROJECT
	TLO	T2,-1		;NO--SET MASK FULL ON
	TLNN	T1,-1		;SEE IF PROJECT
	HLL	T1,.MYPPN##	;BLANK--USE LOGGED IN PROJECT
	TRNN	T1,-1		;SEE IF PROGRAMMER
	TRO	T2,-1		;NO--SET MASK FULL ON
	TRNN	T1,-1		;SEE IF PROGRAMMER
	HRR	T1,.MYPPN##	;BLANK--USE LOGGED IN PROGRAMMER
	PUSHJ	P,SCDCK		;CHECK FOR ANY NEEDED DIRECTORY SHIFTING
	PUSHJ	P,INSWLD	;INSERT WILD-CARDS
	  JRST	E$$IWC		;ERROR IF NO MORE
	SKIPGE	T1		;SEE IF SIXBIT DIRECTORY
	PUSHJ	P,INSWLF	;YES--FIX IT UP
	TLNE	T1,-1		;IF NO PROJECT
	TRNN	T1,-1		;OR PROGRAMMER,
	JRST	E$$NNO		;THEN ERROR
	MOVEM	T1,.PTPPN(P1)	;SET TOP-LEVEL FILE DIRECTORY

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LOOP OVER SFDS

	HRLI	P1,-<.FXLND-1>	;PRESET SFD DEPTH COUNTER
SCWL40:	SKIPN	T1,.FXDIR+2(P2)	;GET NEXT SFD
	JRST	SCWL43		;DONE--JUST CLEANUP
	MOVE	T2,.FXDIM+2(P2)	;GET MASK
	PUSHJ	P,SCDCK		;CHECK FOR DIRECTORY SHIFTING NEEDED
	PUSHJ	P,INSWLS	;INSERT WILD CHARACTERS
	  JRST	E$$IWC		;ERROR IF NO MORE
;[RDH]	JUMPE	T1,E$$NNO	;ERROR IF BLANK
	JUMPN	T1,SCWL43	;STORE SFD
	MOVEM	T1,.PTSFD(P1)	;END OF ACTIVE OUTPUT PATH
	AOBJN	P1,.-1		;CLEAR REST OF OUTPUT PATH BLOCK
	JRST	SCWL45		;FINISH OFF PATH STUFF

SCWL43:	MOVEM	T1,.PTSFD(P1)	;STORE SFD
	ADDI	P2,2		;ADVANCE SPEC POINTER
	AOBJN	P1,SCWL40	;LOOP OVER PATH
SCWL45:	SETZM	.PTSFD(P1)	;FORCE A ZERO

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO SETUP SECONDARY LOOKUP BLOCK

;	P1/	OUTPUT ENTER BLOCK
;	P2/	OUTPUT FILE SPEC BLOCK
;	P3/	INPUT LOOKUP BLOCK
;	P4/	INPUT FILE SPEC BLOCK

SCWL60:	MOVE	P1,SCOLKP	;POINT TO OUTPUT ENTER BLOCK
	MOVE	P2,SCOSP	;POINT TO OUTPUT FILE SPEC BLOCK
	MOVE	P3,SCILKP	;POINT TO INPUT LOOKUP BLOCK
	MOVE	P4,SCISP	;POINT TO INPUT FILE SPEC BLOCK
	MOVE	T1,SCOLLK	;GET LENGTH
	SOS	T1		;MINUS ONE
	HRLZI	T2,1(P1)	;POINT BEYOND FIRST
	HRRI	T2,2(P1)	;SETUP BLT POINTER
	MOVEM	T1,.RBCNT(P1)	;SET LENGTH
	ADDI	T1,(P1)		;POINT TO END
	SETZM	1(P1)		;CLEAR START
	BLT	T2,(T1)		;CLEAR ENTIRE ARRAY

	MOVX	T1,RB.NSE	;GET NON-SUPERSEDING ENTER BIT
	MOVX	T2,FX.SUP	;GET /ERSUPERSEDE BIT
	TDNE	T2,.FXMOD(P2)	;SEE IF USER SET IT
	IORM	T1,.RBCNT(P1)	;YES--TELL MONITOR

	MOVE	T4,SCOPTH	;ADDRESS OF PATH BLOCK
	SKIPE	T1,.PTPPN(T4)	;WAS A PATH GENERATED?
	MOVE	T1,T4		;YES, USE IT
	MOVEM	T1,.RBPPN(P1)	;SET ADDRESS OF OUTPUT PATH BLOCK

	DMOVE	T1,.FXMOD(P2)	;GET THE MODS WORD (AND MASK)
	MOVEI	T3,.PTSCN	;ASSUME /NOSCAN
	TXNE	T1,FX.SCN	;/SCAN SET?
	MOVEI	T3,.PTSCY	;YES, FORCE SCANNING
	TXNN	T2,FX.SCN	;WAS EITHER OF /[NO]SCAN SET?
	MOVEI	T3,0		;NO, USE DEFAULT SETTING
	DPB	T3,[POINTR .PTSWT(T4),PT.SCN]  ;SET SCANNING CONTROL (IF ANY)

	LDB	T1,[POINTR (.FXMOD(P2),FX.PRO)]  ;GET /PROTECTION
	DPB	T1,[POINTR .RBPRV(P1),RB.PRV]  ;STORE FOR ENTER
	MOVE	T2,SCOLLK	;GET LENGTH IN T2!!!
	SKIPG	T1,.FXEST(P2)	;GET /ESTIMATE			[161,164]
	MOVEI	T1,0		; DEFAULT TO 0			[164]
	ADDI	T1,177		;ROUND OFF TO BLOCKS		[313]
	LSH	T1,-7		;CONVERT TO BLOCKS		[161]
	CAILE	T2,.RBEST	;SEE IF ROOM IN ENTER BLOCK	[161]
	MOVEM	T1,.RBEST(P1)	;YES--SET IT FOR ENTER		[161]
	MOVE	T1,.FXVER(P2)	;GET /VERSION			[161]
	CAILE	T2,.RBVER	;SEE IF ROOM IN ENTER BLOCK	[161]
	CAMN	T1,[-1]		; AND SEE IF SET		[161]
	SKIPA			;NO--IGNORE			[161]
	MOVEM	T1,.RBVER(P1)	;YES--SET FOR ENTER		[161]

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

SCWL70:	MOVEI	T1,.FXNAM-2	;PRESET INDEX FOR FILE NAME
	SKIPG	SCWMM		;"ANY" REPLACEMENT MODE?
	MOVEM	T1,SCNWD	;NO, RE-ALIGN INPUT AND OUTPUT FIELDS
	SKIPN	T1,.FXNAM(P2)	;GET OUTPUT NAME
	SKIPA	T1,.RBNAM(P3)	;OR INPUT IF BLANK
	SKIPA	T2,.FXNMM(P2)	;GET OUTPUT MASK
	MOVE	T2,.FXNMM(P4)	;USE INPUT WILDCARD MASK TOO
	PUSHJ	P,INSWLD	;INSERT WILD CHARS		[153]
	  JRST	E$$IWC		;ERROR IF NO MORE
	MOVEM	T1,.RBNAM(P1)	;STORE OUTPUT NAME

	SKIPN	T1,.FXEXT(P2)	;GET OUTPUT EXT
	SKIPA	T1,@SCODFE	;GET DEFAULT
	SKIPA	T2,.FXEXT(P2)	;GET OUTPUT MASK
	MOVE	T2,.FXEXT(P4)	;USE INPUT MASK
	HRLO	T2,T2		;POSITION REAL MASK
	ANDCMI	T1,-1		;STRIP GARBAGE (YES, THIS IS IMPORTANT)
	PUSHJ	P,INSWLS	;INSERT WILD CHARS
	  JRST	E$$IWC		;ERROR IF NO MORE
	HLLZM	T1,.RBEXT(P1)	;STORE RESULT FOR ENTER
	HLRZ	T2,T1		;SAVE EXTENSION			[153]

	MOVE	T1,.RBNAM(P1)	;GET FILE NAME BACK		[153]
	CAIE	T2,'UFD'	;UNLESS .UFD			[153]
	PUSHJ	P,INSWLF	; COMPACT OUT BLANKS		[153]
	MOVEM	T1,.RBNAM(P1)	;STORE RESULT			[153]


	SETCMI	T2,1		;SET SINGLE WILD BIT		[302]
	SKIPG	SCWMM		;RATIONAL SCWILD PROCESSING?
	 CAIA			;YES - SKIP FURTHER CHECKS
	SKIPL	SCWBE		;NO - OK TOO MANY INPUT???
	 CAIA			;YES - SKIP CHECK
	PUSHJ	P,INSWLD	;GO SEE IF ANY LEFT		[302]
	  SKIPA			;NO--WORKED OUT OK		[302]
	JRST	E$$TWC		;YES--TOO MANY ON INPUT		[302]

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WHEN ALL DONE

;[RDH]	FOLLOWING CODE REMOVED SINCE PHILOSOPHICALLY IT IS HIGHLY DUBIOUS
;	AND PRAGMATICALLY IT PROTECTS SFD'S WITH <075> PROTECTION!!!
;
;	SKIPN	T1		;SEE IF DIRECTORY
;	MOVE	T1,.MYPPN##	;DEFAULT--USE SELF
;	TLNN	T1,-1		;SEE IF SFD
;	MOVE	T1,.PTPPN(T1)	;YES--GET OWNER UFD
;	MOVE	T2,SCILKP	;POINT TO INPUT LOOKUP
;	MOVE	T3,.RBPRV(T2)	;GET INPUT PROTECTION
;	MOVE	T2,.RBPPN(T2)	;GET INPUT OWNER
;	SKIPN	T2		;SEE IF DEFAULT
;	MOVE	T2,.MYPPN##	;YES--GET SELF
;	TLNN	T2,-1		;SEE IF SFD
;	MOVE	T2,.PTPPN(T2)	;YES--GET OWNER UFD
;	SKIPE	T1		;IF NO OUTPUT OWNER
;	SKIPN	T2		;OR NO INPUT OWNER
;	JRST	SCDONE		;LEAVE PROT. ALONE
;	SKIPN	.RBPRV(P1)	;IF /PROTECTION
;	CAME	T1,T2		;OR DIFFERENT OWNERS
;	JRST	SCDONE		;LEAVE PROT. ALONE
;	ANDX	T3,<RB.PRV-7B2>	;CLEAR OWNER PROTECTION
;	JUMPE	T3,SCDONE	;IF 000, LEAVE ALONE
;	MOVX	T1,%LDSTP	;GET SYSTEM
;	GETTAB	T1,		;STANDARD FILE PROTECTION
;	  MOVEI	T1,0		;(USE 0XX)
;	ANDX	T1,7B2		;GET OWNER PROTECTION
;	IOR	T1,T3		;INCLUDE INPUT FILE PROT
;	MOVEM	T1,.RBPRV(P1)	;STORE FOR ENTER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

SCDONE:	HLRZ	T1,.RBEXT(P1)	;GET RESULTING EXTENSION
	CAIN	T1,'UFD'	;SEE IF .UFD
	JRST	[SKIPN T1,.RBPPN(P1)	;YES--GET DIRECTORY
		MOVE	T1,.MYPPN##	;BLANK, ASSUME SELF
		TLNN	T1,-1		;SEE IF SFD POINTER
		MOVE	T1,.PTPPN(T1)	;YES--GET UFD
		CAMN	T1,.PPMFD##	;SEE IF MFD:
		JRST	.+1		;YES--ALL SET
		MOVEM	T1,.RBNAM(P1)	;NO--STORE UFD AS NAME
		MOVE	T1,.PPMFD##	;GET MFD
		MOVEM	T1,.RBPPN(P1)	;STORE AS DIRECTORY
		JRST	.+1]		;AND PROCEED
	MOVE	T1,SCCHR	;GET DEVICE CHARACTERISTICS
	MOVE	T2,.RBNAM(P1)	;GET FILE NAME
	TLC	T1,-1-<(DV.TTA)>;WATCH OUT FOR
	TLCE	T1,-1-<(DV.TTA)>; NUL:
	TXNN	T1,DV.DTA!DV.DSK;IF DISK OR DECTAPE,
	SKIPA			;NO
	JUMPE	T2,E$$NDO	;  ERROR IF NULL NAME
	MOVE	T3,SCNOD	;POSITION NODE IN T3 AS A TEMP KLUDGE
	MOVE	T4,SCTYP	;GET DEVTYP
	MOVEI	T2,1		;SET FOR MISC. DEVICE
	TLC	T1,-1-<(DV.TTA)>;IF DEVICE
	TLCN	T1,-1-<(DV.TTA)>; IS NUL:
	JRST	CPOPJ1		; THEN RETURN
	TXNN	T4,TY.SPL	;SEE IF SPOOLED
	TXNE	T1,DV.DSK	;OR DISK
	SETOM	T2		;YES--FLAG AS SUCH
	TXNE	T1,DV.DTA	;SEE IF DECTAPE
	SETZM	T2		;YES--FLAG
	JRST	CPOPJ1		;OK RETURN TO USER
	SUBTTL	SECONDARY WILDCARDING ERRORS

;E.SCO -- REPORT OPEN ERROR

E.SCO::
E$$SCO:	MOVE	T1,['SCO',,[ASCIZ /OPEN failure on /]]
	PUSHJ	P,WLDERR	;ISSUE ERROR
	  PJRST	.TCRLF##	;SKIP REST IF NOT /VERB:FIRST
	MOVE	T1,SCOOPN	;POINT TO OPEN BLOCK
	MOVE	T1,1(T1)	;GET NAME
	PUSHJ	P,TYPST1	;TYPE IT
	LDB	T2,[POINTR (SCTYP,TY.JOB)]  ;GET USER JOB
	PJRST	OPNER1		;GO TYPE IT
;E.SCL  --  PRINT SECONDARY FILE LOOKUP/ENTER ERROR MESSAGE
;CALL IS:
;
;	PUSHJ	P,E.SCL
;	RETURN
;
;E.SCL ASSUMES THAT .SCWLD HAS BEEN CALLED, SETTING UP THE
;SC???? POINTERS TO THE VARIOUS FILE AREAS.
;
;ON RETURN, T1 IS -1 IF THE ERROR SHOULD BE IGNORED (E.G., /OKPROT).

E.SCL::	PUSHJ	P,.SAVE4##	;WANT SOME GOOD ACS
	MOVE	P1,SCOSP	;GET POINTER TO "OWNING" FILE SPEC BLOCK
	MOVE	P2,SCOOPN	;ADDRESS OF FILE OPEN BLOCK
	MOVE	P3,SCOLKP	;ADDRESS OF FILE LOOKUP BLOCK
	HRRZ	T2,.RBEXT(P3)	;GET CODE
	MOVX	T1,FX.PRT	;SEE IF
	TDNE	T1,.FXMOD(P1)	;/OKPROTECTION?
	CAIE	T2,ERPRT%	; AND PROTECTION ERROR?
	JRST	ESCL3		;NOT AN IGNORABLE PROTECTION ERROR
ESCL22:	SETO	T1,		;TELL CALLER TO IGNORE ERROR
	POPJ	P,		;RETURN

ESCL3:	MOVX	T1,FX.NOM	;SEE IF
	TDNN	T1,.FXMOD(P1)	; /OKNONE
	JRST	ESCL5		;NO, ISSUE ERROR MESSAGE
	JUMPE	T2,ESCL22	;YES--IF NOT FOUND, SUPPRESS ERROR
	CAIE	T2,ERSNF%	;SEE IF NO .SFD
	CAIN	T2,ERIPP%	;SEE IF NO .UFD
	JRST	EDFL22		;YES, THEN ALSO QUALIFIES AS NOT FOUND
ESCL5:	SETO	T4,		;SET ERROR
	PUSHJ	P,ELKE10	;ISSUE FORTH A LOOKUP ERROR MESSAGE
	SETZ	T1,		;INDICATE A REAL ERROR
	POPJ	P,		;AND RETURN TO CALLER
;ERROR:	NULL NAME OR DIRECTORY

E$$NDO:	SKIPA	T1,['NDO',,[ASCIZ /Null name in output wild-card/]]
E$$NNO:	MOVE	T1,['NNO',,[ASCIZ /Null directory in output wild-card/]]
	JRST	ENEWC


;ERROR:	INSUFFICIENT INPUT WILD CARD CHARS TO MATCH OUTPUT

E$$IWC:	MOVE	T1,['UWC',,[ASCIZ/Input and output wildcards not aligned/]]
	SKIPL	SCWMM		;BIT-POS-RELEVANT MODE?
	 JRST	.+3		;NO - ABOVE MESSAGE MEANINGLESS
	SKIPN	SCWBC		;TOO MANY/TOO FEW?
	 JRST	ENEWC		;YES - ERROR
	SKIPG	SCWBC		;NO - TOO MANY OR TOO FEW?
E$$TWC:	SKIPA	T1,['TWC',,[ASCIZ /Too many wild-cards in input for output/]]
	MOVE	T1,['IWC',,[ASCIZ /Insufficient wild-cards in input for output/]]
ENEWC:	PUSHJ	P,WLDERR	;ISSUE ERROR
	  PJRST	.TCRLF##	;SKIP REST IF NOT /VERB:FIRST
	PJRST	.TFILE		;TYPE ERROR FILE SPEC
	SUBTTL	SECONDARY WILDCARDING SUBROUTINES

;INSWLS -- ROUTINE TO INSERT WILD CHARACTERS IN A WORD AND LEFT COMPRESS NULL CHARS
;INSWLF -- FIXUP WORD BY LEFT COMPRESSING NULL CHARS

INSWLS:	PUSHJ	P,INSWLD	;INSERT WILD CHARACTERS
	  POPJ	P,		;ERROR RETURN
	AOS	(P)		;GOOD RETURN

INSWLF:	SKIPN	T2,T1		;SHIFT ARGUMENT
	POPJ	P,		;RETURN IF NULL
	MOVEI	T1,0		;CLEAR RESULT
INSWF1:	SKIPE	T2		;IF DONE
	TLNE	T2,(77B5)	;OR NOT NULL
	JRST	INSWF2		;GO SHIFT TO ANSWER
	LSH	T2,6		;ELSE, COMPRESS NULL
	JRST	INSWF1		;AND LOOP
INSWF2:	TLNE	T1,(77B5)	;SEE IF ALL DONE YET
	POPJ	P,		;YES--RETURN
	LSHC	T1,6		;NO--SHIFT SOME MORE
	JRST	INSWF1		;AND LOOP
;INSWLD -- ROUTINE TO INSERT WILD CHARACTERS IN A WORD
;CALL:	MOVE	T1,PROPOSED WORD (TYPED BY USER OR DEFAULTED)
;	MOVE	T2,REPLACEMENT MASK (1=LEAVE BIT ALONE)
;	PUSHJ	P,INSWLD
;	  ERROR RETURN IF INSUFFICIENT INPUT WILD-CARDS TO MATCH
;	SKIP RETURN WITH T1 UPDATED FROM INPUT FILE
;ASSUMES P3 POINTS TO INPUT LOOKUP BLOCK
;GLOBAL VARIABLES SCNBT AND SCNWD MUST BE PRESET FOR FNDNBT ROUTINE
;
;ASSUMES P4 POINTS TO INPUT SCAN BLOCK.
;VARIABLE SCNWD2 MUST BE PRESET FOR RDHWLD ROUTINE
;LOCATION SCWMM HAS SCWILD INSERTION PARAMETERS AS FOLLOWS:
;	<0  OUTPUT WILD BITS REPLACED WITH SAME BIT FROM INPUT (B0_B0)
;	=0  OUTPUT WILD BITS REPLACED WITH BITS FROM SAME WORD
;	>0  OUTPUT WILD BITS REPLACED WITH ANY INPUT (WILD) BITS

INSWLD:	SKIPG	SCWMM		;RATIONAL SCWILD HANDLING?
	 JRST	RDHWLD		;YES - GO ELSEWHERE
	MOVEI	T4,^D35		;BIT COUNTER FOR WORD IN T1
INSWL1:	MOVEI	T3,1		;GET A BIT
	LSH	T3,(T4)		;POSITION
	TDNN	T2,T3		;SEE IF NEED REPLACEMENT
	JRST	INSWL3		;YES--GO DO IT
INSWL2:	SOJGE	T4,INSWL1	;NO--LOOP UNTIL DONE
	JRST	CPOPJ1		;SUCCESS RETURN
INSWL3:	TDZ	T1,T3		;REPLACE--CLEAR OUTPUT BIT
	PUSHJ	P,FNDNBT	;FIND VALUE OF NEXT REPLACEMENT BIT
	 JRST	[SKIPG SCWBE	;ERR TOO MANY OUTPUT?
		 AOS   (P)	;NO - GIVE GOOD RETURN
		 POPJ  P,]	;RETURN APPROPRIATELY
	LSH	T3,(T4)		;POSITION REPLACEMENT BIT
	IOR	T1,T3		;INCLUDE IT IN RESULT
	JRST	INSWL2		;GO REPEAT LOOP
;FNDNBT -- HELPER TO INSWLD TO FIND VALUE OF NEXT REPLACEMENT BIT
;CALL:	PUSHJ	P,FNDNBT
;	  ERROR RETURN IF NO MORE INPUT WILD-CARDS
;	SKIP RETURN WITH VALUE IN BIT 35 OF T3
;PRESERVES ALL OTHER ACS
;GLOBAL VARIABLES SCNBT AND SCNWD MUST HAVE BEEN PRESET ORIGINALLY
;	SCNBT IS BIT DOWN COUNTER FOR SCANNING INPUT SPEC
;	SCNWD IS WORD UP COUNTER FOR SCANNING INPUT SPEC
;		LH= -5 NODE, -4 DEVICE, -3 NAME, -2 EXT, -1 UFD, 0-4 SFD
;		RH=LOCATION OF INPUT SPEC MASK
;LOCAL AC USAGE:
;	T1 CONTAINS SCNBT
;	T2 CONTAINS SCNWD
;	T3 GETS RESULT
;P3 IS ASSUMED TO POINT TO THE INPUT LOOKUP BLOCK

FNDNBT:	PUSH	P,T1		;SAVE ACS
	PUSH	P,T2
	MOVE	T2,SCNWD	;GET SCNWD WHERE IT IS USEFUL
	ADD	T2,P4		;RELOCATE INTO INPUT FILE SPEC BLOCK

FNDNB1:	SOSL	T1,SCNBT	;COUNT TO NEXT BIT
	JRST	FNDNB6		;STILL SAME WORD--PROCEED
FNDNB2:	MOVEI	T2,2		;BIWORD INDEXING INCREMENT
	ADDB	T2,SCNWD	;ADVANCE INDEX
	CAILE	T2,.FXEXT	;HAVE WE RUN OUT OF INPUT YET?
	JRST	FNDNBX		;YES, ERROR RETURN
	MOVEI	T1,^D35		;MOST FIELDS ARE A FULL WORD
	CAIN	T2,.FXEXT	;BUT THE EXTENSION FIELD
	MOVEI	T1,^D17		;IS ONLY A HALF WORD
	ADD	T2,P4		;RELOCATE INDEX INTO FILE SPEC BLOCK
	SKIPN	(T2)		;ANYTHING SPECIFIED HERE?
	JRST	FNDNB2		;NO, ADVANCE TO THE NEXT FIELD THEN
	MOVEM	T1,SCNBT	;YES, SET BIT COUNTER
FNDNB6:	MOVEM	T1,SCNBT	;STORE UPDATED COUNTER
	MOVEI	T3,1		;GET A BIT
	LSH	T3,(T1)		;POSITION IT
	TDNE	T3,1(T2)	;SEE IF WILD IN INPUT SPEC
	JRST	FNDNB1		;NO--REPEAT LOOP

;HERE WHEN FOUND NEXT WILD BIT--GET VALUE

	MOVE	T2,SCNWD	;REFETCH CURRENT INDEX
	PUSHJ	P,SCFLD		;FETCH APPROPRIATE INPUT FIELD
	MOVN	T1,SCNBT	;GET COMPLEMENT OF BIT POS
	LSH	T3,(T1)		;POSITION RESULT
	ANDI	T3,1		;MASK TO ONE BIT
	AOS	-2(P)		;SET SKIP RETURN
FNDNBX:	POP	P,T2		;RESTORE ACS
	POP	P,T1
	POPJ	P,		;RETURN
;HERE TO REPLACE THE OUTPUT WILD CARDS WITH INPUT WILDCARDS FROM
;THE CORRESPONDING INPUT WORDS (FILENAME TO FILENAME, ETC.).
;
;GET CORRESPONDING INPUT WORD AND MASK IN T3 AND T4.
;FALLS THROUGH TO RDHINS.

RDHWLD:	PUSH	P,T2		;NEED ONE EXTRA AC
	MOVEI	T2,2		;BIWORD INDEX INCREMENT
	ADDB	T2,SCNWD	;ADVANCE FIELD INDEX
	PUSHJ	P,SCFLD		;LOCATE AND FETCH APPROPRIATE INPUT FIELD
	CAIL	T2,.FXDIR	;IN RANGE OF DIRECTORY PATH?
	CAILE	T2,.FXDIR+<2*.FXLND>-1  ; . . .
	JRST	RDHWL5		;NO, NO FUNNIES THEN
	JUMPE	T3,RDHWL3	;YES, IF END OF PATH FLAG IT
	SKIPN	SCNWD3		;ANYTHING SPECIAL NEEDING ATTENTION?
	JRST	RDHWL5		;NO, NORMAL
	SKIPG	SCNWD3		;YES, HIT END OF PATH?
	JRST	RDHWL3		;YES, RETURN BLANKS THEN
	SETO	T4,		;NO, ASSUME NONE-WILD MASK
	JRST	RDHWL9		;AND USE WHATEVER THE INPUT PROVIDED

RDHWL3:	SETOB	T4,SCNWD3	;END OF PATH, RETURN NON-WILD
	SETZ	T3,		;WITH NO NAME EITHER
	JRST	RDHWL9		;USE THAT

RDHWL5:	MOVE	T4,P4		;ADDRESS OF INPUT FILE SPEC BLOCK
	ADD	T4,T2		;POINT TO THE INPUT FIELD SPECIFICATION
	CAIE	T2,.FXEXT	;LOOKING AT NORMAL BI-WORD FIELD?
	SKIPA	T4,1(T4)	;YES, FULL WORD WILD MASK
	HRLO	T4,0(T4)	;NO, FILE TYPE, HALF WORD
RDHWL9:	POP	P,T2		;RESTORE AC
;	JRST	RDHINS		;DO WILDCARD INSERT
;HERE TO ACTUALLY UPDATE THE WORD IN T1 BY THE MASKS IN T2 &
;T4 IN CONJUNCTION WITH THE WORD IN T3.  SCWBE IS A FLAG WHICH
;IF .LT. 0 THEN ANY MASK COMBINATION IS LEGAL; IF .EQ. 0 THEN
;MORE INPUT THAN OUTPUT WILDCARDS ILLEGAL; IF .GT. 0 THEN THE
;NUMBER OF INPUT AND OUTPUT WILDCARDS IN EACH WORD MUST BE THE
;SAME.  IF SCWMM .LT. 0 THEN THE WILD BITS IN T1 ARE REPLACED 
;BY THE CORRESPONDING BITS IN T3 - WHETHER OR NOT THEY ARE WILD
;(NOTE: IN THIS CASE, IF SCWBE .GT. 0 THEN INPUT AND OUTPUT
;MASKS MUST BE EQUAL!); IF SCWMM .EQ. 0 THEN WILD BITS IN T1
;ARE FILLED IN BY WILD BITS IN T3 IN ORDER OF OCCURENCE (IF
;THERE ARE MORE OUTPUT THAN INPUT WILDCARDS THEN OUTPUT WILL
;BE FILLED WITH NON-WILD INPUT AS NECESSARY (E.G., THE PIP-
;STYLE COMMAND "*.*[,]=FILE?.EX?[P,PN]" IS EQUIVILENT TO THE
;MORE EXPLICIT COMMAND "FILE?.EX?[,]=FILE?.EX?[P,PN]").
;
;CALL IS:
;
;	MOVE	T1,OUTPUT WORD TO BE UPDATED
;	MOVE	T2,OUTPUT WILD MASK FOR T1 (BIT = 1 IF NON-WILD)
;	MOVE	T3,INPUT WORD TO FILL OUT T1
;	MOVE	T4,INPUT WILD MASK FOR T3
;	PUSHJ	P,RDHINS
;	 ERROR - IMPROPER OR INSUFFICIENT WILDCARDS
;	NORMAL RETURN WITH T1 UPDATED

RDHINS:	PUSHJ	P,.SAVE4##	;NEED 8 ACS!!
	AND	T1,T2		;CLEAR WILD FIELDS
	MOVE	P1,T2		;SAVE T2
	PUSHJ	P,BITCNT	;COUNT NON-WILD BITS
	MOVNM	T2,SCWBC	;SAVE
	CAIN	T2,^D36		;OUTPUT EXPLICIT (I.E., NO WILDCARDS)?
	JUMPE	T4,[MOVE T2,SCNWD	;YES, IF INPUT FULL WILD,
		ADD	T2,P4		;SEE IF INPUT FIELD REALLY SPECIFIED
		SKIPE	(T2)		;IS INPUT FIELD BLANK?
		JRST	.+1		;NO, DO SECONDARY WILDCARDING NORMALLY
		JRST	.POPJ1##]	;YES, THEN OK AS IS, NO ERRORS
	MOVE	T2,T4		;INPUT
	PUSHJ	P,BITCNT	;NON-WILD COUNT
	ADDB	T2,SCWBC	;= <OUTPUT WILD>-<INPUT WILD>
	SKIPGE	SCWBE		;OK ALL?
	 JRST	RDHIN1		;YES
	SKIPE	SCWBE		;NO - OK TOO MANY OUTPUT?
	 JUMPN	T2,CPOPJ	;NO - MUST MATCH EXACTLY
	JUMPL	T2,CPOPJ	;YES - ERR ONLY IF TOO MANY INPUT
RDHIN1:	SKIPL	SCWMM		;ARE WE BEING PICKY
	 JRST	RDHINX		;NO - BE REASONABLY CREATIVE
	SKIPG	SCWBE		;YES - SUPER PICKY?
	 JRST	RDHIN2		;NO - PROCEED
	CAME	P1,T4		;YES - MASKS MATCH?
	 JRST	CPOPJ		;NO - ERROR
RDHIN2:	ANDCM	T3,P1		;CLEAR UNWANTED INPUT FIELDS
	IOR	T1,T3		;FILL IN T1
	JRST	CPOPJ1		;RETURN HAPPILY
;HERE TO FILL IN SECONDARY WILDCARDS IN /SCWILD:BITPIR MODE
;ENTER WITH T1-T4 ALREADY SETUP, P1-P4 AVAILABLE
;(T2 IS IN P1 AND MUST BE RESTORED)

RDHINX:	MOVE	T2,P1		;RESTORE T2
	MOVE	P1,T3		;WILD-BIT COPY OF INPUT WORD
	MOVE	P2,T4		;AND WILD MASK FOR P1
	AND	T3,T4		;T3 = NON-WILD BITS ONLY
	ANDCM	P1,T4		;P1 = WILD BITS ONLY
	MOVSI	P4,-^D36	;LH = - COUNT OF BITS TO BE PROCESSED
				;RH = BIT CURRENTLY BEING PROCESSED
	TDZA	P3,P3		;INITIALIZE WILD COUNT, ENTER LOOP

RDHINL:	LSH	T2,1		;SET MASK FOR NEXT SECONDARY BIT
	ROT	T3,1		;NEXT NON-WILD INPUT BIT
	JUMPGE	T2,RDHINW	;IF WILD OUTPUT HANDLE IT
	ANDCMI	T3,1		;ELSE CLEAR NONWILD INPUT
	JUMPGE	P2,RDHLCX	;REMEMBER LEADING UNUSED WILD INPUT
	JRST	RDHIW4		;NOTHING TO REMEMBER - UPDATE ACCORDINGLY

;HERE FOR NEXT WILD INSERT BIT

RDHINW:	SOSL	SCWBC		;MORE OUTPUT (WILD) THAN INPUT??
	 JRST	RDHIW1		;YES - USE CURRENT BIT FIELD
RDHIW0:	JUMPGE	P2,RDHIW3	;NO - GET NEXT WILD BIT
	LSH	P1,1		;WE DON'T HAVE ONE NOW, SO
	LSH	P2,1		;GET THE NEXT BIT
	AOJA	P3,RDHIW0	;CHECK IT OUT
RDHIW1:	CAIL	P3,(P4)		;LEADING (REMEMBERED) WILD?
	 JRST	RDHIW2		;NO - OR AT LEAST NOT ANYMORE . . .
	JUMPGE	P2,RDHIW3	;YES - IF WILD NOW THEN USE NOW
	LSH	P1,1		;NOT WILD, SO LOOK
	LSH	P2,1		;AT NEXT POSSIBLE CASE
	AOJA	P3,RDHIW1	;AND TRY AGAIN
RDHIW2:	JUMPL	P2,RDHIW4	;CURRENT INPUT BIT WILD?
RDHIW3:	ANDCMI	T3,1		;YES - CLEAR NON-WILD INPUT BIT
	AOS	SCWBC		;UN-ALTER RELATIVE COUNT
RDHIW4:	LSHC	T4,1		;GET NEXT BIT
	LSH	P2,1		;ADVANCE WILD MASK
	AOJA	P3,RDHLCT	;UPDATE POS CNTR, END THIS CYCLE
RDHLCX:	LSH	T4,1		;UPDATE WILD BIT WORD
RDHLCT:	AOBJN	P4,RDHINL	;IF MORE TO DO - DO IT
	IOR	T1,T3		;GET NON-WILD REPLACEMENTS
	IOR	T1,T4		;AND WILD REPLACEMENTS
	JRST	CPOPJ1		;RETURN HAPPILY
;SCFLD  --  HELPER TO SECONDARY WILDCARDING - LOCATE INPUT FIELD

SCFLD:	CAIN	T2,.FXNOD	;WANT NODE NAME?
	JRST	[MOVE	T3,.FXNOD(P4)	;YES, JUST USE INPUT SPECIFICATION
		POPJ	P,]		;RETURN WITH SOMETHING

	CAIN	T2,.FXDEV	;WANT DEVICE NAME?
	JRST	[MOVE	T3,SCIOPN	;YES, ADDRESS OF INPUT OPEN BLOCK
		MOVE	T3,.OPDEV(T3)	;FETCH DEVICE USED IN OPEN
		POPJ	P,]		;RETURN WITH DEVICE NAME

	MOVE	T3,SCILKP	;ADDRESS OF INPUT FILE LOOKUP BLOCK
	CAIN	T2,.FXNAM	;WANT FILE NAME?
	JRST	[MOVE	T3,.RBNAM(T3)	;YES, FETCH FILE NAME
		POPJ	P,]		;RETURN WITH FILE NAME

	CAIN	T2,.FXEXT	;WANT FILE TYPE?
	JRST	[HLLZ	T3,.RBEXT(T3)	;YES, FETCH FILE TYPE
		POPJ	P,]		;RETURN WITH FILE TYPE

;HERE IF A DIRECTORY FIELD - MAY EVEN BE SHIFTED

	CAIL	T2,.FXDIR	;*** RANGE CHECK
	CAILE	T2,.FXDIR+<2*.FXLND>-2  ;*** RANGE CHECK
	ERROR	SD1,<Directory out of range before shifting>,,,[HALT .POPJ##]
	ADD	T2,SCNWDD	;SHIFT DIRECTORY LEVELS AS NEEDED
	SETZM	SCNWDD		;CLEAR VALUE
	CAIL	T2,.FXDIR	;*** RANGE CHECK
	CAILE	T2,.FXDIR+<2*.FXLND>-2  ;*** RANGE CHECK
	ERROR	SD2,<Directory out of range after shifting>,,,[HALT .POPJ##]
	PUSH	P,T2		;PRESERVE INDEX (TO RETURN TO CALLER)
	SUBI	T2,.FXDIR	;GET DIRECTORY LEVEL
	LSH	T2,-1		;REDUCE TO UNI-WORD INDEX
	MOVE	T3,.RBPPN(T3)	;GET DIRECTORY WORD FROM FILE LOOKUP BLOCK
	JUMPE	T2,[TLNN T3,-1		;PPN OR PATH POINTER?
		MOVE	T3,.PTPPN(T3)	;PATH POINTER, RETRIEVE PPN
		POP	P,T2		;RESTORE INDEX
		POPJ	P,]		;RETURN WITH PPN
	TLNN	T3,-1		;PPN OR PATH POINTER?
	ADDI	T3,(T2)		;PATH POINTER, RELOCATE IT
	TLNN	T3,-1		;PPN OR PATH POINTER?
	SKIPA	T3,.PTPPN(T3)	;PATH POINTER, EXTRACT APPROPRIATE LEVEL NAME
	SETZ	T3,		;PPN, ALL SFD'S RETURNED 0
	POP	P,T2		;RESTORE ACTUAL USED INDEX
	POPJ	P,		;RETURN WITH SFD NAME
;SCDCK  --  ADJUST FOR DIRECTORY LEVEL SHIFTING (/SCWILD:(DFIELD!DSAME))

SCDCK:	SKIPN	SCWMD		;IF NEITHER /SCWILD:(DFIELD!DSAME)
	POPJ	P,		;THEN NOTHING TO DO HERE
	MOVE	T3,SCDLEV	;GET CURRENT SHIFTING LEVEL
	ASH	T3,1		;CONVERT TO BI-WORD INDEX
	ADD	T3,SCNWD	;UPCOMING INDEX
	CAIL	T3,.FXDIR+<2*.FXLND>-2  ;SHIFTED OFF THE END?
	JRST	SCDCK3		;YES, ABORT FURTHER SHIFTING
	ADDI	T3,2(P4)	;OFFSET TO UPCOMING BIWORD SPEC
	MOVE	T4,1(T3)	;PEEK AT UPCOMING MASK
	CAMN	T2,[-1]		;IF BOTH "OUTPUT"
	CAME	T4,[-1]		;AND "INPUT" ARE NON-WILD
	CAIA			;(AT LEAST ONE SIDE WILD)
	POPJ	P,		;NO WILDCARDS, IGNORE IT
	AOJE	T4,SCDCK4	;OUTPUT WILD, INPUT NON-WILD?
	CAME	T2,[-1]		;INPUT WILD. OUTPUT WILD TOO?
	JRST	SCDCK2		;YES, BOTH WILD

;OUTPUT NON-WILD, INPUT WILD

	SOS	SCDLEV		;NOTE A RECLAIMABLE FIELD
	POPJ	P,		;BUT OTHERWISE IGNORE

;OUTPUT WILD, INPUT WILD

SCDCK2:	MOVE	T3,SCDLEV	;GET PREVIOUS SHIFTING LEVEL
	ASH	T3,1		;COVNERT TO BIWORD INDEX
	MOVEM	T3,SCNWDD	;SET SHIFTING LEVEL
	ADD	T3,SCNWD	;PEEK AT RESULT
	CAIGE	T3,.FXDIR+<2*.FXLND>-2	;RUN OFF THE END?
	POPJ	P,		;NO, ALL SET
	SOS	SCDLEV		;YES, BACK OFF SHIFT
SCDCK3:	HLLOS	SCNWD3		;AND FLAG THE END
	JRST	SCDCK2		;BACK AND RESET THE SHIFTING LEVEL

;WILD OUTPUT, NON-WILD INPUT

SCDCK4:	AOS	T3,SCDLEV	;ADVANCE SHIFTING LEVEL
	ASH	T3,1		;CONVERT TO BI-WORD INDEX
	MOVE	T4,SCNWD	;COPY OF CURRENT INDEX
	ADD	T4,T3		;PEEK AT SHIFTED RESULT
	CAILE	T4,.FXDIR+<2*.FXLND>-2-2  ;RUN OFF END YET?
	JRST	SCDCK2		;YES, BACK OFF
	ADDI	T4,2(P1)	;NO, POINT AT UPCOMING BI-WORD SPECIFICATION
	SKIPN	(T4)		;ANYTHING SPECIFIED?
	JRST	SCDCK3		;NO, MARK END OF SPEC
	MOVE	T4,1(T4)	;YES, GET IT'S WILDCARD MASK
	AOJE	T4,SCDCK4	;IF NON-WILD, IGNORE AND LOOK FURTHER
	MOVEM	T3,SCNWDD	;WILDCARDS, MATCHED, SET SHIFTING LEVEL
	POPJ	P,		;RETURN
REPEAT	0,<
	SUBTTL	DIRECTORY SUBROUTINES

;SUBROUTINE TO SUPPLY DEFAULTS FOR DIRECTORIES
;CALL:	MOVEI	P1,POINTER TO SPECIFICATION
;	PUSHJ	P,SETDIR
;USES T1-4
;
;HANDLES [,] (IE, DEFAULT PROJECT, DEFAULT PROGRAMMER),
;HANDLES [-] (IE, DEFAULT TO DEFAULT DIRECTORY)
;HANDLES .UFD (IE, DIRECTORY IS REALLY FILE NAME)

SETDIR:	MOVX	T1,FX.DFX	;GET FLAG
	TDNE	T1,.FXMOD(P1)	;SEE IF HERE ALREADY
	POPJ	P,		;YES--RETURN
	IORM	T1,.FXMOD(P1)	;NO--SET FLAG FOR LATER
	MOVX	T1,FX.DIR	;SEE IF DIRECTORY
	TDNE	T1,.FXMOD(P1)	;  SPECIFIED
	JRST	SETDR2		;YES--GO HANDLE IT
	HLRZ	T1,.FXEXT(P1)	;GET EXTENSION
	CAIN	T1,'UFD'	;SEE IF UFD
	JRST	SETDR		;YES--GO DO DEFAULTS
	LDB	T1,[POINTR (.FXMOD(P1),FX.TRM)] ;GET TERMINATOR	[300]
IFN FT$COR,<
	CAIN	T1,.FXTRC	;IF "+"				[300]
	MOVEI	T1,.FXTRO	; TREAT AS 'OR'			[300]
>
	CAIE	T1,.FXTRA	;IF 'AND'			[300]
	CAIN	T1,.FXTRO	; OR 'OR'			[300]
	JRST	SETDR		; NEED TO GO SET DIRECTORY	[300]
	CAMN	P1,.WIFIR	;  OR SECOND FILE
	CAIN	T1,.FXTRN	; OR 'NOT'			[300]
	JRST	SETDR		;YES--SAME AS WILD CARDS
	SETCM	T1,.FXNMM(P1)	;SEE IF WILD NAME
	SETCM	T2,.FXEXT(P1)	;  OR EXT
	TRNN	T2,-1		;IF NOT,
	JUMPE	T1,SETDR4	;  LEAVE DIRECTORY CLEAR
SETDR:	MOVE	T1,[-.FXLND,,.MYPTH##+.PTPPN]  ;POINTER TO DEFAULT PATH
	MOVEI	T2,.FXDIR(P1)	;NO--COPY DEFAULT DIRECTORY
SETDR1:	SKIPN	T3,(T1)		;GET NEXT LEVEL
	SOS	T1		;BLANK--HOLD POINTER
	MOVEM	T3,(T2)		;STORE IN ARGUMENT AREA
	SKIPE	T3		;SEE IF BLANK
	SETOM	T3		;NO--FULL MATCH
	MOVEM	T3,1(T2)	;STORE AWAY
	ADDI	T2,2		;ADVANCE STORAGE
	AOBJN	T1,SETDR1	;LOOP UNTIL DONE
	JRST	SETDR3		;AND PROCEED BELOW
SETDR2:	MOVE	T1,.FXDIR(P1)	;GET DIRECTORY
	MOVE	T2,.MYPPN##	;DEFAULT PPN--GET USER
	TLNN	T1,-1		;SEE IF PROJECT PRESENT
	HLLM	T2,.FXDIR(P1)	;NO--FILL IN MY PROJECT
	TLNN	T1,-1		; ..
	HRROS	.FXDIM(P1)	; AND NO WILDCARD
	TRNN	T1,-1		;SEE IF PROGRAMMER PRESENT
	HRRM	T2,.FXDIR(P1)	;NO--FILL IN MY PROGRAMMER
	TRNN	T1,-1		; ..
	HLLOS	.FXDIM(P1)	; AND NO WILDCARD
SETDR3:
REPEAT 0,<			;SET /OKPRO IF ANY WILD-CARDS	[301]
	SETCM	T1,.FXDIM(P1)	;SEE IF WILD USER
	JUMPE	T1,SETDR4	;NO--OK
>
	MOVX	T1,FX.PRT	;YES--SET
	TDNN	T1,.FXMOM(P1)	; /OKPROTECTION
	IORM	T1,.FXMOD(P1)	; UNLESS /ERPROTECTION
SETDR4:	HLRZ	T1,.FXEXT(P1)	;GET EXTENSION
	CAIE	T1,'UFD'	;SEE IF .UFD
	POPJ	P,		;NO--ALREADY SETUP CORRECTLY
	MOVE	T1,.PPMFD##	;YES--GET CORRECT DIRECTORY
	EXCH	T1,.FXDIR(P1)	;STORE (MFD)
	SETO	T2,		;CLEAR WILDCARDS
	EXCH	T2,.FXDIM(P1)	;SET INTO DIRECTORY
	MOVEM	T1,.FXNAM(P1)	;MOVE DIRECTORY TO NAME
	MOVEM	T2,.FXNMM(P1)	;MOVE DIRECTORY TO NAME
	SETZM	.FXDIR+2(P1)	;CLEAR SUB DIRECTORY
	SETZM	.FXDIM+2(P1)	; ..
	POPJ	P,		;RETURN
> ;END OF REPEAT 0
REPEAT	0,<

;.NXDTW -- GET NEXT WORD FROM DATA FILE
;CALL:	PUSHJ	P,.NXDTW
;	ERROR RETURN IF END-OF-FILE
;	NORMAL RETURN WITH WORD IN T1

.NXDTW::SOSGE	B.DC+.BFCTR	;SEE IF WORD IN BUFFER
	JRST	NXDATR		;NO--READ SOME MORE OF FILE
	ILDB	T1,B.DC+.BFPTR	;FETCH WORD
	JRST	CPOPJ1		;SKIP RETURN

NXDATR:	PUSHJ	P,DODCHN	;EXECUTE DATA CHANNEL UUO
	  IN	DC,		;READ
	    JRST  .NXDTW	;OK TO PROCEED
	PUSHJ	P,DODCHN	;EXECUTE DATA CHANNEL UUO
	  STATZ	DC,IO.ERR	;SEE IF ANY ERRORS
	    PUSHJ P,E.DFE  	;YES
	PUSHJ	P,DODCHN	;EXECUTE DATA CHANNEL UUO
	  STATO	DC,IO.EOF	;SEE IF EOF
	    JRST .NXDTW  	;NO--GET MORE DATA
	POPJ	P,		;YES--EOF RETURN

;ERROR:	I/O ERROR WHILE READING DATA FILE

E.DFE:	PUSHJ	P,.SAVE1##	;SAVE P1
	PUSHJ	P,DODCHN	;DO DATA CHANNEL UUO
	  GETSTS DC,T1		;GET STATUS BITS
	PUSHJ	P,STSERR	;OUTPUT STATUS MESSAGE
	PUSHJ	P,DODCHN	;DO DATA CHANNEL UUO
	  SETSTS DC,(T1)	;CLEAR ERROR BITS
	PJRST	.TFILE		;OUTPUT FILE NAME

;DODCHN -- ROUTINE TO INCLUDE THE DATA CHANNEL IN A UUO AND EXECUTE IT
;CALL:	PUSHJ	P,DODCHN
;	  UUO TO EXECUTE
;	    NON-SKIP POINT
;	SKIP POINT
;USES NO ACS

DODCHN:	PUSH	P,T1		;PRESERVE T1
	MOVE	T1,-1(P)	;GET UUO
	MOVE	T1,(T1)		;GET UUO
	AOS	-1(P)		;ADVANCE RETURN
	IOR	T1,AGDCHN	;INCLUDE DATA CHANNEL
	EXCH	T1,(P)		;RESTORE T1 SAVE UUO
	XCT	(P)		;DO THE UUO
	  JRST	.+2		;NON-SKIP
	AOS	-1(P)		;SKIP
	POP	P,(P)		;DISCARD UUO
	POPJ	P,		;RETURN
> ;END OF REPEAT 0
	SUBTTL	PRIMARY WILDCARDING ERRORS, MARK II

;ERROR:	DIRECTORY OPEN

E.UFO:	MOVEI	T1,[ASCIZ /directory on /]
	PUSHJ	P,OPNERR
	SETOM	UFDEF		;INDICATE ERROR MESS FOR DIRECTORY
	JRST	LOOKD



;ERROR:	DATA FILE OPEN

E.DFO::	MOVEI	T1,[0]
OPNERR:	PUSH	P,T1		;SAVE MESSAGE INSERT
	MOVE	T1,['DFO',,[ASCIZ /Open failure for /]]
	PUSHJ	P,WLDERR	;ISSUE ERROR
	  JRST	[POP   P,T1	;IF NOT /VERB:FIRST
		 PJRST .TCRLF##] ; SKIP REST
	POP	P,T1		;RECOVER INSERT
	PUSHJ	P,STRER1	;OUTPUT STRUCTURE NAME
	MOVE	T2,W.BLK+.FXDEV	;GET DEVICE
	PUSHJ	P,DOPHYS	;GET PHYSICAL BIT
	  DEVTYP T2,		;GET JOB USING IT
	    JRST OPNER2		;GIVE UP IF NOT IMPLEMENTED
	LDB	T2,[POINTR (T2,TY.JOB)]  ;GET USER JOB
OPNER1:	JUMPE	T2,OPNER2	;GIVE UP IF NOT ON RECORD
	MOVEI	T1,[ASCIZ / in use by job /]
	PUSHJ	P,.TSTRG##	;TYPE PREFIX
	HRRZ	T1,T2		;GET JOB NUMBER
	PUSHJ	P,.TDECW##	;TYPE JOB NUMBER
OPNER2:	PJRST	.TCRLF		;END LINE AND RETURN
;ERROR:	DIRECTORY LOOKUP FAILURE

ERUFL:	HRRM	T1,LKPBL+.RBEXT	;REMEMBER FILOP. ERROR CODE
	MOVE	T1,FLPBL+.FOFNC	;PICK UP THE FUNCTION/CHANNEL WORD
	AND	T1,[FO.CHN]	;REDUCE TO JUST THE CHANNEL NUMBER
	MOVEM	T1,BUFCHN(T4)	;AND SAVE THE CHANNEL
	MOVEM	T3,DIRBU-1(T4)	;RESTORE DIRECTORY LIST
	HRRZ	T2,LKPBL+.RBEXT	;POSITION LOOKUP ERROR CODE
	JUMPE	T4,ERMFL	;TOP-LEVEL ([1,1] = MFD) GETS SPECIAL MESSAGE
	SOS	.CTDRF		;DISCOUNT DIRECTORY FOUND SUCCESSFULLY
	CAIE	T2,ERSNF%	;SEE IF SFD ERROR
	CAIG	T2,ERIPP%	;SEE IF NON-EXISTENT ERROR
	SKIPN	SRCH		;AND STR SEARCHING
	JRST	ERUFL5		;ISSUE LOOKUP ERROR MESSAGE

;NO ERROR MESSAGE, JUST ACCUMULATE ERRORS FOR GRAND FINALE SUMMARY

ERUFL2:	CAIN	T2,ERSNF%	;COMPACT ERROR CODE
	MOVEI	T2,2		; SFD IS WORST
	SKIPN	T2		; ..
	MOVEI	T2,3		;EXCEPT FOR FILE MISSING
	CAMLE	T2,LASERR	;SEE IF WORST YET
	MOVEM	T2,LASERR	;YES--REMEMBER IT
	JRST	ERUFL6		;SKIP ERROR MESSAGE, VERIFY THE CHANNEL

;ISSUE ERROR MESSAGE FOR DIRECTORY FILE ACCESS ERROR

ERUFL5:	PUSHJ	P,LKEDR		;ISSUE ERROR MESSAGE

;SINCE FILOP. ERRORS IN GENERAL MAY LEAVE THE CHANNEL IN AN INDETERMINATE
;STATE WE MUST TRY TO SECOND-GUESS THE MONITOR

ERUFL6:	HRRZ	T1,LKPBL+.RBEXT	;ANOTHER COPY OF THE ERROR CODE
	CAIE	T1,ERFNF%	;FILE NOT FOUND?
	CAIN	T1,ERIPP%	; OR PPN NOT FOUND/ILLEGAL?	
	JRST	WILDE		;YES, CHANNEL OK
	CAIE	T1,ERPRT%	;PROTECTION FAILURE?
	CAIN	T1,ERSNF%	; OR SFD NOT FOUND?
	JRST	WILDE		;YES, CHANNEL OK

;NO IDEA WHAT MAY HAVE HAPPENED, TAKE NO CHANCES ON GETTING A BUNCH
;OF STALE CHANNELS LEFT LYING AROUND, RELEASE THIS CHANNEL AND RESTART
;THE I/O (WILDRD WILL RE-OPEN AS NEEDED)

ERUFL8:	MOVE	T4,DEPTH	;CURRENT DIRECTORY NESTING LEVEL
	MOVE	T2,BUFCHN(T4)	;GET DIRECTORY CHANNEL
	PUSHJ	P,WILDRC	;AND CLOSE IT OFF
	SKIPE	T2,BUFCHN(T4)	;IF AN EXTENDED I/O CHANNEL,
	PUSHJ	P,WILDRZ	;THEN RELEASE IT TOO!
	JRST	WILDE		;AND THAT'S THE END OF THAT DIRECTORY
;HERE WHEN LOOKUP ERROR WAS FOR [1,1] (I.E., THE MASTER FILE DIRECTORY)

ERMFL:	PUSHJ	P,LKEMD		;ISSUE SPECIAL MFD ERROR MESSAGE
	JRST	ERUFL8		;AND TROUNCE THE CHANNEL, IF ANY



;ISSUE ERROR IN SFD/UFD/MFD

LKEDR:	SETOM	UFDEF		;FLAG THAT ERROR WAS FOUND
	MOVX	T1,FX.PRT	;SEE IF
	TDNE	T1,W.BLK+.FXMOD	;/OKPROTECTION
	CAIE	T2,ERPRT%	;AND PROTECTION ERROR
	JRST	LKEDR3		;NO, NEED ERROR MESSAGE
	AOS  .CTDRP		;YES, COUNT DIRECTORIES PROTECTED
	POPJ	P,		;BUT OTHERWISE IGNORE FOR NOW

LKEDR3:	PUSHJ	P,E$$LKP	;OUTPUT LOOKUP ERROR
	PJRST	UFDERR		;OUTPUT UFD ERROR AND RETURN

LKEMD:	CAIN	T2,ERIPP%	;SEE IF ILL PPN
	MOVEI	T2,ERFNF%	;CHANGE TO NO SUCH FILE (MFD)
	PUSHJ	P,E$$LKP	;OUTPUT LOOKUP ERROR
	PJRST	MFDERR		;OUTPUT MFD ERROR AND RETURN


;ERROR:	I/O ERROR WHILE READING DIRECTORY

E.UFE:	SKIPE	FLDTA		;SEE IF DECTAPE
	SKIPA	T2,[WC,,0]	;YES--USE THIS CHANNEL
	MOVE	T2,BUFCHN(T4)	;NO--GET EXTENDED CHANNEL 
	HRRI	T2,.FOGET	;GETSTS FUNCTION
	MOVE	T1,[1,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;GET STATUS
	 JFCL			;
	PUSHJ	P,STSERR	;OUTPUT MESSAGE
	SKIPE	FLDTA		;SEE IF DECTAPE
	SKIPA	T2,[WC,,0]	;YES--USE THIS CHANNEL
	MOVE	T2,BUFCHN(T4)	;NO--GET EXTENDED CHANNEL
	HRRI	T2,.FOSET	;SETSTS FUNCTION
	MOVE	T3,T1		;COPY THE STATUS BITS
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;SET STATUS
	 JFCL			;
	PJRST	UFDERR		;OUTPUT UFD ERROR
;MFDERR -- ISSUE MESSAGE THAT ERROR IS IN MFD
;CALL:	PUSHJ	P,MFDERR
;USES T1

MFDERR:	PUSHJ	P,.TSPAC##	;SEPARATE FROM ERROR TEXT
	PUSHJ	P,TYPSTR	;LIST OFFENDING STRUCTURE
	MOVEI	T1,[ASCIZ\ Master File Directory
\]
	PJRST	.TSTRG##	;IDENTIFY SPECIAL DIRECTORY


;UFDERR -- ISSUE MESSAGE THAT ERROR IS IN UFD
;CALL:	PUSHJ	P,UFDERR
;USES T1

UFDERR:	MOVE	T2,FLDTA	;GET DECTAPE FLAG
UFDER2:	PUSH	P,T2		;PRESERVE DECTAPE FLAG
	MOVEI	T1,[ASCIZ / directory /]
	PUSHJ	P,.TSTRG##	;PREFIX DIRECTORY TYPEOUT
	PUSHJ	P,TYPSTR	;OUTPUT STRUCTURE
UFDER3:	POP	P,T2		;RESTORE DECTAPE FLAG
	JUMPN	T2,.TCRLF##	;EXIT NOW IF NOT A DISK STRUCTURE
	PUSHJ	P,UFDLSN	;OUTPUT DIRECTORY
	PJRST	.TCRLF		;END LINE AND RETURN
;E.LKEN -- OUTPUT LOOKUP/ENTER ERROR FOR SCAN-BLOCK
;CALL:	MOVEI	T1,EXTENDED LOOKUP BLOCK
;	MOVEI	T2,LENGTH OF LOOKUP BLOCK
;	MOVEI	T3,SCAN BLOCK (INC. SFDS)
;	PUSHJ	P,E.LKEN
;	RETURN
;
;ON RETURN, IF T1=-1 THEN NO MESSAGE HAS BEEN PRINTED AND THE ERROR
;SHOULD BE IGNORED (E.G., PROTECTION FAILURE AND /OKPROT)

E.LKEN::PUSHJ	P,.SAVE4##	;SAVE THE P'S
	MOVE	P1,T3		;ADDRESS OF FILE SPEC BLOCK
	MOVE	P2,AGOPEN	;ASSUME LAST USED OPEN BLOCK
	MOVE	P3,T1		;ADDRESS OF FILE LOOKUP BLOCK
	PJRST	EDFL10		;HANDLE LIKE NORMAL E.DFL FILE
;E.DFF  --  PRINT PRIMARY FILE OPEN/LOOKUP (FILOP.) ERROR MESSAGE
;CALL IS:
;
;	MOVX	T1,<ERROR>
;	PUSHJ	P,E.DFF
;	RETURN
;
;WHERE <ERROR> IS THE FILOP. ERROR CODE.
;
;E.DFF ASSUMES THAT .LKWLD (OR .CHKFL) HAS BEEN CALLED, SETTING UP THE
;AG???? POINTERS TO THE VARIOUS FILE AREAS.
;
;	****	IN PARTICULAR, E.DFF ASSUMES THAT THE OPEN    ****
;	****	BLOCK IS EMBEDDED IN THE FILOP. BLOCK, AND    ****
;	****	AS SUCH BACK-POINTS TO THE LOOKUP AND/OR      ****
;	****	ENTER BLOCK!				      ****
;
;ON RETURN, T1 IS -1 IF THE ERROR SHOULD BE IGNORED (E.G., /OKPROT).

E.DFF::	PUSHJ	P,.SAVE4##	;SAVE AWAY THE P'S
	MOVE	P1,@AGPNTR	;GET PRIMARY FILE SPEC BLOCK
	MOVE	P2,AGOPEN	;ADDRESS OF OPEN BLOCK
	SUBI	P2,.FOIOS-.FOFNC;BACKPOINT TO THE FILOP. BLOCK
	SKIPN	P3,.FOLEB(P2)	;ADDRESS OF LOOKUP BLOCK
	MOVE	P3,AGLOOK	;NEED A LOOKUP/ENTER BLOCK!
	HRRM	T1,.RBEXT(P3)	;ENSURE ERROR CODE SAVED AWAY
	CAIE	T1,ERDNA%	;DEVICE NOT AVAILABLE?
	CAIN	T1,ERNSD%	;NO SUCH DEVICE?
	JRST	EDFF10		;YES - JUST PRINT DEVICE
	CAIE	T1,ERDDU%	;DEVICE DETACHED?
	CAIN	T1,ERDRS%	;DEVICE RESTRICTED?
	JRST	EDFF10		;YES - JUST PRINT DEVICE
	CAIE	T1,ERDCM%	;DEVICE CONTROLLED BY MDA?
	CAIN	T1,ERDAJ%	;DEVICE ASSIGNED TO ANOTHER JOB?
	JRST	EDFF10		;YES - JUST PRINT DEVICE
	CAIE	T1,ERIDM%	;ILLEGAL DATA MODE?
	CAIN	T1,ERDUM%	;DEVICE IN USE ON MPX CHANNEL?
	JRST	EDFF10		;YES - JUST PRINT DEVICE
	ADDI	P2,.FOIOS-.FOFNC;ADJUST P2 TO BE ADDRESS OF "OPEN" BLOCK
	PJRST	EDFL10		;AND TREAT AS "LOOKUP" ERROR

;HERE ON DEVICE ("OPEN") ERRORS RATHER THAN FILE ("LOOKUP") ERRORS

EDFF10:	ADDI	P2,.FOIOS-.FOFNC;ADJUST P2 TO BE ADDRESS OF "OPEN" BLOCK
	PJRST	EDVE10		;TREAT AS "OPEN" ERROR
;E.DFL  --  PRINT PRIMARY FILE LOOKUP ERROR MESSAGE
;CALL IS:
;
;	PUSHJ	P,E.DFL
;	RETURN
;
;E.DFL ASSUMES THAT .LKWLD (OR .CHKFL) HAS BEEN CALLED, SETTING UP THE
;AG???? POINTERS TO THE VARIOUS FILE AREAS.
;
;ON RETURN, T1 IS -1 IF THE ERROR SHOULD BE IGNORED (E.G., /OKPROT).

E.DFL::	PUSHJ	P,.SAVE4##	;WANT SOME GOOD ACS
	MOVE	P1,@AGPNTR	;GET POINTER TO "OWNING" FILE SPEC BLOCK
	MOVE	P2,AGOPEN	;ADDRESS OF FILE OPEN BLOCK
	MOVE	P3,AGLOOK	;ADDRESS OF FILE LOOKUP BLOCK
EDFL10:	HRRZ	T2,.RBEXT(P3)	;GET CODE
	MOVX	T1,FX.PRT	;SEE IF
;	TDNE	T1,.FXMOM(P1)	;WAS EITHER /ERPROT OR /OKPROT SPECIFIED?
	TDNE	T1,.FXMOD(P1)	;YES, /OKPROTECTION?
	CAIE	T2,ERPRT%	; AND PROTECTION ERROR?
	JRST	EDFL3		;NOT AN IGNORABLE PROTECTION ERROR
	AOS	.CTFLP		;COUNT PROTECTION ERROR
EDFL21:	SOS	.CTFLF		;DON'T COUNT FILE FOUND
EDFL22:	SETO	T1,		;TELL CALLER TO IGNORE ERROR
	POPJ	P,		;RETURN

EDFL3:	MOVX	T1,FX.NOM	;SEE IF
	TDNE	T1,W.BLK+.FXMOD	; /OKNONE (DEFAULT CASE)
	JUMPE	T2,EDFL22	;YES--IF NOT FOUND, SUPPRESS ERROR
	CAIE	T2,ERSNF%	;SEE IF NO .SFD
	CAIN	T2,ERIPP%	;SEE IF NO .UFD
	JRST	EDFL7		;YES, THEN SPECIAL HANDLING
	SKIPE	SRCH		;IF MULT STRS
	JUMPE	T2,EDFL21	; AND MISSING FILE
	SETZ	T4,		;SET WARNING
	PUSHJ	P,ELKE10	;ISSUE FORTH A LOOKUP ERROR MESSAGE
EDFL32:	SETZ	T1,		;INDICATE A REAL ERROR
	POPJ	P,		;AND RETURN TO CALLER

EDFL7:	SKIPN	SRCH		;SEE IF MULTIPLE STRS
	JRST	E$$NXU		;NO--ISSUE MESSAGE
	SOS	.CTDRS		;YES--BACK OFF COUNTER
	SOS	.CTFLS		; ..
	JRST	EDFL21		;RETURN IGNORING THE ERROR

E$$NXU:	MOVE	T1,['NXU',,[ASCIZ /Non-existent/]]
	PUSHJ	P,WLDWRN	;ISSUE WARNING
	  PJRST	.TCRLF##	;SKIP REST IF NOT /VERB:FIRST
	PUSHJ	P,UFDERR	;OUTPUT UFD NAME
	JRST	EDFL32		;RETURN NON-IGNORABLE ERROR
;E.DVE  --  PRINT FILE (DEVICE) OPEN ERROR MESSAGE
;CALL IS:
;
;	MOVX	T1,<FSB>
;	MOVX	T2,<OPN>
;	MOVX	T3,<LEB>
;	MOVX	T4,<CTL>
;	PUSHJ	P,E.DVE
;	RETURN
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPEC BLOCK WHICH GENERATED THE
;CURRENT FILE SPEC (NOT CURRENTLY USED); <OPN> IS THE ADDRESS OF THE
;FILE OPEN BLOCK; AND <LEB> IS THE ADDRESS OF THE FILE LOOKUP BLOCK
;(CURRENTLY NOT USED); AND <CTL> IS 0 TO ISSUE A WARNING,
;1 TO ISSUE FATAL ERROR.
;
;USES T1 - T4.

E.DVE::	PUSHJ	P,.SAVE4##	;SAVE THE P'S
	DMOVE	P1,T1		;POSITION FILE SPEC BLOCK AND OPEN BLOCK
	MOVE	P3,T3		;AND FILE LOOKUP BLOCK OUT OF HARM'S WAY
EDVE10:	MOVSI	T1,'DVE'	;"WLDDVE" PREFIX TO INDICATE A DEVICE ERROR
	MOVEI	T2,WLDWRN	;ASSUME ONLY A "WARNING"
	SKIPE	T4		;SEVERE ERROR?
	MOVEI	T2,WLDERR	;YES, SET FOR AN "ERROR"
	PUSHJ	P,(T2)		;ISSUE PREFIX
	 PJRST	.TCRLF##	;/MESSAGE:NOFIRST, CAP OFF LINE NOW
	HRRZ	T1,.RBEXT(P3)	;FETCH ERROR CODE
	PUSHJ	P,.LKERR	;OUTPUT LOOKUP ERROR
	PUSHJ	P,.TSPAC##	;ONE SPACE OVER ALWAYS
	MOVEI	T1,[ASCIZ\device \]  ;JUST TYPING DEVICE HERE
	HRRZ	T2,.RBEXT(P3)	;FETCH ERROR CODE AGAIN
	CAIE	T2,ERNSD%	;WAS MESSAGE "NO SUCH DEVICE"?
	PUSHJ	P,.TSTRG##	;PREFIX THE DEVICE ITSELF
	MOVE	T1,.OPDEV(P2)	;FETCH DEVICE NAME
	PUSHJ	P,.TSIXN##	;AND TYPE IT OUT FOR USER
	PUSHJ	P,.TCOLN##	;CAP OFF WITH A COLON FOR NEATNESS
	MOVEI	T1,[ASCIZ\/PHYSICAL\]  ;IN CASE PHYSICAL ONLY
	MOVE	T2,.OPMOD(P2)	;GET I/O STATUS AND CONTROL
	TXNE	T2,UU.PHS	;WAS FILOP./OPEN PHYSICAL ONLY
	PUSHJ	P,.TSTRG##	;YES, MODIFY DEVICE ACCORDINGLY
	HRRZ	T1,.RBEXT(P3)	;RETRIEVE ERROR CODE AGAIN
	CAIN	T1,ERIDM%	;ILLEGAL DATA MODE?
	JRST	EDVIDM		;YES
	CAIN	T1,ERDAJ%	;IN USE BY ANOTHER JOB?
	JRST	EDVDAJ		;YES
EDVE20:	PJRST	.TCRLF##	;CAP OFF THE ERROR MESSAGE
;DEVICE IN USE BY ANOTHER JOB, LIST THE JOB FOR THE USER TO SEE

EDVDAJ:	DMOVE	T1,.OPMOD(P2)	;COPY OF DEVICE MODE AND NAME
	TXNN	T1,UU.PHS	;WAS OPEN PHYSICAL ONLY?
	TDZA	T1,T1		;NO, NORMAL LOGICAL DEVICE OPEN
	MOVX	T1,UU.PHY	;YES, SET FOR PHYSICAL-ONLY DEVTYP
	DEVTYP	T2,(T1)		;ASK MONITOR FOR DEVTYP (OWNING JOB)
	 JRST	.TCRLF##	;OH WELL, WE TRIED
	LDB	T1,[POINTR T2,TY.JOB]  ;EXTRACT JOB WHICH OWNS THE DEVICE
	PUSH	P,T1		;SAVE IT
	MOVEI	T1,[ASCIZ\; in use by job \]  ;PREFIX THE JOB NUMBER
	PUSHJ	P,.TSTRG##	;WHICH OWNS THE DEVICE
	POP	P,T1		;RESTORE JOB NUMBER
	PUSHJ	P,.TDECW##	;AND TYPE THE JOB OUT FOR THE USER TO SEE
	PJRST	.TCRLF##	;CAP OFF THE ERROR MESSAGE


;ILLEGAL DATA MODE, LIST THE OFFENDING DATA MODE FOR USER TO SEE

EDVIDM:	MOVEI	T1,[ASCIZ\; I/O mode = \]  ;SO LIST I/O MODE TOO
	PUSHJ	P,.TSTRG##	;PREFIX I/O MODE
	LDB	T1,[POINTR .OPMOD(P2),IO.MOD]  ;FETCH OFFENDING I/O MODE
	MOVE	T1,IOMTB(T1)	;GET APPROPRIATE TEXT
	PUSHJ	P,.TSTRG##	;LIST THE OFFENDING I/O MODE
	PJRST	.TCRLF##	;CAP OFF ERROR STRING

IOMTB:	[ASCIZ\(00) ASCII\]
	[ASCIZ\(01) ASCII\]
	[ASCIZ\(02) Packed Image\]
	[ASCIZ\(03) Byte\]
	[ASCIZ\(04) Undefined\]
	[ASCIZ\(05) Undefined\]
	[ASCIZ\(06) Undefined\]
	[ASCIZ\(07) Undefined\]
	[ASCIZ\(10) Image\]
	[ASCIZ\(11) Undefined\]
	[ASCIZ\(12) Undefined\]
	[ASCIZ\(13) Image Binary\]
	[ASCIZ\(14) Binary\]
	[ASCIZ\(15) Image Dump\]
	[ASCIZ\(16) Dump (records)\]
	[ASCIZ\(17) Dump\]
;E.LKE  --  PRINT FILE LOOKUP/ENTER MESSAGE
;CALL IS:
;
;	MOVX	T1,<FSB>
;	MOVX	T2,<OPN>
;	MOVX	T3,<LEB>
;	MOVX	T4,<CTL>
;	PUSHJ	P,E.LKE
;	RETURN
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPEC BLOCK WHICH GENERATED THE
;CURRENT FILE SPEC (NOT CURRENTLY USED); <OPN> IS THE ADDRESS OF THE
;FILE OPEN BLOCK; AND <LEB> IS THE ADDRESS OF THE FILE LOOKUP BLOCK;
;AND <CTL> IS 0 TO ISSUE A WARNING, 1 TO ISSUE FATAL ERROR.
;
;USES T1 - T4.

E.LKE::	PUSHJ	P,.SAVE4##	;SAVE THE P'S
	DMOVE	P1,T1		;POSITION FILE SPEC BLOCK AND OPEN BLOCK
	MOVE	P3,T3		;AND FILE LOOKUP BLOCK OUT OF HARM'S WAY
ELKE10:	MOVSI	T1,'LKE'	;"WLDLKE" PREFIX TO INDICATE LOOKUP/ENTER
	MOVEI	T2,WLDWRN	;ASSUME ONLY A "WARNING"
	SKIPE	T4		;SEVERE ERROR?
	MOVEI	T2,WLDERR	;YES, SET FOR AN "ERROR"
	PUSHJ	P,(T2)		;ISSUE PREFIX
	 PJRST	.TCRLF##	;/MESSAGE:NOFIRST, CAP OFF LINE NOW
	HRRZ	T1,.RBEXT(P3)	;FETCH ERROR CODE
	PUSHJ	P,.LKERR	;OUTPUT LOOKUP ERROR
	MOVEI	T1,[ASCIZ\ file \]  ;ASSUME A RANDOM FILE
	HLRZ	T2,.RBEXT(P3)	;FETCH A COPY OF THE FILE TYPE
	CAIE	T2,'UFD'	;IF EITHER A USER-
	CAIN	T2,'SFD'	; OR A SUB-FILE-DIRECTORY
	MOVEI	T1,[ASCIZ\ directory \]  ;THEN A NOT-SO-RANDOM FILE
	PUSHJ	P,.TSTRG##	;PREFIX THE FILE ITSELF
	DMOVE	T1,P2		;ADDRESS OF FILE OPEN AND LOOKUP BLOCK
	PUSHJ	P,.TOLEB##	;GO LIST THE FILE SPECIFICATION
ELKE20:	PJRST	.TCRLF##	;CAP OFF THE ERROR MESSAGE
;LKERR -- OUTPUT LOOKUP ERROR MESSAGE
;CALL:	MOVEI	T2,ERROR CODE
;	PUSHJ	P,LKERR
;	ERROR RETURN IF UFD BAD
;USES T1, T2, T3

LKERR:	HRRZ	T2,T2		;GET ERROR CODE
	CAIN	T2,ERIPP%	;SEE IF UFD ERROR
	POPJ	P,		;YES--ERROR RETURN
	AOS	(P)		;NO--ADVANCE RETURN
E$$LKP:	MOVSI	T1,'LKP'
	PUSH	P,T2		;SAVE ERROR
	PUSHJ	P,WLDWRN	;LIST FLAG
	  JRST	[POP	P,T1		;NOT /MESSAGE:FIRST,
		POPJ	P,]		;SKIP REST OF MESSAGE
	POP	P,T1		;RESTORE ERROR CODE

;SUBROUTINE ENTRY TO TYPEOUT A LOOKUP ERROR CODE
;CALL IS:
;
;	MOVX	T1,<ERROR>
;	PUSHJ	P,LKERR
;	RETURN
;
;WHERE <ERROR> IS THE LOOKUP/ENTER/RENAME/FILOP. ERROR CODE.
;
;ON RETURN, THE ERROR HAS BEEN IDENTIFIED AND TYPED.

.LKERR::MOVSI	T2,-LKETBL	;GET LENGTH OF ERROR TABLE
	HRLZ	T1,T1		;PUT CODE IN L.H. LIKE THE TABLE
LKERRL:	HRR	T1,LKETB(T2)	;INCLUDE OTHER HALF
	CAME	T1,LKETB(T2)	;SEE IF MATCH
	AOBJN	T2,LKERRL	;NO--LOOP ON
	JUMPL	T2,LKERR1	;MATCH--GO HANDLE IT
	PUSH	P,T1		;SAVE ERROR CODE
	MOVEI	T1,[ASCIZ \LOOKUP/ENTER failure \]
	PUSHJ	P,.TSTRG##	;PRINT GENERIC ERROR MESSAGE
	HLRZ	T1,0(P)		;FETCH OCTAL ERROR CODE
	PUSHJ	P,.TOCTW##	;TYPE OUT ERROR CODE
	POP	P,T1		;RESTORE ERROR CODE
	POPJ	P,		;RETURN

LKERR1:	HRRZ	T1,LKETB(T2)	;ADDRESS OF ERROR-SPECIFIC TEXT
	PUSHJ	P,.TSTRG##	;TYPE OUT NICE TEXT MESSAGE
	POPJ	P,		;AND RETURN
;LOOKUP/RENAME/ENTER ERROR MESSAGES

DEFINE	ERM (COD,FLG,TXT),<
	COD,,TXT		;;CODE,,ADDRESS OF TEXT
> ;END OF ERM MACRO

LKFDEV==FX.UDV
LKFDIR==FX.UDV!FX.UDR
LKFFLG==FX.UDV!FX.UDR!FX.UNM!FX.UEX

LKETB:				;BIWORD TABLE OF ERROR CODES/FLAGS/MESSAGES

ERM	ERFNF%,LKFFLG,[ASCIZ \Non-existent\]
ERM	ERIPP%,LKFDIR,[ASCIZ \Non-existent UFD\]
ERM	ERPRT%,LKFFLG,[ASCIZ \Protection failure\]
ERM	ERFBM%,LKFFLG,[ASCIZ \File being modified\]
ERM	ERAEF%,LKFFLG,[ASCIZ \Already existing\]
ERM	ERISU%,LKFFLG,[ASCIZ \Illegal file operation sequence\]
ERM	ERTRN%,LKFFLG,[ASCIZ \RIB or directory read error\]
ERM	ERNSF%,LKFFLG,[ASCIZ \Not a "SAVE" file\]
ERM	ERNEC%,LKFFLG,[ASCIZ \Insufficient memory available\]
ERM	ERDNA%,LKFDEV,[ASCIZ \Device is not available\]
ERM	ERNSD%,LKFDEV,[ASCIZ \Non-existent device\]
ERM	ERILU%,LKFFLG,[ASCIZ \Illegal monitor call\]
ERM	ERNRM%,LKFFLG,[ASCIZ \No room or quota exceeded\]
ERM	ERWLK%,LKFFLG,[ASCIZ \Write locked\]
ERM	ERNET%,LKFFLG,[ASCIZ \Insufficient monitor resources\]
ERM	ERPOA%,LKFFLG,[ASCIZ \Partial allocation\]
ERM	ERBNF%,LKFFLG,[ASCIZ \Specified block not free\]
ERM	ERCSD%,LKFFLG,[ASCIZ \Can't supersede directory\]
ERM	ERDNE%,LKFFLG,[ASCIZ \Directory not empty\]
ERM	ERSNF%,LKFFLG,[ASCIZ \Non-existent SFD\]
ERM	ERSLE%,LKFFLG,[ASCIZ \Search list empty\]
ERM	ERLVL%,LKFFLG,[ASCIZ \SFD's nested too deep\]
ERM	ERNCE%,LKFFLG,[ASCIZ \No create\]
ERM	ERFCU%,LKFFLG,[ASCIZ \Can't update file\]
ERM	ERLOH%,LKFFLG,[ASCIZ \Low-seg overlaps High-seg\]
ERM	ERNLI%,LKFFLG,[ASCIZ \Not logged-in\]
ERM	ERENQ%,LKFFLG,[ASCIZ \ENQ locks still set\]
ERM	ERBED%,LKFFLG,[ASCIZ \Bad EXE-format file directory\]
ERM	ERBEE%,LKFFLG,[ASCIZ \Bad EXE-format file extension\]
ERM	ERDTB%,LKFFLG,[ASCIZ \EXE-format file directory too big\]
ERM	ERENC%,LKFFLG,[ASCIZ \Network capacity exceeded\]
ERM	ERTNA%,LKFFLG,[ASCIZ \Task device not available\]
ERM	ERUNN%,LKFFLG,[ASCIZ \Non-existent network node\]

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

ERM	ERSIU%,LKFFLG,[ASCIZ \SFD is in use\]
ERM	ERNDR%,LKFFLG,[ASCIZ \File has an NDR lock\]
ERM	ERJCH%,LKFFLG,[ASCIZ \Too many file users\]
ERM	ERSSL%,LKFFLG,[ASCIZ \Can't rename SFD to lower level\]
ERM	ERCNO%,LKFFLG,[ASCIZ \I/O channel not OPENed\]
ERM	ERDDU%,LKFDEV,[ASCIZ \Device is DETACHed and unuseable\]
ERM	ERDRS%,LKFDEV,[ASCIZ \Device is restricted\]
ERM	ERDCM%,LKFDEV,[ASCIZ \Device is controlled by the MDA\]
ERM	ERDAJ%,LKFDEV,[ASCIZ \Device is in use by another job\]
ERM	ERIDM%,LKFFLG,[ASCIZ \Illegal I/O data mode\]
ERM	ERUOB%,LKFFLG,[ASCIZ \Undefined OPEN bits set\]
ERM	ERDUM%,LKFDEV,[ASCIZ \Device is already in use on an MPX channel\]
ERM	ERNPC%,LKFFLG,[ASCIZ \Insufficient "per-process" space for I/O channel\]
ERM	ERNFC%,LKFFLG,[ASCIZ \No free I/O channels available\]
ERM	ERUFF%,LKFFLG,[ASCIZ \Unknown FILOP. function\]
ERM	ERCTB%,LKFFLG,[ASCIZ \I/O channel too big\]
ERM	ERCIF%,LKFFLG,[ASCIZ \Channel illegal for FILOP. function\]
ERM	ERACR%,LKFFLG,[ASCIZ \Address check reading argument block\]
ERM	ERACS%,LKFFLG,[ASCIZ \Address check writing argument block\]
ERM	ERNZA%,LKFFLG,[ASCIZ \Negative or zero argument count\]
ERM	ERATS%,LKFFLG,[ASCIZ \Argument block too short\]

	LKETBL==.-LKETB
;DATERR -- ISSUE MESSAGE THAT ERROR IS IN A FILE
;CALL:	PUSHJ	P,DATERR
;USES T1

DATERR:	MOVEI	T1,[ASCIZ / file /]
	PUSH	P,T2		;SAVE AC
	HLRZ	T2,W.BLK+.FXEXT	;CHECK EXTENSION FOR SFD
	CAIN	T2,'SFD'	; ..
	MOVEI	T1,[ASCIZ / directory /]
	PUSHJ	P,.TSTRG##	;ISSUE PREFIX
	PUSHJ	P,FILOUT	;OUTPUT FILE NAME AND EXTENSION
	POP	P,T2		;RESTORE AC
	PJRST	.TCRLF		;AND END LINE AND RETURN


;STSERR -- ISSUE I/O STATUS ERROR MESSAGE
;CALL:	GETSTS	T1
;	PUSHJ	P,STSERR
;UPDATES T1 TO CLEAR ERROR BITS

STSERR:	PUSH	P,T1		;SAVE STATUS
	PUSH	P,T2		;SAVE ACS
	PUSH	P,T3		; ..
E$$IOE:	MOVE	T1,['IOE',,[ASCIZ /Error /]]
	PUSHJ	P,WLDWRN	;ISSUE WARNING
	  JRST	[POP  P,T3	;IF NOT
		 POP  P,T2	; /VERB:FIRST
		 POP  P,T1	; SKIP REST
		 POPJ P,]	; OF MESSAGE
	MOVE	T1,-2(P)	;GET STATUS
	PUSHJ	P,.TOCTW	;LIST STATUS
	POP	P,T3		;RESTORE ACS
	POP	P,T2		; ..
	MOVEI	T1,[ASCIZ / while reading/]
	PUSHJ	P,.TSTRG##	;AND REST OF MESSAGE
	POP	P,T1		;RESTORE STATUS
	TRZ	T1,IO.ERR	;CLEAR ERROR BITS
	POPJ	P,		;RETURN
;.TFILB -- OUTPUT SPECIFIC SCAN STYLE BLOCK
;.TFILE--OUTPUT UFD OR FILE NAME
;CALL:	MOVEI	T1,SCAN BLOCK (.TFILB ONLY)
;	PUSHJ	P,.TFILE/.TFILB
;USES T1

.TFILB::HRLZ	T1,T1		;POINT TO SPEC
	HRRI	T1,W.BLK	;POINT TO TEMP AREA
	BLT	T1,W.BLK+.FXLEN-1  ;COPY
.TFILE::HLRZ	T1,W.BLK+.FXEXT	;SEE WHAT KIND OF FILE
	CAIE	T1,'UFD'	;SEE IF DIRECTORY
	JRST	DATERR		;NO--OUTPUT NORMAL FILE NAME
	SKIPN	T2,W.BLK+.FXNAM	;GET NAME
	MOVE	T2,W.BLK+.FXDIR	;ELSE GET DIRECTORY
	MOVE	T1,W.BLK+.FXDIR	;GET DIRECTORY
	CAMN	T1,.PPMFD##	;SEE IF MFD
	MOVEM	T2,W.BLK+.FXDIR	;YES--USE FILE NAME
	SETZB	T2,W.BLK+.FXDIR+2  ;CLEAR SFD
	SETZM	W.BLK+.FXDIM+2	; ..
	JRST	UFDER2		;YES--OUTPUT DIRECTORY


;FILOUT -- OUTPUT NAME OF FILE AND EXTENSION
;CALL:	PUSHJ	P,FILOUT
;USES T1, T2

FILOUT:	TDZA	T1,T1		;FLAG NORMAL
FILOUW:	SETO	T1,		;FLAG "WILD"
	MOVEM	T1,UFDFLW	;SET FOR UFDLSN/W
	PUSHJ	P,TYPSTR	;OUTPUT DEVICE
	HLRZ	T2,W.BLK+.FXEXT	;CHECK EXTENSION		[153]
	TRC	T2,'UFD'	;SEE IF .UFD			[153]
	JUMPE	T2,UFDER3	;YES--USE UFD FORMAT		[153]
	MOVE	T1,W.BLK+.FXNAM	;GET FILE NAME
	PUSHJ	P,.TSIXN##	;LIST IT
	HLLZ	T2,W.BLK+.FXEXT	;GET FILE EXTENSION
	MOVX	T1,FX.NUL	;SEE IF USER SPECIFIED NO EXT
	TDNE	T1,W.BLK+.FXMOD	; SEE IF HE GAVE .
	JUMPE	T2,FILOU1	;NO--SEE IF HE LEFT AS NULL
	PUSHJ	P,.TDOT##	;YES--TYPE SEPARATOR
	MOVE	T1,T2		;GET NAME
	PUSHJ	P,.TSIXN	;LIST EXTENSION
FILOU1:	SKIPN	UFDFLW		;IS THIS "WILD"
	PJRST	UFDLSN		;NO, OUTPUT DIRECTORY AND RETURN
	PJRST	UFDLSW		;YES, CHECK BEFORE OUTPUTTING
;DIRERR -- ISSUE DIRECTORY ERROR MESSAGE
;CALL:	PUSHJ	P,DIRERR
;USES T1

DIRERR:	TDZA	T1,T1		;FLAG NORMAL
DIRERW:	SETO	T1,		;FLAG "WILD"
	MOVEM	T1,UFDFLW	;SAVE FLAG
	MOVEI	T1,[ASCIZ /irectory /]
	PUSHJ	P,STRER1	;OUTPUT DEVICE
	SKIPN	UFDFLW		;NORMAL OR WILD?
				;FALL INTO UFDLSN


;UFDLSN -- ISSUE NAME OF DIRECTORY
;UFDLSW -- ISSUE NAME OF "WILD" DIRECTORY
;CALL:	PUSHJ	P,UFDLSN/W
;USES T1

UFDLSN:	TDZA	T1,T1		;FLAG NORMAL
UFDLSW:	SETO	T1,		;FLAG "WILD"
	MOVEM	T1,UFDFLW	;SAVE FLAG
	PUSH	P,T3		;SAVE SOME ACS
	PUSH	P,T2		; ..
	JUMPE	T1,UFDLS3	;IF NORMAL, ALWAYS TRY TO TYPE SOMETHING

;AT THIS POINT IT IS ALMOST IMPOSSIBLE TO FIGURE OUT WHAT THE CORRECT
;THING TO TYPE SHOULD BE, SINCE SOMETHING AS SIMPLE AS "X:FOO.*" COULD
;EXPAND INTO SEVERAL DOZEN DIFFERENT DEVICE/DIRECTORY COMBINATIONS.
;THEREFORE, TRY TO TYPE BACK ONLY WHAT THE USER TYPED IN SO THAT AT
;LEAST THE WRONG THING IS NOT TYPED OUT . . .

	MOVE	T1,W.BLK+.FXFLD	;GET FIELDS FLAGS
	TXNN	T1,FX.UDR	;DID USER SUPPLY A DIRECTORY?
	JRST	UFDLS9		;NO, NOTHING TO TYPE OUT THEN
;	MOVE	T1,W.BLK+.FXMOM	;THE MODS MASK
;	TXNN	T1,FX.DIR	;IF USER SAID "[]"
;	JRST	[MOVEI	T1,[ASCIZ\[]\]	;THEN TYPE THAT BACK AT HIM
;		PUSHJ	P,.TSTRG##	; (OR HER, OR IT, AS THE CASE MAY BE)
;		JRST	UFDLS9]		;AND LEAVE IT AT THAT

;HERE TO DEFINITELY TRY TO TYPE SOMETHING

UFDLS3:	SKIPE	T1,FRCPPN	;SEE IF FORCING PPN		[154]
	JRST	[MOVEM	T1,W.BLK+.FXDIR	;SET AS UFD		[315]
		SETOM	W.BLK+.FXDIR+1	; NOT WILD		[315]
		JRST	.+1]		;AND PROCEED			[315]
	SETCM	T2,W.BLK+.FXDIM	;GET DIRECTORY MASK		[154]
	MOVE	T1,W.BLK+.FXDIR	;GET DIRECTORY			[154]
	CAMN	T1,.PPMFD##	;IF MFD				[154]
	JUMPE	T2,[HLRZ  T1,W.BLK+.FXEXT  ;YES--GET THE EXTENSION	[337]
		CAIE	T1,'UFD'	;SEE IF .UFD			[337]
		JRST	.+1		;NO--SKIP THIS		[337]
		MOVE	T1,W.BLK+.FXNAM	;YES--GET NAME		[154]
		MOVEM	T1,W.BLK+.FXDIR	;STORE AS DIRECTORY		[154]
		MOVE	T2,W.BLK+.FXNMM	;GET NAME MASK		[154]
		MOVEM	T2,W.BLK+.FXDIM	;STORE AS DIRECTORY MASK	[154]
		JRST	.+1]		;THEN PROCEED			[154]
	MOVEI	T1,W.BLK+.FXDIR	;GET UFD NUMBER
	TLO	T1,2		;INDICATE DOUBLE WORD PATH
	PUSHJ	P,.TDIRB##	;AND LIST IT
UFDLS9:	POP	P,T2		;RESTORE THOSE ACS
	POP	P,T3		; ..
	POPJ	P,		;AND RETURN
;STRERR -- OUTPUT MESSAGE AND STRUCTURE NAME
;CALL:	MOVEI	T1,MESSAGE
;	PUSHJ	P,STRERR
;USES T1

STRERR:	PUSHJ	P,.TSTRG##	;OUTPUT MESSAGE
	MOVEI	T1,[ASCIZ / on /]
STRER1:	PUSHJ	P,.TSTRG##	;OUTPUT IDENTIFICATION
TYPSTR:	SKIPN	T1,LASSTR	;GET LAST REFERENCED DEVICE/STRUCTURE
	MOVE	T1,W.BLK+.FXDEV	;GET DEVICE NAME
TYPST1:	PUSH	P,T2		;SAVE AC
	PUSHJ	P,.TSIXN	;OUTPUT IT
	POP	P,T2		;RESTORE AC
	PJRST	.TCOLN##	; ..



;WLDWRN -- ISSUE WARNING PREFIX
;WLDERR -- ISSUE ERROR PREFIX
;CALL:	MOVSI	T1,ERROR CODE IN SIXBIT
;	HRRI	T1,0 OR ADDRESS OF ASCIZ MESSAGE
;	PUSHJ	P,WLDWRN/WLDERR
;NON-SKIPS IF REST OF LINE TO BE DISCARDED
;USES T1-T3

WLDWRN:	TDZA	T2,T2		;GO FOR WARNING
WLDERR:	MOVEI	T2,"?"-"%"	;GO FOR ERROR
	ADDI	T2,"%"		;CONVERT TO RIGHT TEXT
	HRLZS	T2		;POSITION ERROR INDICATOR
	HRR	T2,T1		;MOVE TEXT POINTER
	HLRZS	T1		;POSITION ERROR CODE
	HRLI	T1,'WLD'	;INDICATE FROM WILD
	HRRZ	T3,(P)		;GET ADDRESS+1 OF CALL
	SUBI	T3,2		;BACKUP TO E$$ POINT
	PUSH	P,T4		;PRESERVE T4
	PUSHJ	P,.ERMSA##	;ISSUE ERROR PREFIX
	POP	P,T4		;RESTORE T4
	TXNE	T1,JWW.FL	;SEE IF /MESSAGE:FIRST
	AOS	(P)		;YES--INDICATE TO DO REST OF LINE
	POPJ	P,		;RETURN
	SUBTTL	SEARCH LIST TRANSLATION LOGIC

;WSTRI  --  INITIALIZE FOR CALLS TO WSTRN
;CALL IS:
;
;	MOVX	T1,<FSB>
;	PUSHJ	P,.WSTRI
;	 ERROR
;	NORMAL RETURN
;
;WHERE <FSB> IS THE ADDRESS OF THE INPUT FILE SPEC BLOCK CONTAINING THE
;FILE SPECIFICATION AS TYPED BY THE USER.
;
;THE ERROR RETURN IS NOT USED.
;
;ON NORMAL RETURN, THE CALLER MAY CALL WSTRN REPEATITIVELY READING THE
;FILE "SEARCH LIST".
;
;USES T2.

.WSTRI::SETZM	WSBZM		;CLEAR START OF TO-BE-CLEARED AREA
	MOVE	T2,[WSBZM,,WSBZM+1]  ;BLT POINTER TO
	BLT	T2,WSEZM-1	;CLEAR TO-BE-CLEARED AREA
	MOVEM	T1,WSISB	;ADDRESS OF INPUT SCAN BLOCK
	JRST	.POPJ1##	;SUCCESSFUL RETURN
;WSTRN  --  READ NEXT DEVICE "SEARCH LIST" FROM USER-SPECIFICATION
;CALL IS:
;
;	MOVX	T1,<FSB>
;	PUSHJ	P,.WSTRC/.WSTRN
;	 EMPTY RETURN
;	NORMAL RETURN
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPEC BLOCK TO RECEIVE THE
;NEXT INPUT FILE SPECIFICATION "SEARCH LIST".
;
;ON EMPTY RETURN THE INPUT SPECIFICATION HAS BEEN EXHAUSTED.
;
;ON NORMAL RETURN THE INPUT FILE SPECIFICATION (AS SET BY CALL TO WSTRI)
;"EXPANSION" IS SET IN THE GIVEN FILE SPEC BLOCK.
;
;THE FOLLOWING LOCAL VARIABLES ARE ALSO SETUP:
;
;	FRCDEV		FORCED DEVICE (IF ANY) TO USE, /PHYSICAL ONLY
;	FRCPPN		FORCED OVERRIDING PPN TO USE (SFDS OK)
;
;	PLNNOD		PATHOLOGICAL NAME NODE SPEC
;	PLNDEV		PATHOLOGICAL NAME DEVICE
;	PLNPTH		PATHOLOGICAL NAME FILE PATH
;	PLNNAM		PATHOLOGICAL NAME FILE NAME
;	PLNEXT		PATHOLOGICAL NAME FILE TYPE
;
;	SRCH		FANCY SEARCHING LOGIC IN EFFECT (FOR ERROR MSGS)
;
;IF THE SELECTED FILE SPECIFICATION IS TO A REMOTE NETWORK FILE
;SYSTEM THEN T2 WILL RETURN 0. IF THE SELECTED FILE SPECIFICATION
;IS A LOCAL FILE THEN THE DEVCHR OF THE DEVICE TO USE IS IN T2.
;IF THE DEVICE IS NUL:, THE DEVCHR BITS DON'T SHOW DV.DSK, DV.MTA,
;ETC. (I.E., YOU CAN TRUST THE DEVCHR RESULTS). IF FRCDEV IS NON-ZERO,
;THEN THE DEVICE SHOULD BE USED PHYSICAL ONLY.
;
;WSTRN IS THE "PRIMARY" CALLING POINT, AND WILL ALWAYS TRY TO FILL
;OUT BLANK FIELDS WITH A DEFAULT (DEVICE GETS "DSK"; DIRECTORY GETS "[-]";
;ANY PATHOLOGICAL NAME DEFAULTS ARE APPLIED, ETC.).
;
;WSTRC IS THE "SECONDARY" CALLING POINT (USED BY CHKTST) WHICH WILL NOT
;FILL OUT BLANK FIELDS. NODE AND DEVICE WILDCARDS ARE SIMPLY PASSED BACK
;DIRECTLY TO THE CALLER. IF AN EXPLICIT NON-WILD DEVICE IS SPECIFIED
;THEN ANY PATHOLOGICAL NAME DEFAULTS WILL BE APPLIED TO BLANK FIELDS.
;
;USES T1 - T4.
.WSTRN::TDZA	T4,T4		;FLAG NORMAL DEFAULTING
.WSTRC::SETO	T4,		;FLAG LEAVE BLANK FIELDS BLANK
	MOVEM	T4,WSBLDF	;REMEMBER FLAG
	PUSHJ	P,.SAVE4##	;NEED LOTS OF ACS
	MOVEM	T1,WSRSB	;REMEMBER RETURNED FILE SPEC BLOCK
	MOVE	T4,T1		;CONCOCT A
	HRL	T4,WSISB	;BLT POINTER TO
	BLT	T4,.FXLEN-1(T1)	;INITIALIZE RETURNED FILE SPEC BLOCK

;NOW DISPATCH ON LAST STATE

	SKIPN	P4,WSTRST	;GET LAST STATE
	JRST	WSTRN2		;FIRST TIME, INITIALIZE
	AOS	(P4)		;SKIP TO INDICATE CONTINUE
	POPJ	P4,		;DISPATCH ON STATE

WSTRN2:	MOVE	P4,WSTPDP	;INITIALIZE WSTR STATE/STACK
	PUSHJ	P4,WNOD		;START UNRAVELING THIS SPECIFICATION
	 JFCL			;HMMM
	SETZB	T1,WSTRST	;ALL DONE HERE
	POPJ	P,		;RETURN EXHAUSTED
;WRTN  --  RETURN REMOTE NETWORK FILE SERVICE SPECIFICATION TO CALLER
;CALL IS:
;
;	MOVX	T1,<NOD>
;	PUSHJ	P4,WRTN
;	 ERROR
;	NORMAL
;
;WHERE <NOD> IS THE NAME OF THE REMOTE NETWORK NODE WHICH IS BEING
;REFERENCED BY THE CURRENT FILE "SEARCH LIST".
;
;ON ERROR, ABORT FURTHER CALLS
;
;ON NORMAL RETURN, KEEP EXPANDING AND RETURNING FILE SEARCH LISTS
;VIA WRTN AND/OR WRTD.
;
;NOTE THAT THE NORMAL RETURN IS EXERCISED BY THE CALLER CALLING WSTRN
;FOR THE NEXT SEARCH LIST . . .
;
;USES T1 - P4.

WRTN:	MOVEM	P4,WSTRST	;SET NEW "STATE"
	MOVE	P1,WSRSB	;ADDRESS OF RETURNED FILE SPEC BLOCK
	SETO	T2,		;INDICATE NO WILDCARDS IN NODE NAME
	DMOVEM	T1,.FXNOD(P1)	;SET REMOTE NODE NAME
	MOVX	T1,FX.WND	;THE WILDCARDS-IN-NODE FLAG
	ANDCAM	T1,.FXFLD(P1)	;CLEAR IN FIELDS CONTROL
	SETZM	DVCH		;NO DEVICE CHARACTERISTICS HERE!
	SKIPN	PLNPD		;CALLED FROM PATHOLOGICAL NAME?
	JRST	WRTRT		;NO, RETURN TO WSTRN CALLER
	MOVE	T1,PLNDEV	;YES, GET DEVICE FROM PATHOLOGICAL EXPANSION
	JRST	WRTDV7		;AND SET FILE SPECIFICATION COMPONET DEFAULTS
;WRTD  --  RETURN NEXT LOCAL DEVICE/DIRECTORY TO CALLER
;CALL IS:
;
;	MOVX	T1,<DEV>
;	PUSHJ	P4,WRTD
;	 ERROR
;	NORMAL
;
;WHERE <DEV> IS THE SIXBIT PHYSICAL DEVICE FOR THE CALLER TO USE.
;
;ON ERROR, ABORT FURTHER CALLS
;
;ON NORMAL RETURN, KEEP EXPANDING AND RETURNING DEVICES VIA WRTD.
;
;NOTE THAT THE NORMAL RETURN IS EXERCISED BY THE CALLER CALLING WSTRN
;FOR THE NEXTFILE SEARCH LIST . . .
;
;WRTD/WRFD SETUP THE FOLLOWING INFORMATION:
;
;	LASSTR		;DEVICE NAME TO USE
;	FRCDEV		;FORCED DEVICE (USE /PHYSICAL, WILL MATCH LASSTR)
;	FRCPPN		;FORCED PPN (WILL MATCH FIRST WORD OF DIRNAM)
;	SRCH		;.NE. 0 IF "FANCY DEVICE LOGIC" (FOR ERROR MESSAGES)
;
;USES T1 - P4

WRFD:	MOVEM	T1,FRCDEV	;SET FORCING DEVICE
WRTD:	MOVEM	P4,WSTRST	;SAVE STATE VARIABLE
	MOVE	P1,WSRSB	;SET ADDRESS OF RETURNED FILE SPEC BLOCK
	SETZM	.FXNOD(P1)	;LOCAL = NO NODE SPECIFIED
	SKIPN	FRCDEV		;FORCED DEVICE?
	TDZA	T3,T3		;NO, NORMAL LOGICAL (???)
	MOVX	T3,FX.PHY	;YES, PHYSICAL ONLY
	IORM	T3,.FXMOD(P1)	;INDICATE ACCORDINGLY IN MODS WORD
	LSH	T3,<^L<FX.PHY>-^L<UU.PHY>>  ;CONVERT FSB /PHY INTO UUO /PHY
	MOVE	T2,T1		;POSITION DEVICE FOR DEVCHR
	DEVCHR	T2,(T3)		;READ DEVICE CHARACTERISTICS
	TXC	T2,DV.DSK!DV.MTA;TRIED AND TRUE
	TXCN	T2,DV.DSK!DV.MTA; TEST FOR NUL:
	TXZ	T2,DVCNUL	;CLEAR NON-NUL: BITS
	MOVEM	T1,LASSTR	;REMEMBER LAST DEVICE
	MOVEM	T2,DVCH		;AND ITS DEVCHR BITS
WRTDV7:	SETO	T2,		;NON-WILD DEVICE MASK
	DMOVEM	T1,.FXDEV(P1)	;SET DEVICE SPEC IN FILE SPEC BLOCK
	MOVX	T1,FX.WND!FX.WDV;THE WILDCARDS-IN-NODE/DEVICE FLAGS
	ANDCAM	T1,.FXFLD(P1)	;CLEAR IN THE RETURNED FILE SPEC BLOCK
	SKIPN	.WLDFL		;/NOSTRS PENDING?
	JRST	WRTRT		;YES, RETURN NOW, NO MONKEYING AROUND

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO SETUP THE DIRECTORY PATH SPECIFICATION TO BE SEARCHED
; (DO I NEED TO CHECK FOR FX.DPT HERE?)

WRTDP:	MOVE	P1,WSRSB	;RESTORE ADDRESS OF FILE SPEC BLOCK
	SKIPE	PLNOVR		;GOT OVERRIDING PATHOLOGICAL COMPONETS?
	SKIPN	PLNPTH		;YES, IS DIRECTORY SPECIFIED?
	SKIPA			;NO TO ONE OF THE ABOVE, DON'T OVERRIDE USER
	JRST	WRTDP1		;PATHOLOGICAL DIRECTORY OVERRIDES USER SPEC
	MOVE	T4,.FXFLD(P1)	;GET FIELDS CONTROL
	SKIPN	T1,AGOBOP	;GET ON-BEHALF-OF PPN (IF ANY)
	MOVE	T1,.MYPPN##	;NONE, USE LOGGED-IN PPN
	TXNE	T4,FX.DPJ	;DEFAULT PROJECT ("[,")?
	HLLM	T1,.FXDIR(P1)	;YO
	TXNE	T4,FX.DPG	;DEFAULT PROGRAMMER (",]")?
	HRRM	T1,.FXDIR(P1)	;YO AGAIN
	TXNE	T4,FX.DPN	;DID USER TYPE "[]" (EXPLICIT NO DIRECTORY)?
	JRST	[SETZM	.FXDIR(P1)	;YES
		MOVSI	T1,.FXDIR(P1)	;CONCOCT A
		HRRI	T1,.FXDIR+1(P1)	; BLT POINTER TO
		BLT	T1,.FXDIR+<2*.FXLND>-1  ;SELECT NO DIRECTORY
		JRST	.+1]		;NOW CHECK FOR DIRECTORY DEFAULTING
	SKIPE	T1,.FXDIR(P1)	;GOT A DIRECTORY PATH YET?
	JRST	WRTDP5		;YES, JUST CHECK IT OUT

;NO DIRECTORY GIVEN, GENERATE A DEFAULT

	SKIPE	WSBLDF		;IF WANT BLANK FIELD LEFT ALONE
	SKIPE	PLNPTH		;AND NO PATHOLOGICAL NAME PATH
	CAIA			;(NO)
	JRST	WRTDP5		;THEN LEAVE ALONE HERE

;WANT SOME SORT OF PATH SUPPLIED

	SKIPN	T4,PLNPTH	;GOT A PATHOLOGICAL NAME DEFAULT?
	TROA	T4,.MYPTH##+.PTPPN  ;NO, USE JOB'S DEFAULT PATH
WRTDP1:	MOVEI	T4,PLNPTH	;YES, USE PATHOLOGICAL EXPANSION
	MOVS	T1,.FXEXT(P1)	;GET FILE TYPE (IF ANY)
	SKIPE	PLNOVR		;GOT OVERRIDING PATHOLOGICAL COMPONETS?
	SKIPN	PLNEXT		;YES, GOT AN EXTENSION?
	TLCA	T1,-1		;USE USER SPEC, LH:=0 IF NO WILDCARDS
	HLRZ	T1,PLNEXT	;PATHOLOGICAL EXTENSION OVERRIDES USER SPEC
	CAIE	T1,'UFD'	;IF "USER-FILE-DIRECTORY"
	SKIPE	FRCPPN		;OR FORCED PPN PENDING
	MOVEI	T4,DEFZRO	;YES, THEN PATH SELECTED ACCORDINGLY
WRTDP2:	SETO	T2,		;FLAG NO WILDCARDS
	MOVE	T3,P1		;ADDRESS TO BUILD FILE SPEC BIWORDS
	HRLI	T4,-.FXLND	;LENGTH OF DIRECTORY ENTRIES
WRTDP3:	SKIPN	T1,(T4)		;NEXT DIRECTORY ENTRY
	SETZ	T2,		;END OF PATH
	CAIN	T2,0		;AT OR PAST END OF PATH?
	SETZ	T1,		;YES
	DMOVEM	T1,.FXDIR(T3)	;SET THIS DIRECTORY LEVEL IN RETURNED FSB
	ADDI	T3,2		;ADVANCE TO NEXT BI-WORD
	AOBJN	T4,WRTDP3	;LOOP FOR ENTIRE DIRECTORY
;	JRST	WRTDP6		;CHECK PPN CONSTRAINTS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;FLESH OUT ANY REMAINING DEFAULTS AND PPN CONSTRAINTS

WRTDP5:	DMOVE	T1,.FXDIR(P1)	;GET PPN

;CHECK FOR A UFD (WHICH USUALLY BELONGS TO [1,1]

	MOVS	T3,.FXEXT(P1)	;GET FILE TYPE (IF ANY)
	TLC	T3,-1		;LH:=0 IF NO WILDCARDS
	CAIN	T3,'UFD'	;IS IT A USER-FILE-DIRECTORY?
	JUMPE	T1,[SKIPE WSBLDF	;WANT BLANKS LEFT ALONE?
		JRST	.+1		;YES, JUST IGNORE
		MOVE	T1,.PPMFD##	;SUPPLY DEFAULT DIRECTORY FOR UFD
		SETO	T2,		;MARK IT NON-WILD
		JRST	.+1]		;AND CONTINUE

;CHECK FOR ANY "DEFERRED" DEFAULTS

	PUSHJ	P,WRTDPP	;HANDLE ANY PPN DEFAULTS

;LAST OF ALL CHECK FOR OVERRIDING PPN

	SKIPE	FRCPPN		;GOT A FORCING PPN PENDING?
	JRST	[MOVE	T1,FRCPPN	;YES, GET OVER-RIDING PPN
		SETO	T2,		;MARK IT NON-WILD
		JRST	.+1]		;AND CONTINUE
	DMOVEM	T1,.FXDIR(P1)	;SET TOP-LEVEL DIRECTORY SPECIFICATION

;CHECK OUT THE REST OF THE SUB-DIRECTORIES

WRTDP7:	SETO	T2,		;FLAG ALL DEFAULTS NON-WILD
	MOVEI	T4,.FXDIR+2(P1)	;ADDRESS OF RETURNED SFD SPECS
	HRLI	T4,-<.FXLND-1>	;MAX SFD'S POSSIBLE
WRTDP8:	SKIPN	T1,(T4)		;GOT A NAME AT THIS LEVEL?
	SETZ	T2,		;NO, END OF DIRECTORY SPECIFICATION
	CAIN	T2,0		;HIT END OF PATH YET?
	TDZA	T1,T1		;YES
	CAIA	T1,0		;IF END OF PATH
	DMOVEM	T1,(T4)		;CLEAR REST OF PATH BLOCK
	ADDI	T4,1		;ADVANCE ONE BI-WORD
	AOBJN	T4,WRTDP8	;LOOP FOR REST OF DIRECTORY
	JRST	WRTDN		;CHECK OUT NAME
;HELPER ROUTINE TO EXPAND PPN DEFAULTS

WRTDPP:	SKIPE	WSBLDF		;WANT TO LEAVE BLANK FIELD ALONE?
	POPJ	P,		;YES

;CHECK PROJECT DEFAULTS

	TLNN	T1,-1		;NO PROJECT AT ALL?
	JRST	[HLL	T1,.MYPPN##	;YES, GET LOGGED-IN PROJECT
		TLO	T2,-1		;MARK IT NON-WILD
		JRST	.+1]		;AND CONTINUE

;CHECK PROGRAMMER DEFAULTS

	TRNN	T1,-1		;OR NO PROGRAMER AT ALL?
	JRST	[HRR	T1,.MYPPN##	;YES, GET LOGGED-IN PROGRAMMER
		TRO	T2,-1		;MARK IT NON-WILD
		JRST	.+1]		;AND CONTINUE

	POPJ	P,		;RETURN WITH PPN IN T1, MASK IN T2
;CHECK DEFAULT NAME AND TYPE (EXTENSION) FIELDS

WRTDN:	MOVE	T1,.FXFLD(P1)	;GET FIELDS FLAGS
	SKIPE	PLNOVR		;PATHOLOGICAL COMPONETS OVERRIDING?
	SKIPN	PLNNAM		;YES, GOT A NAME?
	SKIPA			;NO, TREAT USER NAME NORMALLY
	JRST	WRTDN1		;PATHOLOGICAL NAME OVERRIDES USER SPEC
	TXNN	T1,FX.DNP	;IS NAME IN PPN FORMAT?
	JRST	WRTDN1		;NO - NORMAL ALPHA CASE THEN
	DMOVE	T1,.FXNAM(P1)	;YES, GET NAME AND RELATED MASK
	PUSHJ	P,WRTDPP	;LOOK FOR ANY PPN DEFAULTS ("[,]" ETC.)
	DMOVEM	T1,.FXNAM(P1)	;AND SET BACK THE RESULTS
	AOJE	T2,WRTDN2	;NOTE IF NO WILDCARDS
	JRST	WRTDN3		;CHECK FILE TYPE

WRTDN1:	SKIPN	PLNOVR		;FORCE PATHOLOGICAL NAME IF OVERRIDING
	SKIPN	.FXNAM(P1)	;GOT A NAME?
	SKIPN	T1,PLNNAM	;NO, GOT A DEFAULT NAME?
	JRST	WRTDN3		;NO DEFAULT NAME USED HERE
	SETO	T2,		;YES, INDICATE NON-WILD
	DMOVEM	T1,.FXNAM(P1)	;RETURN DEFAULT NAME
WRTDN2:	MOVX	T1,FX.WNM	;THE WILDCARDS-IN-NAME FLAG
	ANDCAM	T1,.FXFLD(P1)	;NO WILDCARDS THERE

;CHECK EXTENSION

WRTDN3:	SKIPN	PLNOVR		;FORCE PATHOLOGICAL EXTENSION IF OVERRIDING
	SKIPN	.FXEXT(P1)	;GOT AN EXTENSION?
	SKIPN	T1,PLNEXT	;NO, GOT A DEFAULT EXTENSION?
	JRST	WRTDN6		;NO DEFAULT EXTENSION USED HERE
	TRO	T1,-1		;YES, INDICATE NON-WILD
	MOVEM	T1,.FXEXT(P1)	;RETURN DEFAULT EXTENSION
	MOVX	T1,FX.WEX	;THE WILDCARDS-IN-EXTENSION FLAG
	ANDCAM	T1,.FXFLD(P1)	;NO WILDCARDS THERE

;CHECK GENERATION (?)

WRTDN6:

;RETURN FILE "SEARCH LIST" TO WSTRN'S CALLER

WRTRT:	MOVE	T1,WSRSB	;ADDRESS OF RETURNED FILE SPEC BLOCK (G.P.S)
	MOVE	T2,DVCH		;DEVCHR BITS (IF ANY)
	JRST	.POPJ1##	;SUCCESSFUL RETURN TO WSTRN CALL
;WNOD  --  EXPAND FILE SPECIFICATION INTO NODE-SPECIFIC SEARCH LIST
;CALL IS:
;
;	MOVX	P1,<FSB>
;	PUSHJ	P4,WNOD
;	 ABORT
;	NORMAL
;
;WHERE <FSB> IS THE ADDRESS OF THE FILE SPECIFICATION BLOCK TO BE "EXPANDED"
;INTO MULTIPLE FILE "SEARCH LISTS"
;
;ON ABORT RETURN SOMETHING BAD HAPPENED
;
;ON NORMAL RETURN THE INPUT FILE SPECIFICATION HAS BEEN EXHAUSTED SUCCESSFULLY.
;
;USES T1 - P3.

WNOD:	MOVE	P1,WSISB	;SELECT INPUT FILE SPECIFICATION
	SKIPE	WSBLDF		;WANT NODES RETURNED ONE-AT-A-TIME?
	JRST	WNOD2		;NO
	MOVE	T1,.FXFLD(P1)	;FIELDS WORD
	TXNE	T1,FX.WND	;NODE WILDCARDS PRESENT?
	JRST	WNANF		;YES, REQUIRES SOME WORK HERE
	SKIPN	T3,.FXNOD(P1)	;NO, ANY NODE SPEC PRESENT?
	JRST	WNOD2		;NO, ASSUME LOCAL FILE SERVICE
	PUSHJ	P,.NDNAM##	;TRY TO FORCE TO FULL NAME
	CAME	T1,.MYNOD##	;LOCAL OR REMOTE FILE SERVICE?
	PJRST	WRTN		;REMOTE, NOTHING MORE WE CAN DO HERE

;LOCAL FILE SERVICE SELECTED, EITHER IMPLICITLY OR EXPLICITLY

WNOD2:	MOVE	P1,WSISB	;SELECT INPUT FILE SPEC BLOCK
	DMOVE	T1,.FXDEV(P1)	;GET DEVICE AND WILDCARDS
	MOVE	T3,.FXMOD(P1)	;GET DEVICE MODS (/PHYSICAL, ETC.)
	PJRST	WDEV		;GO HANDLE DEVICE SELECTION
;CHECK OUT POTENTIAL WILDCARDED NETWORK NODE MATCH
;CALL IS:
;
;	MOVE	T1,<NOD>
;	PUSHJ	P4,WNODW
;	 ABORT
;	NORMAL
;
;WHERE <NOD> IS THE NAME OF THE NODE TO BE CHECKED AGAINST THE USER-
;SPECIFIED NODE NAME SPECIFICATION.
;
;IF THE NODE NAME MATCHES IT IS PROCESSED.
;
;ON ABORT RETURN THE CALLER SHOULD IN TURN ABORT.
;
;ON NORMAL RETURN THE CALLER SHOULD ADVANCE TO THE NEXT NODE IN
;THE LIST AND GIVE IT IN TURN TO WNODW.

WNODW:	MOVE	P1,WSISB	;SELECT INPUT FILE SPEC BLOCK
	MOVE	T2,T1		;COPY OF NAME
	XOR	T2,.FXNOD(P1)	;COMPARE AND
	AND	T2,.FXNOM(P1)	;CONTRAST WITH FILE SPECIFICATION
	JUMPN	T2,P4P0J1	;JUST SKIP THIS ONE IF IT DOESN'T MATCH SPECS
	CAMN	T1,.MYNOD##	;THIS NODE IS ACCEPTABLE, LOCAL OR REMOTE?
	JRST	[MOVEM	T1,-2(P4)	;LOCAL NODE, FLAG SPECIAL
		JRST	P4P0J1]		;MORE WORK REQUIRED
	PUSHJ	P4,WRTN		;REMOTE, DEFER TO NETWORK FILE SERVICE
	 POPJ	P4,		;OOPS - ABORT
	JRST	P4P0J1		;TRY FOR ANOTHER NODE
;HERE FOR NODE WILDCARDS - ANF-10 NETWORK

WNANF:	PUSH	P4,[0]		;LOCAL-NODE-MATCHED FLAG
	PUSH	P4,[0]		;OUR COUNTER/INDEX
WNANF1:	AOS	T3,(P4)		;ADVANCE TO NEXT NODE SLOT
	CAILE	T3,377		;EXHAUSTED ALL POSSIBLE NODES YET?
	JRST	WNANF7		;YEAH, NOW TRY FOR DECNET.
	SETZ	P2,		;NO KNOWN NODE
	PUSHJ	P,.NDNAM##	;CONVERT NODE NUMBER INTO AN ANF-10 NAME
	JUMPLE	T2,WNANF1	;NO SUCH ANF-10 NODE, TRY THE NEXT NUMBER
	PUSHJ	P4,WNODW	;KRUNCH ON POSSIBLE NODE
	 JRST	P4P2J0		;OOPS - ABORT
	JRST	WNANF1		;LOOP BACK FOR THE NEXT NODE

WNANF7:				;FALL INTO WNDCN . . .



;HERE FOR NODE WILDCARDS - DECNET-10 NETWORK

WNDCN:	SETZM	0(P4)		;INITIALIZE NODE SEARCH
WNDCN1:	MOVE	T3,0(P4)	;FETCH LAST NODE VALUE
	MOVE	T2,[DN.FLS!DN.FLR+<.DNNDI,,2>]  ;STEP REACHABLE NODES
	MOVEI	T1,T2		;DNET. ARG POINTER TO
	DNET.	T1,		;READ NEXT DECNET NODE NAME
	 JRST	WNDCN7		;ERROR? ABORT DECNET NODE SEARCH
	JUMPE	T3,WNDCN7	;END OF LIST, ABORT DECNET NODE SEARCH
	MOVEM	T3,0(P4)	;REMEMBER THIS NODE FOR NEXT TIME
	MOVE	T1,T3		;POSITION NODE NAME
	PUSHJ	P4,WNODW	;SEE IF THIS NODE IS INTERESTING
	 JRST	P4P2J0		;OOPS - ABORT
	JRST	WNDCN1		;LOOP BACK FOR THE NEXT NODE

WNDCN7:	POP	P4,T3		;PITCH EXHAUSTED NODE COUNTER
	POP	P4,T3		;RETRIEVE LOCAL-NODE-MATCHED FLAG
	JUMPE	T3,P4P0J1	;IF DIDN'T MATCH LOCAL, ALL DONE
	PJRST	WNOD2		;FINISH OFF WITH LOCAL NODE MATCH
;WDEV  --  EXPAND LOGICAL DEVICE INTO PHYSICAL DEVICE/PATH/ETC.
;CALL IS:
;
;	MOVX	T1,<DEVICE>
;	MOVX	T2,<MASK>
;	MOVX	T3,<MODS>
;	PUSHJ	P4,WDEV
;	 ABORT
;	NORMAL
;
;WHERE <DEVICE> IS THE DEVICE NAME TO BE EXPANDED INTO A LIST OF PHYSICAL
;DEVICE NAMES, ASSOCIATED PATHS, ETC.; <MASK> IS THE WILDCARD MASK ASSO-
;CIATED WITH THE DEVICE (-1 = NO WILDCARDS); AND <MODS> ARE ANY MODIFIERS
;FOR THE DEVICE (/PHYSICAL, /DSKONLY, ETC.).
;
;ON ABORT RETURN AN ERROR HAS OCCURED.
;
;ON NORMAL RETURN THE DEVICE HAS BEEN EXPANDED SUCCESSFULLY AND RETURNED
;TO THE CALLER (OF WSTRN).
;
;USES T1 - P3.

WDEV:	SETZM	FRCDEV		;CLEAR FORCED DEVICE
	SETZM	FRCPPN		; AND FORCED PPN FLAGS
	SETOM	SRCH		;ASSUME FANCY DISK LOGIC (FOR ERROR MSGS)
	CAIN	T1,0		;GOT A DEVICE SPECIFIED?
	SKIPA	T1,['DSK   ']	;NO, DEFAULT TO "DSK:"
	AOJN	T2,WWCD		;HANDLE WILDCARDS DIFFERENTLY
	MOVE	P1,T1		;SAVE DEVICE IN P1
	MOVE	P2,T3		;AND ITS MODIFIERS IN P2
	SKIPN	.WLDFL		;IS THIS A /NOSTRS CALL?
	JRST	WDEV80		;YES, JUST PASS DEVICE STRAIGHT THROUGH
	TXNE	P2,FX.PHY	;PHYSICAL ONLY?
	JRST	WDEV51		;YES, CAN'T BE PATHOLOGICAL IN NATURE THEN

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;TRY TO EXPAND THE DEVICE AS A PATHOLOGICAL NAME FIRST

WDEV20:	SKIPN	T1,PLNPD	;NESTED PATHOLOGICAL?
	JRST	WDEV23		;NO, TOP LEVEL
	HRRZI	T1,-PLNPD(T1)	;NESTING LEVEL (*2)
	SUBI	T1,1		; (TWO WORD ENTRIES ON THE STACK)
	CAME	P1,PLNPD(T1)	;HAVE WE EXPANDED THIS NAME ALREADY?
	SOJG	T1,.-2		;NO, CHECK REST OF STACK
	JUMPG	T1,WDEV50	;TREAT /PHYSICAL IF ALREADY EXPANDED ONCE

;HERE TO TRY TO EXPAND AS A PATHOLOGICAL NAME SINCE IT HAS NOT YET BEEN
;EXPANDED.

WDEV23:	SKIPN	T1,PLNPD	;PATHOLOGICAL NAME STACK POINTER
	MOVE	T1,PLNPDP	;FIRST TIME, INITIALIZE POINTER
	PUSH	T1,P1		;SAVE THIS NAME AS THE NEW CURRENT ONE
	PUSH	T1,[0]		;INITIALIZE INDEX INTO CURRENT NAME
	MOVX	T2,.PTFRN	;READ LOGICAL NAME FUNCTION
	MOVEM	T2,PLNBL+.PTFCN	;SET IN PATH. FUNCTION WORD
	MOVX	T2,PT.RCN	;RETURN INFORMATION FLAG
	MOVEM	T2,PLNBL+.PTLNF	;SET IN PATH. FLAGS WORD
	MOVEM	P1,PLNBL+.PTLNM	;SET NAME IN NAME WORD
	MOVE	T2,[.PTLLB,,PLNBL]  ;PATH. ARG POINTER TO
	PATH.	T2,		;READ PATHOLOGICAL NAME INFORMATION
	 JRST	WDEV51		;NOT A PATHOLOGICAL DEVICE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO LOOP OVER EACH NAME COMPONET EXPANDING EACH IN ITS TURN TO RETURN
;TO THE CALLER (WSTRN) A LIST OF PHYSICAL NAMES.

WDEV30:	MOVEM	T1,PLNPD	;SET NEW STATE/NESTER
	HRRZI	T1,-PLNPD(T1)	;CALCULATE NESTING DEPTH
	CAILE	T1,<PLN$MX*2>	;WITHIN ARBITRARY LIMITS?
	 ERROR	PNO,<Pathological name stack overflow on >,,WDEV3F,P4P0J0
WDEV33:	SKIPN	T1,PLNPD	;ADDRESS OF CURRENT INDEX
	 HALT	P4P0J0		;BETTER NOT HAPPEN
	AOSG	PLNZAP		;DID WE GET ZAPPED SOMEWHERE?
	JRST	WDEV44		;YES, MUST GO RE-READ NAME FIRST
	MOVE	T2,PLNBL+.PTLNF	;FETCH THE PATHOLOGICAL NAME FLAGS WORD
	TXNN	T2,PT.OVR	;WANT TO OVERRIDE THE LOOKUP BLOCK DIR/NAM/EXT?
	TDZA	P3,P3		;NO
	SETO	P3,		;YES
	MOVEM	P3,PLNOVR	;SET OVERRIDE FLAG ACCORDINGLY
	MOVE	P3,(T1)		;CURRENT INDEX INTO PLNBL NAME BLOCK
	SKIPN	T1,PLNBL+.PTLSB+.PTLSL(P3)  ;COMPONET DEVICE (SEARCH LIST)
	JRST	WDEV40		;NULL, ALL DONE WITH THIS PATHOLOGICAL DEVICE
	MOVEM	T1,PLNDEV	;HANG ON TO IT FOR A BIT
	MOVE	T1,PLNBL+.PTLSB+.PTNOD(P3)  ;COMPONET NODE NAME
	MOVEM	T1,PLNNOD	;SET DEFAULT NODE NAME
	MOVE	T1,PLNBL+.PTLSB+.PTFIL(P3)  ;COMPONET FILE NAME
	MOVEM	T1,PLNNAM	;SET DEFAULT FILE NAME
	MOVE	T1,PLNBL+.PTLSB+.PTEXT(P3)  ;COMPONET FILE TYPE
	HLLZM	T1,PLNEXT	;SET DEFAULT FILE TYPE
	SKIPN	T2,AGOBOP	;GET ON-BEHALF-OF PPN
	MOVE	T2,.MYPPN##	;USE LOGGED-IN PPN
	SETCM	T1,PLNBL+.PTLSB+.PTLPP(P3)  ;GET PPN FIELD (-1 = [,])
	TLCN	T1,-1		;DEFAULT PROJECT?
	HLL	T1,T2		;YES
	TRCN	T1,-1		;DEFAULT PROGRAMMER?
	HRR	T1,T2		;YES
	SKIPA	T2,[IOWD .FXLND+2,PLNPTH]  ;WHERE TO STORE DEFAULT PATH
WDEV35:	MOVE	T1,PLNBL+.PTLSB+.PTLPP(P3)  ;GET PATH COMPONET
	PUSH	T2,T1		;SAVE IN DEFAULT PATH BLOCK
	CAIE	T1,0		;DONE YET?
	AOJA	P3,WDEV35	;NO, LOOP FOR MORE PATH
	ADDI	P3,.PTLPP+1	;UPDATE CURRENT INDEX
	MOVE	T1,PLNPD	;GET PATHOLOGICAL NAME STACK POINTER
	MOVEM	P3,(T1)		;SAVE NEW DEVICE INDEX

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SEE WHAT THIS PARTICULAR NAME COMPONET WANTS TO DO

	SKIPN	T3,PLNNOD	;GOT A DEFAULT NODE NAME HERE?
	JRST	WDEV38		;NO
	CAMN	T3,.MYNOD##	;EXPLICITLY LOCAL?
	JRST	WDEV38		;YES, DO LOCAL FILE SERVICE
	PUSHJ	P,.NDNAM##	;TRY TO MAKE SENSE OUT OF IT
	JUMPLE	T2,WDEV33	;IF UNKNOWN, JUST IGNORE IT
	CAMN	T1,.MYNOD##	;EXPLICITLY LOCAL?
	JRST	WDEV38		;YES - THEN IGNORE IT
	PUSH	P4,P2		;SAVE MODS
	PUSHJ	P4,WRTN		;PROPAGATE REMOTE NODE
	 JFCL			;C'EST LA VIE
	POP	P4,P2		;RESTORE MODS
	JRST	WDEV33		;ADVANCE TO NEXT PATHOLOGICAL NAME COMPONET

;NOW GO EXPAND THIS DEVICE AND SEE WHAT HAPPENS

WDEV38:	MOVE	T1,PLNDEV	;RESTORE DEVICE NAME
	SETO	T2,		;NO WILDCARDS HERE
	MOVE	T3,P2		;KEEP SAME OLD MODS
	PUSH	P4,P2		;AND PRESERVE OURS ACROSS WDEV
	PUSHJ	P4,WDEV		;EXPAND THIS DEVICE
	 JFCL			;IGNORE DEVICE ERRORS
	POP	P4,P2		;RESTORE OUR LAST MODS
	JRST	WDEV33		;AND GET NEXT PATHOLOGICAL NAME COMPONET
;HERE WHEN A PATHOLOGICAL NAME HAS BEEN EXPANDED COMPLETELY

WDEV40:	SETZM	PLNBDF		;CLEAR START OF PATHOLOGICAL NAME "DEFAULTS"
	MOVE	T1,[PLNBDF,,PLNBDF+1]  ;BLT POINTER TO
	BLT	T1,PLNEDF-1	;CLEAR PATHOLOGICAL NAME "DEFAULTS"
	MOVE	T1,PLNPD	;GET CURRENT STACK POINTER
	POP	T1,T2		;UNSTACK THIS INDEX
	POP	T1,T2		;AND ITS NAME
	MOVEM	T1,PLNPD	;SAVE NEW PREVIOUS POINTER
	ANDI	T1,-1		;JUST THE ADDRESS
	CAIG	T1,PLNPD	;STILL NESTED?
	SETZB	T1,PLNPD	;NO
	JUMPE	T1,P4P0J1	;IF ALL DONE, RETURN SUCCESSFULLY
	SETOM	PLNZAP		;STILL NESTED, TELL WDEV33 TO RE-READ NAME
	JRST	P4P0J1		;SUCCESFUL RETURN TO WDEV38


;UNSTACK THE PREVIOUS PATHOLOGICAL NAME (ALSO ENTER HERE TO RE-READ
;A ZAPPED (BY SAVWS) CURRENT PATHOLOGICAL NAME EXPANSION)

WDEV44:	MOVX	T2,.PTFRN	;READ FUNCTION
	MOVEM	T2,PLNBL+.PTFCN	;SET IN FUNCTION WORD
	MOVX	T2,PT.RCN	;RETURN NAMES FLAG
	MOVEM	T2,PLNBL+.PTLNF	;SET IN FLAGS WORD
	MOVE	T2,-1(T1)	;PREVIOUS PATHOLOGICAL NAME
	MOVEM	T2,PLNBL+.PTLNM	;SET IN NAME WORD
	MOVE	T2,[.PTLLB,,PLNBL]  ;PATH. ARG POINTER TO
	PATH.	T2,		;RE-READ PATHOLOGICAL NAME INFO
	 ERROR	PND,<Pathological name dissolved whilst reading >,,WDEV3E,WDEV40
	JRST	WDEV33		;FINISH THIS DEVICE OFF


;ERROR HELPER(S)

WDEV3E:	MOVE	T1,PLNBL+.PTLNM	;GET THE PATHOLOGICAL DEVICE NAME
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
	PJRST	.TCOLN##	;CAP OFF WITH A ":"

WDEV3F:	PUSHJ	P,.SAVE1##	;NEED A PROTECTED AC HERE
	HRRZ	P1,PLNPD	;CURRENT STACK POINTER
	SUBI	P1,PLNPD	;NESTING LEVEL (*2)
	CAIA			;ENTER LOOP
WDEV3G:	PUSHJ	P,.TSTRG##	;TYPE OUT SEPARATING TEXT
	SUBI	P1,1		;(TWO WORD ENTRIES)
	MOVE	T1,PLNPD(P1)	;LATEST DEVICE
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
	PUSHJ	P,.TCOLN##	;AND CAP IT OFF WITH A ":"
	MOVEI	T1,[ASCIZ/ <= /];(>) AND A SEPARATOR
	SOJG	P1,WDEV3G	;LOOP IF NEEDED
	POPJ	P,		;ALL DONE WITH ERROR TEXT
;HERE WHEN NOT A PATHOLOGICAL DEVICE, CHECK FOR ERSATZ ONES

WDEV50:	TXO	P2,FX.PHY	;FORCE /PHYSICAL
WDEV51:	TXNN	P2,FX.PHY	;NEED PHYSICAL ONLY?
	TDZA	P3,P3		;NO
	MOVEI	P3,UU.PHY	;YES
	MOVE	T2,P1		;REFETCH OUR DEVICE
	MOVE	T1,[1,,T2]	;DSKCHR ARG POINTER TO
	DSKCHR	T1,(P3)		;SEE IF CONTROLLER-CLASS
	 SETZ	T1,		;ASSUME NOT
	LDB	T2,[POINTR T1,DC.TYP]  ;GET ARGUMENT TYPE
	CAIE	T2,.DCTCN	;GENERIC CONTROLLER (RP:)?
	CAIN	T2,.DCTCC	;SPECIFIC CONTROLLER (RPA:)?
	JRST	WKCN		;YES, HANDLE
	CAIN	T2,.DCTPU	;SPECIFIC PHYSICAL UNIT (RPA1:)?
	JRST	WKCN		;YES, HANDLE
	CAIN	T2,.DCTAB	;STRUCTURE ABBREVIATION (BL: FOR BLKA:,BLKB:)?
	JRST	WKAB		;YES, HANDLE

;ELIMINATED CONTROLLER/UNIT/ABBREVIATIONS, TRY ERSATZ DEVICE

	MOVEM	P1,PTQBL+.PTFCN	;SET NAME IN PATH QUERY BLOCK
	MOVE	T1,[.PTMAX,,PTQBL]  ;PATH. ARG POINTER TO
	PATH.	T1,(P3)		;QUERY MONITOR ABOUT DEVICE
	 JRST	WDEV60		;MUST NOT BE A DISK
	MOVE	T2,PTQBL+.PTSWT	;GET SSL SWITCHES
	TXNE	T2,PT.DLN	;[1021] IS THIS A PATHOLOGICAL NAME?
	JRST	WDEV58		;[1021] YES, MUST BE ASSIGN LOGICAL NAME THEN
	TXNE	T2,PT.IPP	;IMPLIED PPN (ERSATZ DEVICE)?
	SKIPA	T3,PTQBL+.PTPPN	;YES, GET OVERRIDING PPN
	SETZ	T3,		;NO, NO FORCED PPN
	MOVEM	T3,FRCPPN	;SET FORCED PPN AS NEEDED
	JUMPE	T3,WDEV55	;SKIP SYS: CHECKING IF NOT ERSATZ
	HLRZ	T3,PTQBL+.PTFCN	;GET GENERIC PART OF RESULTANT DEVICE
	CAIN	T3,'SYS'	;"SYS:" ?
	TXNN	T2,PT.NEW	;/NEW ENABLED ALSO?
	CAIA			;NO
	SETOM	FRC14		;YES, FORCE [1,4] AFTER [1,5]
;	CAIE	T3,'OLD'	;"OLD:" ?
;	CAIN	T3,'NEW'	;"NEW:" ?
;	SETOM	FRC14		;YES, THEY FORCE [1,4] ALSO

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW EXPAND SEARCH LIST OF SPECIFIED DEVICE

WDEV55:	LDB	T3,[POINTR T2,PT.SLT]  ;GET DEVICE'S SEARCH LIST
	CAIN	T3,.PTSLA	;ALL SEARCH LIST?
	JRST	WSLA		;YES
	CAIN	T3,.PTSLJ	;JOB SEARCH LIST?
	JRST	WSLJ		;YES
	CAIN	T3,.PTSLS	;SYS SEARCH LIST?
	JRST	WSLS		;YES
	JUMPE	T3,WDEV60	;NO SEARCH LIST, MUST BE ASSIGN LOGICAL NAME
				; OF EITHER AN EXPLICIT DISK STRUCURE (E.G.,
				; DSKA:) OR A RANDOM DEVICE (RDA700:)
	ERROR	UST,<Unknown search list type >,,.+1,WDEV60
	LDB	T1,[POINTR PTQBL+.PTSWT,PT.SLT]  ;REFETCH SEARCH LIST TYPE
	PUSHJ	P,.TOCTW##	;AND LIST IN OCTAL
	MOVEI	T1,[ASCIZ\ for device \]
	PUSHJ	P,.TSTRG##	;SEPARATING TEXT
	MOVE	T1,P1		;GET FUNNY DEVICE
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
	PJRST	.TCOLN##	;AND CAP OFF THE MESSAGE



;[1021] HERE FOR "RANDOM" DEVICE WHICH CLAIMS TO BE PATHOLOGICAL DEVICE -
;[1021] MUST BE ASSIGN LOGICAL NAME FOR A PATHOLOGICAL NAME THEN.

WDEV58:	MOVE	T1,P1		;[1021] PRESUMED LOGICAL NAME
	DEVNAM	T1,		;[1021] TRANSLATE TO PATHOLOGICAL NAME
	 JRST	WDEV80		;[1021] GIVE UP
	MOVE	P1,T1		;[1021] REPOSITION NEW-FOUND DEVICE NAME
	JRST	WDEV20		;[1021] AND RE-TRY PATHOLOGICAL EXPANSION
;DEVICE MUST BE LOGICAL NAME A LA ".ASSIGN DSKC LPT"

WDEV60:	MOVE	T1,P1		;ANOTHER COPY
	DEVNAM	T1,(P3)		;ANOTHER UUO
	 JRST	WDEV80		;ANOTHER DUH?
	MOVEM	T1,DCQBL+.DCNAM	;SET NAME IN DSKCHR BLOCK
	MOVE	T2,[.DCMAX,,DCQBL]  ;DSKCHR ARG POINTER TO
	DSKCHR	T2,UU.PHY	;TRY TO DECIPHER STRUCTURE
	 JRST	WDEV63		;CAN'T - USE DEVNAM RESULTS INSTEAD
	SKIPE	DCQBL+.DCSNM	;GET A STRUCTURE NAME BACK?
	MOVE	T1,DCQBL+.DCSNM	;YES, GET STRUCTURE NAME
WDEV63:	PUSHJ	P4,WRFD		;RETURN DEVICE TO CALLER
	 POPJ	P4,		;DUH?
	JSP	T1,WSLXC	;ANY FUNNIES HANGING AROUND?
	MOVE	T1,FRCDEV	;RESTORE DEVICE TO USE
	JRST	WDEV63		;AND RETURN IT YET AGAIN


;DEVICE IS TOTALLY UNINTELLIGIBLE, JUST RETURN IT AND SEE WHAT HAPPENS

WDEV80:	SETZM	SRCH		;NO FANCY MULTIPLE DEVICE (DSK) LOGIC
	TXNE	P2,FX.PHY	;/PHYSICAL ONLY SPECIFIED?
	SKIPA	T1,P1		;YES
	SETZ	T1,		;NO
	MOVEM	T1,FRCDEV	;SET ALTERNATE PHYSICAL ONLY FLAG
	MOVE	T1,P1		;RETURN USER'S DEVICE IN T1
	PJRST	WRTD		;AND JUST RETURN
;RETURN ALL SEARCH LIST

WSLA:	SETZ	T1,		;INITIALIZE ALL: EXPANSION

;LOOP FOR EACH DISK STRUCTURE IN THE ALL: SEARCH LIST

WSLA2:	SYSSTR	T1,		;GET FIRST/NEXT STRUCTURE
	 SETZ	T1,		;DUH?
	JUMPE	T1,WSLA8	;EXIT AFTER THE LAST ONE HAS BEEN RETURNED
	PUSH	P4,T1		;SAVE NAME FOR NEXT CALL
	PUSHJ	P4,WRFD		;SET FRCDEV AND RETURN IT
	 JRST	P4P1J0		;ABORT RETURN
	POP	P4,T1		;RESTORE LAST STRUCTURE
	JRST	WSLA2		;SEE WHAT'S NEXT

;ALL DONE WITH ALL SEARCH LIST, CHECK FOR FUNNIES

WSLA8:	JSP	T1,WSLXC	;CHECK FOR ANY FUNNY DEFERRED ACTIONS
	JRST	WSLA		;YUP, RETURN ALL SEARCH LIST YET AGAIN



;HERE TO RETURN THE JOB'S SEARCH LIST

WSLJ:	SETO	T2,		;INITIALIZE FOR GOBSTR LOOP

;LOOP OVER EACH STRUCTURE IN THE JOB'S ACTIVE SEARCH LIST

WSLJ2:	MOVE	T1,[1,,T2]	;JOBSTR ARG POINTER TO
	JOBSTR	T1,		;READ NEXT STRUCTURE IN JOB'S SEARCH LIST
	 SETZ	T2,		;DUH?
	JUMPE	T2,WSLJ8	;EXIT AFTER LAST STRUCTURE
	PUSH	P4,T2		;SAVE THIS STRUCTURE NAME
	MOVE	T1,T2		;POSITION IN T1
	PUSHJ	P4,WRFD		;AND RETURN FORCING THE DEVICE
	 JRST	P4P1J0		;ERROR
	POP	P4,T2		;RESTORE LAST DEVICE RETURNED
	JRST	WSLJ2		;AND ADVANCE TO NEXT ONE

;ALL DONE WITH JOB'S SEARCH LIST, SEE IF ANYTHING KINKY GOING ON

WSLJ8:	JSP	T1,WSLXC	;ANY DEFERRED STUFF LURKING AROUND?
	JRST	WSLJ		;YES
;HERE TO RETURN THE SYSTEM SEARCH LIST

WSLS:	SETO	T4,		;INITIALIZE FOR GOBSTR LOOP

;LOOP FOR EACH STRUCTURE IN THE SYSTEM SEARCH LIST

WSLS2:	SETZB	T2,T3		;JOB 0 := SYSTEM
	MOVE	T1,[3,,T2]	;GOBSTR ARG POINTER TO
	GOBSTR	T1,		;READ NEXT STR FROM SYSTEM SEARCH LIST
	 SETZ	T4,		;DUH?
	JUMPE	T4,WSLS8	;EXIT AFTER LAST STRUCTURE
	PUSH	P4,T4		;SAVE THIS STRUCTURE
	MOVE	T1,T4		;POSITION DEVICE AND
	PUSHJ	P4,WRFD		;RETURN, FORCING THE DEVICE
	 JRST	P4P1J0		;ERROR
	POP	P4,T4		;RESTORE LAST STRUCTURE
	JRST	WSLS2		;ADVANCE TO THE NEXT ONE

;ALL DONE WITH THE SYSTEM SEARCH LIST, CHECK FOR DEFERRED GOODIES

WSLS8:	JSP	T1,WSLXC	;ANY DEFERRED PATHS/PPNS/ETC?
	JRST	WSLS		;YES, REPEAT THE SEARCH LIST



;DEFERRED GOODIE CHECKER

WSLXC:	SKIPN	FRC14		;NEED TO DO A FRCPPN OF [1,4]?
	JRST	P4P0J1		;NO, ALL DONE HERE
	MOVE	T2,.PPSYS##	;YES, GET STD: PPN
	MOVEM	T2,FRCPPN	;SET NEW FORCING PPN
	SETZM	FRC14		;[1,4] NO LONGER DEFERRED
	JRST	(T1)		;REPEAT THE SEARCH LIST
;HERE TO RETURN STRUCTURES BASED ON CONTROLLER/UNIT NAMES

WKCN:	MOVE	T3,P1		;DEVICE AS SPECIFIED
	PUSHJ	P,.MKMSK##	;GENERATE TRAILING MASK
	PUSH	P4,T1		;SAVE MASK
	PUSH	P4,P1		; AND ITS DEVICE
	SETZB	T1,KCNPD	;INITIALIZE FOR UNIT/STR SEARCH

;LOOP OVER EACH DISK UNIT, LOOKING FOR NOT-YET-RETURNED STRUCTURES

WKCN2:	SYSPHY	T1,		;GET A DISK UNIT
	 SETZ	T1,		;DUH?
	JUMPE	T1,P4P2J1	;EXIT WHEN DONE
	MOVE	T2,T1		;COPY OF THIS UNIT
	AND	T2,-1(P4)	;MASK OFF DON'T CARE FIELDS
	CAME	T2,-0(P4)	;MATCH WHAT USER DOES CARE ABOUT?
	JRST	WKCN2		;NO, ADVANCE TO NEXT UNIT
	MOVEM	T1,DCQBL+.DCNAM	;YES, STASH UNIT NAME IN DSKCHR BLOCK
	MOVE	T2,[.DCMAX,,DCQBL]  ;DSKCHR ARG BLOCK TO
	DSKCHR	T2,UU.PHY	;READ STRUCTURE ON UNIT INFORMATION
	 JRST	WKCN2		;DUH???
	SKIPN	T2,DCQBL+.DCSNM	;GET ASSOCIATED STRUCTURE NAME
	JRST	WKCN2		;BLANK? NO STRUCTURE MOUNTED I GUESS
	SKIPN	T3,KCNPD	;GET STRUCTURE STACK POINTER
	JRST	WKCN5		;FIRST ONE, ALWAYS USE IT
	HRRZI	T3,-KCNPD(T3)	;LENGTH OF STR STACK
	CAME	T2,KCNPD(T3)	;RETURNED THIS STRUCTURE ALREADY?
	SOJG	T3,.-1		;LOOP FOR WHOLE STACK
	JUMPG	T3,WKCN2	;DON'T RETURN SAME STRUCTURE MORE THAN ONCE
WKCN5:	SKIPN	T3,KCNPD	;GET STRUCTURE STACK POINTER
	MOVE	T3,KCNPDP	;FIRST TIME, INITIALIZE STACK POINTER
	PUSH	T3,T2		;NOTE THIS STRUCTURE SEEN
	MOVEM	T3,KCNPD	;SAVE POINTER
	PUSH	P4,T1		;SAVE CURRENT UNIT NAME
	MOVE	T1,T2		;SET STRUCTURE NAME
	PUSHJ	P4,WRFD		;AND RETURN FORCING DEVICE
	 JRST	P4P3J0		;ERROR
	POP	P4,T1		;RESTORE LAST UNIT
	JRST	WKCN2		;AND ADVANCE TO THE NEXT ONE
;HERE FOR STRUCTURE ABBREVIATION

WKAB:	MOVE	T3,P1		;STRUCTURE NAME
	PUSHJ	P,.MKMSK##	;MAKE A WILDCARD MASK OUT OF IT
	MOVE	T2,T1		;POSITION MASK FOR WWCD
	MOVE	T1,P1		;WITH ITS NAME IN T1
	SETZ	T3,		;CLEAR ANY DEVICE OK
	AOJA	T2,WWCD		;TREAT AS REGULAR WILDCARDED DEVICE



;HERE FOR DEVICE WILDCARDS

WWCD:	SUBI	T2,1		;UNDO WDEV'S AOJN
	PUSH	P4,T1		;SAVE WILDCARD DEVICE
	PUSH	P4,T2		;SAVE WILDCARD MASK
	TXNN	T3,FX.ADO	;ANY DEVICE OK?
	JRST	WWCD7		;NO, DSKONLY
	SETZ	T3,		;YES, INITIALIZE FOR DVPHY. LOOP

;LOOP RETURNING EACH PHYSICAL DEVICE IN THE SYSTEM (EXCLUDING TTY:, PTY:,
;TSK:, MPX:, NUL:, AND DISK DEVICE/STRUCTURES)

WWCD1:	SETO	T2,		;-1 := ALL DEVICES
	MOVE	T1,[2,,T2]	;DVPHY. ARG POINTER TO
	DVPHY.	T1,		;READ NEXT PHYSICAL DEVICE NAME
	 SETZ	T3,		;DUH?
	JUMPE	T3,WWCD3	;CHECK OUT THE DISKS WHEN DONE HERE
	MOVE	T2,T3		;COPY OF THIS DEVICE
	XOR	T2,-1(P4)	;CONTRAST WITH USER SPECIFICATION
	TDNE	T2,-0(P4)	;DOES THIS DEVICE MATCH THE USER'S?
	JRST	WWCD1		;NO, IGNORE IT
	PUSH	P4,T3		;YES, SAVE IT FOR NEXT TIME
	MOVE	T1,T3		;POSITION IT AND
	PUSHJ	P4,WRFD		;RETURN, FORCING THE DEVICE
	 JRST	P4P3J0		;ERROR
	POP	P4,T3		;LAST DEVICE RETURNED
	JRST	WWCD1		;ADVANCE TO THE NEXT ONE

;NOW RETURN TTYNNN AND PTYNNN DEVICES

WWCD3:	MOVSI	T1,'TTY'	;FIRST THE TTY DEVICES
	DMOVE	T2,-1(P4)	;FETCH DEVICE SPECIFICATION AND MASK
	PUSHJ	P4,WWCDX	;RETURN ALL GENERIC DEVICES
	 JRST	P4P2J0		;ABORT TIME
	MOVSI	T1,'PTY'	;NEXT THE PTY DEVICES
	DMOVE	T2,-1(P4)	;FETCH DEVICE SPECIFICATION AND MASK
	PUSHJ	P4,WWCDX	;RETURN ALL GENERIC DEVICES
	 JRST	P4P2J0		;ABORT TIME

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW RETURN EACH DISK STRUCTURE

WWCD7:	SETZ	T1,		;INITIALIZE FOR SYSSTR LOOP

;LOOP RETURNING EACH DISK STRUCTURE IN THE SYSTEM

WWCD8:	SYSSTR	T1,		;GET NEXT STRUCTURE
	 SETZ	T1,		;DUH?
	JUMPE	T1,P4P2J1	;EXIT WHEN ALL DONE
	MOVE	T2,T1		;COPY OF THIS STRUCTURE
	XOR	T2,-1(P4)	;CONTRAST WITH USER SPECIFICATION
	TDNE	T2,-0(P4)	;DOES THIS DEVICE MATCH THE USER'S?
	JRST	WWCD8		;NO, ADVANCE TO THE NEXT ONE
	PUSH	P4,T1		;YES, SAVE CURRENT DEVICE
	PUSHJ	P4,WRFD		;RETURN FORCING DEVICE
	 JRST	P4P3J0		;ERROR
	POP	P4,T1		;RESTORE LAST DEVICE
	JRST	WWCD8		;LOOP
;ROUTINE TO "EXPAND" ALL INCARNATIONS OF A GENERIC DEVICE

WWCDX:	PUSH	P4,T2		;SAVE DEVICE SPECIFICATION
	PUSH	P4,T3		;AND WILDCARD MASK
	PUSH	P4,T1		;SAVE SPECIFIC GENERIC TYPE
	PUSH	P4,[-1]		;INITIALIZE "UNIT" INDEX/COUNTER

;LOOP BUILDING EACH "UNIT"

WWCDX1:	AOS	T2,0(P4)	;GET NEXT UNIT NUMBER
	CAILE	T2,777		;WITHIN LIMITS?
	JRST	P4P4J1		;DONE, SUCCESS RETURN
	MOVEI	T3,3		;MAXIMUM UNIT NUMBER IS THREE DIGITS
	LSHC	T1,^D27		;POSITION UNIT TO ENTER LOOP
WWCDX3:	LSH	T1,3		;FIRST HALF OF AN ASCII OCTAL DIGIT
	LSHC	T1,3		;SECOND HALF OF AN ASCII OCTAL DIGIT
	TRNE	T1,-1		;ANYTHING OF SIGNIFICANCE YET?
	ADDI	T1,'  0'	;YES, ASCIIZE THIS DIGIT
	SOJG	T3,WWCDX3	;LOOP FOR REST OF UNIT NUMBER
	TRNN	T1,-1		;DID WE GET ANYTHING?
	MOVEI	T1,'0  '	;NO - THEN MUST BE UNIT 0
	TRNN	T1,777700	;GOT A SINGLE-DIGIT UNIT NUMBER?
	LSH	T1,6+6		;YES, LEFT-JUSTIFY IT
	TRNN	T1,770000	;GOT A DOUBLE-DIGIT UNIT NUMBER?
	LSH	T1,6		;YES, LEFT-JUSTIFY IT
	HLL	T1,-1(P4)	;SET GENERIC NAME FIELD
	MOVE	T2,T1		;SCRATCH COPY OF DEVICE NAME
	XOR	T2,-3(P4)	;CONTRAST WITH USER SPECIFICATION
	TDNE	T2,-2(P4)	;DOES THIS DEVICE MATCH THE USER'S?
	JRST	WWCDX1		;NO, IGNORE IT AND TRY FOR ANOTHER
	MOVE	T2,T1		;ANOTHER SCRATCH COPY OF DEVICE NAME
	DEVCHR	T2,UU.PHY	;SEE IF IT ACTUALLY EXISTS
	JUMPE	T2,WWCDX1	;IF NOT, SKIP IT AND TRY THE NEXT
				; (IT COULD BE ARGUED THAT A SUCCESS RETURN
				;  SHOULD BE TAKEN NOW ON THE BASIS THAT
				;  "HOLES" SHOULD NEVER EXIST . . . )
	PUSHJ	P4,WRFD		;RETURN THIS DEVICE TO THE CALLER
	 JRST	P4P4J0		;ABORT TIME
	JRST	WWCDX1		;TRY FOR MORE DEVICES
;SOME USEFUL WSTR? CONSTANT DATA

WSTPDP:	-WST$LN,,WSTRST		;MAJOR WSTR STATE/STACK
PLNPDP:	-PLN$LN,,PLNPD		;PATHOLOGICAL NAME STATE/STACK POINTER
KCNPDP:	-KCN$LN,,KCNPD		;DISK STRUCTURE STATE/STACK POINTER
	0			;END OF LIST



P4P4J1:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P3J1:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P2J1:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P1J1:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P0J1:	AOS	(P4)		;SKIP
	POPJ	P4,		; RETURN

P4P4J0:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P3J0:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P2J0:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P1J0:	POP	P4,T1		;POP OFF A STACK ENTRY
P4P0J0:	POPJ	P4,		;NON-SKIP RETURN
;SAVWS  --  ROUTINE TO SAVE THE WSTR? STATE, ENABLING RECURSION
;CALL IS:
;
;	PUSHJ	P,.SAVWS
;	"RETURN"
;
;SAVWS SAVES THE CURRENT WSTRI/WSTRN STATE ON THE PROGRAM STACK, THEN
;CALLS THE CALLER SUCH THAT WHEN THE CALLER RETURNS SAVWS REGAINS
;CONTROL AND RESTORES THE WSTRI/WSTRN STATE, THEN PROPAGATES THE
;RETURN (JUST LIKE THE .SAVE1/ETC. ROUTINES).
;
;SAVWS USES ***LOTS*** OF PROGRAM STACK SPACE!
;
;PRESERVES ALL ACS

.SAVWS::SKIPN	WSTRST		;ANYTHING HAPPENING?
	POPJ	P,		;NO, NOTHING TO DO
	DMOVEM	T1,SAVWT1	;SAVE
	DMOVEM	T3,SAVWT3	; THE TEMPS
	POP	P,T1		;ADDRESS AT WHICH TO CONTINUE IN CALLER
	JUMPG	P,SAVWS2	;ONLY LENGTH CHECK IF TRADITIONAL POINTER
	HLRZ	T4,P		;GET "LENGTH"
	CAIGE	T4,-<WSLPM+40>	;ADEQUATE ROOM ON STACK?
	JRST	SAVWS2		;LOOKS LIKE IT
	SKIPN	.CTFLR		;IF THIS IS THE FIRST FILE TO BE REJECTED,
	OUTSTR	[ASCIZ\% Program stack too small to save WSTRx state
\]				;WARN USER OF POSSIBLE "?PDL OVERFLOW"
	AOS	.CTFLR		;COUNT THIS UP (JUNKY, BUT . . .)

;PUSH WSTR? STATE ONTO STACK

SAVWS2:	SKIPE	PLNPD		;CURRENTLY EXPANDING A PATHOLOGICAL NAME?
	SETOM	PLNZAP		;YES, WE'RE GONNA ZAP IT!
	MOVE	T4,[-WSLPM,,WSBPM]  ;AOBJN POINTER TO WSTR? DATA BASE
	PUSH	P,(T4)		;SAVE A STATE DATUM
	AOBJN	T4,.-1		;LOOP FOR ENTIRE AREA

;NOW IT GETS COMPLICATED, BUT THE COMPLICATION SAVES A LOT OF STACK SPACE!

	SETOM	SAVWSX		;INIT STACK POINTER TABLE INDEX

;LOOP SAVING STATE/STACKS ONLY AS ACTUALLY NEEDED

SAVWS3:	AOS	T4,SAVWSX	;ADVANCE INDEX
	SKIPN	T4,WSTPDP(T4)	;GET NEXT STATE/STACK
	JRST	SAVWS5		;DONE THEM ALL
	ANDI	T4,-1		;WANT JUST THE ADDRESS
	SKIPN	T3,(T4)		;FETCH CURRENT STATE/STACK POINTER
	TROA	T3,(T4)		;NONE, SET INITIAL
	ANDI	T3,-1		;REDUCE TO JUST CURRENT MAXIMUM ADDRESS
	PUSH	P,(T3)		;SAVE LAST USED ITEM
	CAME	T3,T4		;GOT ENTIRE STATE/STACK YET?
	SOJA	T3,.-2		;NO, GO BACK FOR THE REST
	JRST	SAVWS3		;YES, SAVE THE OTHER STATE/STACKS
;NOW CALL OUR CALLER, SO THAT WE INTERCEPT HIS RETURN

SAVWS5:	PUSH	P,SAVWSX	;SAVE TABLE INDEX
	PUSH	P,DEFZRO	;SKIP COUNTER (INITIALLY 0)
	PUSH	P,T1		;ADDRESS TO CONTINUE IN CALLER
	DMOVE	T1,SAVWT1	;RESTORE
	DMOVE	T3,SAVWT3	; THE TEMPS
	PUSHJ	P,@0(P)		;CALL OUR CALLER
RETWS:	 CAIA			;NON-SKIP RETURN
	AOS	-1(P)		;SKIP RETURN
	DMOVEM	T1,SAVWT1	;SAVE
	DMOVEM	T3,SAVWT3	; THE TEMPS
	POP	P,T1		;TOSS OFF JUNK ADDRESS
	POP	P,T1		;HANG ONTO THE SKIP COUNT
	POP	P,SAVWSX	;SET STATE/STACK TABLE POINTER (BACKWARDS)

;NOW RESTORE THE VARIOUS STATE/STACKS AS NEEDED

RETWS3:	SOSGE	T4,SAVWSX	;ADVANCE TABLE INDEX
	JRST	RETWS5		;ALL DONE
	MOVE	T4,WSTPDP(T4)	;GET NEXT STATE/STACK POINTER
	MOVE	T3,T4		;PROTOTYPE FINAL POINTER
	POP	P,(T4)		;RESTORE STATE FLAG
	SKIPN	T4,(T4)		;FETCH COPY OF STATE FLAG
	JRST	RETWS3		;IF EMPTY, THEN DONE
	AOBJN	T3,.+1		;ELSE INIT THE PUSH'ER
	POP	P,(T3)		;RESTORE A STATE/STACK DATUM
	CAME	T3,T4		;RESTORED ENTIRE STATE/STACK YET?
	AOBJN	T3,.-2		;NO, RESTORE THE REST
	JRST	RETWS3		;YES, RESTORE THE OTHER STATE/STACKS

RETWS5:	MOVE	T4,[-WSLPM,,WSBPM]  ;AOBJN POINTER TO WSTR? DATA BASE
	POP	P,WSLPM-1(T4)	;RESTORE A STATE DATUM
	SUBI	T4,2		;(STEPPING BACKWARDS)
	AOBJN	T4,.-2		;LOOP FOR ENTIRE AREA

;NOW FINALLY RESTORE THE TEMPS AND PROPAGATE OUR CALLER'S RETURN

	ADDM	T1,(P)		;PROPAGATE THE SKIPNESS
	DMOVE	T1,SAVWT1	;RESTORE
	DMOVE	T3,SAVWT3	; THE TEMPS
	POPJ	P,		;RETURN TO CALLER'S CALLER AS APPROPRIATE
;TEST ROUTINE

WX:	MOVE	T1,.WIFIR	;ADDRESS OF INPUT SCAN BLOCK
	PUSHJ	P,.WSTRI	;INITIALIZE FOR LOOP
	 JFCL			;NEVER GET HERE

WXL:	MOVEI	T1,Y.BLK	;A "SCRATCH" FILE SPEC BLOCK
	PUSHJ	P,.WSTRN	;GET NEXT FILE SEARCH LIST
	 JRST	[SKIPN	.JBBPT		;IS DDT LOADED?
		EXIT			;NO???
		JSR	@.JBBPT		;CAUSE A BREAKPOINT
		JRST	WX]		;TRY AGAIN
	MOVEI	T1,Y.BLK	;ADDRESS OF RESULTANT FILE SPEC BLOCK
	MOVX	T2,<FX.UND!FX.UDV!FX.UDR!FX.UNM!FX.UEX!FX.UGN>
				; BUT DON'T BOTHER WITH SWITCHES
	PUSHJ	P,.TOFSB##	;TYPE OUT ONE FILE SPEC BLOCK
	MOVEI	T1,[ASCIZ\/FRCDEV\]
	SKIPE	FRCDEV		;FRCDEV SET?
	PUSHJ	P,.TSTRG##	;YES
	MOVEI	T1,[ASCIZ\/FRCPPN\]
	SKIPE	FRCPPN		;FRCPPN SET?
	PUSHJ	P,.TSTRG##	;YES
	PUSHJ	P,.TCRLF##	;CAP OFF THIS LINE
	JRST	WXL		;GO FOR NEXT DEVICE
;TEST ROUTINE TO VERIFY THE WILDCARDS MASK TO AID IN CONVERTING
;OLD PROGRAMS TO NEW STUFF

FX.W:	SKIPE	.FXNOD(P1)	;GOT A NODE NAME?
	SKIPA	T3,.FXNOM(P1)	;YES, GET WILDCARD MASK
	SETO	T3,		;NO, THEN ASSUME NO WILDCARDS
	AOJE	T3,.+3		;IF NO WILDCARDS THEN OK
	TXON	T1,FX.WND	;WILDCARDS, DOES FIELDS FLAGS REFLECT THIS?
	OUTSTR	[ASCIZ\% Node wildcards but FX.WND not set
\]

	SKIPE	.FXDEV(P1)	;GOT A DEVICE NAME?
	SKIPA	T3,.FXDEM(P1)	;YES, GET WILDCARD MASK
	SETO	T3,		;NO, THEN ASSUME NO WILDCARDS
	AOJE	T3,.+3		;IF NO WILDCARDS THEN OK
	TXON	T1,FX.WDV	;WILDCARDS, DOES FIELDS FLAGS REFLECT THIS?
	OUTSTR	[ASCIZ\% Device wildcards but FX.WDV not set
\]

	MOVSI	T4,-.FXLND	;AOBJN POINTER FOR DIRECTORY BIWORDS
	HRR	T4,P1		;ADDRESS OF RELEVANT FILE SPEC BLOCK
	SKIPN	.FXDIR(T4)	;GOT A DIRECTORY NAME?
	JRST	.+7		;END OF DIRECTORY
	MOVE	T3,.FXDIM(T4)	;YES, GET WILDCARD MASK
	AOJE	T3,.+3		;IF NO WILDCARDS THEN OK
	TXON	T1,FX.WDR	;WILDCARDS, DOES FIELDS FLAGS REFLECT THIS?
	OUTSTR	[ASCIZ\% Directory wildcards but FX.WDR not set
\]
	ADDI	T4,1		;FOR BIWORD INDEX
	AOBJN	T4,.-7		;LOOP FOR REST OF THE DIRECTORY BIWORDS

	SKIPE	.FXNAM(P1)	;GOT A NAME NAME?
	SKIPA	T3,.FXNMM(P1)	;YES, GET WILDCARD MASK
	SETO	T3,		;NO, THEN ASSUME NO WILDCARDS
	AOJE	T3,.+3		;IF NO WILDCARDS THEN OK
	TXON	T1,FX.WNM	;WILDCARDS, DOES FIELDS FLAGS REFLECT THIS?
	OUTSTR	[ASCIZ\% Name wildcards but FX.WNM not set
\]

	SKIPE	T3,.FXEXT(P1)	;GOT A EXTENSION?
	TLOA	T3,-1		;YES, GET WILDCARD MASK
	SETO	T3,		;NO, THEN ASSUME NO WILDCARDS
	AOJE	T3,.+3		;IF NO WILDCARDS THEN OK
	TXON	T1,FX.WEX	;WILDCARDS, DOES FIELDS FLAGS REFLECT THIS?
	OUTSTR	[ASCIZ\% Extension wildcards but FX.WEX not set
\]

	POPJ	P,		;DONE HERE
	SUBTTL	USEFUL SUBROUTINES

REPEAT	0,<

;SETSYS -- SETUP DIRECTORY FOR SYS:
;CALL:	PUSHJ	P,SETSYS
;USES T1, T2

SETSYS:	MOVE	T1,.PPSYS##	;GET LOCATION OF SYS:
SETPPN:	CAMN	T1,.PPMFD##	;IF MFD:
	JRST	[MOVE  T2,W.BLK+.FXDIR ;GET DIRECTORY			[153]
		 CAMN  T2,.PPMFD## ;UNLESS MFD,			[153]
		 POPJ  P,	;(YES--RETURN)			[153]
		 MOVEM T2,W.BLK+.FXNAM	; STORE AS NAME			[153]
		 MOVE  T2,W.BLK+.FXDIM ;GET DIRECTORY MASK		[153]
		 MOVEM T2,W.BLK+.FXNMM ;STORE AS NAME MASK		[153]
		 JRST  .+1]	;PROCEED			[153]
	MOVEM	T1,FRCPPN	;OVERRIDE DIRECTORY		[154]
	MOVE	T2,.PPMFD##	;GET MFD
	CAMN	T2,W.BLK+.FXDIR	;SEE IF SAME			[154]
	JRST	SETPP1		;YES--GO DIDDLE NAME
	MOVEM	T1,W.BLK+.FXDIR	;AND OVERSTORE REQUEST		[154]
	SETOM	W.BLK+.FXDIM	;AND NO WILD DIRECTORY		[154]
	SETZM	W.BLK+.FXDIR+2	;CLEAR SUB DIRECTORY		[154]
	SETZM	W.BLK+.FXDIM+2	; AND MASK			[154]
	POPJ	P,		;RETURN

SETPP1:	MOVEM	T1,W.BLK+.FXNAM	;STORE OVER NAME		[154]
	SETOM	W.BLK+.FXNMM	;CLEAR WILD CARD		[154]
	POPJ	P,		;RETURN
> ;END REPEAT 0



;SETOPN -- SETUP OPEN BLOCK WORD 1 AND 2
;CALL:	PUSHJ	P,SETOPN
;RETURNS WITH T1, T2 SETUP, T3=0
;USES NO ACS

SETOPN:	SETZB	T1,T3		;OPEN MFD
	SKIPN	PHYS		;SEE IF PHYS I/O REQUESTED
	SKIPE	SRCH		;OR IF USING A SEARCH LIST
	TXO	T1,UU.PHS	;YES--SET FOR PHYS OPEN
	SKIPE	T2,FRCDEV	;FORCED DEVICE?
	TXO	T1,UU.PHS	;YES, THEN PHYSICAL ONLY
	JUMPN	T2,.POPJ##	;DONE IF FORCING DEVICE
	SKIPN	T2,LASSTR	;GET STRUCTURE OR		[310]
	MOVE	T2,W.BLK+.FXDEV	;GET ARGUMENT DEVICE
	POPJ	P,		;RETURN
;DOPHYS -- PERFORM A LOGICAL OR PHYSICAL CALLI AS NEEDED
;CALL:	PUSHJ	P,DOPHYS
;	CALLI TO BE EXECUTED
;	CPOPJ RETURN POINT
;	SKIP RETURN POINT
;USES T1

DOPHYS:	MOVE	T1,(P)		;FETCH CALLI
	MOVE	T1,(T1)		; ..
	AOS	(P)		;ADVANCE RETURN POINT
	SKIPE	PHYS		;SEE IF PHYS I/O REQUESTED
	TRO	T1,UU.PHY	;YES--TURN ON PHYSICAL BIT
	XCT	T1		;DO THE CALLI
	POPJ	P,		;OK RETURN
CPOPJ1:	AOS	(P)		;SKIP
CPOPJ:	POPJ	P,		;RETURN



;ROUTINE TO COUNT NUMBER OF "1" 'S IN A WORD
;
;CALL IS:
;
;	MOVE	T2,WORD
;	PUSHJ	P,BITCNT
;	RETURN WITH T2 = COUNT OF "1"'S IN WORD
;ALL OTHER AC'S PRESERVED

BITCNT:	PUSH	P,T1		;PRESERVE T1
	PUSH	P,T3		;& T3
	SETZ	T3,		;INITIAL COUNT
	MOVN	T1,T2		;CLASSIC LOOP
	TDZE	T2,T1		;STRAIGHT FROM
	AOJA	T3,.-2		;"THE BOOK"
	MOVEI	T2,(T3)		;SET COUNT IN T2
	POP	P,T3		;3T &
	POP	P,T1		;1T EVRESERP
	POPJ	P,		;
;.LKZAP -- ABORT/ZAP ALL .LKWLD'S DIRECTORY CHANNELS
;
;CALL IS:
;
;	PUSHJ	P,.LKZAP
;	RETURNS NON-SKIP ALWAYS
;USES T1, T2, T3

.LKZAP::MOVEI	T3,.FXLND	;GET THE NUMBER OF DIRECTORY CHANNELS
	SKIPE	AGPNTR		;GOT A CURRENT STATE/POINTER?
	SETZM	@AGPNTR		;YES, KILL OFF CURRENT STATE
	SETZM	AGPNTR		;AND KILL OFF THE STATE POINTER AS WELL

;Now kill off any directory-searching I/O channels left active

LKZAP1:	SKIPN	T2,BUFCHN(T3)	;GET THE CHANNEL NUMBER (IF ANY)
	JRST	LKZAP2		;NONE. TRY THE NEXT ONE UP
	HRRI	T2,.FOREL	;GET THE FUNCTION CODE (RELEASE)
	MOVE	T1,[1,,T2]	;GET THE FILOP. ARG POINTER
	FILOP.	T1,		;RELEASE THE CHANNEL
	  JFCL			;PUNT ERRORS HERE
	SETZM	BUFCHN(T3)	;WE DON'T OWN THIS CHANNEL ANYMORE
LKZAP2:	SOJG	T3,LKZAP1	;LOOP FOR ALL POSSIBLE CHANNELS
	POPJ	P,		;THEN RETURN
	SUBTTL	DATA STORAGE

DEFZRO:	REPEAT	.FXLND+1,<EXP 0>;A DEFAULT PATH (ALMOST) BLOCK

	XLIST	;LITERALS
	LIT
	LIST
	RELOC
.WILDZ::!		;START OF LOW CORE AREA

FWAZER:!	;START OF TEMPORARIES (CLEARED EACH REQUEST)

W.BLK:	BLOCK	.FXLEN		;OUR VERY OWN SCRATCH FILE SPEC BLOCK
X.BLK:	BLOCK	.FXLEN		;INTERNAL BLOCK TO HOLD PRIMARY WILDCARDING
Y.BLK:	BLOCK	.FXLEN		;INTERNAL BLOCK TO HOLD SPECIFIC "SEARCH LIST"
Z.BLK:	BLOCK	.FXLEN		;INTERNAL BLOCK FOR CHKXXX "SEARCH LIST"


FLDTA:	BLOCK	1		;FLAG THAT DISK DEVICE
NOTDSK:	BLOCK	1		;FLAG THAT NOT A DTA/DISK DEVICE
LASSTR:	BLOCK	1		;LAST STR FROM SEARCH UUOS
LASERR:	BLOCK	1		;LAST ERROR OF DIRECTORY NATURE
DIRFLG:	BLOCK	1		;-1 IF NEED TO EXPAND THIS DIRECTORY
				; USED WHEN RETURNING SFD/UFD AS DATA FILE
FNDSFD:	BLOCK	.FXLND+1	;+N IF SFD FIRST PASS, -1 IF SECOND	[316]
				;  0=NEITHER, -2 IF WILD FILE AND WILD STR)
UFDEF:	BLOCK	1		;FLAG THAT UFD ERROR WAS REPORTED
PHYS:	BLOCK	1		;FLAG TO FORCE PHYSICAL I/O
SRCH:	BLOCK	1		;FLAG FOR SEARCH LIST IN USE

UFDFLW:	BLOCK	1		;-1 IF "WILD" ERROR MESSAGE WANTED
				; SUCH AS "NO SUCH FILES AS"

.WIFIR::BLOCK	1		;FIRST P1 IN LINKED SET
.WILAS::BLOCK	1		;LAST P1 IN LINKED SET
.WXPRC::BLOCK	1		;.NE. 0 IF CONCATENATED FILE EXPRESSION
.WLDFL::BLOCK	1		;FILE WILD FLAG (-1=WILD FILE, +1=WILD STR ONLY,
.WLDNE::BLOCK	1		;.NE.0 THEN ABORT CURRENT FILE SPEC SET

.CTNDS::BLOCK	1		;NUMBER OF NODES LOOKED AT
.CTNDF::BLOCK	1		;NUMBER OF NODES SUCCESSFULLY FOUND
.CTNDR::BLOCK	1		;NUMBER OF NODES REJECTED (UNIMPLEMENTED)
.CTNDP::BLOCK	1		;NUMBER OF NODES WITH UNREPORTED UID ERRORS
.CTDVS::BLOCK	1		;NUMBER OF DEVICES LOOKED AT
.CTDRS::BLOCK	1		;NUMBER OF DIRECTORIES LOOKED AT
.CTDRF::BLOCK	1		;NUMBER OF DIRECTORIES FOUND
.CTDRP::BLOCK	1		;NUMBER OF DIRS WITH UNREPORTED PROT ERRORS
.CTFLS::BLOCK	1		;NUMBER OF FILES LOOKED AT
.CTFLF::BLOCK	1		;NUMBER OF FILES FOUND
.CTFLR::BLOCK	1		;NUMBER OF FILES REJECTED
.CTFLP::BLOCK	1		;NUMBER OF FILES WITH UNREPORTED PROT ERRORS
DIRB:	BLOCK	1		;BLOCK FOR DIRECTORY FOR SFD LOOKUPS
DIRBS:	BLOCK	1		; (SCANNING SWITCH)
DIRBU:	BLOCK	.FXLND		; (ACTUAL DIRECTORY LIST)
DIRBE:	BLOCK	1		;0 TO FORCE END

DEPTH:	BLOCK	1		;INDEX OF DIRECTORY DEPTH (0=MFD)
				;USED TO INDEX INTO FOLLOWING TABLES.
				;USUALLY CARRIED IN T4.
DIRNAM:	BLOCK	.FXLND+1	;CURRENT DIRECTORY SPEC
DIRMSK:	BLOCK	.FXLND+1	;CURRENT DIRECTORY MASK
BUFCHN:	BLOCK	.FXLND+1	;DIRECTORY FILE CHANNEL
BUFUSI:	BLOCK	.FXLND+1	;USETI IN DIRECTORY
BUFCNT:	BLOCK	.FXLND+1	;COUNT DOWN OF FILES IN BLOCK (WITHIN .WLDBF)
BUFPOS:	BLOCK	.FXLND+1	;INDEX IN BLOCK (WITHIN .WLDBF)

.WLDBF:	BLOCK	200		;BUFFER FOR READING DIRECTORIES

FLPBL:	BLOCK	FLPLN		;FILOP. BLOCK TO OPEN/LOOKUP DIR FILES
LKPBL:	BLOCK	LKPLN		;LOOKUP BLOCK FOR UFD/SFD

DVCH:	BLOCK	1		;LAST DEVICE CHARACTERISTICS
LWAZER==.-1	;END OF CLEARED AREA
AGLENP:	BLOCK	1	;LENGTH OF FILE SPEC BLOCK
AGPFSB:	BLOCK	1	;POINTER TO FIRST FILE SPEC BLOCK
AGLIMS:	BLOCK	1	;POINTER TO LAST FILE SPEC BLOCK
AGPNTR:	BLOCK	1	;POINTER TO POINTER TO CURRENT FILE SPEC BLOCK
AGLENL:	BLOCK	1	;LENGTH OF LOOKUP BLOCK
AGLOOK:	BLOCK	1	;ADDRESS OF LOOKUP BLOCK
AGOPEN:	BLOCK	1	;ADDRESS OF OPEN BLOCK
AGFLAG:	BLOCK	1	;USER'S FLAGS
AGFOPF:	BLOCK	1	;FILOP. FLAGS (STUPID FO.PRV)
AGEODN:	BLOCK	1	;ROUTINE TO NOTIFY AT END OF DIRECTORY
AGDFEX:	BLOCK	1	;ADDRESS OF DEFAULT EXTENSION TABLE (FUTURE)
AGOBOP:	BLOCK	1	;ON-BEHALF-OF-PPN WORD

ASCFLG:	BLOCK	1	;.NE. 0 THEN EXTENDED I/O CHANNELS AVAILABLE
UOCFLG:	BLOCK	1	;.NE. 0 THEN FILOP USE-OPEN-CHANNEL AVAILABLE

;TEMP BLOCK FOR ERROR ROUTINE TO HOLD FILE SPEC STUFF

E.BLK:	BLOCK	.FXLEN	;W.BLK HELD HERE WHILST PROCESSING ERROR MESSAGES

B.DC::	BLOCK	3	;DATA
;STORAGE FOR CHK???

FLCRDT:	BLOCK	1	;FILE'S CREATION DATE-TIME
FLACDT:	BLOCK	1	;FILE'S ACCESS DATE
FLPHDT:	BLOCK	1	;FILE'S PHYSICAL MEDIA CREATION DATE/TIME

CHKRCT:	BLOCK	1	;FILES REJECTED (AS OPPOSED TO "UN"FOUND)
CHKTCT:	BLOCK	1	;CHKTST COUNTER


;SECONDARY FILE BLOCKS ('IFAND' AND 'IFNOT')

CHKSCB:	BLOCK	10	;SCWILD ARG BLOCK

CHKSIF:	BLOCK	1	;ADDRESS OF PRIMARY OR INPUT FILE
CHKSOF:	BLOCK	1	;ADDRESS OF SECONDARY OR OUTPUT FILE

CHKFOB:	BLOCK	.FOMAX	;SECONDARY FILE FILOP. BLOCK
CHKLEB:	BLOCK	CHKLEL	;SECONDARY FILE LOOKUP/ENTER BLOCK
CHKPAT:	BLOCK	.PTMAX	;SECONDARY FILE PATH BLOCK (RETURNED)
;STORAGE FOR WSTR??

WNODXX:	BLOCK	2	;*** TILL DNET. ACCEPTS ARGS IN THE ACS

WSBZM:!			;START OF WSTRI TO-BE-CLEARED
WSBPM:!			;START OF WSTR? TO-BE-PUSHED

WSISB:	BLOCK	1	;INPUT FILE SPEC BLOCK ADDRESS (FROM WSTRI)
WSRSB:	BLOCK	1	;RETURNED FILE SPEC BLOCK ADDRESS (FROM WSTRN)

WSBLDF:	BLOCK	1	;.NE. 0 TO LEAVE BLANK FIELDS DEFAULTED BLANK

FRCDEV:	BLOCK	1	;FORCED DEVICE (ALWAYS USE /PHYSICAL ONLY)
FRCPPN:	BLOCK	1	;FORCED PPN (E.G., ERSATZ DEVICE)
FRC14:	BLOCK	1	;.LT. 0 THEN [SYS] AFTER CURRENT EXPANSION

PLNBDF:			;BEGIN OF PATHOLOGICAL NAME DEFAULTS
PLNOVR:	BLOCK	1	;DIR/NAME/EXT OVERRIDE USER FSB
PLNNOD:	BLOCK	1	;DEFAULT NODE
PLNDEV:	BLOCK	1	;DEFAULT DEVICE
PLNPTH:	BLOCK	.FXLND	;DEFAULT FILE PATH
	BLOCK	1	;END OF PATH
PLNNAM:	BLOCK	1	;DEFAULT FILE NAME
PLNEXT:	BLOCK	1	;DEFAULT FILE TYPE
PLNGEN:	BLOCK	1	;DEFAULT FILE GENERATION
PLNEDF:			;END (+1) OF PATHOLOGICAL NAME DEFAULTS

PLNZAP:	BLOCK	1	;.NE. 0 THEN PLNBL HAS BEEN TRASHED

WSEPM:!			;END (+1) OF WSTR? TO-BE-PUSHED
	WSLPM==WSEPM-WSBPM	;LENGTH OF TO-BE-PUSHED


;WSTR? STATE/STACKS - START OF CONDITIONALLY SAVED BY SAVWS

WSTRST:	BLOCK	WST$LN+1;WSTR STATE/STACK
PLNPD:	BLOCK	PLN$LN+1;PATHOLOGICAL NAME STACK
KCNPD:	BLOCK	KCN$LN+1;STRUCTURE STACK

;WSTR? SCRATCH AREA - NEVER SAVED BY SAVWS

DCQBL:	BLOCK	.DCMAX	;DSKCHR QUERY BLOCK
PTQBL:	BLOCK	.PTMAX	;PATH QUERY BLOCK
PLNBL:	BLOCK	.PTLLB	;PATHOLOGICAL NAME BLOCK

WSEZM:			;END (+1) OF WSTRI TO-BE-CLEARED


;FOR SAVWS

SAVWSX:	BLOCK	1	;WSTPDP TABLE INDEXER

SAVWT1:	BLOCK	1	;FOR SAVING T1
SAVWT2:	BLOCK	1	;FOR SAVING T2
SAVWT3:	BLOCK	1	;FOR SAVING T3
SAVWT4:	BLOCK	1	;FOR SAVING T4
;STORAGE FOR SCWLD

SCISP:	BLOCK	1	;INPUT SPEC LOCATION
SCIOPN:	BLOCK	1	;INPUT OPEN LOCATION
SCILKP:	BLOCK	1	;INPUT LOOKUP LOCATION
SCOSP:	BLOCK	1	;OUTPUT SPEC LOCATION
SCOOPN:	BLOCK	1	;OUTPUT OPEN LOCATION
SCOLKP:	BLOCK	1	;OUTPUT LOOKUP LOCATION
SCOPTH:	BLOCK	1	;OUTPUT PATH BLOCK LOCATION
SCODFE:	BLOCK	1	;ADDRESS OF DEFAULT EXTENSION
SCOLLK:	BLOCK	1	;OUTPUT LOOKUP LENGTH
SCDCTL:	BLOCK	1	;DEFAULT .FXCTL TO USE

SCWMM:	BLOCK	1	;TYPE OF SCWILD INSERT
SCWMD:	BLOCK	1	;TYPE OF DIRECTORY SHIFTING
SCWBE:	BLOCK	1	;OUTPUT/INPUT MASK CONSTRAINT

SCBZM:			;BEGINING TO TO-BE-CLEARED

SCCHR:	BLOCK	1	;DEV CHR
SCTYP:	BLOCK	1	;DEV TYP
SCNOD:	BLOCK	1	;TEMP TO HOLD NODE NAME
SCNBT:	BLOCK	1	;TEMP FOR FNDNBT
SCNWD:	BLOCK	1	;TEMP FOR FNDNBT
SCNWDD:	BLOCK	1	;TEMP FOR RDHWLD
SCNWD3:	BLOCK	1	;TEMP FOR RDHWLD
SCWBC:	BLOCK	1	;TEMP FOR RDHWLD
SCDLEV:	BLOCK	1	;SHIFTING LEVEL FROM SCDCK

SCEZM:			;END (+1) OF TO-BE-CLEARED

SCWPTH:	BLOCK	.PTMAX	;DEFAULT INTERNAL PATH BLOCK TO USE

.WILDL==:.-.WILDZ	;LENGTH OF LOW CORE AREA

	PRGEND
	TITLE	.WILDD	SWIL dummy network wildcard file operations
	SUBTTL

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

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000			;NICE PURE CODE


	COMMENT	\

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

\
	SUBTTL	LKWLN	Dummy network wildcard file processor

	ENTRY	.LKWLN

.LKWLN::PUSH	P,T1		;SAVE FILE SPEC BLOCK ADDRESS
	MOVE	T1,['WLD',,'NNF'] ;PREFIX
	MOVE	T2,["?",,NNFTXT];ERROR, AND TEXT BODY
	MOVEI	T3,.LKWLN	;A RANDOM ADDRESS
	PUSHJ	P,.ERMSA##	;START UP THE ERROR MESSAGE
	TXNN	T1,JWW.FL	;WANT TEXT?
	PJRST	LKWLN9		;NO, CAP OFF MESSAGE NOW

	MOVE	T1,0(P)		;FETCH ADDRESS OF FILE SPEC BLOCK
	MOVX	T2,<FX.UND!FX.UDV!FX.UDR!FX.UNM!FX.UEX!FX.UGN>
				; BUT DON'T BOTHER WITH SWITCHES
	PUSHJ	P,.TOFSB##	;TYPE OUT ONE FILE SPEC BLOCK
LKWLN9:	POP	P,T1		;RESTORE STACK
	SOS	.CTNDF##	;DISCOUNT THIS NODE
	AOS	.CTNDP##	;AND CALL IT INACCESSIBLE
	PJRST	.TCRLF##	;AND CAP IT ALL OFF

NNFTXT:	ASCIZ\No network file service available for \
REPEAT	0,<
	PRGEND
	TITLE	WLDSTR	STRUCTURE SUBROUTINES
	SUBTTL

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

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000			;NICE PURE CODE


	COMMENT	\

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

\
ND FT$COR,-1		;+ TREATED SAME AS 'OR'
ND FT$SFD,-1		;SUB-FILE DIRECTORIES

IFLE .FXLND-1,<FT$SFD==0
		.FXLND==1>
;.INSTR -- ROUTINE TO INITIALIZE STRUCTURE SEARCH LOOP
;.INIST -- SAME AS .INSTR BUT ALSO CAUSES FRCPPN TO BE SET.
;CALL:	MOVE	T1,DEVICE
;	MOVE	T2,1B0 IF /PHYSICAL
;	PUSHJ	P,.INSTR
;NON-SKIP IF NOT A DISK
;SKIP WITH CODES PRESET FOR .NXSTR
;  AND T1=0 IF NO SCANNING, =1B0 IF SCANNING

	ENTRY	.INIST,.INSTR

.INIST::SETZM	SUBSTR		;INDICATE .INIST CALL	[321]
	SKIPA			;			[321]
.INSTR::SETOM	SUBSTR		;INDICATE .INSTR CALL
	PUSHJ	P,.SAVE1##	;SAVE P1
	MOVSI	T3,'SYS'	;SEE IF
	DEVCHR	T3,UU.PHY	; PHYSICAL
	TRNN	T3,-1		; POSSIBLE
	TXZ	T2,UU.PHS	;NO--CLEAR ARGUMENT
	LSH	T2,-^D35	;POSITION TO BIT 35
	MOVEM	T2,PHYS		;STORE FOR UUO
	SETOM	SY2RCH		;ASSUME AT LEAST 5.02
	MOVEM	T1,W.BLK##+.FXDEV	;SAVE DEVICE
	SETZM	SYSRCH		;CLEAR
	SETZM	STRMSK		; FLAGS
	SETZM	STRMTH		; FOR .NXSTR
	SETZM	SRCH		;CLEAR SEARCH MODE
	MOVE	T2,T1		;COPY ARGUMENT DEVICE
	PUSHJ	P,DOPHYS##	;GET
	  DEVCHR T2,		; ITS CHARACTERISTICS
	MOVS	T1,W.BLK##+.FXDEV	;GET NAME AGAIN
	CAIN	T1,'NUL'	;SEE IF NUL:
	TLO	T2,-1-<(DV.TTA)> ;YES--FAKE DEVCHR FOR OLD MONITORS
	TLC	T2,-1-<(DV.TTA)> ;SEE IF NUL:
	TLCE	T2,-1-<(DV.TTA)> ; ..
	TXNN	T2,DV.DSK	;OR NOT DISK
	POPJ	P,		;RIGHT--ERROR

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;INSTR -- INTERNAL ROUTINE TO INITIALIZE .NXSTR

INSTR:	SETZM	FRCPPN		;INDICATE NOT OVERRIDING PPN	[154]
IFN FT$SFD,<
	MOVE	T3,W.BLK##+.FXDEV	;GET STRUCTURE
	MOVEI	T4,0		;CLEAR ANSWER
	MOVE	T2,[3,,T3]	;SETUP CODE
	PUSHJ	P,DOPHYS##	;ASK MONITOR FOR
	  PATH.	T2,		;  SYS IDENT.
	    JRST INSTR3		;NOT IMPLEMENTED--TRY OLD WAY
	MOVE	T1,P1		;SAVE DEVICE PPN
	HLRZ	T2,T3		;GET GENERIC STR NAME
;**;	[334]	INSERT 08-JUN-77 LCR.
	CAIN	T2,'SYS'	;[334] IF ANY SYS
	SETOM	SYSRCH		;[334] THEN SET SEARCHING 'SYS' FLAG.
	CAIE	T2,'SYS'	;LOOK FOR SYS:
	TXNE	T4,PT.IPP	;NO--SEE IF IGNORE DIRECTORY ARGS
	JRST	.+2		;YES--CLOBBER ARGUMENT
	JRST	INSTR2		;NO--PROCEED
	CAIN	T2,'SYS'	;IF SYS,
	HRLI	T3,'DSK'	;SWITCH TO DSK TO GET RIGHT SUBSET
	MOVEM	T3,W.BLK##+.FXDEV	;  LIKE "SYSA:", ETC.
	SKIPN	SUBSTR		;IF INTERNAL CALL,
	PUSHJ	P,SETPPN##	;  SET REQUESTED PPN
;**;[336] REMOVE NEXT 2 REDUNDANT LINES
;	TXNN	T4,PT.IPP	;SEE IF IGNORE PPN
;	SETOM	SYSRCH		;NO--SET SYS FLAG

;HERE TO SEE IF SPECIAL SEARCH LIST NEEDED

INSTR2:	LDB	T1,[POINTR (T4,PT.SLT)]  ;GET S/L CODE
	JUMPE	T1,INSTR3		;PROCEED IF NOTHING SPECIAL
	SETZM	SY2RCH		;EXPLICIT INFO, SO CLEAR FLAGS
	SETZM	SYSRCH		; ..
	CAIE	T1,.PTSLA	;SEE IF ALL S/L
	CAIN	T1,.PTSLS	;OR SYS S/L
	SETOM	SYSRCH		;YES--FLAG FOR ALL OR SYS
	CAIN	T1,.PTSLS	;SEE IF SYS S/L
	SETOM	SY2RCH		;YES--FLAG FOR SYS
	JRST	INSTR7		;AND SKIP AD HOC KLUDGERY
>
INSTR3:	MOVE	T2,W.BLK##+.FXDEV	;GET DEVICE NAME
	MOVE	T3,[1,,T2]	;SET FOR DSKCHR
	PUSHJ	P,DOPHYS##	;DO PHYS I/O CALL
	  DSKCHR T3,		;SEE IF SYS OR GENERIC
	    JRST INSTR5		;FAILED--MUST BE SYS:
	LDB	T1,[POINTR (T3,DC.TYP)]  ;GET NAME CLASS
	JUMPE	T1,INSTR7		;JUMP IF DSK:
	CAIN	T1,.DCTAB	;IF STR ABBR. (SE:)
	JRST	INSTM1		;  GO SET MASK
	CAIN	T1,.DCTCN	;IF CONTROLLER CLASS (DP:)
	JRST	INSTM4		;  GO SET DSKCHR MASK
	CAIN	T1,.DCTCC	;IF CONTROLLER (DPA:)
	JRST	INSTM5		;  GO SET IT
	JRST	INSTRX		;NOTHING SPECIAL--USE USER'S DEVICE


;HERE WHEN STR ABBREVIATION FOUND (LIKE SE: FOR SEFI: AND SEMA:)

INSTM1:	MOVE	T3,W.BLK##+.FXDEV	;GET ABBREVIATION
	DEVNAM	T3,		;CONVERT TO PHYSICAL IF WE CAN
	  MOVE	T3,W.BLK##+.FXDEV	;IF NOT DO THE BEST WE CAN
	PUSHJ	P,.MKMSK##	;GET MASK OF SIZE
	JRST	INSTM8		;AND GO STORE


;HERE WHEN CONTROLLER CLASS (DP:)

INSTM4:	MOVX	T1,DC.CNT	;SET MASK FOR TYPE OF CONTROLLER
	JRST	INSTM8		;AND GO STORE


;HERE WHEN CONTROLLER (DPA:)

INSTM5:	MOVX	T1,<DC.CNT!DC.CNN>	;SET MASK FOR TYPE AND NUMBER OF CONTROLLER

;HERE WITH T1=MASK, T3=MATCH

INSTM8:	MOVEM	T1,STRMSK	;STORE MASK
	MOVEM	T3,STRMTH	;STORE MATCH
	JRST	INSTR6		;AND FLAG FOR SYSSTR TYPE SEARCHING


;HERE WHEN SYS SEARCH LIST IS SELECTED

INSTR5:	SKIPN	SYSRCH		;SEE IF ALREADY SETUP
	PUSHJ	P,SETSYS##	;SETUP DIRECTORY FOR SYS:
INSTR6:	SETOM	SYSRCH		;FLAG FOR SYSTEM SEARCH LIST (F/S LIST)

;HERE WHEN ANY SEARCH LIST IS SELECTED

INSTR7:	SETOM	SRCH		;FLAG TO USE A SEARCH LIST
INSTRX:	SETZM	LASSTR		;CLEAR STRUCTURE TO START
	SKIPE	T1,SRCH		;SEE IF SEARCHING
	MOVX	T1,UU.PHS	;YES--RETURN /PHYSICAL
	JRST	.POPJ1##	;AND SKIP RETURN
;.NXSTR -- ROUTINE TO GET NEXT STRUCTURE
;CALL:	PUSHJ	P,.NXSTR
;NEVER SKIPS. RETURNS NAME IN T1, 0 IF DONE.
;RESULT SHOULD ALWAYS BE USED PHYSICAL ONLY

	ENTRY	.NXSTR

.NXSTR::SKIPN	SRCH		;HERE FOR NEXT--SEE IF SEARCHING
	JRST	CPOPJZ		;NO--GO TO NEXT REQUEST
NXSTR2:	MOVE	T1,LASSTR	;GET F/S NAME FOR LIST
	SKIPE	SYSRCH		;NEED A NEW F/S
	JRST	NXSTR3		;FROM SYSTEM F/S LIST
	SKIPN	T1		;SEE IF FIRST PASS
	SETOM	T1		;YES--BLANKETY-BLANK UUO
	MOVE	T2,[1,,T1]	;SETUP POINTER
	JOBSTR	T2,		;FROM JOB'S SEARCH LIST
	  HALT	CPOPJZ
	JRST	NXSTR5		;GOT IT

NXSTR3:	SKIPE	SY2RCH		;NEEDS SYS: S.L.
	SKIPE	STRMSK		;IF MASK, NEEDS ALL STR LIST
	JRST	.+2		;YES--USE IT
	JRST	NXSTR4		;GO USE REAL SYS: SEARCH LIST
	SYSSTR	T1,		;CAN'T--USE ALL STRS IN SYSTEM
	  HALT	CPOPJZ
	JRST	NXSTR5		;GOT IT--GO PROCESS

NXSTR4:	SKIPN	T1		;SEE IF AT START
	SETOM	T1		;YES--FOOLISH UUO
	MOVEM	T1,GOBST+2	;STORE STR IN GOBSTR'S ARG LIST
	SETZM	GOBST		;SPECIFY JOB 0
	MOVX	T1,%LDSYS	;GET LOCATION OF SYS:
	GETTAB	T1,		;FROM MONITOR
	  MOVE	T1,[1,,1]	;(LEV. C)
	MOVEM	T1,GOBST+1	;STORE IN ARGUMENT
	MOVEI	T1,GOBST	;SETUP SHORT BLOCK
	GOBSTR	T1,		;ASK MONITOR
	  HALT	CPOPJZ		;GIVE UP IF ERROR
	MOVE	T1,GOBST+2	;GET ANSWER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE WITH RESULT FROM S/L IN T1

NXSTR5:	CAMN	T1,[-1]		;LOOK FOR END
	JRST	CPOPJZ		;YES--DONE
	JUMPE	T1,CPOPJZ	;IF ZERO, ALL DONE
	MOVEM	T1,W.BLK##+.FXDEV
	MOVEM	T1,LASSTR	;SAVE FOR SEARCH

	MOVEM	T1,.WLDBF##	;DO A DSKCHR			[303]
	MOVE	T3,[.DCSAJ+1,,.WLDBF##]
	PUSHJ	P,DOPHYS##	; TO HANDLE			[303]
	  DSKCHR T3,		; SINGLE ACCESS			[303]
	    HALT CPOPJZ		; ..				[303]
	TXNE	T3,DC.SAF	;SEE IF SINGLE ACCESS		[303]
	JRST	[PJOB T2,	;YES--GET OUR JOB		[303]
		 XOR  T2,.WLDBF##+.DCSAJ ;COMPARE TO S.A. USER	[303]
		 TRNE T2,-1	;SEE IF MATCH			[303]
		 JRST NXSTR2	;NO--IGNORE STRUCTURE		[303]
		 JRST .+1]	;YES--OK TO TRY IT		[303]
	SKIPN	T2,STRMSK	;SEE IF MASKING RESULTS
	JRST	NXSTRX		;NO--PROCEED WITH RESULTS
	SKIPL	T2		;SKIP IF NAME MASKING
	SKIPA	T1,T3		;POSITION DSKCHR FOR MATCH
	MOVE	T1,W.BLK##+.FXDEV	;YES--GET BACK NAME		[303]
	XOR	T1,STRMTH	;SEE IF MATCHES
	TDNE	T1,STRMSK	;WHERE IMPORTANT
	JRST	NXSTR2		;NO--GO GET NEXT STR


;HERE TO RETURN VALUE TO THE CALLER

NXSTRX:	SKIPA	T1,W.BLK##+.FXDEV	;RETURN RESULT
CPOPJZ:	MOVEI	T1,0		;RETURN ZERO
	POPJ	P,		;RETURN
;DATA

	XLIST
	LIT
	LIST

	RELOC

;IMPURE STUFF

SUBSTR:	BLOCK	1		;FLAG CALL TO SUBROUTINE .NXSTR

.FRCPP::!			;GLOBAL ADDRESS
FRCPPN:	BLOCK	1		;FORCED PPN

GOBST:	BLOCK	5		;GOBSTR PARAMETER AREA

STRMSK:	BLOCK	1		;MASK FOR MATCHING STRS
				;  BY NAME IF LT 0, BY DSKCHR IF GT 0
STRMTH:	BLOCK	1		;MATCH FOR ABOVE
LASSTR:	BLOCK	1		;LAST STRUCTURE RETURNED

PHYS:	BLOCK	1		;PHYSICAL ONLY FLAG

SRCH:	BLOCK	1		;FLAG FOR SEARCH LIST IN USE
SYSRCH:	BLOCK	1		;FLAG FOR SYSTEM SEARCH LIST IN USE
SY2RCH:	BLOCK	1		;FLAG FOR REAL SYS: SEARCH LIST

> ;END REPEAT 0

	END