Google
 

Trailing-Edge - PDP-10 Archives - ap-c796e-sb - lokwld.mac
There are no other files named lokwld.mac in the archive.
	TITLE	LOKWLD -- SUBROUTINE TO PERFORM WILDCARD LOOKUP
	SUBTTL	P.CONKLIN/PFC		9-OCT-71


;***COPYRIGHT 1970, 1971  DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***


	INTERN	VLOKWL
VLOKWL==101,,0		;VERSION OF LOKWLD

;SUBROUTINE TO SCAN DIRECTORIES AND RETURN LOOKUP BLOCKS FOR THE
;VARIOUS NAMES WHICH MATCH WILD-CARDS.

;ASSEMBLY INSTRUCTIONS:
;
;	.COMPILE LOKWLD
;
;THEN LOAD THE .REL FILE WITH ANY PROGRAM NEEDING IT.
;THIS SUBROUTINE WORKS ON THE DATA BASE LEFT BY THE COMMAND DECODER.
;A LIST OF PARAMETER AREAS DEFINES THE FILES REQUESTED AND THE VARIOUS
;SYSTEM STRUCTURES AND DIRECTORIES ARE SEARCHED.

	ENTRY	.LKWLD

;ONLY ONE PRINCIPLE ENTRY POINT IS DEFINED--GET THE FIRST OR NEXT FILE.
;CALL:	(MOVEI I,0 INITIALLY)
;	PUSHJ	P,.LKWLD
;RETURN CPOPJ IF NO MORE DISK FILES WITH T2=-1 (DONE) OR THE NEXT DEVCHR
;SKIP RETURN WITH I POINTING TO PARAMETER AREA WHICH MATCHED AND FILE
;IN AREA POINTED TO BY J
;RETURNS T1=FILE NAME, T2=EXTENSION (RH=0), T3=STR NAME, T4=DIRECTORY

;SECONDARY ENTRY POINTS:
;	PUSHJ	P,.OPWLD
;		OPENS CHANNEL DC FOR THE SAME STRUCTURE
;		RETURNS T2=DEVICE, T3=BUFFER POINTER
;	PUSHJ	P,,NXDTW
;	  EOF RETURN
;	NORMAL RETURN WITH NEXT WORD IN T1
;		READS ONE WORD IN BINARY
;	PUSHJ	P,E.DFL
;		REPORTS LOOKUP ERROR 
;	(CODE IN RH T2, OPTIONAL STR IN T1,
;	PROT. IN 0-8 T3, DIRECTORY IN T4)
;	PUSHJ	P,.LKERR
;		REPORTS LOOKUP ERROR MESSAGE (NO FILE)
;	(CODE IN T1)

	INTERN	.NXDTW,.OPWLD,E.DFL,.TFILE,.LKERR
	INTERN	.WLDFL		;FLAG (-1 IF WILD, +1 IF STR WILD)

	TWOSEG
	RELOC	400000
;ACCUMULATORS


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

I=10	;INDEX TO COMMAND SCANNER DATA BASE

M=15	;MESSAGE POINTER
C=16	;CHARACTER
P=17	;PUSH DOWN LIST

;CHANNELS

MC==2	;READ MFD
UC==3	;READ UFD
DC==4	;READ DATA

;COMMUNICATION WITH THE MONITOR

D.GDSK==7B17	;GENERIC DSK IN DSKCHR UUO
D.DSK==1B1	;DISK DEVICE IN DEVCHR UUO
G.SYSP==1,,16	;GETTAB OF SYS: PPN
G.MFDP==0,,16	;GETTAB OF MFD PPN
G.STS==17,,11	;GETTAB OF SYSTEM STATES WORD
GD.STS==7B9	;LEVEL-D DISK SERVICE FIELD IN STATES
GD.ST2==6B9	;5.03 VARIANT OF LEVEL-D OR GREATER

LN.DRB==1	;LENGTH OF DIRECTORY BLOCK

	EXTERN	I.INZR	;INITIAL PARAMETER AREA
	EXTERN	I.LZER	;LENGTH OF EACH PARAMETER AREA
	EXTERN	I.NXZR	;LAST+1 PARAMETER AREA

	EXTERN	.TCRLF	;TYPE END OF LINE
	EXTERN	.TSTR	;TYPE ASCII STRING
	EXTERN	.TOCT	;TYPE OCTAL NUMBER
	EXTERN	.TSIXN	;TYPE SIXBIT WORD
	EXTERN	.TXWD	;TYPE WORD AS TWO OCTAL NUMBERS
	EXTERN	.TCHR	;TYPE CHARACTER
	EXTERN	.TNEWL	;FORCE BEGINNING OF LINE


	EXTERN	.JBFF	;START OF FREE CORE


	OPDEF	PJRST	[JRST]
	SUBTTL	LOOKUP ONE FILE

;HERE ON EXTERNAL CALL

.LKWLD:	JUMPN	I,UFD1		;IF ALREADY SETUP, CONTINUE
	MOVEI	T1,G.MFDP	;GET LOCATION OF MFD
	GETTAB	T1,		;FROM MONITOR
	  MOVE	T1,[1,,1]	;(LEV C)
	MOVEM	T1,MFDPPN	;SAVE FOR LATER
	SKIPA	I,I.INZR	;BRAND NEW--GET STARTING POINT

;LOOP OVER EACH FILE SPECIFICATION IN THE REQUEST
; TO FIND ANY AND ALL FILES WHICH MATCH IT

LOOKST:	ADDI	I,I.LZER	;NOT BRAND NEW--ADVANCE PARAMETER
	SETO	T2,		;FLAG ALL DONE JUST IN CASE
	CAML	I,I.NXZR	;SEE IF AT END YET
	POPJ	P,		;YES--FAILURE RETURN

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

	SETZM	FWAZER		;CLEAR TEMPORARIES
	MOVE	T1,[FWAZER,,FWAZER+1]  ; ..
	BLT	T1,LWAZER	; ..
	MOVEM	I,IFIR		;SAVE STARTING BLOCK
;LOOP TO DISCOVER A SET OF CONCATENATED FILE SPECIFICATIONS
;THE USER HAS CONCATENATED THEM TO CAUSE A SINGLE PASS WILD SEARCH.

LOOK1:	MOVEM	I,ILAS		;SAVE ENDING BLOCK
	HLRZ	T1,I.EXT(I)	;GET EXTENSION
	CAIE	T1,'UFD'	;SEE IF .UFD
	JRST	LOOK2		;NO--ALREADY SETUP CORRECTLY
	MOVE	T1,MFDPPN	;YES--GET CORRECT DIRECTORY
	EXCH	T1,I.DIR(I)	;STORE (MFD)
	MOVEM	T1,I.NAM(I)	;MOVE DIRECTORY TO NAME
	SETO	T1,		;CLEAR WILDCARDS
	EXCH	T1,I.DIRM(I)	;SET INTO DIRECTORY
	MOVEM	T1,I.NAMM(I)	;MOVE DIRECTORY TO NAME
LOOK2:	MOVSI	T1,(X.ADD)	;TEST FOR +
	TDNN	T1,I.MOD(I)	; IN CURRENT BLOCK
	JRST	DIR1		;NO--GO AHEAD AND WORK
	MOVE	T1,I.DEV(I)	;YES--COMPARE DEVICES
	ADDI	I,I.LZER	;ADVANCE TO NEXT ONE
	CAMGE	I,I.NXZR	;SEE IF OFF END
	CAME	T1,I.DEV(I)	;TEST
	JRST	DIR1		;DIFFERENT--IGNORE +
	MOVE	T1,IFIR		;SAME--COMPARE DIRECTORY
	MOVE	T2,I		; ENTRY
	HRLI	T1,-2*LN.DRB	; BY
LOOK3:	MOVE	T3,I.DIR(T2)	; ENTRY
	AOS	T2		; ..
	CAMN	T3,I.DIR(T1)	; ..
	AOBJN	T1,LOOK3	;LOOP BACK
	JUMPGE	T1,LOOK1	;LOOP IF MATCHED
;HERE WHEN CONCATENATED REQUESTS HAVE BEEN SELECTED TO DETERMINE
; WHAT TYPE OF SEARCHING TO DO ACROSS STRS

DIR1:	MOVE	I,IFIR		;REFETCH POINTER
	MOVSI	T1,(X.PHYS)	;SEE IF USER ASKED FOR PHYS.
	TDNN	T1,I.MOD(I)	; ..
	JRST	NOTPHY		;NO--SKIP TESTS
	MOVSI	T1,'SYS'	;YES--SEE IF POSSIBLE
	DEVCHR	T1,1B19		; BY TRYING ONE
	TRNE	T1,-1		;SEE IF GOT SOMETHING BACK
	SETOM	PHYS		;YES--SET FOR PHYS I/O
NOTPHY:	MOVE	T2,I.DEV(I)	;FIND OUT IF STRUCTURE SEARCH NECESSARY
	MOVEM	T2,FSTR		;STORE IN CURRENT STRUCTURE IN CASE NOT
	PUSHJ	P,DOPHYS	;PERFORM PHYSICAL I/O CALL
	  DEVCHR T2,		;SEE IF DISK TYPE DEVICE
	TLNN	T2,(D.DSK)	; ..
	POPJ	P,		;NO--RETURN
	SETO	T1,		;SEE IF ANY WILDCARDS
	CAMN	T1,I.NAMM(I)	;CHECK NAME
	CAME	T1,I.DIRM(I)	;NO--CHECK DIRECTORY
	JRST	SEEIFD		;YES--GO SEE IF LEVEL D
	XOR	T1,I.EXT(I)	;NO--CHECK EXTENSION
	CAMN	I,ILAS		;SEE IF CONCATENATION
	TRNE	T1,-1		;TEST EXT. MASK
	JRST	SEEIFD		;WILD--GO SEE IF LEVEL D

;HERE IF NOT A WILD FILE SPECIFICATION

	MOVSI	T1,(X.STRS)	;NOT WILD--SEE IF STR WILD
	TDNN	T1,I.MOD(I)	; BEING RQUESTED
	JRST	STR7		;NO--JUST USE USER'S DEVICE
	MOVEI	T1,1		;YES--FLAG STR WILD (BUT NOT FILE)
	JRST	DIR2		;AND GO SELECT A SEARCH LIST

;HERE WHEN THE FILE IS WILD

SEEIFD:	SETOB	T1,.WLDFL	;SET WILD FILE FLAG
DIR2:	MOVE	T2,[G.STS]	;SEE IF LEVEL D SYSTEM
	GETTAB	T2,		; ..
	  MOVEI	T2,0		;(NO)
	TLNN	T2,(GD.STS)	;TEST FIELD
	JRST	DIR3		;NO--NO FUNNY F/S LOGIC
	MOVEM	T1,.WLDFL	;YES--STORE FILE WILD FLAG
	TLNE	T2,(GD.ST2)	;SEE IF 5.03 OR LATER
	SETOM	SY2RCH		;YES--SET FLAG THAT REAL SYS: SL IS AVAILABLE
;HERE WHEN STRUCTURE WILD-CARD IS INDICATED
;CHECK DEVICE TO DETERMINE WHAT TYPE OF SEARCH LIST TO USE

	MOVE	T2,FSTR		;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 DIR4		;FAILED--MUST BE SYS:
	TLNN	T3,(D.GDSK)	;SEE IF GENERIC
	JRST	DIR5		;YES--PROCEED BELOW
	SKIPL	.WLDFL		;NO--SEE IF WILD FILE FLAG
	SETZM	.WLDFL		;YES--CLEAR WILD CARD INDICATOR
	JRST	STR7		;USE USER'S DEVICE

;HERE IF LEVEL-C WILDCARD INDICATED
;NEED TO CHECK FOR "SYS:" AND FIXUP DIRECTORY IF SO

DIR3:	MOVS	T1,I.DEV(I)	;GET DEVICE
	CAIN	T1,'SYS'	;SEE IF "SYS:"
	PUSHJ	P,SETSYS	;YES--SETUP FOR SYS:
	JRST	STR7		;PROCEED WITHOUT F/S LOGIC

;HERE WHEN SYS SEARCH LIST IS SELECTED

DIR4:	PUSHJ	P,SETSYS	;SETUP DIRECTORY FOR SYS:
	SETOM	SYSRCH		;FLAG FOR SYSTEM SEARCH LIST (F/S LIST)

;HERE WHEN ANY SEARCH LIST IS SELECTED

DIR5:	SETZM	LASSTR		;PRESET FOR SEARCH UUO
	SETOM	SRCH		;FLAG TO USE A SEARCH LIST
;BACK HERE TO GO TO NEXT STRUCTURE

STR1:	CLOSE	MC,10		;PREVENT UPDATE OF ACCESS DATES
	SKIPN	SRCH		;HERE FOR NEXT--SEE IF SEARCHING
	JRST	LOOKEN		;NO--GO TO NEXT STRUCTURE
	MOVE	T1,LASSTR	;GET F/S NAME FOR LIST
	SKIPE	SYSRCH		;NEED A NEW F/S
	JRST	STR2		;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	LOOKEN
	JRST	STR4		;GOT IT

STR2:	SKIPE	SY2RCH		;NEEDS SYS: S.L.
	JRST	STR3		;GO USE REAL SYS: SEARCH LIST
	SYSSTR	T1,		;CAN'T--USE ALL STRS IN SYSTEM
	  HALT	LOOKEN
	JRST	STR4		;GOT IT--GO PROCESS

STR3:	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
	MOVE	T1,I.DIR(I)	;GET SYSPPN
	MOVEM	T1,GOBST+1	;STORE IN ARGUMENT
	MOVEI	T1,GOBST	;SETUP SHORT BLOCK
	GOBSTR	T1,		;ASK MONITOR
	  HALT	LOOKEN		;GIVE UP IF ERROR
	MOVE	T1,GOBST+2	;GET ANSWER

STR4:	CAMN	T1,[-1]		;LOOK FOR END
	JRST	LOOKEN		;YES--DONE
	JUMPE	T1,LOOKEN	;IF ZERO, ALL DONE
	MOVEM	T1,FSTR
	MOVEM	T1,LASSTR	;SAVE FOR SEARCH
;HERE TO START ONE DEVICE (NEW F/S)

STR7:	AOS	NOSTRS		;COUNT STR FOUND
	PUSHJ	P,SETOPN	;SETUP OPEN BLOCK
	MOVEI	T3,B.MC
	OPEN	MC,T1
	  JRST	E.MFO		;FAILURE

	MOVEI	T1,BF.MC	;SETUP SPECIAL BUFFER AREA
	EXCH	T1,.JBFF	;IN OUR RESERVED LOCATION
	INBUF	MC,1		;JUST ONE BUFFER FOR MFD READING
	EXCH	T1,.JBFF	;RESTORE .JBFF
	CAILE	T1,BF.UC	;SEE IF WE WON
	HALT	.		;NO--DIE

	PUSHJ	P,SETOPN	;SETUP OPEN BLOCK
	MOVEI	T3,B.UC
	OPEN	UC,T1
	  JRST	E.UFO		;FAILURE

	MOVEI	T1,BF.UC	;SETUP SPECIAL BUFFER AREA
	EXCH	T1,.JBFF	;IN OUR RESERVED LOCATION
	INBUF	UC,2		;TWO BUFFERS FOR UFD READING
	EXCH	T1,.JBFF	;RESTORE .JBFF
	CAILE	T1,BF.UE	;SEE IF WE WON
	HALT	.		;NO--DIE
;HERE TO LOOK THROUGH MFD FOR NEXT UFD

	MOVE	T1,I.DIR(I)	;SET SPECIFIED DIRECTORY IN PLACE
	MOVEM	T1,UFDPPN	;IN THE LOOKUP AREA
	SETOB	T1,NOUFD	;SET FLAG FOR NO WILDCARD
	CAMN	T1,I.DIRM(I)	;SEE IF A WILDCARD SPECIFIED
	JRST	MFD7		;NO--SKIP WILDCARD LOGIC
	SETZM	NOUFD		;YES--CLEAR FLAG
	MOVE	T1,MFDPPN	;LOOK-UP MFD
	MOVSI	T2,'UFD'
	MOVEI	T3,0
	MOVE	T4,MFDPPN
	LOOKUP	MC,T1
	  JRST	E.MFL		;FAILURE

;HERE TO LOOK FOR NEXT UFD

MFD1:	CLOSE	UC,10		;DON'T UPDATE ACCESS DATE
	SKIPL	NOUFD		;SEE IF WILDCARD FLAG SET
	PUSHJ	P,NXMFDW	;YES--GET NEXT MFD WORD--UFD NAME
	  JRST	STR1		;JUMP IF ALL DONE
	MOVEM	T1,UFDPPN	;SAVE IT
	PUSHJ	P,NXMFDW	;GET EXTENSION WORD
	  JRST	E.MFX		;BAD MFD READ IF EOF HERE
	HLRZ	T1,T1		;POSITION EXTENSION FOR TEST
	CAIE	T1,'UFD'	;SEE IF A UFD
	  JRST	MFD1		;LOOP BACK IF NOT A UFD
	MOVE	T3,UFDPPN	;GET UFD NAME
	JUMPE	T3,MFD1		;LOOP BACK IF EMPTY NAME
	AOS	NOUFD		;COUNT ACTUAL NUMBER OF UFDS
	XOR	T3,I.DIR(I)	;COMPARE WITH REQUEST
	AND	T3,I.DIRM(I)
	JUMPN	T3,MFD1		;LOOP-BACK IF NOT REQUESTED
MFD7:	AOS	NOUFDF		;COUNT THAT WE FOUND A UFD
;HERE TO LOOK-UP NEXT UFD

	MOVE	T1,I.NAM(I)	;SET SPECIFIED FILE NAME
	MOVEM	T1,FNAM		;INTO THE LOOKUP AREA
	MOVE	T1,I.EXT(I)	;ALSO THE EXTENSION
	HLLZM	T1,FEXT		; ..
	SKIPL	.WLDFL		;SEE IF WILD CARD
	JRST	UFD7		;NO--GO SKIP WILDCARD LOGIC
	MOVE	T1,UFDPPN	;LOOK-UP UFD
	MOVSI	T2,'UFD'
	MOVEI	T3,0
	MOVE	T4,MFDPPN
	LOOKUP	UC,T1
	  JRST	E.UFL
	AOS	NSUFD		;COUNT SUCCESSFUL LOOKUP
;HERE TO LOOK FOR NEXT FILE IN THIS UFD

UFD1:	SKIPGE	.WLDFL		;SEE IF WILDCARD FLAG IS SET
	PUSHJ	P,NXUFDW	;YES--GET NEXT UFD WORD--FILE NAME
	  JRST	MFD1		;JUMP IF ALL DONE
	MOVEM	T1,FNAM		;SAVE IT
	PUSHJ	P,NXUFDW	;GET EXTENSION WORD
	  JRST	E.UFX		;BAD UFD READ IF EOF HERE
	HLLZM	T1,FEXT		;SAVE IT
	SKIPN	FNAM		;SEE IF NAME MATCHES
	JRST	UFD1		;IGNORE IF EMPTY ENTRY
	AOS	NOFIL		;COUNT SOMETHING IN UFD
	MOVE	I,IFIR		;POSITION TO FIRST OF SET

;LOOP OVER THE CONCATENATED REQUESTS TO SEE IF IT MATCHES ANY

UFD3:	MOVE	T3,FNAM		;GET FILE NAME
	XOR	T3,I.NAM(I)
	AND	T3,I.NAMM(I)
	JUMPN	T3,UFD5		;FILE NAME MISMATCH--IGNORE
	HLLZ	T3,FEXT		;SEE IF EXTENSION MATCHES
	XOR	T3,I.EXT(I)
	TLNN	T3,(T3)		; ..
	JRST	UFD7		;MATCHES--REPORT WINNINGS
UFD5:	ADDI	I,I.LZER	;FAILS--MOVE TO NEXT OF + SET
	CAMG	I,ILAS		;SEE IF BEYOND END
	JRST	UFD3		;NO--TRY IT
	MOVE	I,ILAS		;RESET I TO A MEANINGFUL PLACE
	JRST	UFD1		;YES--MISMATCH GO GET NEXT FILE

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

UFD7:	AOS	NOFILF		;COUNT FILE FOUND
	MOVE	T1,FNAM		;GET FILE NAME
	HLLZ	T2,FEXT		;AND EXTENSION
	MOVE	T3,FSTR		;AND STR
	MOVE	T4,UFDPPN	;AND DIRECTORY
	JRST	CPOPJ1		;RETURN SUCCESSFULLY
;HERE AT END OF A REQUEST TO SEE IF ANYTHING WAS FOUND
;IF NOT, AN APPROPRIATE ERROR MESSAGE WILL BE TYPED

LOOKEN:	MOVE	I,ILAS		;RESET POINTER
	MOVSI	T1,(X.NOMK)	;SEE IF WE CARE IF ANY MATCHED
	TDNN	T1,I.MOD(I)	; ..
	SKIPE	NOFILF		;YES--SEE IF ANYTHING FOUND
	JRST	LOOKST		;YES--GO BACK TO NEXT REQUEST
	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	HRLZI	T1,I.DEV(I)	;COPY ORIGINAL REQUEST
	HRRI	T1,FSTR		;  INTO ANSWER AREA
	BLT	T1,MOD		;  FOR TYPE OUT
	SKIPE	NOFIL		;NO--SEE IF ANY FILES EXAMINED
	JRST	E.NSF		;YES--JUST NO SUCH FILES
	SKIPE	NOUFDF		;NO--SEE IF ANY UFDS MATCHED
	JRST	E.DEM		;YES--DIRECTORY EMPTY
	SKIPE	NOSTRS		;SEE IF ANY STRUCTURES FOUND
	JRST	E.NSD		;YES--JUST NO SUCH DIRECTORY

;ERROR:	SEARCH LIST IS EMPTY

E.SLE:	MOVEI	M,[ASCIZ /% Search list empty for device /]
	PUSHJ	P,.TSTR		;TYPE MESSAGE
	PUSHJ	P,TYPSTR	;AND STR NAME
	JRST	LOOKNX		;AND RETURN

;ERROR:	NO DIRECTORY MATCHES THE USER'S REQUEST

E.NSD:	MOVEI	M,[ASCIZ /% No such d/]  ;NO--NO SUCH DIRECTORY
	PUSHJ	P,DIRERR	;ISSUE DIRECTORY ERROR
	JRST	LOOKNX		;GO ISSUE CRLF AND RETURN

;ERROR:	THE DIRECTORY IS EMPTY

E.DEM:	SKIPE	UFDEF		;SEE IF WE FOUND AN ERROR YET
	JRST	LOOKST		;YES--DON'T REPORT IT AGAIN
	SKIPN	NSUFD		;SEE IF ANY SUCCESSFULLY LOOKED UP
	JRST	E.NXD		;NO--GO GIVE MESSAGE
	MOVEI	M,[ASCIZ /% D/]
	PUSHJ	P,DIRERR	;ISSUE DIRECTORY ERROR
	MOVEI	M,[ASCIZ / is empty/]
	PUSHJ	P,.TSTR		;DIRECTORY EMPTY MESSAGE
	JRST	LOOKNX		;GO ISSUE CRLF AND RETURN
;ERROR:	ALL MATCHING UFDS WERE NON-EXISTENT

E.NXD:	MOVEI	M,[ASCIZ /% Non-existent/]
	PUSHJ	P,UFDERR	;ISSUE DEVICE AND UFD CODE
	JRST	LOOKST		;AND START OVER

;ERROR:	NO FILE MATCHES THE USER'S REQUEST

E.NSF:	MOVEI	M,[ASCIZ /% No such files as /]
	PUSHJ	P,FILOUT	;ISSUE FILE ERROR

LOOKNX:	PUSHJ	P,.TCRLF	;ISSUE NEW LINE
	JRST	LOOKST		;GO BACK FOR NEXT REQUEST
	SUBTTL	DIRECTORY SUBROUTINES

;NXMFDW -- GET NEXT WORD FROM MFD FILE
;CALL:	PUSHJ	P,NXMFDW
;	ERROR RETURN IF END-OF-FILE
;	NORMAL RETURN WITH WORD IN T1
;USES M, C

NXMFDW:	SOSGE	B.MC+2		;SEE IF WORD IN BUFFER
	JRST	NXMFDR		;NO--READ SOME MORE OF MFD
	ILDB	T1,B.MC+1	;FETCH WORD
	JRST	CPOPJ1		;SKIP RETURN

NXMFDR:	IN	MC,		;READ
	  JRST	NXMFDW		;OK TO PROCEED

	STATZ	MC,740000	;SEE IF ANY ERRORS
	  PUSHJ	P,E.MFE		;YES
	STATO	MC,20000	;CHECK FOR EOF
	  JRST	NXMFDW		;NO--GO BACK TO READ SOME MORE
	POPJ	P,		;YES--GIVE EOF RETURN


;ERROR:	MFD OPEN

E.MFO:	MOVEI	M,[ASCIZ /MFD/]
	PJRST	OPNERR

;ERROR: MFD LOOKUP ERROR

E.MFL1:	MOVEI	T2,0		;FUDGE FILE NOT FOUND ERROR
E.MFL:	PUSHJ	P,LKERR		;OUTPUT LOOKUP ERROR
	  JRST	E.MFL1		; (IF UFD FAILED)
	MOVEI	M,[0]
	JRST	E.MFY

;ERROR:	MFD IS ODD NUMBER OF WORDS LONG

E.MFX:	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% Strange EOF in/]
E.MFY:	PUSHJ	P,MFDERR	;OUTPUT MFD ERROR
	JRST	STR1		;AND TRY NEXT STRUCTURE

;ERROR:	I/O ERROR WHILE READING MFD

E.MFE:	GETSTS	MC,T1		;DATA ERROR--GET STATUS
	PUSHJ	P,STSERR	;OUTPUT MESSAGE
	SETSTS	MC,(T1)		;AND CLEAR ERROR BITS
	PJRST	MFDER1		;OUTPUT MFD ERROR
;NXUFDW -- GET NEXT WORD FROM UFD FILE
;CALL:	PUSHJ	P,NXUFDW
;	ERROR RETURN IF END-OF-FILE
;	NORMAL RETURN WITH WORD IN T1
;USES M, C

NXUFDW:	SOSGE	B.UC+2		;SEE IF WORD IN BUFFER
	JRST	NXUFDR		;NO--READ SOME MORE OF UFD
	ILDB	T1,B.UC+1	;FETCH WORD
	JRST	CPOPJ1		;SKIP RETURN

NXUFDR:	IN	UC,		;READ
	  JRST	NXUFDW		;OK TO PROCEED

	STATZ	UC,740000	;SEE IF ANY ERRORS
	  PUSHJ	P,E.UFE		;YES
	STATO	UC,20000	;SEE IF EOF SET
	  JRST	NXUFDW		;YES--LOOP BACK
	POPJ	P,		;NO--EOF RETURN


;ERROR:	UFD OPEN

E.UFO:	MOVEI	M,[ASCIZ /UFD/]
	PJRST	OPNERR

;ERROR:	UFD LOOKUP FAILURE

E.UFL:	TRNN	T2,-1		;SEE IF NON-EXISTENT ERROR
	SKIPL	SRCH		;AND STR SEARCHING
	JRST	.+2		;NO--PROCEED
	JRST	MFD1		;YES--SKIP MESSAGE FOR NOW
	PUSHJ	P,LKERR		;OUTPUT LOOKUP ERROR
	  JRST	E.MFL1		; (IF UFD FAILED)
	SETOM	UFDEF		;FLAG THAT ERROR WAS FOUND
	MOVEI	M,[0]
	JRST	E.UFY

;ERROR:	UFD IS ODD NUMBER OF WORDS LONG

E.UFX:	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% Strange EOF in/]
E.UFY:	PUSHJ	P,UFDERR	;OUTPUT UFD ERROR
	JRST	MFD1		;AND TRY NEXT DIRECTORY

;ERROR:	I/O ERROR WHILE READING UFD

E.UFE:	GETSTS	UC,T1		;DATA ERROR--GET STATUS
	PUSHJ	P,STSERR	;OUTPUT MESSAGE
	SETSTS	UC,(T1)		;AND CLEAR ERROR BITS
	PJRST	UFDER1		;OUTPUT UFD ERROR
;.NXDTW -- GET NEXT WORD FROM DATA FILE
;CALL:	PUSHJ	P,.NXDTW
;	ERROR RETURN IF END-OF-FILE
;	NORMAL RETURN WITH WORD IN T1
;USES M, C

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

NXDATR:	IN	DC,		;READ
	  JRST	.NXDTW		;OK TO PROCEED

	STATZ	DC,740000	;SEE IF ANY ERRORS
	  PUSHJ	P,E.DFE		;YES
	STATO	DC,20000	;SEE IF EOF
	  JRST	.NXDTW		;NO--GET MORE DATA
	POPJ	P,		;YES--EOF RETURN



;ERROR:	DATA FILE OPEN

E.DFO:	MOVEI	M,[ASCIZ /data file/]
OPNERR:	PUSH	P,M		;SAVE MESSAGE INSERT
	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% Open failure for/]
	PUSHJ	P,.TSTR		;OUTPUT ERROR
	POP	P,M		;RECOVER INSERT
	PUSHJ	P,STRERR	;OUTPUT STRUCTURE NAME
	PJRST	.TCRLF		;END LINE AND RETURN

;ERROR:	DATA FILE LOOKUP ERROR

E.DFL:	SKIPE	T1		;SEE IF BETTER STR SPECIFIED
	MOVEM	T1,FSTR		;YES--UPDATE DIAGNOSTIC
	SKIPE	T4		;SEE IF BETTER UFD SPECIFIED
	MOVEM	T4,UFDPPN	;YES--UPDATE DIAGNOSTIC
	PUSHJ	P,LKERR		;OUTPUT LOOKUP ERROR
	  JRST	.+2		; (IF UFD FAILED)
	PJRST	.TFILE		;OUTPUT FILE NAME AND RETURN
	SKIPE	SRCH		;SEE IF MULTIPLE STRS
	JRST	E.NXU		;NO--ISSUE MESSAGE
	SOS	NOSTRS		;YES--BACK OFF COUNTER
	POPJ	P,		;AND RETURN
E.NXU:	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% Non-existent/]
	PJRST	UFDERR		;OUTPUT UFD NAME AND RETURN
;ERROR:	I/O ERROR WHILE READING DATA FILE

E.DFE:	GETSTS	DC,T1		;GET STATUS BITS
	PUSHJ	P,STSERR	;OUTPUT STATUS MESSAGE
	SETSTS	DC,(T1)		;CLEAR ERROR BITS
	PJRST	.TFILE		;OUTPUT FILE NAME
;LKERR -- OUTPUT LOOKUP ERROR MESSAGE
;CALL:	MOVEI	T2,ERROR CODE
;	MOVEI	T3,PROTECTION IF ERROR 2
;	PUSHJ	P,LKERR
;	ERROR RETURN IF UFD BAD
;USES T1, T2, T3, M, C

LKERR:	HRRZ	T1,T2		;GET ERROR CODE
	CAIN	T1,1		;SEE IF UFD ERROR
	POPJ	P,		;YES--ERROR RETURN
	AOS	(P)		;NO--ADVANCE RETURN
	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% /]
	PUSHJ	P,.TSTR		;LIST FLAG

;SUBROUTINE ENTRY TO TYPEOUT A LOOKUP ERROR CODE
;CALL IS SAME AS LKERR EXCEPT ERROR IN T1 (LH=0)
;AND ALWAYS RETURNS CPOPJ
;WILL GIVE HUMAN MESSAGE FOR COMMON ERRORS

.LKERR:	CAIE	T1,6		;SEE IF RIB ERROR OR
	CAIG	T1,2		; OTHER KIND OF COMMON ERROR
	JRST	LKERR1		;YES--GO HANDLE
	MOVEI	M,[ASCIZ /Lookup failure /]
	PUSHJ	P,.TSTR		;NO--PRINT OCTAL CODE
	PJRST	.TOCT		;  AND RETURN
LKERR1:	MOVEI	M,[ASCIZ /Non-existent/]
	CAIN	T1,1
	MOVEI	M,[ASCIZ /Non-existent UFD/]
	CAIN	T1,6
	MOVEI	M,[ASCIZ /RIB or directory read error/]
	CAIE	T1,2
	PJRST	.TSTR		;ISSUE MESSAGE AND RETURN
	MOVEI	M,[ASCIZ /Protection/]
	PUSHJ	P,.TSTR		;ISSUE PROTECTION MESSAGE
	LSH	T3,-^D27	;POSITION PROTECTION CODE
	MOVEI	C," "
	SKIPE	T3
	PUSHJ	P,.TCHR
	SKIPE	T1,T3
	PUSHJ	P,.TOCT
	MOVEI	M,[ASCIZ / failure/]
	PJRST	.TSTR		;AND RETURN
;STSERR -- ISSUE I/O STATUS ERROR MESSAGE
;CALL:	GETSTS	T1
;	PUSHJ	P,STSERR
;UPDATES T1 TO CLEAR ERROR BITS
;USES M, C

STSERR:	PUSHJ	P,.TNEWL	;FORCE BEGINNING OF LINE
	MOVEI	M,[ASCIZ /% Error /]
	PUSHJ	P,.TSTR		;ISSUE MESSAGE
	PUSH	P,T1		;SAVE STATUS
	PUSH	P,T2		;SAVE ACS
	PUSH	P,T3		; ..
	PUSHJ	P,.TOCT		;LIST STATUS
	POP	P,T3		;RESTORE ACS
	POP	P,T2		; ..
	POP	P,T1		;RESTORE STATUS
	TRZ	T1,740000	;CLEAR ERROR BITS
	MOVEI	M,[ASCIZ / while reading/]
	PJRST	.TSTR		;AND REST OF MESSAGE
;MFDERR -- ISSUE MESSAGE THAT ERROR IS IN MFD
;CALL:	MOVEI	M,MESSAGE
;	PUSHJ	P,MFDERR
;USES T1, M, C

MFDERR:	PUSHJ	P,.TSTR		;ISSUE REMNANTS OF MESSAGE
MFDER1:	MOVEI	M,[ASCIZ / MFD/]
	PUSHJ	P,STRERR	;OUTPUT STRUCTURE NAME
	PJRST	.TCRLF		;END LINE AND RETURN



;.TFILE--OUTPUT UFD OR FILE NAME
;CALL:	PUSHJ	P,.TFILE
;USES T1, M, C

.TFILE:	HLRZ	T1,FEXT		;SEE WHAT KIND OF FILE
	CAIE	T1,'UFD'	;SEE IF DIRECTORY
	JRST	DATERR		;NO--OUTPUT NORMAL FILE NAME
	JRST	UFDER1		;YES--OUTPUT DIRECTORY



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

UFDERR:	PUSHJ	P,.TSTR		;SEND REST OF MESSAGE
UFDER1:	MOVEI	M,[ASCIZ / UFD [/]
	PUSHJ	P,UFDLSN	;OUTPUT DIRECTORY
	PUSHJ	P,STRER1	;OUTPUT STRUCTURE
	PJRST	.TCRLF		;END LINE AND RETURN



;DATERR -- ISSUE MESSAGE THAT ERROR IS IN A FILE
;CALL:	PUSHJ	P,DATERR
;USES T1, M, C

DATERR:	MOVEI	M,[ASCIZ / file /]
	PUSH	P,T2		;SAVE AC
	PUSHJ	P,FILOUT	;OUTPUT FILE NAME AND EXTENSION
	POP	P,T2		;RESTORE AC
	PJRST	.TCRLF		;AND END LINE AND RETURN
;FILOUT -- OUTPUT MESSAGE AND NAME OF FILE AND EXTENSION
;CALL:	MOVEI	M,MESSAGE
;	PUSHJ	P,FILOUT
;USES T1, T2, M, C

FILOUT:	PUSHJ	P,.TSTR		;TYPE PREFIX
	PUSHJ	P,TYPSTR	;OUTPUT DEVICE
	MOVE	T2,FNAM		;GET FILE NAME
	PUSHJ	P,.TSIXN	;LIST IT
	HLLZ	T2,FEXT		;GET FILE EXTENSION
	MOVEI	C,"."		;AND SEPARATOR
	MOVSI	T1,(X.NULL)	;SEE IF USER SPECIFIED NO EXT
	SKIPN	T2		; OR WE HAVE EXPLICIT EXT.
	TDNN	T1,I.MOD(I)	; NULL, SEE IF HE GAVE .
	PUSHJ	P,.TCHR		;YES--TYPE SEPARATOR
	PUSHJ	P,.TSIXN	;LIST EXTENSION
	MOVEI	M,[ASCIZ /[/]
	PJRST	UFDLSN		;OUTPUT DIRECTORY AND RETURN



;DIRERR -- ISSUE DIRECTORY ERROR MESSAGE
;CALL:	MOVEI	M,MESSAGE + D
;	PUSHJ	P,DIRERR
;USES T1, M, C

DIRERR:	PUSHJ	P,.TSTR		;OUTPUT FIRST LETTER
	MOVEI	M,[ASCIZ /irectory [/]
	PUSHJ	P,UFDLSN	;OUTPUT DIRECTORY
	PJRST	STRER1		;OUTPUT DEVICE


;UFDLSN -- ISSUE MESSAGE AND NAME OF DIRECTORY
;CALL:	MOVEI	M,MESSAGE
;	PUSHJ	P,UFDLSN
;USES T1, M, C

UFDLSN:	PUSHJ	P,.TSTR		;IDENTIFY UFD
	PUSH	P,T4		;SAVE SOME ACS
	PUSH	P,T3		; ..
	PUSH	P,T2		; ..
	MOVE	T4,UFDPPN	;GET UFD NUMBER
	PUSHJ	P,.TXWD		;AND LIST IT
	MOVEI	M,[ASCIZ /]/]
	PUSHJ	P,.TSTR		;OUTPUT END OF DIRECTORY
	POP	P,T2		;RESTORE THOSE ACS
	POP	P,T3		; ..
	POP	P,T4		; ..
	POPJ	P,		;AND RETURN
;STRERR -- OUTPUT MESSAGE AND STRUCTURE NAME
;CALL:	MOVEI	M,MESSAGE
;	PUSHJ	P,STRERR
;USES T1, M, C

STRERR:	PUSHJ	P,.TSTR		;OUTPUT MESSAGE
STRER1:	MOVEI	M,[ASCIZ / on device /]
	PUSHJ	P,.TSTR		;OUTPUT IDENTIFICATION
TYPSTR:	PUSH	P,T2		;SAVE AC
	MOVE	T2,FSTR		;GET DEVICE NAME
	PUSHJ	P,.TSIXN	;OUTPUT IT
	POP	P,T2		;RESTORE AC
	MOVEI	C,":"		;AND SEPARATOR
	PJRST	.TCHR		; ..



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

SETSYS:	MOVE	T1,[G.SYSP]	;GET LOCATION OF SYS:
	GETTAB	T1,		;FROM MONITOR
	  MOVE	T1,[1,,1]	;(LEV C)
	MOVEM	T1,I.DIR(I)	;AND OVERSTORE REQUEST
	SETOM	I.DIRM(I)	;AND NO WILD DIRECTORY
	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,1B19		;YES--TURN ON PHYSICAL BIT
	XCT	T1		;DO THE CALLI
	POPJ	P,		;OK RETURN
CPOPJ1:	AOS	(P)		;SKIP
	POPJ	P,		;RETURN



;.OPWLD -- OPEN DATA CHANNEL FOR WILD LOOKUP
;CALL:	PUSHJ	P,.OPWLD
;RETURNS T2=DEVICE NAME, T3=BUFFER POINTER ADDRESS
;USES T1

.OPWLD:	PUSHJ	P,SETOPN	;SETUP OPEN BLOCK
	MOVEI	T3,B.DC		;SET BUFFER POINTERS
	OPEN	DC,T1		;OPEN DEVICE
	  JRST	E.DFO		;IN CASE OF ERROR
	POPJ	P,		;RETURN



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

SETOPN:	MOVEI	T1,14		;OPEN MFD (BINARY READ)
	SKIPN	PHYS		;SEE IF PHYS I/O REQUESTED
	SKIPE	SRCH		;OR IF USING A SEARCH LIST
	TLO	T1,(1B0)	;YES--SET FOR PHYS OPEN
	MOVE	T2,FSTR
	POPJ	P,		;RETURN
	XLIST	;LITERALS
	LIT
	LIST
	RELOC

FWAZER:!	;START OF TEMPORARIES (CLEARED EACH REQUEST)
		;THIS PARALLELS INPUT PARAMETER AREA
FSTR:	BLOCK	1	;CURRENT STRUCTURE
FNAM:	BLOCK	2	;CURRENT FILE NAME
FEXT:	BLOCK	1	;CURRENT FILE EXTENSION
UFDPPN:	BLOCK	2*LN.DRB  ;CURRENT DIRECTORY
MOD:	BLOCK	1	;CURRENT SWITCHES

LASSTR:	BLOCK	1	;LAST STR FROM SEARCH UUOS
NOSTRS:	BLOCK	1	;NUMBER OF STRS IN SEARCH LIST
NOFILF:	BLOCK	1	;NUMBER OF FILES FOUND
NOFIL:	BLOCK	1	;NUMBER OF FILES LOOKED AT
NOUFDF:	BLOCK	1	;NUMBER OF UFDS FOUND
NOUFD:	BLOCK	1	;NUMBER OF UFDS LOOKED AT
NSUFD:	BLOCK	1	;NUMBER OF EXISTENT UFDS FOUND
.WLDFL:	BLOCK	1	;FILE WILD FLAG (-1=WILD FILE, +1=WILD STR ONLY, 0=NEITHER)
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
SYSRCH:	BLOCK	1	;FLAG FOR SYSTEM SEARCH LIST IN USE
SY2RCH:	BLOCK	1	;FLAG FOR REAL SYS: SEARCH LIST
IFIR:	BLOCK	1	;FIRST I IN LINKED SET
ILAS:	BLOCK	1	;LAST I IN LINKED SET
GOBST:	BLOCK	5	;GOBSTR PARAMETER AREA
LWAZER==.-1	;END OF CLEARED AREA


MFDPPN:	BLOCK	1	;DIRECTORY FOR MFD

B.MC:	BLOCK	3	;MFD BUFFER HEADER
B.UC:	BLOCK	3	;UFD
B.DC:	BLOCK	3	;DATA

BF.MC:	BLOCK	203	;MFD BUFFER RING
BF.UC:	BLOCK	406	;UFD
BF.UE:!

	LOC	0
I.DEV:!	BLOCK	1	;DEVICE
I.NAM:!	BLOCK	1	;FILE NAME
I.NAMM:!BLOCK	1	;FILE NAME MASK
I.EXT:!	BLOCK	1	;FILE EXTENSION
I.DIR:!	BLOCK	LN.DRB	;FILE DIRECTORY
I.DIRM:!BLOCK	LN.DRB	;FILE DIRECTORY MASK
I.MOD:!	BLOCK	1	;FILE CONTROL SWITCHES

X.NULL==1B1		;NO . TYPED FOR EXTENSION
X.PHYS==1B3		;PHYSICAL I/O REQUESTED
X.NOMK==1B4		;ALL OK IF NO FILES MATCH WILDCARD
X.ADD==1B6		;NEXT FILE IS PART OF WILDCARD
X.STRS==1B9		;REQUEST WILD STR SEARCH EVEN IF NO WILD FILE

	END