Google
 

Trailing-Edge - PDP-10 Archives - bb-x130a-sb - swifil.mac
There are 7 other files named swifil.mac in the archive. Click here to see a list.
	TITLE	.FILE	SWIL file-level operations
	SUBTTL	Robert Houk/RDH

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

	SALL				;PRETTY LISTINGS
	.DIREC	FLBLST			;PRETTIER LISTINGS

	TWOSEG	400000

Copyright (C) Digital Equipment Corporation 1984.

	COMMENT	\

Copyright (C) 1984
Digital Equipment Corporation, Maynard, Massachusetts, U.S.A.

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.

\


;SWIFIL VERSION IDENTIFICATION

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

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

IF2,<	PURGE	CSTVER,MAJVER,MINVER,EDTVER>
	SUBTTL	Revision history

;INITIAL CREATION 21-MAR-80
	SUBTTL	IOINA - Allocate and initialize I/O CDB

;IOINA  --  ALLOCATE AND INITIALIZE AN I/O CHANNEL CONTROL BLOCK
;Call is:
;
;	MOVX	T2,<IVC>
;	PUSHJ	P,.IOINA
;	 error return
;	normal return
;
;Where <IVC> is the address of the initialization vector used to setup
;the CDB.
;
;On error return no memory was available.
;
;On normal return the CDB has been allocated and is set for use by the
;file operations. The address of the CDB is returned in T1.
;
;Uses T2 - T4.

	ENTRY	.IOINA
	INTERN	IOINA0,	IOINA1

.IOINA:
IOINA0:
IOINA1:	PUSHJ	P,IOINA5	;ALLOCATE THE CDB
	 POPJ	P,		;NO MEMORY
	PJRST	.IOINI		;NOW SETUP THE CDB

;ALLOCATE THE CDB

IOINA5:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
	PUSHJ	P,TSAV12##	;ALSO SAVE THE VECTOR POINTER
	PUSHJ	P,.INVWI##	;INITIALIZE INVWD
	PUSHJ	P,.INVWD##	;READ THE EXTRA SPACE ALLOCATION REQUESTED
	ADDI	T1,.IOMAX	;ADD IN BASE SIZE OF THE CDB
	PUSHJ	P,.MMGWD##	;ALLOCATE A HUNK OF MEMORY
	 STOPCD	<Memory allocation failed in IOINA5>
	MOVEM	T2,-T1(P)	;SAVE ADDRESS OF NEW CDB
	CAILE	T1,.IOMAX	;WAS THERE ANY EXTRA SPACE?
	MOVEM	T1,.IOXSZ(T2)	;YES, SET "EXTRA" SPACE MARKER
	MOVEI	T1,.IOMAX	;BASE SIZE OF THE CDB
	MOVEM	T1,.IOSIZ(T2)	;SET THAT TOO IN THE CDB
	JRST	.POPJ1##	;SUCCESSFUL RETURN
	SUBTTL	IOINI - Initialize an I/O CDB

;IOINI  --  INITIALIZE AN I/O CHANNEL CONTROL BLOCK
;Call is:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<IVC>
;	PUSHJ	P,.IOINI
;	 error return
;	normal return
;
;Where <CDB> is the address of the "I/O Channel Control Block"; and
;<IVC> is the address of the initialization vector used to setup the
;CDB.
;
;The error return is not exercised.
;
;On normal return the CDB is set for use by file open routines.
;
;Uses T4.

	ENTRY	.IOINI
	INTERN	IOINI0,	IOINI1

.IOINI:	PUSHJ	P,.SACIO##	;SETUP IO
IOINI0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
IOINI1:	PUSHJ	P,.INVWI##	;SETUP FOR INVWD CALLS
	MOVEM	T1,.IOCVR(IO)	;SAVE VERSION WORD IN THE CDB
	SETZM	.IOCCF(IO)	;CLEAR ALL FLAGS
	SETZM	.IOBZI(IO)	;ZERO START OF TO-BE-ZEROED BLOCK
	MOVSI	T4,.IOBZI(IO)	;CONCOCT A
	HRRI	T4,.IOBZI+1(IO)	; BLT POINTER TO
	BLT	T4,.IOEZI-1(IO)	;  ZERO THE CDB
	MOVEI	T4,.IOMAX	;INITIAL SIZE OF THE CDB
	SKIPN	.IOSIZ(IO)	;IS THE SIZE SET (PRESUMABLY CORRECTLY)?
	MOVEM	T4,.IOSIZ(IO)	;NO, SET IN THE CDB FOR OTHERS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW SETUP THE CDB BASED ON THE INITIALIZATION VECTOR

;ANY "EXTRA" SPACE REQUIREMENTS

	PUSHJ	P,.INVWD##	;GET DEFAULT EXTRA SPACE REQUIREMENTS
				; AND JUST EAT IT (ONLY MEANINGFUL FOR IOINA)
	SKIPE	T4,.IOXSZ(IO)	;ANY "EXTRA" SPACE ALLOCATED?
	MOVEI	T4,.IOXBZ	;YES, GET START INDEX
	MOVEM	T4,.IOXFF(IO)	;AND SET FIRST FREE EXTRA SPACE (IF ANY)
				; (NOTE .IOXFF IS OFFSET RELATIVE TO THE CDB)

;DEFAULT BUFFERING VALUE (COUNT,,TOTAL BUFFERING SPACE)

	PUSHJ	P,.INVWD##	;GET DEFAULT .IODBF WORD
	MOVEM	T1,.IODBF(IO)	;AND SET IT IN THE CDB

;DEFAULT BUFFERING LIMIT (MAXIMUM TOTAL BUFFERING SPACE)

	PUSHJ	P,.INVWD##	;GET DEFAULT .IOMBF WORD
	MOVEM	T1,.IOMBF(IO)	;AND SET IT IN THE CDB

;I/O CONTROL WORD (I/O STRUCTURING AND FILE DATA MODE)

	PUSHJ	P,.INVWD##	;GET FILE I/O CONTROL WORD
	MOVEM	T1,.IOIOC(IO)	;SET IN THE CDB

;I/O ERROR WORD (DEFAULT ERROR HANDLING CONTROL)

	PUSHJ	P,.INVWD##	;GET FILE I/O ERROR WORD
	MOVEM	T1,.IOIOE(IO)	;AND SET IT IN THE CDB

;I/O MODE WORD (FILE OPEN/CLOSE/ETC. PARAMETERS)

	PUSHJ	P,.INVWD##	;GET FILE I/O MODE WORD
	MOVEM	T1,.IOIOM(IO)	;SET IN THE CDB

;I/O RETURN VALUES SETTING (RESERVED)

	PUSHJ	P,.INVWD##	;GET THE DEFAULT .IOIOR WORD
;***	MOVEM	T1,.IOIOR(IO)	;AND SET IT IN THE CDB

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SET THE VARIOUS SERVICE ROUTINE DISPATCH POINTERS

	XMOVEI	T4,OPII		;INITIAL WSR
	MOVEM	T4,.IOWSR(IO)	;SET IN THE CDB
	XMOVEI	T4,.IOIIE##	;INITIAL ISR IS ERROR FILE NOT OPEN
	MOVEM	T4,.IOISR(IO)	;SET IN CDB
	XMOVEI	T4,.POPJ1##	;INITIAL ISR SHUTDOWN SUCCEEDS
	MOVEM	T4,.IOISS(IO)	;SET IN CDB
	XMOVEI	T4,.IOOIE##	;INITIAL OSR IS ERROR FILE NOT OPEN
	MOVEM	T4,.IOOSR(IO)	;SET IN CDB
	XMOVEI	T4,.POPJ1##	;INITIAL OSR SHUTDOWN SUCCEEDS
	MOVEM	T4,.IOOSS(IO)	;SET IN CDB

	JRST	.POPJ1##	;ALL DONE
REPEAT	0,<

	SUBTTL	IOWNI - Initialize WILD control block

;IOWNI  --  INITIALIZE WILD CONTROL BLOCK
;Call is:
;
;	MOVX	T1,<WCB>
;	MOVX	T2,<IVC>
;	PUSHJ	P,.IOWNI
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <WCB> is the address of the "Wild Control Block"; and <IVC> is
;the address of the initialization vector which contains the various
;"constants" etc. used to initialize the WCB for subsequent calls to
;the file opening routines.
;
;The error return is not exercised.
;
;On normal return the WCB is ready for calls to the open routines.
;
;Uses T3, T4.

	ENTRY	.IOWNI

.IOWNI:	PUSHJ	P,.SACWI##	;SETUP WI (AND SAVE THE P'S)
	PUSHJ	P,.INVWI##	;SETUP FOR INVWD CALLS
	MOVEM	T1,.WDWVR(WI)	;SET PROTOCOL VERSION
	SETZM	.WDBZR(WI)	;ZERO START OF TO-BE-ZEROED BLOCK
	MOVSI	T4,.WDBZR(WI)	;CONCOCT A
	HRRI	T4,.WDBZR+1(WI)	; BLT POINTER TO
	BLT	T4,.WDEZR-1(WI)	;  ZERO THE WCB
	MOVEI	T4,.WDMAX	;INITIAL LENGTH OF THE WCB
	MOVEM	T4,.WDSIZ(WI)	;SET FOR ANYONE INTERESTED
	XMOVEI	T4,OPII		;INITIAL "STATE"
	MOVEM	T4,.WDWSR(WI)	;SET IN STATE DISPATCH WORD

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW SETUP THE WCB FROM THE INITIALIZATION VECTOR

;INITIAL CONTROL FLAGS

	PUSHJ	P,.INVWD##	;CONTROL FLAGS
	MOVEM	T1,.WDCCF(WI)	;SET IN THE WCB

;COUNT OF THE I/O STREAMS

	PUSHJ	P,.INVWD##	;COUNT OF PARALLEL INPUT STREAMS
	HRRZM	T1,.WDNFI(WI)	;SET IN THE WCB
	PUSHJ	P,.INVWD##	;COUNT OF PARALLEL OUTPUT STREAMS
	HRRZM	T1,.WDNFO(WI)	;SET IN THE WCB

	JRST	.POPJ1##	;ALL DONE
> ;END OF REPEAT 0
REPEAT	0,<

	SUBTTL	IOPIO - OPEN input and output file streams

;IOPIO  --  OPEN [NEXT] SET OF INPUT [READ ONLY] AND OUTPUT [WRITE ONLY] FILES
;Call is:
;
;	MOVX	T1,<WCB>
;	PUSHJ	P,.IOPIO
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <WCB> is the address of the input "Wild Control Block".
;
;On error return M0 has a status code indicating either input file
;stream exhausted (no more input files) or file access error (with
;the error I/O CDB address in T2.
;
;On normal return the next input file(s) is(are) open and ready for
;reading via "PUSHJ P,@.IOISR(XX)" calls and the corresponding output
;files are open and ready for writing via "PUSHJ P,@.IOOSR(XX)" calls.

	ENTRY	.IOPIO

.IOPIO:	PUSHJ	P,.SACWI##	;SETUP WORKING ACS (SAVE P'S, ETC.)
	MOVE	P4,.WDPRI(WI)	;SETUP PRIMARY INPUT WILD DATA BLOCK ADDRESS
	MOVE	IO,.WFCDB(P4)	;AND ASSOCIATED I/O CDB
	SKIPN	.WDWSR(WI)	;MAKE SURE WE HAVE A DISPATCH ADDRESS
	STOPCD			;CALLER MUCKED UP
	JRST	@.WDWSR(WI)	;DISPATCH ON STATE CODE

;HERE TO INITIALIZE FOR LOCAL/REMOTE FILE INPUT OPERATIONS

OPII:	MOVE	T1,.WDCCF(WI)	;GET CONTROL FLAGS
	TXNN	T1,WD.PRN	;PRIMARY INPUT SPECIFIED?
	TXO	T1,WD.PR1	;NO, USE FIRST SPEC THEN
	MOVEM	T1,.WDCCF(WI)	;REMEMBER FOR FUTURE REFERENCE
	JFFO	T1,.+1		;GET PRIMARY INPUT "STREAM NUMBER"
	CAML	T2,.WDNFI(WI)	;WITHIN USER SPECS?
	STOPCD			;NO
	IMULI	T2,.WFMAX	;GET WFB OFFSET FROM FIRST BLOCK
	ADDI	T2,.W1IWF	;RELOCATE INTO THE WILD CONTROL BLOCK
	ADD	T2,WI		;ADDRESS OF PRIMARY INPUT WFB
	MOVEM	T2,.WDPRI(WI)	;SAVE ADDRESS FOR FUTURE CALLS
	MOVE	P4,T2		;AND SET FOR USAGE BELOW
	MOVE	IO,.WFCDB(P4)	;POINT TO I/O CDB
	MOVE	P1,.WFFSB(P4)	;GET FIRST INPUT SPEC
	JRST	OPII12		;AND ENTER NODE-SEGREGATION CODE
> ;END REPEAT 0
	SUBTTL	IOPND - OPEN [wild] input network/node stream

;IOPND  --  OPEN [WILD] INPUT NODE
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOPND
;	 EXCEPTION RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB which contains the pointer
;to the SCAN file spec blocks.
;
;IOPND is used to open a link to a remote DAP server only, and not
;to a real file. This routine is for the use of the NFT/NIP "NETWORK"
;command.
;
;The exception error is taken if a "file access" error occurs, if a
;file initialization error occurs, or if there are no more files
;available (i.e., the input file specification is exhausted).
;
;On normal return a DAP link has been established to the "next" node.
;The I/O CDB file parameters have been set as appropriate.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOPND
	INTERN	IOPND0,	IOPND1

.IOPND:	PUSHJ	P,.SACIO##	;SETUP I/O
IOPND0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
IOPND1:	PUSHJ	P,TSAV14##	;AND THE T ACS TOO
	MOVX	M0,IO.OND	;OPEN NETWORK/DAP ONLY, NO FILE
	IORM	M0,.IOCCF(IO)	;MARK THAT FOR OTHERS
	PJRST	IOPIN2		;NOW GO DO WILD AND WACKY STUFF
	SUBTTL	IOPIN - OPEN [wild] input file stream

;IOPIN  --  OPEN [WILD] INPUT FILE
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOPIN
;	 EXCEPTION RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB which contains the pointer
;to the SCAN file spec blocks.
;
;The exception error is taken if a file access error occurs, if a
;file initialization error occurs, or if there are no more files
;available (i.e., the input file specification is exhausted).
;
;On normal return a file has been OPENed and is available for reading.
;The I/O CDB file parameters have been set as appropriate.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOPIN
	INTERN	IOPIN0,	IOPIN1

.IOPIN:	PUSHJ	P,.SACIO##	;SETUP I/O
IOPIN0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
IOPIN1:	PUSHJ	P,TSAV14##	;AND THE T ACS TOO
IOPIN2:	MOVE	P1,.IOCCF(IO)	;GET CHANNEL CONTROL FLAGS
	TXNN	P1,IO.OPN	;IS A FILE ALREADY/STILL OPEN HERE?
	JRST	IOPIN3		;NO
	PUSHJ	P,IOABO1	;YES, GET RID OF IT
	 JFCL			;HMMMM

;CLEAR OUT POSSIBLY-STALE FILE INFORMATION

IOPIN3:	SETZM	.IOBZC(IO)	;START OF TO-BE-CLEARED ON CLOSE
	MOVEI	T2,.IOBZC+1(IO)	;CONCOCT A
	HRLI	T2,-1(T2)	; BLT POINTER TO
	BLT	T2,.IOEZC-1(IO)	;  CLEAR THE TO-BE-CLEARED AREA

;NOW DISPATCH BASED ON CURRENT WILDCARDED INPUT STATE

IOPIN5:	SKIPE	.IOWSR(IO)	;FIRST CALL?
	JRST	@.IOWSR(IO)	;NO, DISPATCH TO STATE ROUTINE

;HERE TO INITIALIZE FOR WILD CARD FILE SEARCHES

OPII:	SETZM	.IOFSC(IO)	;CLEAR POINTER TO INITIALIZE .LKWLD
	JRST	OPIIL		;START UP, ASSUMING LOCAL FILE SERVICE

;HERE WHEN INPUT STREAM EXHAUSTED

OPII30:	XMOVEI	T1,OPII90	;SET SERVICE DISPATCH ADDRESS
	MOVEM	T1,.IOWSR(IO)	; TO RETURN INPUT EXHAUSTED CODE
	MOVX	M0,$EFIXN	;INPUT STREAM EXHAUSTED NORMALLY
	POPJ	P,		;RETURN WITH EXCEPTION CODE

OPII90:	MOVX	M0,$EFIXE	;INPUT STREAM EXHAUSTED (REDUNDANTLY)
	POPJ	P,		;RETURN WITH ERROR CODE
;HERE FOR LOCAL FILE REQUEST

OPIIL:	XMOVEI	T1,OPIL		;ADDRESS OF LOCAL "STATE" SERVICE ROUTINE
	MOVEM	T1,.IOWSR(IO)	;SET FOR FUTURE CALLS TO IOPIN
OPIL:	MOVE	T1,[12,,%%FXVE]	;PROTOCOL VERSION WORD
	MOVEM	T1,.IOLKW+0(IO)	;ZEROTH .LKWLD WORD
	MOVSI	T1,.IOFSB(IO)	;ADDRESS OF ADDRESS OF "FIRST" SPEC
	HRRI	T1,.IOFSL(IO)	;ADDRESS OF ADDRESS OF "LAST" SPEC
	MOVEM	T1,.IOLKW+1(IO)	;FIRST .LKWLD WORD
	MOVSI	T1,.I1OPN(IO)	;ADDRESS OF INPUT "OPEN" BLOCK
	HRRI	T1,.I1LKP(IO)	;ADDRESS OF INPUT "LOOKUP" BLOCK
	MOVEM	T1,.IOLKW+2(IO)	;SECOND .LKWLD WORD
	MOVE	T1,[.FXMAX,,.RBMAX-1]  ;FSB LENGTH,,LOOKUP BLOCK LENGTH
	MOVEM	T1,.IOLKW+3(IO)	;THIRD .LKWLD WORD
	MOVX	T1,FW.ADO	;ANY DEVICE OK
	HRRI	T1,.IOFSC(IO)	;ADDRESS OF ADDRESS OF "CURRENT" SPEC
	MOVEM	T1,.IOLKW+4(IO)	;FOURTH .LKWLD WORD
	MOVSI	T1,0		;NOTHING
	MOVEM	T1,.IOLKW+5(IO)	;FIFTH .LKWLD WORD
	MOVSI	T1,0		;NOTHING
	MOVEM	T1,.IOLKW+6(IO)	;SIXTH .LKWLD WORD
	XMOVEI	T1,.IOPPN(IO)	;ADDRESS OF ON-BEHALF-OF-PPN
	MOVEM	T1,.IOLKW+7(IO)	;SEVENTH .LKWLD WORD
				;FALL INTO LOCAL WILD INPUT LOOP

;ENTER HERE TO RETURN NEXT LOCAL INPUT FILE

OPIL10:	SETZM	.IOQCT(IO)	;NO IOQAT YET (IN CASE OF ERROR)
	MOVSI	T1,10		;LENGTH OF .LKWLD BLOCK
	HRRI	T1,.IOLKW(IO)	;ADDRESS OF .LKWLD BLOCK
	PUSHJ	P,.LKWLD##	;GENERATE PRIMARY-WILDCARDED INPUT SPEC
	 JRST	OPIL70		;FAILED - SEE WHY

;IF THE FILE ACTUALLY BELONGS TO A REMOTE FILE SYSTEM THEN .LKWLD WILL HAVE
;CALLED .LKWLN.

	MOVE	T1,.IOCCF(IO)	;RETRIEVE COPY OF THE CHANNEL CONTROL
	TXNE	T1,IO.LKN!IO.OND;WAS THIS A REMOTE FILE REQUEST?
	JRST	OPIIR		;YES, SWITCH TO REMOTE FILE SERVICE THEN
	TXNN	T1,IO.NET	;LOCAL, GOT A NET CONNECTION HANGING AROUND?
	JRST	OPIL12		;NO
	PUSHJ	P,NTZAP1##	;YES, ABORT THE NETWORK LINK
	 JFCL			;THIS SHOULDN'T HAPPEN
OPIL12:	MOVEI	T1,.IFRED	;GENERIC READ FUNCTION
	SETZ	T2,		;*** TEMP
	PUSHJ	P,FILOP		;OPEN THE POTENTIAL FILE FROM .LKWLD
	 JRST	OPIL50		;FILE OPEN FAILURE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SEE IF FILE REALLY VALID/DESIRED

	PUSHJ	P,.CHKTM##	;SEE IF THE FILE MATCHES
	 JRST	OPIL67		;IT DOESN'T, TOSS THIS ONE AND TRY FOR ANOTHER
	MOVE	T3,.IOIOM(IO)	;GET I/O MODE CONTROL
	TXNE	T3,IM.DQA!IM.DQI;OK TO CALL /QUERY PROCESSOR?
	JRST	OPIL20		;NO (E.G., OUT = IN; OUT WILL CALL IOQAT)
	SETZ	T1,		;NO OUTPUT SIDE HERE
	MOVE	T2,IO		;INPUT SIDE I/O CDB
	PUSHJ	P,IOQAT1	;CALL /QUERY PROCESSOR
	 JRST	OPIL65		;USER PROBABLY REJECTED THE FILE

;WE LIKE THIS FILE, SEE IF NEED TO ALLOCATE BUFFERS

OPIL20:	MOVE	T1,.IOIOM(IO)	;GET FILE MODE CONTROL WORD
	TXNE	T1,IM.SBO	;SUPPRESS BUFFER ALLOCATION AT OPEN?
	JRST	OPIL30		;YES
	PUSHJ	P,FILBF		;NO, ALLOCATE BUFFERS AS NEEDED
	 POPJ	P,		;OOPS, NO MEMORY OR SOMETHING

;ALL DONE, RETURN INPUT FILE READY TO BE READ

OPIL30:	JRST	.POPJ1##	;SUCCESSFUL RETURN
;SEE WHY FILOP FAILED

OPIL50:	PUSHJ	P,OPIE00	;SEE IF SHOULD IGNORE THIS ERROR
	 JRST	OPIL10		;YES, STEP TO NEXT FILE
	POPJ	P,		;TAKE ERROR/EXCEPTION RETURN TO CALLER
				; (WHO SHOULD CALL THE ERROR PRINTER)


;CHECK OUT EXCEPTION RETURN FROM .IOQAT

OPIL65:	CAIE	M0,$EFRJU	;REJECTED BY USER?
	POPJ	P,		;NO, SOME BIZARRE ERROR!

;HERE TO REJECT CURRENT FILE (TOSS OUT GARBAGE, ETC) AND TRY FOR ANOTHER

OPIL67:	PUSHJ	P,IOABO0	;TOSS OUT CURRENTLY [ALMOST] OPENED FILE
	 JFCL			;DUH?
	JRST	OPIL10		;AND TRY FOR ANOTHER FILE



;HERE TO SEE WHY .LKWLD FAILED (ERROR OR NO MORE INPUT FILES)

OPIL70:	AOJE	T1,OPII30	;IF T1 = -1 THEN NO MORE FILES
	MOVX	M0,$EFNAD	;ERROR - INPUT NOT A DISK
	POPJ	P,		;RETURN ERROR CONDITION
;HERE FOR REMOTE FILE SYSTEM

OPIIR:	TXNN	T1,IO.OND	;DOING DAP-ONLY STUFF?
	JRST	OPIIR2		;NO, REAL FILE THINGS
	SKIPN	T1,.IOFSY(IO)	;YES, GET PSEUDO-CURRENT FILE SPEC BLOCK
	MOVE	T1,.IOFSC(IO)	;OOPS - NONE (.LKWLN NOT CALLED), FAKE IT
	MOVEM	T1,.IOFSY(IO)	;SET FOR RANDOM HACKERY
	SKIPN	T2,.FXNOD(T1)	;GET THE NODE NAME
	MOVE	T2,.MYNOD##	;NONE, DEFAULT TO LOCAL NODE THEN
	MOVEM	T2,.FXNOD(T1)	;KEEP OPWN HAPPY
OPIIR2:	PUSHJ	P,OPWN		;FIRST ESTABLISH A DAPPISH LINK WITH REMOTE
	 JRST	[SOS	.CTNDF##	;DISCOUNT NODE FOUND
		PUSHJ	P,OPIE00	;DOES THE USER CARE ABOUT THIS ERROR?
		 JRST	OPIIL		;NO, IGNORE, STEP ON TO NEXT WHATEVER
		MOVE	T1,.IOFSY(IO)	;ADDRESS OF NETWORK FILE SPEC BLOCK
		MOVE	T1,.FXNOD(T1)	;NAME OF ERRANT NODE
		MOVEM	T1,.I1NOD(IO)	;SET SOMETHING FOR ERROR TYPEOUT
		PUSHJ	P,OPFND		;NOW SET .IOFND FROM .I1NOD
		AOS	.CTFLF##	;FAKE OUT WILD'S "LOOKED" ROUTINE
					; SINCE WE ARE ABOUT TO ISSUE ERROR
					; MESSAGE ANYWAY, DON'T WANT THE
					; SUMMARY "% NO SUCH NODES" STUFF
		POPJ	P,]		;PROPAGATE ERROR BACK TO CALLER
	XMOVEI	T1,OPIR		;REMOTE WILD FILE INPUT SERVICE
	MOVEM	T1,.IOWSR(IO)	;SET FOR FUTURE CALLS TO .IOPIN
	JRST	OPIR03		;START UP FILE LOOP


;HERE TO FIND THE NEXT REMOTE FILE TO READ

OPIR:	MOVX	T1,IO.YAF	;THE FILE-COMING FLAG
	TDNN	T1,.IOCCF(IO)	;CAN WE EXPECT A FILE?
	JRST	OPIIL		;NO, SWITCH BACK TO LOCAL MODE
	ANDCAB	T1,.IOCCF(IO)	;YET ANOTHER FILE EXPECTED
OPIR03:	MOVE	P1,FICFTB+.IFRED;GET CHANNEL I/O BITS
	IORB	P1,.IOCCF(IO)	;MARK THEM IN THE CDB
	TXNE	P1,IO.OND	;OPEN FOR DAP ONLY?
	JRST	.POPJ1##	;YES, SUCCESSFUL THEN
	TXNN	P1,IO.NET	;OUT OF CURIOUSITY, IS THE NET STILL THERE?
	STOPCD	<Network link disappeared in OPIR03>
	SETZM	.IDNMS(IO)	;NO NAME MESSAGES SEEN YET
	SETZM	.IOQCT(IO)	;AND NO IOQAT YET EITHER (IN CASE OF ERROR)
	MOVX	T1,IO.YAE	;*** FUNNY ERROR PENDING FROM -20?
	TDNE	T1,.IOCCF(IO)	;*** ERROR PENDING?
	JRST	[ANDCAM	T1,.IOCCF(IO)	;*** CLEAR OUT FOR NOW
		PUSHJ	P,RDSTC1##	;*** RETRIEVE ERROR CODE
		  JFCL			;*** DUH?
		JRST	OPIR51]		;*** PROCESS DEFERRED FILE-OPEN ERROR
	MOVX	T1,IO.YAS	;YET ANOTHER SILLY BIT
	TDNE	T1,.IOCCF(IO)	;NEED TO CLEAN UP FROM PREVIOUS ERROR?
	JRST	OPIR55		;YES, OLD FILE STILL HANGING AROUND

OPIR10:	PUSHJ	P,RDMSG1##	;READ IN NEXT DAP MESSAGE CODE
	 POPJ	P,		;NETWORK DIED?
OPIR11:	JSP	T4,.CDISP##	;DISPATCH ON MESSAGE TYPE
		OPIR20,,$DHATR	;MAIN ATTRIBUTES
		OPIR20,,$DHALC	;ALLOCATION ATTRIBUTES
		OPIR20,,$DHTIM	;DATE/TIME ATTRIBUTES
		OPIR20,,$DHPRT	;PROTECTION ATTRIBUTES
		OPIR30,,$DHNAM	;RESULTANT NAME MESSAGE
		OPIR40,,$DHACK	;ACK, READY TO READ FILE
		OPIR50,,$DHSTS	;STATUS, PROBABLY AN ERROR
		OPIR70,,$DHACM	;ACCESS COMPLETE - NO MORE FILES
		0		;ALL OTHERS ILLEGAL
	JRST	.RDEOS##	;DAP MESSAGE OUT OF SEQUENCE


;RECEIVED ATTRIBUTES (OF SOME FORM)

OPIR20:	PUSHJ	P,RDDAP1##	;READ IN THE DAP ATTRIBUTES
	 POPJ	P,		;NETWORK DIED?
	JRST	OPIR10		;BACK FOR MORE


;HERE ON A NAME MESSAGE OF SOME FLAVOR

OPIR30:	PUSHJ	P,RDDAP1##	;READ IN THE NAME MESSAGE
	 POPJ	P,		;NETWORK DIED?
	PUSHJ	P,DPRNM1	;PROCESS THE NAME STRING
	 STOPCD	<DPRNM1 failed reading resultant name string in OPIR30>
	JRST	OPIR10		;BACK FOR MORE


;ACK RECEIVED, WE HAVE A FILE FOR READ

OPIR40:	PUSHJ	P,RDDAP1##	;EAT REST OF THE ACK
	 POPJ	P,		;NETWORK DIED?
	AOS	.CTDVS##	;COUNT AS AT LEAST ONE DEVICE SEEN
	AOS	.CTDRS##	; AND A DIRECTORY SEEN
	AOS	.CTDRF##	;  AND A DIRECTORY FOUND
	AOS	.CTFLS##	;   AND A FILE SEEN
	AOS	.CTFLF##	;    AND A FILE FOUND TOO
	AOS	.IODFC(IO)	;COUNT UP FILES FOR THIS ACCESS
	PUSHJ	P,DPIAF1	;SET FILE ATTRIBUTES FROM DAP ATTRIBUTES
	 STOPCD	<DPIAF failed in OPIR40>
	PUSHJ	P,.CHKTM##	;SEE IF THE FILE IS REALLY DESIRED
	 JRST	OPIR67		;NOPE
	MOVE	T3,.IOIOM(IO)	;GET I/O MODE CONTROL
	TXNE	T3,IM.DQA!IM.DQI;NEED TO CALL IOQAT?
	JRST	OPIR46		;NO
	SETZ	T1,		;YES, NO OUTPUT FILE HERE
	MOVE	T2,IO		;ADDRESS OF INPUT FILE CDB
	PUSHJ	P,IOQAT1	;CALL THE /QUERY PROCESSOR
	 JRST	OPIR65		;USER PROBABLY REJECTED THE FILE

;SET UP THE ISR(S)

OPIR46:	MOVX	T1,IO.OPN	;THE FILE-IS-OPEN FLAG
	IORM	T1,.IOCCF(IO)	;MARK IN THE CDB
	MOVE	P1,.IOCCF(IO)	;I/O CONTROL FLAGS
	XMOVEI	T1,.IOIIN##	;REMOTE INPUT INITIALIZE
	TXNN	P1,IO.INP	;INPUT REQUESTED?
	XMOVEI	T1,.IOIIE##	;NO, THEN SELECT ERROR ISR INSTEAD
	MOVEM	T1,.IOISR(IO)	;SET INPUT I/O SERVICE ROUTINE
	XMOVEI	T1,.IOOIN##	;REMOTE OUTPUT INITIALIZE
	TXNN	P1,IO.OUT	;OUTPUT REQUESTED?
	XMOVEI	T1,.IOOIE##	;NO, THEN SELECT ERROR ISR INSTEAD
	MOVEM	T1,.IOOSR(IO)	;SET OUTPUT I/O SERVICE ROUTINE

	JRST	.POPJ1##	;RETURN ALL SET UP
;Received STATUS message

OPIR50:	PUSHJ	P,RDSTS1##	;READ IN REST OF STATUS MESSAGE
	 POPJ	P,		;NETWORK DIED?
OPIR51:	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"
	CAIN	M0,$EGAOK	;"A-OK"
	JRST	OPIR10		;YES, IGNORE, KEEP LOOKING FOR THE ACK
	MOVEM	M0,.IOERR(IO)	;SAVE THE ERROR
	SKIPE	.IODFC(IO)	;ANY FILES AT ALL?
	JRST	OPIR52		;YES, JUST REPORT THE ERROR AS NEEDED

;No files have yet been seen, which presumably means no NAME messages
;have been received (but never NEVER underestimate the creativity of
;"their" network software), which presumably means no files are forth-
;coming under any circumstances. Fake out the error typer by providing
;the input file specification as the resultant file strings so that
;error messages look pretty.

	MOVE	T4,.IOFSY(IO)	;THE FILE SPEC BLOCK THAT GOT US HERE
	MOVE	T3,.FSDEV(T4)	;ADDRESS OF DEVICE SPEC STRING
	SKIPN	.IOFDV(IO)	;GOT A RESULTANT DEVICE STRING?
	MOVEM	T3,.IOFDV(IO)	;NO, FAKE IT WITH INPUT SPECIFICATION
	MOVE	T3,.FSDIR(T4)	;ADDRESS OF DIRECTORY SPEC STRING
	SKIPN	.IOFDR(IO)	;GOT A RESULTANT DIRECTORY STRING?
	MOVEM	T3,.IOFDR(IO)	;NO, FAKE IT WITH INPUT SPECIFICATION
	MOVE	T3,.FSNAM(T4)	;ADDRESS OF FILE NAME SPEC STRING
	SKIPN	.IOFNM(IO)	;GOT A RESULTANT FILE NAME STRING?
	MOVEM	T3,.IOFNM(IO)	;NO, FAKE IT WITH INPUT SPECIFICATION
	MOVE	T3,.FSEXT(T4)	;ADDRESS OF FILE TYPE SPEC STRING
	SKIPN	.IOFEX(IO)	;GOT A RESULTANT FILE TYPE STRING?
	MOVEM	T3,.IOFEX(IO)	;NO, FAKE IT WITH INPUT SPECIFICATION
	MOVE	T3,.FSGEN(T4)	;ADDRESS OF FILE GENERATION SPEC STRING
	SKIPN	.IOFGN(IO)	;GOT A RESULTANT GENERATION STRING?
	MOVEM	T3,.IOFGN(IO)	;NO, FAKE IT WITH INPUT SPECIFICATION

;WILD assumes life is wonderful and AOSes its .CTxxx counters before-
;hand, SOSing them back down if an error occurs. Accordingly, set the
;.CTxxx counters following WILDs lead, backing off counters based on
;the actual error (that's OPIE00's job).

	AOS	.CTDVS##	;COUNT UP A DEVICE SEEN
	AOS	.CTDRS##	;COUNT UP A DIRECTORY SEEN
	AOS	.CTDRF##	;COUNT UP A DIRECTORY FOUND
	AOS	.CTFLS##	;COUNT UP A FILE SEEN
				; WILD'S LOOKED WILL NOW SAY "NO SUCH FILES"
	AOS	.CTFLF##	;COUNT UP A FILE FOUND

OPIR52:	PUSHJ	P,OPIE00	;SHOULD WE TELL THE USER ABOUT THIS ONE?
	 JRST	OPIR55		;NO, EAT IT, SKIP TO NEXT FILE
	AOS	.CTFLF##	;ERROR MESSAGE COUNTS AS FILE FOUND . . .
	MOVX	T1,IO.YAF!IO.YAS;FLAG TO INTERCEPT NEXT CALL TO OPIR
	IORM	T1,.IOCCF(IO)	;SO CAN SEND THE "CONTINUE" CODES
	POPJ	P,		;PROPAGATE ERROR TO USER


;Here to skip to the next file after a file-access error

OPIR55:	ANDCAM	T1,.IOCCF(IO)	;CLEAR OUT THE IO.YAS FLAG

;At this point, we rather hysterically try to avoid hanging the link
;in a funny protocol state. The only state that is continuable is if
;it is a wildcarded file access, and the error is a file-specific error
;(e.g., protection failure). This is determined by the receipt of NAME
;messages (don't blame me, go read the spec!). If any name messages have
;been received, it is assumed that the remote will ALWAYS terminate the
;current access with an ACCOMP(RESPONSE) message. In all other cases the
;DAP link is simply aborted - which at least leaves the DAP protocol in
;a known state . . .

	SKIPN	.IODFC(IO)	;IF FILES HAVE BEEN SEEN
	SKIPE	.IDNMS(IO)	;ERROR SANS ANY NAME MESSAGES?
	CAIA			;FILES AND/OR NAME MESSAGES!
	JRST	OPIR59		;NO FILES AND NO NAME MESSAGES, GIVE UP
	LDB	T1,PDPEMA##	;GET JUST THE MAC CODE
	CAIE	T1,2		;"UNSUPPORTED" CLASS?
	CAILE	T1,7		;"FORMAT", "INVALID", "SYNC", ETC?
	JRST	OPIR58		;YES, JUST GIVE UP NOW!
	PUSHJ	P,XDASK1##	;SKIP THIS FILE, ADVANCE TO THE NEXT
	 POPJ	P,		;NET DIED???

;Now see if the remote is gonna cooperate with us. If we get another
;STATUS message then the link/protocol is probably lost forever, any
;other message is probably good stuff, and we slip back into the file
;processing "state".

	PUSHJ	P,RDMSG1##	;READ IN NEXT DAP MESSAGE CODE
	 POPJ	P,		;OH WELL, I'M NOT TOO SURPRISED...
	CAIE	T2,$DHSTS	;ANOTHER STATUS?
	JRST	OPIR11		;NO, ASSUME GOOD STUFF (ANOTHER FILE)

;We now check for the various pathological cases that I have empirically
;observed are not recoverable . . . There is some slight possibility
;that this is a second valid error on the same file, but I have never
;yet seen that case . . .

	PUSHJ	P,RDSTS1##	;PROCESS/DECODE THE DAP STATUS MESSAGE
	 POPJ	P,		;DUH?

;Currently the VAX doesn't like to ACCOMP(SKIP) (and I don't know what
;it does want - if anything - to continue).

	LDB	T1,PDPEMA##	;GET JUST THE MAC CODE
	CAIE	T1,2		;"UNSUPPORTED" CLASS?
	CAILE	T1,7		;"FORMAT", "INVALID", "SYNC", ETC?
	JRST	OPIR58		;YES, JUST GIVE UP NOW!

;And TOPS20 seems to like the ACCOMP(SKIP), it even sends back a code
;that I can only interpret (from the protocol specification) as "OK"
;but then nothing else ever happens, and the link "hangs".

	MOVD1	T2,STC		;GET THE DAP STATUS CODE (COMPLETE)
	MOVD1	T3,FST		;GET THE REMOTE FILE SYSTEM TYPE
	CAIN	T3,$DVFT2	;TOPS-20?
	CAIE	T2,000001	;FAVORITE SCREWY TOPS-20 STATUS CODE
	CAIA			;NO
	JRST	OPIR58		;YES, HOPELESS, BREAK OFF NOW

;Hmmm . . . Well, assume another error, and process accordingly

	JRST	OPIR51		;LOOP BACK AND PROCESS ANOTHER ERROR


;Here to break off the link, complaining to the user

OPIR58:	PUSHJ	P,NTZAP1##	;STOMP THE LINK INTO SUBMISSION
	 JFCL			;HO HUM
	MOVEI	M0,$EERSP	;REMOTE SCREWY PROTOCOL
	POPJ	P,		;EXCEPTION RETURN TO CALLER


;Here to break off the link, advancing to the next file spec (a la .LKWLD)

OPIR59:	PUSHJ	P,NTZAP1##	;PITCH THE NETWORK LINK
	 JFCL			;HO HUM
	JRST	OPIIL		;BACK TO NEXT FILE SPEC TO PROCESS
;HERE WHEN REMOTE FILE REJECTED BY /QUERY PROCESSOR

OPIR65:	CAIE	M0,$EFRJU	;REJECTED BY USER?
	POPJ	P,		;NO, FUNNY ERROR
	SOS	.CTFLF##	;YES, THEN DISCOUNT FILE SUCCESSFULLY FOUND
	AOS	.CTFLR##	;AND COUNT IT AS REJECTED INSTEAD

;CLOSE THE FILE AND ADVANCE TO THE NEXT ONE

OPIR67:	MOVD	T1,AOP		;GET FILE ACCESS OPTIONS
	TFNE	T1,GNG		;GO/NO-GO SET?
	JRST	OPIR68		;YES
	PUSHJ	P,XDACL1##	;NO, PITCH THE CURRENT UNWANTED INPUT FILE
	 JFCL			;HOHUM
	JRST	OPIR10		;TRY FOR ANOTHER FILE

OPIR68:	PUSHJ	P,XDASK1##	;SEND AN ACCOMP(SKIP) MESSAGE
	 POPJ	P,		;NETWORK DIED?
	JRST	OPIR10		;TRY FOR THE NEXT FILE


;HERE WHEN NO MORE REMOTE FILES

OPIR70:	PUSHJ	P,RDDAP1##	;EAT THE REST OF THE ACCESS COMPLETE
	 JFCL			;HMMM
	MOVD1	T1,A2F		;GET ACCESS COMPLETE FUNCTION
	CAIE	T1,$DVARS	;IS IT "RESPONSE"
	STOPCD	<ACCESS COMPLETE not ACCOMP(RESPONSE) in OPIR70>

;***	NOW TRY TO FAKE OUT LKWLD'S LOOKED ROUTINE INTO ISSUING A MORE
;***	MEANINGFUL "NO SUCH FILES" RATHER THAN "SEARCH LIST EMPTY"

	SKIPE	.IODFC(IO)	;*** PROCESSED ANY FILES?
	JRST	OPIR73		;*** YES
	SKIPN	.CTDRS##	;*** SEEN ANY DEVICES
	SKIPE	.CTDRS##	;*** OR DIRECTORIES?
	JRST	OPIR73		;*** YES, LEAVE WELL ENOUGH ALONE THEN
	AOS	.CTFLS##	;*** FAKE WITH FILE SEEN, RETURN "NO SUCH FILES"
OPIR73:	JRST	OPIIL		;BACK FOR MORE FILE STUFF
;HERE FROM OPIR TO ESTABLISH A NEW NETWORK DAP LINK

OPWN:	MOVX	P1,IO.LKN!IO.YAF!IO.YAE!IO.YAS  ;"STATE" CONTROL FLAGS
	ANDCAB	P1,.IOCCF(IO)	;UPDATE CHANNEL CONTROL FLAGS
	MOVE	P2,.IOFSY(IO)	;"CURRENT" FILE SPEC BLOCK ADDRESS
	SKIPN	T2,.FXNOD(P2)	;GET RESULTANT NODE NAME
	STOPCD	<No node in FSB passed from .LKWLD in OPWN>
	TXNE	P1,IO.NET	;TALKING TO A REMOTE NODE?
	CAME	T2,.ION6M(IO)	;YES, IS IT THE RIGHT ONE?
	CAIA			;NEED A [NEW] DAP CHANNEL
	JRST	OPWN05		;ALREADY TALKING TO THE RIGHT FAL
	PUSHJ	P,DPINI1	;OPEN A DAPPISH NETWORK CONNECTION
	 POPJ	P,		;CAN'T TALK TO REMOTE NODE
	MOVE	T2,.ION6M(IO)	;GET RESULTANT NODE NAME
	MOVEM	T2,.I1NOD(IO)	;POSITION FOR SCWLD, IOQAT, ETC.
	PUSHJ	P,OPFND		;SETUP .IOFND

;TALKING TO A REMOTE FAL

OPWN05:	MOVE	P1,FICFTB+.IFRED;GET CHANNEL I/O BITS
	IORB	P1,.IOCCF(IO)	;MARK THEM IN THE CDB
	TXNE	P1,IO.OND	;OPEN NETWORK/DAP LINK ONLY?
	JRST	.POPJ1##	;YES
;***	MOVE	P2,.IOFSY(IO)	;RETRIEVE FILE SPEC BLOCK
;***	LDB	T4,[POINTR .IOIOC(IO),IC.MOD]  ;GET FILE MODE
;***	MOVE	T1,.IOIOM(IO)	;GET I/O MODE CONTROL
;***	TXNE	T1,IM.CMD	;DOES .IOIOC MODE OVERRIDE?
;***	JRST	OPWN10		;YES, USE AS SPECIFIED
;***	MOVEI	T3,.ICDEF	;NO, SELECT "DEFAULT"
;***	LDB	T2,[POINTR .FXCTL(P2),FX.DAM]  ;USER-SPECIFIED /DATAMODE
;***	JUMPN	T2,OPWN08	;IF SET THEN /DATAMODE GOVERNS ACCESS
;***	LDB	T2,[POINTR .FXCTL(P2),FX.IOM]  ;USER-SPECIFIED /IOMODE
;***	JUMPE	T2,OPWN09	;IF NEITHER /DATAMODE NOR /IOMODE THEN DEFAULT
;***OPWN08:	MOVE	T3,MDMOTB(T2)	;TRANSLATE INTO INTERNAL FILE MODE
;***OPWN09:	DPB	T3,[POINTR .IOIOC(IO),IC.MOD]  ;AND SET FOR ALL

;NOW SETUP DAP AREAS FOR TRANSMISSION TO THE REMOTE FAL

OPWN10:	PUSHJ	P,DPWAF1	;CONVERT FILE STUFF INTO DAP STUFF
	 STOPCD	<DPWAF failed in OPWN10>
	PUSHJ	P,DPWAA1	;ALSO SET ACCESS MESSAGE
	 STOPCD	<DPWAA failed in OPWN10>

;SEND MAIN ATTRIBUTES

OPWN20:	MOVEI	T2,$DHATR	;MAIN ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND MAIN ATTRIBUTES
	 POPJ	P,		;FAILED

;SEND THE FILE ACCESS MESSAGE

OPWN30:	MOVEI	T3,$DVARD	;READ ACCESS FUNCTION
	MOVD1M	T3,AFC		;SET ACCESS FUNCTION FIELD
	MOVDII	T3,FAC,GET	;"GET" ACCESS
	MOVDM	T3,FAC		;SET FILE ACCESS FIELD
	MOVD	T1,CNF		;GET REMOTE'S CONFIGURATION FLAGS
	MOVDII	T3,ADS,DMA	;ALWAYS WANT MAIN ATTRIBUTES RETURNED
	TFNE	T1,TEA		;IF REMOTE SUPPORTS DATE/TIME ATTRIBUTES
	TFO	T3,DDT		; THEN REQUEST DATE/TIME ATTRIBUTES BE RETURNED
	TFNE	T1,PEA		;IF REMOTE SUPPORTS PROTECTION ATTRIBUTES
	TFO	T3,DFP		; THEN REQUEST PROTECTION ATTRIBUTES TOO
	TFNE	T1,NAM		;IF REMOTE SUPPORTS NAME MESSAGES
	TFO	T3,DNM		; THEN REQUEST NAME SPECIFICATION BE RETURNED
				; (OTHERWISE DPIA00 WILL HAVE TO "FAKE IT")
	MOVE	T1,.IODPV(IO)	;REMOTE'S DAP PROTOCOL LEVEL
	CAIL	T1,007000	;7.0 OR LATER?
	TFO	T3,DN3		;YES, MUST EXPLICITLY REQUEST 3-PART NAMES
	MOVE	T1,.IOFSY(IO)	;ADDRESS OF FILE SPEC BLOCK
	MOVE	T1,.FXFLD(T1)	;GET FIELDS FLAGS
	TFNN	T3,DN3		;REQUESTING 3-PART NAME MESSAGES?
	TXNE	T1,FX.WDV!FX.WDR!FX.WNM!FX.WEX!FX.WGN  ;ANY WILDCARDS IN FILE?
	TFZ	T3,DNM		;YES, ALREADY GETTING LOTS OF NAME MESSAGES

;NOTE THAT WHILE KNOWN WILDCARDS WILL CAUSE APPROPRIATE NAME MESSAGES (VOL,
;DEV, NAM) TO BE SENT BACK TO US, ABSENCE OF EXPLICIT WILDCARDS DOESN'T
;MEAN IT IS NOT A WILD SPEC - REMEMBER /STR!! IT DOESN'T HURT TO GET RE-
;DUNDANT NAME MESSAGES, SO WE MAY WELL GET THEM IN SOME CASES.

	MOVDM	T3,ADS		;SET ACCESS DISPLAY FIELD
	MOVEI	T2,$DHACS	;FILE ACCESS MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND FILE ACCESS MESSAGE
	POPJ	P,		;FAILED

;FILE ACCESS SENT, SHOULD NOW GET FILE(S) RETURNED FROM REMOTE

OPWN50:	PUSHJ	P,XDFLS1##	;FLUSH OUT THE TRANSMIT BUFFER
	 POPJ	P,		;BOATS

;NOW CLEAR OUT RESULTANT FILE INFORMATION PREPARATORY TO RECEIVING NEW FILE
;NAME/ATTRIBUTES IN OPIRXX

	SETZM	.IODFC(IO)	;CLEAR COUNT OF FILES FOR THIS ACCESS
	SETZM	.I1FLP+.FODEV(IO)  ;CLEAR DEVICE NAME
	SETZM	.I1DEV(IO)	;CLEAR DEVICE NAME
	SETZM	.I1DCH(IO)	;CLEAR DEVICE CHARACTERISTICS
	SETZM	.I1DTY(IO)	;CLEAR DEVICE TYPE
	SETZM	.I1DSZ(IO)	;CLEAR DEVICE BLOCKSIZE
	SETZM	.I1IOS(IO)	;CLEAR DEVICE I/O STATUS
	SETZM	.I1PTH(IO)	;CLEAR START OF PATH BLOCK
	MOVSI	T3,.I1PTH(IO)	;CONCOCT
	HRRI	T3,.I1PTH+1(IO)	; A BLT POINTER TO
	BLT	T3,.I1PTH+.PTMAX-1(IO)  ;CLEAR PATH BLOCK
	SETZM	.I1PT2(IO)	;CLEAR START OF PATH BLOCK
	MOVSI	T3,.I1PT2(IO)	;CONCOCT
	HRRI	T3,.I1PT2+1(IO)	; A BLT POINTER TO
	BLT	T3,.I1PT2+.PTMAX-1(IO)  ;CLEAR PATH BLOCK
	SETZM	.I1LKP(IO)	;CLEAR START OF LOOKUP/ENTER BLOCK
	MOVSI	T3,.I1LKP(IO)	;CONCOCT
	HRRI	T3,.I1LKP+1(IO)	; A BLT POINTER TO
	BLT	T3,.I1LKP+.RBMAX-1(IO)  ;CLEAR LOOKUP/ENTER BLOCK
	SETZM	.I1GEN(IO)	;CLEAR FILE GENERATION
	JRST	.POPJ1##	;SUCCESSFUL RETURN
;HERE FROM .LKWLD WHEN A FILE SPEC REQUEST IS IDENTIFIED AS DIRECTED
;TO A REMOTE FILE SYSTEM
;
;T1 HAS THE ADDRESS OF WILD'S INTERNAL FILE SPEC BLOCK WITH THE TARGET
;NODE SET.

.LKWLN::MOVEM	T1,.IOFSY(IO)	;SAVE "CURRENT" FILE SPEC BLOCK
	MOVX	T2,IO.LKN	;THE LKWLN-CALLED FLAG
	IORM	T2,.IOCCF(IO)	;FLAG FOR OPIL TO SEE
	JRST	.POPJ1##	;TELL LKWLD TO SKIP-RETURN TO OPIL

;HERE ON "LOOKUP" FAILURE - CHECK FOR /OKPROT AND FRIENDS
;CALL IS:
;
;	MOVE	M0,<COD>
;	PUSHJ	P,OPIE00
;	 IGNORE RETURN
;	MESSAGE RETURN
;
;Where <COD> is the internal error/exception code (and not FILOP.,
;NSP., etc. error codes)
;
;If the error should be ignored (e.g., a protection failure and /OKPROT
;is set) the non-skip return is taken.
;
;If an error message is needed the skip return is taken to the caller,
;who should then propagate an error return to his caller.
;
;Preserves all acs (yes, even - especially - M0)

OPIE00:	PUSHJ	P,.SAVE4##	;NEED SOME ACS TO PLAY WITH HERE
	MOVE	P1,.IOFSC(IO)	;FETCH POINTER TO CURRENT FILE SPEC BLOCK
	DMOVE	P2,.FXMOD(P1)	;GET /OKPROT, /OKNONE, ETC
	CAIN	M0,$EFPRT	;PROTECTION FAILURE?
	JRST	OPIE10		;YES
	CAIN	M0,$EFFNF	;FILE NOT FOUND?
	JRST	OPIE20		;YES
	CAIE	M0,$EFDNF	;DIRECTORY NOT FOUND?
	CAIN	M0,$EFSNF	;SUB-DIRECTORY NOT FOUND?
	JRST	OPIE23		;YES, TREAT SORTA LIKE FILE NOT FOUND
	CAIN	M0,$EFNSD	;DEVICE NOT FOUND?
	JRST	OPIE26		;YES
	CAIE	M0,$EFURO	;UNRECOGNIZED OBJECT/SERVER?
	CAIN	M0,$EFNSN	;NODE NOT FOUND?
	JRST	OPIE30		;YES
	CAIN	M0,$EFUID	;NODE FOUND, BUT REJECTED USERID/ETC.?
	JRST	OPIE33		;YES
	JRST	.POPJ1##	;OOPS, NEED AN ERROR MESSAGE TYPED!
;PROTECTION FAILURE

OPIE10:	TXNN	P2,FX.PRT	;/OKPROT SPECIFIED?
	JRST	.POPJ1##	;NO, ERROR MESSAGE TIME
	AOS	.CTFLP##	;NOTE A PROTECTION FAILURE OCCURRED
OPIE17:	SOS	.CTFLF##	;DISCOUNT FILE FOUND
	POPJ	P,		;AND OTHERWISE IGNORE THE ERROR


;FILE NOT FOUND

OPIE20:	TXNE	P2,FX.NOM	;/OKNONE SPECIFIED?
	POPJ	P,		;YES, TOTALLY IGNORE IT
	SKIPN	.WLDFL##	;/ERNONE, IS WILD IN THE ACT?
	JRST	.POPJ1##	;NO (E.G., NO WILDCARDS AND /NOSTR), ERROR
	JRST	OPIE17		;YES, DEFER ERROR FOR WILD/LOOKED TO FIND
				; (AND ISSUE "NO SUCH FILES" MESSAGE)


;SUB/DIRECTORY NOT FOUND

OPIE23:	TXNE	P2,FX.NOM	;/OKNONE SPECIFIED?
	POPJ	P,		;YEAH, TOTALLY IGNORE IT
	SKIPN	.WLDFL##	;/ERNONE, IS WILD IN THE ACT?
	JRST	.POPJ1##	;NO (E.G., NO WILDCARDS AND /NOSTR), ERROR
	SOS	.CTDRS##	;WE HAVE NEITHER SEEN
	SOS	.CTDRF##	; NOR FOUND A DIRECTORY AFTER ALL
	SOS	.CTFLS##	;ALSO DISCOUNT THE ACTUAL FILE SEEN
	JRST	OPIE17		;DEFER ERROR FOR WILD/LOOKED TO FIND


;DEVICE NOT FOUND

OPIE26:	TXNN	P2,FX.NOM	;/OKNONE SPECIFIED?
	JRST	.POPJ1##	;NO, TIME FOR ERROR MESSAGE
	SOS	.CTDVS##	;DISCOUNT DEVICE SELECTED
	POPJ	P,		;DEFER ERROR


;NO SUCH NODE

OPIE30:	TXNN	P2,FX.NOM	;/OKNONE SPECIFIED?
	JRST	.POPJ1##	;NO, TYPE ERROR MESSAGE
	SOS	.CTNDS##	;YES, DISCOUNT NODE SEEN
	POPJ	P,		;IGNORE ERROR


;USERID/PASSWORD/ACCOUNT REJECTED BY REMOTE NODE

OPIE33:	TXNN	P2,FX.UID	;/OKUID SPECIFIED?
	JRST	.POPJ1##	;NO, TYPE ERROR MESSAGE
	AOS	.CTNDP##	;COUNT UP NODES "PROTECTED" AGAINST US
	POPJ	P,		;IGNORE ERROR
	SUBTTL	IOPOU - OPEN output file stream

;IOPOU  --  CREATE OUTPUT FILE
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<ICD>
;	PUSHJ	P,.IOPOU
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB which points to the file
;spec blocks; and <ICD> is the address of the input I/O CDB which
;was primary wildcarded and from which the output file specification
;is to be generated, or = -1 if no input spec is provided.
;
;The error return is taken if the file cannot (or should not - 
;user said "NO" to /QUERY) be created.
;
;On normal return, the output file is OPEN and ready for output.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOPOU
	INTERN	IOPOU0,	IOPOU1

.IOPOU:	PUSHJ	P,.SACIO##	;SETUP I/O
IOPOU0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
IOPOU1:	PUSHJ	P,TSAV14##	;ALSO SAVE THE T ACS
	CAIN	T2,0		;GOT AN INPUT CDB?
	MOVE	T2,IO		;NO, FAKE UP ONE
	MOVEM	T2,.IOSCD(IO)	;SAVE "INPUT" CDB
	MOVE	T1,.IOCCF(IO)	;GET CHANNEL CONTROL
	TXNN	T1,IO.OPN	;[STILL] GOT A FILE OPEN?
	JRST	IOPOU3		;NO
	PUSHJ	P,IOABO1	;YES, GET RID OF IT
	 JFCL			;OH WELL

;CLEAR OUT ANY POSSIBLY-STALE FILE INFORMATION

IOPOU3:	SETZM	.IOBZC(IO)	;START OF TO-BE-CLEARED ON CLOSE
	MOVEI	T2,.IOBZC+1(IO)	;CONCOCT A
	HRLI	T2,-1(T2)	; BLT POINTER TO
	BLT	T2,.IOEZC-1(IO)	;  CLEAR THE TO-BE-CLEARED AREA

;SETUP CALL TO .SCWLD

IOPOU5:	MOVE	T2,.IOSCD(IO)	;ADDRESS OF "INPUT" CDB
	MOVE	T4,[12,,%%FXVE]	;PROTOCOL FOR WILD
	MOVEM	T4,.IOSCW+0(IO)	;ZEROTH .SCWLD WORD
	MOVSI	T4,.IOFSC(T2)	;ADDRESS OF ADDRESS OF INPUT FILE SPEC BLOCK
	HRRI	T4,.IOFSB(IO)	;ADDRESS OF ADDRESS OF OUTPUT FILE SPEC BLOCK
	MOVEM	T4,.IOSCW+1(IO)	;FIRST .SCWLD WORD
	MOVSI	T4,.I1OPN(T2)	;INPUT OPEN BLOCK
	HRRI	T4,.I1OPN(IO)	;OUTPUT OPEN BLOCK
	MOVEM	T4,.IOSCW+2(IO)	;SECOND .SCWLD WORD
	MOVSI	T4,.I1LKP(T2)	;INPUT LOOKUP BLOCK
	HRRI	T4,.I1LKP(IO)	;OUTPUT ENTER BLOCK
	MOVEM	T4,.IOSCW+3(IO)	;THIRD .SCWLD WORD
	MOVE	T4,[[0,,-1],,.RBMAX-1]  ;DEFAULT TYPE,,ENTER BLOCK LENGTH
	MOVEM	T4,.IOSCW+4(IO)	;FOURTH .SCWLD WORD
	MOVEI	T4,.I1PTH(IO)	;ADDRESS OF PATH BLOCK
	MOVEM	T4,.IOSCW+5(IO)	;FIFTH .SCWLD WORD
	MOVEI	T4,.IOSCF(IO)	;ADR OF SCWILD PROCESSING FLAGS (DEFAULT .FXCTL)
	MOVEM	T4,.IOSCW+6(IO)	;SIXTH .SCWLD WORD
	MOVEI	T1,SCENEV##	;/SCERROR:NEVER VALUE
	DPB	T1,[POINTR .IOSCF(IO),FX.SCE]  ;SET DEFAULT .FXCTL

;NOW GENERATE SECONDARY-WILDCARDED FILE SPEC

	MOVSI	T1,7		;LENGTH OF .SCWLD BLOCK
	HRRI	T1,.IOSCW(IO)	;ADDRESS OF .SCWLD BLOCK
	PUSHJ	P,.SCWLD##	;GENERATE OUTPUT FILE SPEC
	 JRST	[MOVX	M0,$EFISW	;ILLEGAL SECONDARY WILDCARDING
		POPJ	P,]		;ERROR RETURN

;***	.SCWLD RETURNS NODE NAME IN T3 FOR THE PRESENT . . .

	SKIPE	T1,T3		;IF NO NODE NAME, LEAVE IT BLANK
	PUSHJ	P,.NDNAM##	;TRY TO MAKE SENSE OF THE NODE NAME
	MOVEM	T1,.I1NOD(IO)	;SAVE NODE NAME FOR THE WORLD TO SEE
	MOVE	T2,.IOFSB(IO)	;ADDRESS OF FIRST OUTPUT FILE SPEC BLOCK
	MOVEM	T2,.IOFSC(IO)	;SET AS CURRENT FILE SPEC BLOCK
	MOVE	T2,.IOIOM(IO)	;GET MODE CONTROL
	TXNE	T2,IM.DQA	;DISABLE IOQAT CALLS?
	JRST	OPOU12		;YES
	PUSHJ	P,FILRA		;SET UP NAME STRINGS FOR QUERY PROCESSOR
	 JFCL			;NEVER FAILS
	MOVE	T1,IO		;OUTPUT SIDE CDB
	MOVE	T2,-T2(P)	;INPUT SIDE CDB
	PUSHJ	P,IOQAA1	;HANDLE ANY /QUERY:ASK PROCESSING NEEDED
	 POPJ	P,		;USER PROBABLY SAID "NO"

;CREATE THE FILE

OPOU12:	MOVE	T2,.IOFSB(IO)	;ADDRESS OF FILE SPEC BLOCK
	MOVE	T2,.FXMOD(T2)	;FILE MODS
	MOVEI	T1,.IFWRT	;ASSUME SIMPLE WRITE
	TXNE	T2,FX.APP	;/APPEND?
	MOVEI	T1,.IFAPP	;YES
	SKIPN	T2,.I1NOD(IO)	;PICKUP NODE NAME
	MOVE	T2,.MYNOD##	;NONE SPECIFIED, DEFAULT TO LOCAL
	CAME	T2,.MYNOD##	;DESTINATION LOCAL NODE?
	JRST	OPOR		;NO, REMOTE CREATE

;LOCAL CREATE

	SETZ	T2,		;*** TEMP
	PUSHJ	P,FILOP		;CREATE THE OUTPUT FILE
	 JRST	OPOU50		;SEE WHY CREATION FAILED

;NOW HANDLE ANY QUERY:TELL PROCESSING SINCE WE NOW KNOW THE REAL FINAL
;FILE INFORMATION (ACTUAL DISK STRUCTURE, ETC.)

	MOVE	T1,IO		;OUTPUT SIDE CDB
	MOVE	T2,.IOSCD(IO)	;INPUT SIDE CDB
	PUSHJ	P,IOQTT1	;HANDLE ANY /QUERY:TELL PROCESSING NEEDED
	 STOPCD	<IOQTT failed in OPOU>

;NOW SEE IF NEED TO ALLOCATE BUFFERS

	MOVE	T1,.IOIOM(IO)	;GET FILE MODE CONTROL WORD
	TXNE	T1,IM.SBO	;SUPPRESS BUFFER ALLOCATION AT OPEN?
	JRST	OPOU30		;YES
	PUSHJ	P,FILBF		;NO, ALLOCATE BUFFERS AS NEEDED
	 POPJ	P,		;OOPS, NO MEMORY OR SOMETHING

;OUTPUT FILE ALL SET AND READY TO WRITE

OPOU30:	JRST	.POPJ1##	;WE HAVE A NEW OUTPUT FILE

;FILE CREATION ERROR

OPOU50:	POPJ	P,		;FOR NOW
;HERE FOR A REMOTE FILE CREATE

;HERE WITH NODE NAME IN T2

OPOR:	MOVEM	T1,.IOFOP(IO)	;REMEMBER CREATE/APPEND FUNCTION
	MOVE	T4,.IOCCF(IO)	;CHANNEL CONTROL FLAGS
	TXNE	T4,IO.NET	;NETWORK CHANNEL OPEN?
	CAME	T2,.ION6M(IO)	;YES, TALKING TO RIGHT NODE?
	CAIA			;MUST OPEN [NEW] NETWORK CHANNEL
	JRST	OPOR03		;ALREADY HAVE A CHANNEL TO USE
	PUSHJ	P,DPINI1	;OPEN A [DAPISH] NETWORK CHANNEL
	 POPJ	P,		;CAN'T, THEN CAN'T CREATE FILE EITHER
	MOVE	T2,.ION6M(IO)	;GET RESULTANT NODE NAME
	MOVEM	T2,.I1NOD(IO)	;AND SET IN THE NODE WORD (PARANOIA)
	PUSHJ	P,OPFND		;NOW SETUP .IOFND

;WE ARE TALKING TO A REMOTE FAL, PREPARE TO SEND FILE REQUEST

OPOR03:	MOVE	T1,.IOFOP(IO)	;FILE OPERATION
	MOVE	T1,FICFTB(T1)	;APPROPRIATE FLAGS TO SET
	IORM	T1,.IOCCF(IO)	;SET USEFUL BITS IN CDB
;***OPOR05:	MOVE	P2,.IOFSB(IO)	;ADDRESS OF FILE SPEC BLOCK
;***	MOVE	T1,.IOIOM(IO)	;GET MODE CONTROL
;***	TXNE	T1,IM.CMD	;FORCED TO USE .IOIOC?
;***	JRST	OPOR10		;DON'T SELECT MODE, USE .IOIOC AS SUPPLIED
;***	LDB	T2,[POINTR .FXCTL(P2),FX.DAM]  ;USER-SUPPLIED /DATAMODE
;***	JUMPN	T2,OPOR08	;IF SET THEN /DATAMODE GOVERNS ACCESS
;***	LDB	T2,[POINTR .FXCTL(P2),FX.IOM]  ;USER-SUPPLIED /IOMODE
;***	JUMPE	T2,OPOR10	;IF NEITHER /DATAMODE NOR /IOMODE THEN .IOIOC
;***OPOR08:	MOVE	T3,MDMOTB(T2)	;CONVERT TO INTERNAL MODE
;***OPOR09:	DPB	T3,[POINTR .IOIOC(IO),IC.MOD]  ;SET INTERNAL DATA MODE

;NOW SETUP DAP AREAS FOR TRANSMISSION TO THE REMOTE FAL

OPOR10:	PUSHJ	P,DPOAF1	;CONVERT FROM FILE BLOCKS TO DAP META-JUNK
	 STOPCD	<DPOAF failed in OPOR>
	PUSHJ	P,DPOAA1	;ALSO SET THE ACCESS MESSAGE FIELDS
	 STOPCD	<DPOAA failed in OPOR>

;SEND FILE ATTRIBUTES

OPOR20:	MOVEI	T2,$DHATR	;FILE ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND MAIN ATTRIBUTES MESSAGE
	 CAIA			;HMMM
	JRST	OPOR22		;CHECK ALLOCATION ATTRIBUTES
	STOPCD	<Main attributes xmit failed in OPOR20>

;SEE IF ALLOCATION ATTRIBUTES NEEDED

OPOR22:	MOVD	T3,M11		;ALLOCATION ATTRIBUTES MENU
	TMZ	T3,<ALP,AAL>	;CLEAR STUFF IN COMMON WITH MAIN ATTR
	FJUMPE	T3,M11,OPOR26	;DON'T SEND IF NOTHING NEW TO SAY
	MOVD	T3,CNF		;GET REMOTE CONFIGURATION FLAGS
	TFNN	T3,AEA		;DOES REMOTE SUPPORT ALLOC ATTR?
	JRST	OPOR26		;NO
	MOVEI	T2,$DHALC	;YES, ALLOCATION ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND ALLOCATION ATTRIBUTES MESSAGE
	 CAIA			;HMMM
	JRST	OPOR26		;CHECK DATE/TIME ATTR
	STOPCD	<Allocation attributes xmit failed in OPOR22>

;SEE IF DATE/TIME ATTRIBUTES NEEDED

OPOR26:	MOVD	T3,M13		;DATE/TIME ATTRIBUTES MENU
	FJUMPE	T3,M13,OPOR28	;SKIP IF DATE/TIME STUFF NOT NEEDED
	MOVD	T3,CNF		;GET REMOTE CONFIGURATION FLAGS
	TFNN	T3,TEA		;CAN REMOTE HANDLE A DATE/TIME ATTR MSG?
	JRST	OPOR28		;NO
	MOVEI	T2,$DHTIM	;YES, DATE/TIME ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND DATE/TIME ATTRIBUTES MESSAGE
	 CAIA			;HMMM
	JRST	OPOR28		;CHECK PROTECTION ATTRIBUTES
	STOPCD	<Date/time attributes xmit failed in OPOR26>

;SEE IF PROTECTION ATTRIBUTES NEEDED

OPOR28:	MOVD	T3,M14		;PROTECTION ATTRIBUTES MENU
	FJUMPE	T3,M14,OPOR40	;DON'T SEND IF NO PROTECTION TO SEND
	MOVD	T3,CNF		;GET REMOTE CONFIGURATION FLAGS
	TFNN	T3,PEA		;DOES REMOTE SUPPORT PROTECTION ATTR?
	JRST	OPOR40		;NO
	MOVEI	T2,$DHPRT	;YES, PROTECTION ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND PROTECTION ATTRIBUTES MESSAGE
	 CAIA			;HMMM
	JRST	OPOR40		;SEND THE ALL-IMPORTANT ACCESS MESSAGE
	STOPCD	<Protection attributes xmit failed in OPOR28>


;ATTRIBUTES SENT, NOW SEND THE ACCESS MESSAGE

OPOR40:	MOVEI	T3,$DVAWR	;CREATE A FILE
	MOVD1M	T3,AFC		;SET ACCESS FUNCTION WORD
	MOVDII	T3,FAC,PUT	;"PUT" ACCESS
	MOVDM	T3,FAC		;SET FILE ACCESS OPTIONS FIELD
	MOVD	T1,CNF		;GET REMOTE CONFIGURATION FLAGS
	MOVDII	T3,ADS,DMA	;ALWAYS WANT MAIN ATTRIBUTES RETURNED
	TFNE	T1,TEA		;IF THE REMOTE SUPPORTS DATE/TIME ATTRIBUTES
	TFO	T3,DDT		; THEN REQUEST DATE/TIME ATTR BE RETURNED
	TFNE	T1,PEA		;IF THE REMOTE SUPPORTS PROTECTION ATTRIBUTES
	TFO	T3,DFP		; THEN REQUEST PROTECTION ATTR BE RETURNED
	TFNE	T1,NAM		;IF THE REMOTE SUPPORTS THE NAME MESSAGE
	TFO	T3,DNM		; THEN REQUEST A RESULTANT NAME BE RETURNED
	MOVDM	T3,ADS		;SET ACCESS DISPLAY FIELD
	MOVEI	T2,$DHACS	;FILE ACCESS MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND FILE ACCESS MESSAGE
	 CAIA			;HMMM
	JRST	OPOR50		;WAIT FOR ACK
	STOPCD	<File access xmit failed in OPOR40>


;FILE ACCESS SENT, GET RESULTANT ATTRIBUTES AND ACKNOWLEDGEMENT

OPOR50:	PUSHJ	P,XDFLS1##	;INSURE THAT EVERYTHING SENT
	 POPJ	P,		;SIGH
OPOR51:	PUSHJ	P,RDMSG1##	;READ IN A DAP MESSAGE CODE
	 POPJ	P,		;NETWORK MUST HAVE DIED
	JSP	T4,.CDISP##	;DISPATCH ON MESSAGE TYPE
		OPOR52,,$DHSTS	;STATUS (ERROR - SIGH)
		OPOR55,,$DHATR	;MAIN ATTRIBUTES, SLURP IT UP
		OPOR55,,$DHALC	;ALLOCATION ATTRIBUTES, GET IT TOO
		OPOR55,,$DHTIM	;DATE/TIME ATTRIBUTES, READ IT IN
		OPOR55,,$DHPRT	;PROTECTION ATTRIBUTES, READ IT IN
		OPOR57,,$DHNAM	;RESULTANT NAME, GET IT
		OPOR60,,$DHACK	;ACCESS ACKNOWLEDGEMENT, WE ARE HAPPY
		0		;NO OTHER MESSAGES ACCEPTABLE
	JRST	.RDEOS##	;MESSAGE OUT OF SEQUENCE

;RECEIVED STATUS IN REPLY TO ACCESS, PROBABLY ERROR

OPOR52:	PUSHJ	P,RDSTS1##	;READ IN REST OF STATUS MESSAGE
	 POPJ	P,		;NETWORK MUST HAVE DIED
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"
	CAIN	M0,$EGAOK	;"A-OK"
	JRST	OPOR51		;YES (DUH?) TRY FOR THE ACK
	POPJ	P,		;PROPAGATE ERROR


;RESULTANT FILE INFORMATION, ABSORB IT FOR THE CALLER, IF HE CARES

OPOR55:	PUSHJ	P,RDDAP1##	;READ IN REST OF INFORMATION
	 POPJ	P,		;SIGH
	JRST	OPOR51		;WE WANT THAT ACK!

;RESULTANT FILE NAME, PROCESS NAME STUFF FOR IOQAT

OPOR57:	PUSHJ	P,RDDAP1##	;READ IN THE NAME STRING
	 POPJ	P,		;NET DIED?
	PUSHJ	P,DPRNM1	;PROCESS THE RECEIVED NAME STRING
	 POPJ	P,		;DUH?
	JRST	OPOR51		;BACK FOR THE ACK

;REMOTE ACKNOWLEDGED OUR FILE ACCESS REQUEST

OPOR60:	PUSHJ	P,RDDAP1##	;EAT REST OF ACK
	 POPJ	P,		;DUH?
	MOVX	P1,IO.OPN	;THE FILE-IS-OPEN BIT
	IORB	P1,.IOCCF(IO)	;MARK THE CDB AS OWNING AN OPEN FILE


;SETUP FILE INFORMATION TO RETURN TO USER

;***	PUSHJ	P,DPIAF1	;SETUP RETURNED ATTRIBUTES/ET AL
;***	 STOPCD	<DPIAF failed in OPOR60>
	PUSHJ	P,DPDCH1	;*** TRANSLATE DEVICE/FILE CHARACTERISTICS
	 JFCL			;*** HUM
	MOVEM	T2,.IODCH(IO)	;*** SET CDB DEVICE/FILE CHARACTERISTICS


;SELECT THE ISRS

OPOR70:	MOVE	P1,.IOCCF(IO)	;I/O CONTROL FLAGS
	XMOVEI	T1,.IOIIN##	;REMOTE INPUT INITIALIZE
	TXNN	P1,IO.INP	;INPUT REQUESTED?
	XMOVEI	T1,.IOIIE##	;NO, THEN SELECT ERROR ISR INSTEAD
	MOVEM	T1,.IOISR(IO)	;SET INPUT I/O SERVICE ROUTINE
	XMOVEI	T1,.IOOIN##	;REMOTE OUTPUT INITIALIZE
	TXNN	P1,IO.OUT	;OUTPUT REQUESTED?
	XMOVEI	T1,.IOOIE##	;NO, THEN SELECT ERROR ISR INSTEAD
	MOVEM	T1,.IOOSR(IO)	;SET OUTPUT I/O SERVICE ROUTINE

;NOW HANDLE ANY QUERY:TELL PROCESSING SINCE WE NOW KNOW THE REAL FINAL
;FILE INFORMATION (ACTUAL DISK STRUCTURE, ETC.)

	MOVE	T1,IO		;OUTPUT SIDE CDB
	MOVE	T2,-T2(P)	;INPUT SIDE CDB
	PUSHJ	P,IOQTT1	;HANDLE ANY /QUERY:TELL PROCESSING NEEDED
	 STOPCD	<IOQTT failed in OPOR>

;ALL SET FOR SUBSEQUENT DATA WRITES

	JRST	.POPJ1##	;SUCCESSFUL RETURN
;OPFND - HELPER FOR OPXXX ROUTINES

OPFND:	XMOVEI	T1,FILOTO	;OUR TYPE-OUT ROUTINE
	PUSHJ	P,.XTYPO##	;SET NEW TYPEOUT
	MOVE	T1,[POINT 7,.IOSND(IO)]  ;DESTINATION BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SAVE IT AWAY
	XMOVEI	T1,.IOSND(IO)	;ADDRESS OF NODE STRING BLOCK
	MOVEM	T1,.IOFND(IO)	;SET IN NODE NAME POINTER LOCATION
	MOVE	T1,T2		;THE NODE NAME
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT NODE NAME
	PJRST	FILOTZ		;TERMINATE STRING
	SUBTTL	IOFDL - Delete OPEN file

;IOFDL  --  DELETE CURRENTLY OPEN FILE
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOFDL
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB whose currently OPENed file
;is to be deleted.
;
;On error return the file couldn't be deleted (error code in M0). The
;file is still OPEN!
;
;On normal return the file has been deleted. In particular, the CDB
;has been CLOSEd.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOFDL
	INTERN	IOFDL0,	IOFDL1

.IOFDL:	PUSHJ	P,.SACIO##	;SET UP IO TO POINT TO THE CDB
IOFDL0:	PUSHJ	P,.SAVE4##	;NEED SOME ACS HERE
IOFDL1:	PUSHJ	P,TSAV14##	;SAVE THE USER'S T ACS TOO

;SET UP THE TERTIARY "RENAME" BLOCK FOR FILOP

	MOVX	T1,.RBMAX	;SIZE OF FILE BLOCK
	MOVEM	T1,.I1LK3+.RBCNT(IO)  ;SET IN COUNT WORD OF FILE BLOCK
	SETZM	.I1LK3+.RBNAM(IO)  ;DELETE = BLANK NAME

REPEAT	0,<
;CHECK /QUERY

	MOVE	T1,.IOIOM(IO)	;I/O MODE CONTROL
	TXNE	T1,IM.DQA	;DISABLE IOQAT?
	JRST	IOFDL5		;YES
	SETZ	T1,		;NO "OUTPUT"
	MOVE	T2,IO		;ONLY "INPUT"
	PUSHJ	P,IOQAT1	;HANDLE ANY /QUERY NECESSARY
	 POPJ	P,		;USER SAID "NO" TO THIS FILE
> ;END REPEAT 0

;DELETE THE FILE

IOFDL5:	MOVE	T1,.IOCCF(IO)	;CHANNEL CONTROL
	TXNE	T1,IO.NET	;IS THIS A NETWORKED FILE?
	JRST	IONDL0		;YES, DIFFERENT
	MOVEI	T1,.IFDLT	;DELETE FUNCTION
	SETZ	T2,		;*** TEMP
	PUSHJ	P,FILOP		;DELETE THE FILE
	 JRST	IOFDL9		;DELETE FAILED
	PJRST	IOCLO7		;MARK FILE CLOSED TO ACCESS

;HERE WHEN DELETE FILOP FAILS

IOFDL9:	POPJ	P,		;ERROR RETURN TO THE CALLER
;HERE TO DELETE A NETWORK-BASED (REMOTE FILE SYSTEM) FILE

IONDL0:	MOVEI	P2,IM.CDL	;DELETE-ON-CLOSE FLAG
	PJRST	IONC00		;AND "CLOSE" THE FILE
	SUBTTL	IOFPR - Print OPEN file (spool to lineprinter)

;IOFPR  --  PRINT CURRENTLY OPEN FILE
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOFPR
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB whose currently OPENed file
;is to be printed via spooling to the lineprinter queue.
;
;IOFPR takes the file currently OPEN via the CDB and passes it (i.e.,
;the file specification) to the systemlineprinter spooler processor
;to be printed as a standard print request. The print spooler processor
;is always the file system host, not the local host.
;
;No actual file or I/O processing is performed on the file, the CDB is
;unaffected - it is used solely as a handle on the file specification
;to be submitted (but see "normal return" below).
;
;On error return the file couldn't be printed (error code in M0). The
;file is still OPEN.
;
;On normal return the file has been printed. Note also that the file
;has been CLOSEd as well (This is an artifact of the DAP protocol -
;such is life).
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOFPR
	INTERN	IOFPR0,	IOFPR1

.IOFPR:	PUSHJ	P,.SACIO##	;SET UP IO TO POINT TO THE CDB
IOFPR0:	PUSHJ	P,.SAVE4##	;NEED SOME ACS HERE
IOFPR1:	PUSHJ	P,TSAV14##	;SAVE THE USER'S T ACS TOO

REPEAT	0,<
;CHECK /QUERY

	MOVE	T1,.IOIOM(IO)	;I/O MODE CONTROL
	TXNE	T1,IM.DQA	;DISABLE IOQAT?
	JRST	IOFDL5		;YES
	SETZ	T1,		;NO "OUTPUT"
	MOVE	T2,IO		;ONLY "INPUT"
	PUSHJ	P,IOQAT1	;HANDLE ANY /QUERY NECESSARY
	 POPJ	P,		;USER SAID "NO" TO THIS FILE
> ;END REPEAT 0

;PRINT THE FILE

IOFPR5:	MOVE	T1,.IOCCF(IO)	;CHANNEL CONTROL
	TXNE	T1,IO.NET	;IS THIS A NETWORKED FILE?
	JRST	IONPR0		;YES, DIFFERENT
	MOVEI	T2,.QUPRT	;IDENTIFY PRINT REQUEST
	PUSHJ	P,QUEOP1##	;ISSUE QUEUE. TO GALAXY
	 POPJ	P,		;CAN'T DO IT

;NOW CLOSE THE FILE (BE "COMPATIBLE" WITH DAP/REMOTE ACCESS - SIGH)

	MOVE	P2,.IOIOM(IO)	;LOAD MODE CONTROL FOR IOCLO ROUTINES
	TXZ	P2,IM.CXX	;NO CLOSE-TIME OPTIONS HERE!
	PUSHJ	P,IOCLO3	;NOW REALLY "CLOSE" THE FILE
	 CAIA			;DUH?
	JRST	.POPJ1##	;SUCCESSFUL RETURN
	PUSHJ	P,IOABO1	;BLAST THE RECALCITRANT THING
	 JFCL			;DOUBLE-DUH?
	JRST	.POPJ1##	;SUCCESSFUL (MAYBE) RETURN
;HERE TO PRINT A NETWORK-BASED (REMOTE FILE SYSTEM) FILE

IONPR0:	MOVX	P2,IM.CPR	;PRINT-ON-CLOSE FLAG
	PJRST	IONC00		;GO "CLOSE" THE FILE
	SUBTTL	IOFRN - Rename OPEN file

;IOFRN  --  RENAME OPEN FILE
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOFRN
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB containing the already OPEN
;file to be RENAMEd, and both the input file spec blocks and the tertiary
;"output" file spec blocks.
;
;On error return either the file couldn't be renamed or the user rejected
;the file via /QUERY:ASK.
;
;On normal return the file has been RENAMEd to the new specification and
;CLOSEd to further access.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOFRN
	INTERN	IOFRN0,	IOFRN1

.IOFRN:	PUSHJ	P,.SACIO##	;SETUP I/O
IOFRN0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
IOFRN1:	PUSHJ	P,TSAV14##	;ALSO SAVE THE T ACS

;SETUP CALL TO .SCWLD

	MOVE	T4,[12,,%%FXVE]	;SCAN/WILD PROTOCOL VERSION WORD
	MOVEM	T4,.IOSCW+0(IO)	;ZEROTH .SCWLD WORD
	MOVSI	T4,.IOFSC(IO)	;ADDRESS OF ADDRESS OF INPUT FILE SPEC BLOCK
	HRRI	T4,.IOFS3(IO)	;ADDRESS OF ADDRESS OF OUTPUT FILE SPEC BLOCK
	MOVEM	T4,.IOSCW+1(IO)	;FIRST .SCWLD WORD
	MOVSI	T4,.I1OPN(IO)	;INPUT OPEN BLOCK
	HRRI	T4,.I1OP3(IO)	;OUTPUT OPEN BLOCK
	MOVEM	T4,.IOSCW+2(IO)	;SECOND .SCWLD WORD
	MOVSI	T4,.I1LKP(IO)	;INPUT LOOKUP BLOCK
	HRRI	T4,.I1LK3(IO)	;OUTPUT ENTER BLOCK
	MOVEM	T4,.IOSCW+3(IO)	;THIRD .SCWLD WORD
	MOVE	T4,[[0,,-1],,.RBMAX-1]  ;DEFAULT TYPE,,ENTER BLOCK LENGTH
	MOVEM	T4,.IOSCW+4(IO)	;FOURTH .SCWLD WORD
	MOVSI	T4,0		;NOTHING YET
	HRRI	T4,.IOSCF(IO)	;SCWILD PROCESSING FLAGS
	MOVEM	T4,.IOSCW+5(IO)	;FIFTH .SCWLD WORD
	SETZM	.IOSCF(IO)	;SET OK TOO MANY INPUT WILDCARDS
	MOVEI	T1,.I1PT3(IO)	;ADDRESS OF PATH BLOCK
	MOVEM	T1,.I1LK3+.RBPPN(IO)  ;SET PATH BLOCK TO USE

;NOW GENERATE SECONDARY-WILDCARDED FILE SPEC

	MOVSI	T1,6		;LENGTH OF .SCWLD BLOCK
	HRRI	T1,.IOSCW(IO)	;ADDRESS OF .SCWLD BLOCK
	PUSHJ	P,.SCWLD##	;GENERATE OUTPUT FILE SPEC
	 JRST	[MOVX	M0,$EFISW	;ILLEGAL SECONDARY WILDCARDING
		POPJ	P,]		;ERROR RETURN
	JUMPE	T3,IOFRN3	;NO NODE IS NO CHANGE IN THE NODE
	CAME	T3,.I1NOD(IO)	;IS NEW NODE THE SAME AS OLD NODE?
	STOPCD	<Can't RENAME to a new node in IOFRN>
IOFRN3:	MOVE	P1,.IOCCF(IO)	;CHANNEL CONTROL
	TXNE	P1,IO.NET	;LOCAL OR REMOTE FILE SERVICE?
	JRST	IORRN0		;REMOTE, DIFFERENT CODE!

;CHECK /QUERY

IOFRN4:	PUSHJ	P,FILTA		;GENERATE THE TERTIARY STRINGS
	 JFCL			;DUH?
	MOVE	T1,.IOFS3(IO)	;ADDRESS OF FIRST OUTPUT FILE SPEC BLOCK
	MOVEM	T1,.IOCU3(IO)	;SET AS CURRENT FILE SPEC BLOCK
	MOVE	T1,.IOIOM(IO)	;GET IO MODE CONTROL
	TXNE	T1,IM.DQA	;DISABLE IOQAT CALLS?
	JRST	IOFRN5		;YES
	SETO	T1,		;OUTPUT SIDE IS ACTUALLY "TERTIARY" INPUT
	MOVE	T2,IO		;INPUT SIDE CDB
	PUSHJ	P,IOQAT1	;HANDLE ANY /QUERY PROCESSING NEEDED
	 POPJ	P,		;USER PROBABLY SAID "NO"

;RENAME THE FILE

IOFRN5:	MOVEI	T1,.IFRNM	;"RENAME" FILE OPERATION
	SETZ	T2,		;*** TEMP
	MOVE	P4,.IOFS3(IO)	;ADDRESS OF "OUTPUT" FSB
	EXCH	P4,.IOFSC(IO)	;SET AS "CURRENT" FSB FOR FLPA TO SEE
	PUSHJ	P,FILOP		;RENAME THE OUTPUT FILE
	 JRST	[MOVEM	P4,.IOFSC(IO)	;RESTORE "INPUT" FSB ADDRESS
		JRST	IOFRN9]		;RENAME FAILED
	MOVEM	P4,.IOFSC(IO)	;RESTORE "INPUT" FSB ADDRESS
	PUSHJ	P,IOCLO0	;CLOSE OFF ACCESS TO THE FILE
	 JFCL			;HMMM
	JRST	.POPJ1##	;THE RENAME SUCCEEDED, TELL CALLER

;HERE WHEN THE RENAME FILOP FAILS

IOFRN9:	POPJ	P,		;PASS ERROR TO CALLER
;HERE TO RENAME A NETWORKED (REMOTE FILE SYSTEM) FILE

IORRN0:	MOVD	T1,CNF		;REMOTE'S CONFIG FLAGS
	TFNN	T1,CFN		;SUPPORT ACCOMP(RENAME)?
	JRST	[MOVEI	M0,$EFRNA	;NO REMOTE ACCOMP(RENAME) SUPPORT
		POPJ	P,]		;AND THAT IS THE END OF THAT
	MOVE	T1,.IOFS3(IO)	;ADDRESS OF FIRST OUTPUT FILE SPEC BLOCK
	MOVEM	T1,.IOCU3(IO)	;SET AS CURRENT FILE SPEC BLOCK
	PUSHJ	P,DPOTN1	;SETUP TERTIARY NAME MESSAGE FIELDS
	 POPJ	P,		;ILLEGAL SOMETHING OR OTHER
	MOVE	P4,.IOCU3(IO)	;ADDRESS OF "OUTPUT" FILE SPEC BLOCK
	EXCH	P4,.IOFSC(IO)	;SET IT AS "THE CURRENT" FILE SPEC BLOCK
	PUSHJ	P,DPOAF0	;AND SET ANY FILE ATTRIBUTES SPECIFIED
	 JRST	[MOVEM	P4,.IOFSC(IO)	;RESTORE PROPER "INPUT" FILE SPEC BLOCK
		POPJ	P,]		;PROPAGATE ERROR RETURN
	MOVEM	P4,.IOFSC(IO)	;RESTORE PROPER "INPUT" FILE SPEC BLOCK

;FIRST CHECK FOR ANY /QUERY PROCESSING

IORRN4:	MOVE	T1,.IOIOM(IO)	;GET IO MODE CONTROL
	TXNE	T1,IM.DQA	;DISABLE IOQAT CALLS?
	JRST	IORR01		;YES
	SETO	T1,		;OUTPUT SIDE IS ACTUALLY "TERTIARY" INPUT
	MOVE	T2,IO		;INPUT SIDE CDB
	PUSHJ	P,IOQAT1	;HANDLE ANY /QUERY PROCESSING NEEDED
	 POPJ	P,		;USER PROBABLY SAID "NO"

;SHIP THE RENAME INFO TO THE REMOTE

IORR01:	PUSHJ	P,IOCLP1	;BUILD MASK OF CLOSE-TIME OPTIONS
	 POPJ	P,		;THIS CAN'T FAIL!
	PUSHJ	P,IOCLQ1	;CONVERT MASK INTO AFO MASK
	 POPJ	P,		;THIS ALSO SHOULDN'T FAIL
	MOVDM	T1,AFO		;SET ANY CLOSE-TIME ACCOMP OPTIONS
	MOVDII	P3,M07,A2F	;ALWAYS SEND ACCOMP FUNCTION FIELD
	FJUMPE	T1,AFO,IORR04	;ANY OPTIONS TO SET?
	TMO	P3,AFO		;YUP, FLAG THEM TO BE SENT TOO
IORR04:	MOVDM	P3,M07		;SET ACCOMP [HIDDEN] MENU FIELD
	MOVEI	T1,$DVACB	;ACCOMP(CHANGE-BEGIN) (RENAME) FUNCTION
	MOVDM	T1,A2F		;SET IN DAP MESSAGE BLOCK
	MOVEI	T2,$DHACM	;DAP ACCOMP MESSAGE TYPE
	PUSHJ	P,XDDAP1##	;FIRE OFF ACCOMP(CHANGE-BEGIN)
	 POPJ	P,		;NET DIED?

;NOW ALL THE ATTRIBUTES/ETC.

IORR10:	MOVD	T1,CNF		;GET REMOTE CONFIGURATION
IORR11:	TFNN	T1,CFA		;SUPPORT ACCOMP(RENAME/ATTR)?
	JRST	IORR12		;NO
	MOVEI	T2,$DHATR	;YES, ATTRIBUTES MESSAGE TYPE
	PUSHJ	P,XDDAP1##	;FIRE OFF AN ATTRIBUTES MESSAGE
	 POPJ	P,		;NET DIED?

IORR12:	MOVD	T1,CNF		;THE CONFIG AGAIN
IORR13:	TFNN	T1,CFD		;SUPPORT ACCOMP(RENAME/DATETIME)?
	JRST	IORR14		;NO
	MOVEI	T2,$DHTIM	;YES, DATE/TIME ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;FIRE OFF DATE/TIME ATTRIBUTES MESSAGE
	 POPJ	P,		;NET DIED?

IORR14:	MOVD	T1,CNF		;THE CONFIG YET AGAIN
IORR15:	TFNN	T1,CFP		;SUPPORT ACCOMP(RENAME/PROTECTION)?
	JRST	IORR16		;NO
	MOVEI	T2,$DHPRT	;YES, PROTECTION ATTRIBUTES MESSAGE CODE
	PUSHJ	P,XDDAP1##	;FIRE OFF PROTECTION ATTRIBUTES MESSAGE
	 POPJ	P,		;NET DIED

IORR16:	MOVEI	T2,$DHNAM	;NAME MESSAGE CODE
	PUSHJ	P,XDDAP1##	;FIRE OFF NAME MESSAGE
	 POPJ	P,		;NET DIED?
	MOVEI	T1,$DVACE	;ACCOMP(CHANGE-END) FUNCTION
	MOVD1M	T1,A2F		;SET IN MESSAGE BLOCK
	MOVEI	T2,$DHACM	;ACCOMP MESSAGE TYPE AGAIN
	PUSHJ	P,XDDAP1##	;TERMINATE THE ACCOMP(RENAME) SEQUENCE
				; (KEEPING AFO AS SPECIFIED ABOVE)
	 POPJ	P,		;NET DIED?

;FLUSH OUT DATA AND GET REMOTE'S RESPONSE

	PJRST	IONC29		;COMMON CODE FROM HERE ON OUT . . .
	SUBTTL	IOFSU - Submit OPEN file (to batch processor)

;IOFSU  --  SUBMIT CURRENTLY OPEN FILE
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOFSU
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB whose currently OPENed file
;is to be submitted to the batch processing system.
;
;IOFSU submits the file currently OPEN via the CDB and passes it (i.e.,
;the file specification) to the system batch processor to be run as
;a standard batch job. The batch processor host is always the file system
;host processor, not the local host.
;
;No actual file or I/O processing is performed on the file, the CDB is
;unaffected - it is used solely as a handle on the file specification
;to be submitted.
;
;On error return the file couldn't be submitted. The file is still OPEN.
;
;On normal return the file has been submitted. Note also that the file
;has been CLOSED!
;
;Uses T1, T2, T3, T4.

	ENTRY	.IOFSU
	INTERN	IOFSU0,	IOFSU1

.IOFSU:	PUSHJ	P,.SACIO##	;SET UP IO TO POINT TO THE CDB
IOFSU0:	PUSHJ	P,.SAVE4##	;NEED SOME ACS HERE
IOFSU1:	PUSHJ	P,TSAV14##	;SAVE THE USER'S T ACS TOO

REPEAT	0,<
;CHECK /QUERY

	MOVE	T1,.IOIOM(IO)	;I/O MODE CONTROL
	TXNE	T1,IM.DQA	;DISABLE IOQAT?
	JRST	IOFDL5		;YES
	SETZ	T1,		;NO "OUTPUT"
	MOVE	T2,IO		;ONLY "INPUT"
	PUSHJ	P,IOQAT1	;HANDLE ANY /QUERY NECESSARY
	 POPJ	P,		;USER SAID "NO" TO THIS FILE
> ;END REPEAT 0

;SUBMIT THE FILE

IOFSU5:	MOVE	T1,.IOCCF(IO)	;CHANNEL CONTROL
	TXNE	T1,IO.NET	;IS THIS A NETWORKED FILE?
	JRST	IONSB0		;YES, DIFFERENT
	MOVEI	T2,.QUBAT	;IDENTIFY BATCH REQUEST
	PUSHJ	P,QUEOP1##	;ISSUE QUEUE. TO GALAXY
	 POPJ	P,		;CAN'T DO IT

;NOW CLOSE THE FILE (BE "COMPATIBLE" WITH DAP/REMOTE ACCESS - SIGH)

	MOVE	P2,.IOIOM(IO)	;LOAD MODE CONTROL FOR IOCLO ROUTINES
	TXZ	P2,IM.CXX	;NO CLOSE-TIME OPTIONS HERE!
	PUSHJ	P,IOCLO3	;NOW REALLY "CLOSE" THE FILE
	 CAIA			;DUH?
	JRST	.POPJ1##	;SUCCESSFUL RETURN
	PUSHJ	P,IOABO1	;BLAST THE RECALCITRANT THING
	 JFCL			;DOUBLE-DUH?
	JRST	.POPJ1##	;SUCCESSFUL (MAYBE) RETURN
;HERE TO SUBMIT A NETWORK-BASED (REMOTE FILE SYSTEM) FILE

IONSB0:	MOVX	P2,IM.CSU	;SUBMIT-ON-CLOSE FLAG
	PJRST	IONC00		;GO "CLOSE" THE FILE
	SUBTTL	IODDE - DAP-mode file delete operation

;IODDE  --  DAP-MODE DELETE
;Call is:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<RTN>
;	PUSHJ	P,.IODDE
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the controlling I/O CDB; and <RTN> is
;the address of a processing routine to be called for each file
;processed (deleted) by the remote DAP (FAL) process.
;
;On error return, the network died, or the remote doesn't support the
;requested access (e.g., /QUERY:ASK), etc. An error code is in M0.
;
;On normal return the specified file(s) (as indicated by the file spec
;block (.IOFSB) pointer) have been deleted.

	ENTRY	.IODDE
	INTERN	IODDE0,	IODDE1

.IODDE:	PUSHJ	P,.SACIO	;SETUP CDB CONTEXT
IODDE0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S TOO
IODDE1:	CAIN	T2,0		;GOT A PROCESSING ROUTINE?
	XMOVEI	T2,.POPJ1##	;NO, SUPPLY A DEFAULT
	CAIN	T3,0		;GOT AN ERROR PROCESSOR?
	XMOVEI	T3,.POPJ##	;NO, SUPPLY A DEFAULT
	PUSHJ	P,TSAV13##	;SAVE IT FOR LATER
	MOVEI	T1,0		;DAP "DELETE" FUNCTION
	PJRST	IODX00		;GO DO THE DAP-MODE FILE OPERATION
	SUBTTL	IODDI - DAP-mode file directory list operation

;IODDI  --  DAP-MODE DIRECTORY
;Call is:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<RTN>
;	PUSHJ	P,.IODDI
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the controlling I/O CDB; and <RTN> is
;the address of a processing routine to be called for each file
;processed (listed) by the remote DAP (FAL) process.
;
;On error return, the network died, or the remote doesn't support the
;requested access (e.g., /QUERY:ASK), etc. An error code is in M0.
;
;On normal return the specified file(s) (as indicated by the file spec
;block (.IOFSB) pointer) have been "directory'ed".

	ENTRY	.IODDI
	INTERN	IODDI0,	IODDI1

.IODDI:	PUSHJ	P,.SACIO	;SETUP CDB CONTEXT
IODDI0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S TOO
IODDI1:	CAIN	T2,0		;GOT A PROCESSING ROUTINE?
	XMOVEI	T2,.POPJ1##	;NO, SUPPLY A DEFAULT
	CAIN	T3,0		;GOT AN ERROR PROCESSOR?
	XMOVEI	T3,.POPJ##	;NO, SUPPLY A DEFAULT
	PUSHJ	P,TSAV13##	;SAVE IT FOR LATER
	MOVEI	T1,2		;DAP "DIRECTORY" FUNCTION
	PJRST	IODX00		;GO DO THE DAP-MODE FILE OPERATION
	SUBTTL	IODRN - DAP-mode file rename operation

;IODRN  --  DAP-MODE RENAME
;Call is:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<RTN>
;	PUSHJ	P,.IODRN
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the controlling I/O CDB; and <RTN> is
;the address of a processing routine to be called for each file
;processed (renamed) by the remote DAP (FAL) process.
;
;On error return, the network died, or the remote doesn't support the
;requested access (e.g., /QUERY:ASK), etc. An error code is in M0.
;
;On normal return the specified file(s) (as indicated by the file spec
;block (.IOFSB) pointer) have been renamed.

	ENTRY	.IODRN
	INTERN	IODRN0,	IODRN1

.IODRN:	PUSHJ	P,.SACIO	;SETUP CDB CONTEXT
IODRN0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S TOO
IODRN1:	CAIN	T2,0		;GOT A PROCESSING ROUTINE?
	XMOVEI	T2,.POPJ1##	;NO, SUPPLY A DEFAULT
	CAIN	T3,0		;GOT AN ERROR PROCESSOR?
	XMOVEI	T3,.POPJ##	;NO, SUPPLY A DEFAULT
	PUSHJ	P,TSAV13##	;SAVE IT FOR LATER
	MOVNI	T1,1		;DAP "RENAME" FUNCTION
	PJRST	IODX00		;GO DO THE DAP-MODE FILE OPERATION
	SUBTTL	IODEX - DAP-mode file execute operation

;IODEX  --  DAP-MODE EXECUTE
;Call is:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<RTN>
;	PUSHJ	P,.IODEX
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the controlling I/O CDB; and <RTN> is
;the address of a processing routine to be called for each file
;processed (executed) by the remote DAP (FAL) process.
;
;On error return, the network died, or the remote doesn't support the
;requested access (e.g., /QUERY:ASK), etc. An error code is in M0.
;
;On normal return the specified file(s) (as indicated by the file spec
;block (.IOFSB) pointer) have been executed.

	ENTRY	.IODEX
	INTERN	IODEX0,	IODEX1

.IODEX:	PUSHJ	P,.SACIO	;SETUP CDB CONTEXT
IODEX0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S TOO
IODEX1:	CAIN	T2,0		;GOT A PROCESSING ROUTINE?
	XMOVEI	T2,.POPJ1##	;NO, SUPPLY A DEFAULT
	CAIN	T3,0		;GOT AN ERROR PROCESSOR?
	XMOVEI	T3,.POPJ##	;NO, SUPPLY A DEFAULT
	PUSHJ	P,TSAV13##	;SAVE IT FOR LATER
	MOVEI	T1,1		;DAP "EXECUTE" FUNCTION
	PJRST	IODX00		;GO DO THE DAP-MODE FILE OPERATION
	SUBTTL	DAP-mode file operations

;IODXnn - MAIN BODY OF .IODDE, .IODDI, .IODRN, .IODEX
;
;Call with "function" in T1
;
;	-1  =	RENAME
;	00  =	DELETE
;	01  =	EXECUTE
;	02  =	DIRECTORY LIST

IODX00:	MOVEM	T1,.I1FLP(IO)	;HANG ON TO "FUNCTION"
	MOVE	T1,.IOFSB(IO)	;ADDRESS OF PRIMARY FILE SPEC BLOCK
	MOVEM	T1,.IOFSC(IO)	;MAKE IOQAT HAPPY
	MOVEM	T1,.IOFSY(IO)	;MAKE DPWAA HAPPY
	MOVE	T2,.FXNOD(T1)	;GET REMOTE NODE
	PUSHJ	P,DPINI1	;ESTABLISH A DAP LINK
	 POPJ	P,		;CAN'T
	MOVE	T2,.ION6M(IO)	;GET RESULTANT NODE NAME
	MOVEM	T2,.I1NOD(IO)	;POSITION FOR SCWLD, IOQAT, ETC.
	PUSHJ	P,OPFND		;SETUP .IOFND

;CHECK FOR FILE CONSTRAINT SWITCHES (/BEFORE, ETC)

	MOVE	P1,.IOFSC(IO)	;ADDRESS OF "CURRENT" FILE SPEC BLOCK
	HRRZI	T3,.FXBOM(P1)	;ADDRESS OF FILE-CONSTRAINTS SWITCHES
	HRLI	T3,-<.FXFLM-.FXBOM>  ;LENGTH OF CONSTRAINTS
	SETO	T4,		;NO-VALUE VALUE
	CAMN	T4,0(T3)	;FILE-CONSTRAINT SPECIFIED?
	AOBJN	T3,.-1		;NO, CHECK REST OF THEM
	JUMPL	T3,IODXE0	;ERROR IF FILE CONSTRAINT SPECIFIED
				;*** SMARTEN THIS UP FOR -10S??

;SETUP FILE SPECIFICATION FIELD(S)

	PUSHJ	P,DPWAA1	;SETUP THE FILESPEC ET AL IN THE ACCESS MESSAGE
	 POPJ	P,		;DIED
	SKIPL	.I1FLP(IO)	;NEED ANOTHER FILE SPEC (E.G., RENAME)?
	JRST	IODX03		;NO
	PUSHJ	P,DPWAN1	;YES, SETUP SECONDARY NAME SPEC TOO
	 POPJ	P,		;DIED??

;SETUP ACCESS MESSAGE FUNCTION CODE FIELD

IODX03:	MOVE	P1,.IOFSC(IO)	;ADDRESS OF "CURRENT" FILE SPEC BLOCK
	MOVE	P2,.I1FLP(IO)	;RETRIEVE "FUNCTION" CODE
	ADDI	P2,1		;MAKE NON-ZERO INDEX
	MOVD	T3,CNF		;REMOTE CONFIGURATION FLAGS
	XCT	IODXTC(P2)	;DOES REMOTE SUPPORT REQUESTED OPERATION?
	 JRST	[XCT	IODXTE(P2)	;NO, FETCH ERROR CODE
		POPJ	P,]		;TAKE ERROR RETURN
	XCT	IODXTF(P2)	;GET APPROPRIATE DAP ACCESS FUNCTION CODE
	MOVD1M	T1,AFC		;SET ACCESS FUNCTION FIELD

;SETUP ACCESS MESSAGE OPTIONS FIELD

	SETZB	T1,T2		;INITIALLY NO FLAGS
	MOVE	M0,.FXCTL(P1)	;CONTROL SWITCHES
	TXNN	M0,FX.QRA	;/QUERY:ASK SPECIFIED?
	JRST	IODX04		;NO
	TFNN	T3,CGN		;YES, DOES REMOTE SUPPORT GO/NOGO?
	JRST	IODXE2		;NO REMOTE GO/NOGO SUPPORT
	TFO	T1,GNG		;YES, NEED GO/NOGO OPTION
IODX04:	MOVDM	T1,AOP		;SET ACCESS OPTIONS

;SETUP ACCESS MESSAGE FILE AND SHARED ACCESS FIELDS (CLEARED)

	SETZB	T1,T2		;INITIALLY NO FLAGS
	MOVDM	T1,FAC		;CLEAR OUT FILE ACCESS
	MOVDM	T1,SHR		;AND SHARED ACCESS FIELDS

;SETUP ACCESS MESSAGE RETURNED DISPLAY FIELD

IODX10:	MOVDII	T1,ADS,<DMA>	;ALWAYS ASK FOR MAIN ATTRIBUTES
	MOVE	M0,.FXFLD(P1)	;FIELDS-FLAGS
	TXNN	M0,FX.WDV!FX.WDR!FX.WNM!FX.WEX!FX.WGN  ;WILDCARDS?
	JRST	IODX12		;NO EXPLICIT WILDCARDS
	XCT	IODXTW(P2)	;WE NEED WILDCARDS - DOES REMOTE HAVE THEM?
	JRST	IODXE1		;NO REMOTE WILDCARD SUPPORT
	TFO	T1,DN3		;REQUEST 3-PART NAME MESSAGES (WILDCARDED)
	JRST	IODX13		;CHECK FOR REST OF ATTRIBUTES

IODX12:	TFNE	T3,NAM		;IF REMOTE SUPPORTS NAME MESSAGES
	TFO	T1,DNM		; ASK FOR RESULTANT FILE SPEC (NON-WILDCARDED)
IODX13:	TFNE	T3,TEA		;IF REMOTE SUPPORTS DATE/TIME ATTRIBUTES
	TFO	T1,DDT		; ASK FOR DATE/TIME ATTRIBUTES
	TFNE	T3,PEA		;IF REMOTE SUPPORTS PROTECTION ATTRIBUTES
	TFO	T1,DFP		; ASK FOR FILE PROTECTION ATTRIBUTES
	MOVE	M0,.IODPV(IO)	;GET REMOTE PROTOCOL LEVEL
	CAIGE	M0,007000	;IMPLEMENTATIONS BEFORE VERSION 7.0
	TFZ	T1,DN3		; FORCE 3-PART NAMES ON THEIR OWN
	TFNE	T3,NAM		;IF REMOTE DOESN'T SUPPORT RESULTANT NAME MSG
	CAIGE	M0,005006	;IMPLEMENTATIONS BEFORE VERSION 5.6
	SETZB	T1,T2		; PRETTY MUCH IGNORE THE DISPLAY FIELD
	MOVDM	T1,ADS		;SET RETURN "DISPLAY" REQUESTED

;ALL SET, SEND ACCESS MESSAGE TO THE REMOTE

	MOVEI	T2,$DHACS	;ACCESS MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND ACCESS MESSAGE
	 STOPCD	<File access xmit failed in IODX00>
	SKIPL	.I1FLP(IO)	;NEED SECOND FILE SPEC (E.G., RENAME)?
	JRST	IODX19		;NO
	MOVEI	T2,$DHNAM	;YES, NEED A NAME MESSAGE TOO
	PUSHJ	P,XDDAP1##	;SEND SECONDARY NAME MESSAGE
	 STOPCD	<Secondary name xmit failed in IODX00>
IODX19:	PUSHJ	P,XDFLS1##	;FORCE OUT REQUEST
	 POPJ	P,		;NETWORK DIED?

;LOOP RECEIVING COMPLETE FILES

IODX29:	SETZM	.IOFNM(IO)	;FLAG FILE NOT YET PROCESSED
	SETZM	.IOQCT(IO)	;NO ACTIVITY YET FOR THIS "FILE"

;NOW LOOP RECEIVING NAME MESSAGES AND ATTRIBUTES

IODX30:	PUSHJ	P,RDMSG1##	;START UP A NEW DAP INPUT MESSAGE
	 POPJ	P,		;NET MUST HAVE DIED
IODX31:	JSP	T4,.CDISP##	;DISPATCH ON MESSAGE TYPE
		IODX33,,$DHSTS	;STATUS, PROBABLY SOME SORT OF ERROR
		IODX35,,$DHNAM	;RESULTANT NAME MESSAGE (SUCCESSFUL FILE)
		IODX37,,$DHATR	;MAIN ATTRIBUTES
		IODX37,,$DHALC	;ALLOCATION ATTRIBUTES
		IODX37,,$DHTIM	;DATE/TIME ATTRIBUTES
		IODX37,,$DHPRT	;PROTECTION ATTRIBUTES
		IODX51,,$DHACK	;ACK, THIS FILE COMPLETE
		IODX70,,$DHACM	;ACCOMP, ALL DONE
		0		;ALL OTHERS ILLEGAL
	JRST	.RDEOS##	;DAP MESSAGE OUT OF SEQUENCE


;RECEIVED STATUS

IODX33:	PUSHJ	P,RDSTS1##	;READ IN THE STATUS
	 POPJ	P,		;DUH?
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"?
	CAIN	M0,$EGAOK	;"A-OK"?
	JRST	IODX30		;YES, JUST IGNORE

;***

	PUSHJ	P,ERMSX1##	;COMPLAIN ABOUT THE ERROR
	 JFCL			;IGNORE
	MOVD1	T1,STC		;GET DAP STATUS CODE
	CAIE	T1,40000+$DSFNF	;"FILE NOT FOUND"?
	CAIN	T1,50000+$DSFNF	;"FILE NOT FOUND"?
	JRST	IODX77		;YES, AWFUL CASE
	PUSHJ	P,XDCSK0##	;SEND A CONTROL(SKIP)
	 POPJ	P,		;NET DIED
	PUSHJ	P,XDFLS0##	;FLUSH OUT THE CONTROL MESSAGE
	 POPJ	P,		;NET DIED
	JRST	IODX29		;CONTINUE WITH ANY FURTHER FILES


;RECEIVED NAME MESSAGE

IODX35:	SKIPE	.IOFNM(IO)	;GOT A NAME STILL "PENDING"?
	JRST	IODX50		;YES, THEN END OF PREVIOUS FILE
	PUSHJ	P,RDDAP1##	;READ IN REST OF NAME MESSAGE
	 POPJ	P,		;NETWORK DIED
	PUSHJ	P,DPRNM1	;PROCESS THE RECEIVED NAME
	 POPJ	P,		;NETWORK DIED
	JRST	IODX30		;BACK FOR MORE (LOOP TILL ACK)


;RECEIVED ATTRIBUTES

IODX37:	PUSHJ	P,RDDAP1##	;READ IN THE REST OF THE ATTRIBUTES
	 POPJ	P,		;NETWORK MUST HAVE DIED
	JRST	IODX30		;BACK FOR MORE (LOOP TILL ACK)


;RECEIVED ACK, TIME TO PROCESS ONE FILE

IODX50:	PUSHJ	P,RDMSR1##	;RE-EAT THE NAME MESSAGE
	 STOPCD	<RDMSR failed in IODX50>
	JRST	IODX52		;AND PROCESS THE CURRENT FILE

IODX51:	PUSHJ	P,RDDAP1##	;PROCESS THE RECEIVED ACK
	 POPJ	P,		;OOPS
IODX52:	PUSHJ	P,DPIAF1	;SETUP WHAT ATTRIBUTES ARE MEANINGFUL
	 STOPCD	<DPIAF failed in IODX50>
	MOVE	T3,.IOIOM(IO)	;GET I/O MODE CONTROL
	TXNE	T3,IM.DQA	;WANT TO SKIP IOQAT?
	JRST	IODX55		;YES
	SETZ	T1,		;NO OUTPUT FILE HERE
	MOVE	T2,IO		;ADDRESS OF INPUT FILE CDB
	PUSHJ	P,IOQAT1	;CALL THE /QUERY PROCESSOR
	 JRST	IODX59		;USER PROBABLY REJECTED THE FILE
IODX55:	MOVD	T1,AOP		;GET ACCESS OPTIONS
	TFNN	T1,GNG		;IS THIS A GO/NOGO'ED FILE?
	JRST	IODX57		;NO, ALL SET
	PUSHJ	P,XDACL1##	;YES, SEND AN ACCOMP(CLOSE) FOR THIS ONE
	 POPJ	P,		;NET DIED?
IODX57:	PUSHJ	P,@-T2(P)	;CALL USER-SUPPLIED ROUTINE
	 POPJ	P,		;HE SAID TO ABORT
	JRST	IODX60		;CAP OFF THIS FILE

;ABORT THE CURRENT FILE, SKIP TO THE NEXT ONE

IODX59:	PUSHJ	P,XDASK1##	;SEND A ACCOMP(SKIP)
	 POPJ	P,		;DIED?


;DONE WITH CURRENT FILE, PROCEDE TO NEXT ONE

IODX60:	MOVD1	T1,AFC		;ACCESS FUNCTION CODE
	CAIE	T1,$DVARN	;RENAME?
	JRST	IODX29		;NO, PROCEDE TO NEXT FILE

;NOW LOOP RECEIVING NAME MESSAGES AND ATTRIBUTES

IODX61:	PUSHJ	P,RDMSG1##	;START UP A NEW DAP INPUT MESSAGE
	 POPJ	P,		;NET MUST HAVE DIED
IODX62:	JSP	T4,.CDISP##	;DISPATCH ON MESSAGE TYPE
		IODX63,,$DHSTS	;STATUS, PROBABLY SOME SORT OF ERROR
		IODX65,,$DHNAM	;RESULTANT NAME MESSAGE (SUCCESSFUL FILE)
		IODX67,,$DHATR	;MAIN ATTRIBUTES
		IODX67,,$DHALC	;ALLOCATION ATTRIBUTES
		IODX67,,$DHTIM	;DATE/TIME ATTRIBUTES
		IODX67,,$DHPRT	;PROTECTION ATTRIBUTES
		IODX69,,$DHACK	;ACK, THIS FILE COMPLETE
		IODX70,,$DHACM	;ACCOMP, ALL DONE
		0		;ALL OTHERS ILLEGAL
	JRST	.RDEOS##	;DAP MESSAGE OUT OF SEQUENCE


;RECEIVED STATUS

IODX63:	PUSHJ	P,RDSTS1##	;READ IN THE STATUS
	 POPJ	P,		;DUH?
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"?
	CAIN	M0,$EGAOK	;"A-OK"?
	JRST	IODX61		;YES, JUST IGNORE

;***

	PUSHJ	P,ERMSX1##	;COMPLAIN ABOUT THE ERROR
	 JFCL			;IGNORE
	MOVD1	T1,STC		;GET DAP STATUS CODE
	CAIE	T1,40000+$DSFNF	;"FILE NOT FOUND"?
	CAIN	T1,50000+$DSFNF	;"FILE NOT FOUND"?
	JRST	IODX77		;YES, AWFUL CASE
	PUSHJ	P,XDCSK0##	;SEND A CONTROL(SKIP)
	 POPJ	P,		;NET DIED
	PUSHJ	P,XDFLS0##	;FLUSH OUT THE CONTROL MESSAGE
	 POPJ	P,		;NET DIED
	JRST	IODX29		;CONTINUE WITH ANY FURTHER FILES


;RECEIVED NAME MESSAGE

IODX65:	PUSHJ	P,RDDAP1##	;READ IN REST OF NAME MESSAGE
	 POPJ	P,		;NETWORK DIED
	PUSHJ	P,DPRNM1	;PROCESS THE RECEIVED NAME
	 POPJ	P,		;NETWORK DIED
	JRST	IODX61		;BACK FOR MORE (LOOP TILL ACK)


;RECEIVED ATTRIBUTES

IODX67:	PUSHJ	P,RDDAP1##	;READ IN THE REST OF THE ATTRIBUTES
	 POPJ	P,		;NETWORK MUST HAVE DIED
	JRST	IODX61		;BACK FOR MORE (LOOP TILL ACK)


;RECEIVED ACK

IODX69:	PUSHJ	P,RDDAP1##	;CAP OFF THE ACK
	 POPJ	P,		;OOPS
	JRST	IODX29		;PROCEDE TO NEXT FILE


;ACCESS COMPLETE RECEIVED

IODX70:	MOVD	T4,AFC		;GET THE ACCESS FUNCTION CODE AGAIN
	CAIN	T4,$DVADR	;DIRECTORY LIST?
	SKIPN	.IOFNM(IO)	;YES, STILL HAVE A UNPROCESSED FILE?
	CAIA			;NO FUNNY STUFF HERE
	JRST	IODX50		;(SIGH) GO FINISH OFF TRAILING FILE
	PUSHJ	P,RDDAP1##	;READ IN THE REST OF THE MESSAGE
	 POPJ	P,		;DUH?
	MOVD	T1,A2F		;GET ACCOMP TYPE
	CAIE	T1,$DVARS	;ACCOMP(RESPONSE)?
	STOPCD	<ACCOMP(junk) in IODX70>
	PUSHJ	P,IOABO1	;NOW STOMP ON THE CDB
	 JFCL			;HO HUM
	JRST	.POPJ1##	;FUNCTION COMPLETED

;HERE FOR "FILE NOT FOUND" - THE CONTROL(SKIP) DOESN'T WORK WORTH DIGESTED
;BEANS HERE - VAX AND RSX WILL LOOP SENDING FILE-NOT-FOUND STATUS MESSAGES
;FOREVER; THE -20 SIMPLY IGNORES THE LINK AND HANGS FOREVER.
;
;ACCORDINGLY, STOMP ON THE LINK (WE CAN'T EVEN SEND AN ACCOMP OR ABORT OR
;ANYTHING TO GET OUT OF THIS CASE WITHOUT BREAKING THE LINK!)

IODX77:	PUSHJ	P,NTZAP1##	;STOMP ON THE LINK
	 JFCL			;DUH?
	PJRST	.POPJ1##	;"SUCCESSFUL" RETURN
				; I AGREE THAT "SUCCESSFUL" IS A DEBATABLE
				; RETURN, BUT AN ERROR MESSAGE HAS BEEN
				; ISSUED, SO . . .


;ERROR - REMOTE DOES NOT SUPPORT FILE CONSTRAINT SWITCHES

IODXE0:	MOVEI	M0,$EFRNC	;NO REMOTE FILE CONSTRAINT SWITCHES
	POPJ	P,

;ERROR - REMOTE DOES NOT SUPPORT WILDCARDS

IODXE1:	MOVEI	M0,$EFRNW	;NO REMOTE WILDCARDS
	POPJ	P,

;ERROR - REMOTE DOES NOT SUPPORT GO/NOGO

IODXE2:	MOVEI	M0,$EFRNG	;NO REMOTE GO/NOGO SUPPORT
	POPJ	P,
;TABLE(S) OF REMOTE SUPPORT

IODXTC:	TFNN	T3,REN		;RENAME
	CAIA			;DELETE
	TFNN	T3,CMF		;EXECUTE
	CAIA			;DIRECTORY

IODXTE:	MOVEI	M0,$EFRNR	;NO REMOTE RENAME SUPPORT
	MOVEI	M0,-1		;NOTHING
	MOVEI	M0,$EFRNX	;NO REMOTE EXECUTE SUPPORT
	MOVEI	M0,-1		;NOTHING

IODXTF:	MOVEI	T1,$DVARN	;RENAME
	MOVEI	T1,$DVADL	;DELETE
	MOVEI	T1,$DVAEC	;EXECUTE
	MOVEI	T1,$DVADR	;DIRECTORY

IODXTW:	TFNN	T3,WLD		;RENAME - DOES REMOTE SUPPORT WILDCARDS?
	TFNN	T3,WLD		;DELETE - DOES REMOTE SUPPORT WILDCARDS?
	TFNN	T3,WLD		;EXECUTE - DOES REMOTE SUPPORT WILDCARDS?
	CAIA			;DIRECTORY - DON'T CARE
	SUBTTL	IOABO - Abort the OPEN file

;IOABO  --  ABORT THE CURRENT FILE - IF ANY
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOABO
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB.
;
;The error return is not exercised.
;
;On normal return any I/O associated with the I/O stream has been
;aborted and the CDB is restored to inactive state.
;
;Uses T1, T2, T3, T4

	ENTRY	.IOABO
	INTERN	IOABO0,	IOABO1

.IOABO:	PUSHJ	P,.SACIO##	;SETUP IO
IOABO0:	PUSHJ	P,.SAVE4##	;NEED A FLAG AC
IOABO1:	MOVE	P1,.IOCCF(IO)	;CHANNEL CONTROL FLAGS
	TXNN	P1,IO.OPN	;IS THERE A FILE OPEN?
	PJRST	IOCLO7		;NO, JUST MARK CHANNEL CLOSED THEN
	TXNE	P1,IO.NET	;YES - NETWORK CHANNEL?
	JRST	IONA00		;YES, DO IT DIFFERENTLY

;WIPE OUT ANY LOCAL I/O IN PROGRESS

	HRLZ	T3,.IOCHN(IO)	;I/O CHANNEL
	HRRI	T3,.FOCLS	;"CLOSE" FUNCTION
	MOVX	T4,CL.RST	;"RESET" (I.E., ABORT) ANY OUTPUT FILE
				; MAGTAPE PROCESSING COULD BE SMARTER HERE
				; BY BACKSPACING TO START OF FILE . . .
	MOVE	T1,[2,,T3]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;ZAPETH THE FILE
	 JFCL			;DUH?
	PJRST	IOCLO7		;AND MARK IT CLOSED
;ABORT NETWORK FILE IN PROGRESS
;
;Some attempt is made to preserve the link with the remote FAL process,
;but if exactly the "right" things don't happen then the network channel
;is simply aborted, and will have to be re-established for the next file.
;This can cause real problems if some sort of wildcarding is being per-
;formed by the remote FAL!

IONA00:	PUSHJ	P,RDEAT0##	;EAT ANYTHING CURRENTLY IN PROGRESS
	 JFCL			;DUH?
	TXNN	P1,IO.OPN	;A FILE OPEN HERE?
	PJRST	IOCLO7		;NO, THEN ALL DONE

;ABORT THE OPENED FILE

	PUSHJ	P,XDABM0##	;STOMP ON ANY PENDING MESSAGE
	 JFCL			;EXPECT THE ERROR RETURN

	MOVD1	T1,FST		;*** GET THE REMOTE FILE SYSTEM TYPE
	CAIN	T1,$DVFF1	;*** GOOD OLE FCS-11?
	JRST	[TXNE	P1,IO.OUT	;*** DOING INPUT OR OUTPUT?
		JRST	.+1		;*** OUTPUT, "KILL" THE FILE
		PUSHJ	P,XDACL0##	;*** INPUT, DO SHORT-FORM CLOSE
		 PJRST	IONA80		;***  OTHERWISE FCS-11 WILL KILL
					;***  (READ: "DELETE") THE INPUT
					;***  FILE!!
		JRST	IONA27]		;*** BLUNDER ONWARDS
	PUSHJ	P,XDAKL0##	;KILL/RESET (SHORT FORM) THE FILE
	 JRST	IONA80		;FORGET IT, ABORT THE LINK
IONA27:	PUSHJ	P,XDFLS0##	;FLUSH THE OUTPUT BUFFERS
	 JRST	IONA80		;FORGET IT, ABORT THE LINK

;WAIT FOR THE ACK FROM THE REMOTE

IONA30:	PUSHJ	P,RDMSG0##	;READ IN A DAP MESSAGE CODE
	 JRST	IONA80		;ABORT THE LINK
	JSP	T4,.CDISP##	;DISPATCH ON RECEIVED MESSAGE TYPE
		IONA40,,$DHDAT	;DATA MESSAGE, JUST EAT IT
		IONA50,,$DHSTS	;STATUS, MAYBE ERROR
		IONA60,,$DHNAM	;NAME MESSAGE, ASSUME MORE INPUT FILES
		IONA70,,$DHACM	;ACCESS COMPLETE, MUST BE ACCOMP(RESPONSE)
		0		;THAT'S IT
	JRST	IONA80		;JUST ABORT THE LINK

;DATA MESSAGE, JUST EAT IT

IONA40:	PUSHJ	P,RDEAT0##	;EAT THE REST OF THE MESSAGE
	 JRST	IONA80		;ABORT THE LINK
	JRST	IONA30		;GO GET THAT BLASTED ACK

;STATUS MESSAGE, POSSIBLE ERROR STATUS

IONA50:	PUSHJ	P,RDSTS0##	;RECEIVE THE DAP STATUS MESSAGE CODES
	 JRST	IONA80		;ABORT THE LINK
				;*** BUT SEE ALSO IONC50!!!
				;*** DO I HAVE TO CHECK TOPS20 HERE ALSO?
	POPJ	P,		;PROPAGATE A REALLY INCONVENIENT ERROR!

;GOT A NAME MESSAGE, ALMOST THE SAME THING AS AN ACK, ONLY MORE INPUT FILES
;ARE COMMING

IONA60:	PJRST	IONC60		;SAME AS NORMAL CLOSE FROM HERE ON


;GOT THE ACKNOWLEDGEMENT (I.E., ACCOMP(RESPONSE))

IONA70:	PJRST	IONC70		;SAME AS NORMAL CLOSE FROM HERE ON


;SOMETHING BAD, JUST ABORT THE ENTIRE LINK

IONA80:	PUSHJ	P,NTZAP0##	;STOMPETH UPON THE NETWORK CHANNEL
	 JFCL			;OH COME NOW!
	PJRST	IOCLO7		;MARK CDB CLOSED
	SUBTTL	IOCLO - CLOSE the OPEN file

;IOCLO  --  CLOSE THE CURRENT OPEN FILE
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IOCLO
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB controlling the "open" file.
;
;On error return the monitor was unable to successfully close the file
;(detailed reason currently unavailable)
;
;Uses T1, T2, T3, and T4.

	ENTRY	.IOCLO
	INTERN	IOCLO0,	IOCLO1

.IOCLO:	PUSHJ	P,.SACIO##	;SETUP IO
IOCLO0:	PUSHJ	P,.SAVE4##	;PRESERVE THE P'S
IOCLO1:	MOVE	P1,.IOCCF(IO)	;GET CHANNEL CONTROL FLAGS
	TXNN	P1,IO.OPN	;DO WE HAVE A FILE OPEN?
	JRST	[MOVX	M0,$EICNO	;CHANNEL NOT "OPEN"
		JRST	.M0ERR##]	;RETURN ERROR STATUS

;GO DO ANY FINAL I/O CLEANUP THAT MIGHT BE NEEDED

	PUSHJ	P,@.IOISS(IO)	;CALL INPUT SHUTDOWN ROUTINE
	 POPJ	P,		;PROPAGATE ERROR
	PUSHJ	P,@.IOOSS(IO)	;CALL OUTPUT SHUTDOWN ROUTINE
	 POPJ	P,		;PROPAGATE ERROR

;I/O EFFECTIVELY COMPLETE, CLOSE OFF THE FILE

	PUSHJ	P,IOCLP1	;BUILD CLOSE-OPTIONS IN P2
	 POPJ	P,		;URK!
	TXNE	P1,IO.NET	;IS THIS A NETWORK FILE?
	JRST	IONC00		;YES

;LOCAL FILE SYSTEM, TELL MONITOR WE ARE DONE WITH THE FILE

IOCLO3:	TXNE	P2,IM.CDL	;WANT TO DELETE FILE ON CLOSE?
	PJRST	IOFDL1		;YES (TAKES PRECEDENCE OVER PRINT/SUBMIT)
	MOVE	T2,.IOFSC(IO)	;ADDRESS OF "CURRENT" FILE SPEC BLOCK
	MOVE	T2,.FXCTL(T2)	;GET CONTROL FLAGS
	SETZ	T4,		;TOPS-10 CLOSE BITS
	TXNN	T2,FX.ALC!FX.CTG;USER SPECIFY /ALLOCATE OR /CONTIGUOUS?
	TXNE	P2,IM.CTG!IM.MFA;OR OTHERWISE MAINTAIN FILE ALLOCATION?
	TXO	T4,CL.DLL	;YES
	TXNE	P2,IM.SAD	;SUPPRESS ACCESS DATE UPDATE?
	TXO	T4,CL.ACS	;YES
	HRLZ	T3,.IOCHN(IO)	;I/O CHANNEL NUMBER
	HRRI	T3,.FOCLS	;"CLOSE" FUNCTION
	MOVE	T1,[2,,T3]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;CLOSE THE CURRENT FILE
	JRST	[MOVEM	T1,.I1IOS(IO)	;SAVE I/O STATUS
		MOVX	M0,$EIECF	;ERROR CLOSING CHANNEL
		JRST	.M0ERR##]	;RETURN ERROR STATUS

;NOW IS THE TIME TO PRINT AND/OR SUBMIT THE FILE IF REQUESTED
;
;SUBMIT TAKES PRECEDENCE OVER PRINT IN THAT IF SUBMIT IS SET THEN [NO]PRINT
;IS INTERPRETED AS /OUTPUT:[NO]LOG. ALTHOUGH THIS IS A KROCK, DAP DOESN'T
;REALLY ADDRESS THIS ISSUE, SO . . .

	TXNN	P2,IM.CSU!IM.CPR;WANT EITHER PRINT OR SUBMIT?
	PJRST	IOCLO7		;NO, TRULY DONE WITH THE FILE THEN
	MOVEI	T2,.QUBAT	;ASSUME SUBMIT
	TXNN	P2,IM.CSU	;WANT SUBMIT?
	MOVEI	T2,.QUPRT	;NO, WANTED PRINT INSTEAD
	PUSHJ	P,QUEOP0##	;GO DIDDLE THE FILE
	 POPJ	P,		;OOPS
				;CONTINUE IN IOCLO7

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;MARK THE FILE "CLOSED" FOR I/O PURPOSES (BUT MAY STILL HAVE THE DEVICE)

IOCLO7:	MOVX	T1,IO.CFC	;THE FILE-IS-OPEN BIT(S)
	ANDCAB	T1,.IOCCF(IO)	;MARK FILE "NOT OPEN" IN THE CDB
				;BUT THE "CHANNEL" IS STILL IN USE
;***	SETZM	.IOBZC(IO)	;START OF TO-BE-CLEARED ON CLOSE
;***	MOVEI	T2,.IOBZC+1(IO)	;CONCOCT A
;***	HRLI	T2,-1(T2)	; BLT POINTER TO
;***	BLT	T2,.IOEZC-1(IO)	;  CLEAR THE TO-BE-CLEARED AREA
;***	MOVE	T2,.IOIOM(IO)	;GET I/O MODE CONTROL
;***	MOVEI	T3,.ICDEF	;DEFAULT FILE DATA MODE
;***	TXNN	T2,IM.CMD	;.IOIOC MODE OVERRIDDING?
;***	DPB	T3,[POINTR .IOIOC(IO),IC.MOD]  ;RESET (TO ALLOW DEFAULT TO WORK)
	PJRST	IORLS8		;RESET STATE (ISR) PROCESSORS

;***	MOVE	T2,.IOIOM(IO)	;I/O MODE FLAGS
;***
;THE FOLLOWING CHECK FOR IO.WCR IS KROCKED OUT UNTIL I CAN FIGURE OUT
;HOW TO MAKE THE MONITOR BELIEVE MY FILOP.S
;

;***	TXNE	T2,IM.WCR	;USER PROMISE TO CALL IORLS WHEN HE'S DONE?
;***	TXNN	T1,IO.NET	;YES, IS THIS NETWORK?
;***	CAIA			;NOT A NETWORKED IM.WCR CHANNEL
;***	JRST	[MOVD1	T1,FST		;*** REMOTE FILE SYSTEM TYPE
;***		CAIN	T1,$DVFF1	;*** FCS-11?
;***		JRST	IORLS1		;*** YES, MUST BREAK NETWORK CONNECTION
;***					;***  AFTER EVERY FILE (BUG IN REMOTE)
;***		JRST	IORLS8]		;*** NO, OK
;***
;***	TXNE	T2,IM.WCR	;WILL USER CALL IORLS LATER?
;***	JRST	IORLS1		;NO, SO CLEAN UP NOW
;***	JRST	IORLS8		;YES, JUST SET STATE PROCESSORS
;HERE TO CLOSE A NETWORK FILE

IONC00:	SKIPLE	.IODIM(IO)	;AN INPUT MESSAGE PENDING?
	STOPCD	<DAP input message in progress at call to IONC00>
	SKIPLE	T1,.IODOM(IO)	;AN OUTPUT MESSAGE PENDING?
	STOPCD	<DAP output message in progress at call to IONC00>

;***	IS IT WORTHWHILE TO SEND ACCOMP(EOS) TO SYNC FIRST?

IONC20:	MOVDII	P3,M07,A2F	;ALWAYS SEND AT LEAST THE FUNCTION FIELD
	PUSHJ	P,IOCLQ1	;BUILD AFO MASK OF CLOSE OPTIONS
	 POPJ	P,		;CAN'T FAIL
	MOVDM	T1,AFO		;SET ACCESS COMPLETE FILE OPTIONS
	FJUMPE	T1,AFO,IONC23	;ARE THERE ANY ACCESS OPTIONS?
	TMO	P3,AFO		;YES, FLAG OPTIONS FIELD IN THE [HIDDEN] MENU
IONC23:	MOVD	T1,AOP		;GET FILE ACCESS OPTIONS
	TFNN	T1,ACK		;DOES THIS DATA STREAM WANT TO BE CHECKSUMMED?
	JRST	IONC25		;NO, SKIP CRC STUFF
	MOVE	T4,.IOCCF(IO)	;YES, CRC REQUESTED, GET CHANNEL CONTROL FLAGS
	TXNE	T4,IO.IOA	;HAS FILE EVER BEEN I/O ACTIVE?
	TXNE	T4,IO.NCK	;YES - BUT DOES CALLER WANT TO SUPPRESS CRC?
	JRST	IONC25		;EITHER NO I/O, OR EXPLICIT NO CRC
	TMO	P3,<AFO,CKS>	;YES, FLAG CHECKSUM FIELD IN THE [HIDDEN] MENU
	TXNE	T4,IO.INP	;WAS THE FILE OPEN FOR INPUT?
	SKIPA	T3,.IODIK(IO)	;YES, GET INPUT DATA STREAM CRC
	MOVE	T3,.IODOK(IO)	;NO, GET OUTPUT DATA STREAM CRC
	MOVD1M	T3,CKS		;SET DAP CRC FIELD
IONC25:	MOVEI	T2,$DVACL	;"CLOSE" FUNCTION
	MOVD1M	T2,A2F		;SET ACCOMP FUNCTION FIELD
	MOVDM	P3,M07		;SET THE HIDDEN ACCOMP MENU FIELD
	MOVEI	T2,$DHACM	;ACCESS COMPLETE MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SHIP ACCOMP(CLOSE)
	 POPJ	P,		;NETWORK DIED? I WONDER IF THE FILE IS CLOSED?
IONC29:	PUSHJ	P,XDFLS1##	;FORCE OUT THE ACCOMP(CLOSE) MESSAGE
	 POPJ	P,		;SIGH

;WAIT FOR REMOTE'S RESPONSE TO OUR ACCESS COMPLETE COMMAND

IONC30:	PUSHJ	P,RDMSG1##	;READ IN DAP MESSAGE CODE
	 POPJ	P,		;NETWORK DIED
	JSP	T4,.CDISP##	;DISPATCH ON MESSAGE TYPE
		IONC40,,$DHDAT	;DATA, JUST ABSORB IT
		IONC50,,$DHSTS	;STATUS, MAYBE AN ERROR
		IONC60,,$DHNAM	;NAME MESSAGE, MORE INPUT FILE(S)
		IONC70,,$DHACM	;ACCESS COMPLETE, CHECK FOR ACCOMP(RESPONSE)
		0		;NO MORE
	JRST	.RDEOS##	;DAP MESSAGE OUT OF SEQUENCE


;DATA MESSAGE, JUST EAT IT

IONC40:	PUSHJ	P,RDEAT1##	;EAT THE DAP MESSAGE
	 POPJ	P,		;SIGH
	JRST	IONC30		;WAIT FOR THE ACCOMP(RESPONSE)


;STATUS MESSAGE, MAYBE ERROR

IONC50:	PUSHJ	P,RDSTS1##	;READ IN THE STATUS MESSAGE
	 POPJ	P,		;OOPS
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"?
	CAIN	M0,$EGAOK	;"A-OK"?
	JRST	IONC30		;YES (DUH?) EAT IT
	MOVD	T1,FST		;*** FILE SYSTEM TYPE
	CAIN	T1,$DVFT2	;*** TOPS-20?
	JRST	[LDB	T1,PDPEMA##	;*** YES, GET MACCODE
		CAIE	T1,4		;*** FILE-NOT-OPEN CLASS?
		JRST	.+1		;*** NO, NORMAL
		MOVX	T1,IO.YAF!IO.YAE;*** YES, THE -20 HAS CLOSED THE
		IORM	T1,.IOCCF(IO)	;*** FILE SUCCESSFULLY, AND ADVANCED
					;*** TO THE NEXT FILE, WHICH IS A
					;*** (E.G.) PROTECTION FAILURE
		MOVEI	T1,[ASCIZ\   <<No filename supplied by remote file server>>\]
		MOVEM	T1,.IOFNM(IO)	;*** LIFE . . .
		SETZM	.IOFEX(IO)	;*** NO EXTENSION EITHER
		SETZM	.IOFGN(IO)	;*** NO GENERATION EITHER
					;*** BUT MUST PRESERVE DEVICE, DIRECTORY
		JRST	IONC73]		;*** FOR NOW, NORMAL FILE CLOSURE
	POPJ	P,		;PROPAGATE ERROR


;NAME MESSAGE, MORE INPUT FILE(S) COMING UP

IONC60:	PUSHJ	P,RDMSR0##	;RE-EAT THIS NAME MESSAGE FOR OPIRXX
	 STOPCD
	MOVX	T1,IO.YAF	;THE YET-ANOTHER-FILE FLAG
	IORM	T1,.IOCCF(IO)	;TELL OPIR ANOTHER FILE IS COMING
	JRST	IONC73		;OTHERWISE TREAT AS ACCOMP(RESPONSE)


;ACCESS COMPLETE - MAKE SURE IT'S THE FLAVOR WE WANT

IONC70:	PUSHJ	P,RDDAP1##	;READ IN REST OF ACCOMP MESSAGE
	 POPJ	P,		;OOPS
	MOVD1	T3,A2F		;ACCESS COMPLETE FUNCTION CODE
	CAIE	T3,$DVARS	;ACCOMP(RESPONSE)?
	JRST	IOCNE1		;NO, MESSAGE OUT OF SEQUENCE
IONC73:	MOVX	T3,IO.CNC	;NETWORK-LEVEL CLOSE
	ANDCAM	T3,.IOCCF(IO)	;CLEAR FLAGS IN THE CONTROL WORD
	JRST	IOCLO7		;MARK FILE SUCCESSFULLY CLOSED


IOCNE1:	STOPCD	<ACCOMP(junk) received in reply to ACCOMP(CLOSE)>
;IOCLP - SETUP CLOSE-OPTIONS LIKE /DELETE, ETC.

IOCLP1:	MOVE	P1,.IOCCF(IO)	;RETRIEVE CHANNEL CONTROL
	MOVE	P2,.IOIOM(IO)	;GET MODE CONTROL TOO
	MOVE	T1,.IOFSC(IO)	;ADDRESS OF CURRENT FILE SPEC BLOCK
	DMOVE	T3,.FXCTL(T1)	;FILE CONTROL SWITCHES
	TXNN	T4,FX.DEL	;/[NO]DELETE ON CLOSE?
	JRST	IOCLP3		;NO
	TXNN	T3,FX.DEL	;/DELETE OR /NODELETE?
	TXZA	P2,IM.CDL	;/NODELETE
	TXO	P2,IM.CDL	;/DELETE
IOCLP3:	TXNN	T4,FX.PRI	;/[NO]PRINT ON CLOSE?
	JRST	IOCLP4		;NO
	TXNN	T3,FX.PRI	;/PRINT OR /NOPRINT?
	TXZA	P2,IM.CPR	;/NOPRINT
	TXO	P2,IM.CPR	;/PRINT
IOCLP4:	TXNN	T4,FX.SUB	;/[NO]SUBMIT ON CLOSE?
	JRST	IOCLP5		;NO
	TXNN	T3,FX.SUB	;/SUBMIT OR /NOSUBMIT?
	TXZA	P2,IM.CSU	;/NOSUBMIT
	TXO	P2,IM.CSU	;/SUBMIT
IOCLP5:	JRST	.POPJ1##	;ALL DONE HERE



;IOCLQ1 - GENERATE DAP AFO MASK OF CLOSE OPTIONS

IOCLQ1:	SETZB	T1,T2		;ASSUME NO "FILE OPTIONS"

;***	AT THIS POINT, I SHOULD CHECK FOR THE REMOTE'S WILLINGNESS TO
;***	ACCEPT THE VARIOUS "OPTIONS" - BUT WHAT DO I DO IF THE REMOTE
;***	DOESN'T? CLOSE THE FILE ANYWAY? ERROR RETURN WITH THE FILE STILL
;***	OPEN?

	TXNE	P2,IM.CDL	;DELETE ON CLOSE?
	TFO	T1,DLT		;YES
	TXNE	P2,IM.CPR	;PRINT ON CLOSE?
	TFO	T1,SPC		;YES
	TXNE	P2,IM.CSU	;SUBMIT ON CLOSE?
	TFO	T1,SCF		;YES
	JRST	.POPJ1##	;RETURN WITH AFO MASK IN T1/T2
	SUBTTL	IORLS - RELEASE an OPEN file and I/O channel

;IORLS  --  RELEASE AN I/O CHANNEL
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,.IORLS
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <CDB> is the address of the I/O CDB controlling an I/O stream.
;
;on error return the file couldn't be CLOSEd (if a file was OPEN) or
;an error occured trying to RELEASE the I/O device/etc.
;
;On normal return the CDB has been "shut down" - any device still
;allocated has been returned to the monitor, buffers are freed up, etc.
;
;Uses T1, T2, T3, T4.

	ENTRY	.IORLS
	INTERN	IORLS0,	IORLS1

.IORLS:	PUSHJ	P,.SACIO##	;SETUP IO
IORLS0:	PUSHJ	P,.SAVE4##	;WANT A PRESERVED AC
IORLS1:	MOVE	P1,.IOCCF(IO)	;GET A COPY OF THE CHANNEL CONTROL FLAGS
	TXNN	P1,IO.OPN	;IS A FILE CURRENTLY OPEN?
	JRST	IORLS2		;NO
	PUSHJ	P,IOABO1	;YES, ZAP THE FILE
	 POPJ	P,		;OOPS
	MOVE	P1,.IOCCF(IO)	;NEW COPY OF CHANNEL CONTROL FLAGS
IORLS2:	TXNE	P1,IO.NET	;NETWORK FILE?
	JRST	IONR00		;YES, HANDLE DIFFERENTLY
	TXNN	P1,IO.DEV	;DO WE HAVE A DEVICE "HANGING AROUND"
	SKIPE	.IOCHN(IO)	;OR A CHANNEL EVEN (SHOULDN'T HAPPEN)?
	CAIA			;YES, NEED TO STOMP ON IT
	JRST	IORLS4		;NO, GO CHECK FOR BUFFERS
	HRLZ	T3,.IOCHN(IO)	;I/O CHANNEL
	HRRI	T3,.FOREL	;"RELEASE" FUNCTION
	MOVE	T1,[1,,T3]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;RELEASE THE DEVICE/CHANNEL
	 SKIPA	T1,.IOCHN(IO)	;ERROR RELEASING THE CHANNEL
	JRST	IORLS4		;CHANNEL RELEASED
	RESDV.	T1,		;STOMP ON THE CHANNEL GOOD 'N HARD
	 JFCL			;WELL, THE CHANNEL IS USELESS IN ANY CASE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;HERE TO MARK THE CHANNEL FREE AND DE-ALLOCATE ANY BUFFERS

IORLS4:	SETZM	.IOCHN(IO)	;THE CHANNEL IS NO LONGER IN USE HERE
	MOVX	P1,IO.CFR	;THE DEVICE-IS-ALLOCATED BIT(S)
	ANDCAB	P1,.IOCCF(IO)	;CLEAR IT IN THE CDB
	SETZM	.I1FIO(IO)	;CLEAR CHANNEL-IN-USE DEVICE FLAGS
	SETZM	.I1FIO+1(IO)	; AND ASSOCIATED DEVICE NAME
	TXNN	P1,IO.OBA	;ANY OUTPUT BUFFERS LYING AROUND?
	JRST	IORLS5		;NO
	DMOVE	T2,.IOOAC(IO)	;YES, GET ALLOCATION AND ADDRESS WORDS
	CAILE	T2,0		;SOMETHING THERE?
	CAIG	T3,0		;SOMETHING THERE?
	STOPCD	<File output buffers trashed in IORLS>
	XMOVEI	T4,.IOOBH(IO)	;ADDRESS OF OUTPUT RING HEADER
	PUSHJ	P,IOBFZ0	;FREE UP THE BUFFER RING
	 STOPCD	<File output buffer deallocation failed in IORLS>
	MOVX	P1,IO.OBA	;THE OUTPUT-BUFFERS-ALLOCATED BIT
	ANDCAB	P1,.IOCCF(IO)	;CLEAR IT IN THE CDB
IORLS5:	TXNN	P1,IO.IBA	;ANY INPUT BUFFERS LYING AROUND?
	JRST	IORLS7		;NO
	DMOVE	T2,.IOIAC(IO)	;YES, GET ALLOCATION AND ADDRESS WORDS
	CAILE	T2,0		;SOMETHING THERE?
	CAIG	T3,0		;SOMETHING THERE?
	STOPCD	<File input buffers trashed in IORLS>
	XMOVEI	T4,.IOIBH(IO)	;ADDRESS OF INPUT RING HEADER
	PUSHJ	P,IOBFZ1	;FREE UP THE BUFFER RING
	 STOPCD	<File input buffer deallocation failed in IORLS>
	MOVX	P1,IO.IBA	;THE INPUT-BUFFERS-ALLOCATED BIT
	ANDCAB	P1,.IOCCF(IO)	;CLEAR IN THE CDB
IORLS7:	MOVX	P1,IO.CFR	;CLEAR-ON-RELEASE BITS
	ANDCAB	P1,.IOCCF(IO)	;CAN'T DO ANY I/O NOW
	SETZM	.IOBZR(IO)	;CLEAR START OF TO-BE-CLEARED ON RELEASE
	MOVEI	T2,.IOBZR+1(IO)	;CONCOCT A
	HRLI	T2,-1(T2)	; BLT POINTER TO
	BLT	T2,.IOEZR-1(IO)	;  CLEAR THE TO-BE-CLEARED AREA
IORLS8:	XMOVEI	T2,.IOIIE##	;INPUT-NOT-OPEN ISR
	MOVEM	T2,.IOISR(IO)	;SET IN CDB
	XMOVEI	T2,.POPJ1##	;INPUT SHUTDOWN ROUTINE
	MOVEM	T2,.IOISS(IO)	;SET IN CDB
	XMOVEI	T2,.IOOIE##	;OUTPUT-NOT-OPEN OSR
	MOVEM	T2,.IOOST(IO)	;SET IN CDB
	XMOVEI	T2,.POPJ1##	;OUTPUT SHUTDOWN ROUTINE
	MOVEM	T2,.IOOSS(IO)	;SET IN CDB
	JRST	.POPJ1##	;ALL DONE
;HERE FOR NETWORK FILES
;
;FOR THE TIME BEING (AND MAYBE EVEN FOREVER) WE JUST ABORT THE LINK,
;AS THERE IS NOTHING REALLY TO BE GAINED FROM A DISCONNECT INITIATE,
;WAIT FOR POSSIBLE DATA, READ DISCONNECT CONFIRM SEQUENCE. ABORTING
;IS QUICKER, AND STILL SAFE (SINCE THE DAP PIPELINE IS GUARANTEED TO
;BE SYNCHRONIZED (AND IN PARTICULAR, EMPTY) BY THE TIME CONTROL GETS
;HERE. (ACTUALLY, IF RUNNING PASSIVE, IT IS POSSIBLE THAT A DAP RE-
;QUEST IS JUST COMING DOWN THE LINE, BUT IF WE GET HERE FOR A PASSIVE
;DAP PROCESS SOMETHING IS PRETTY SCREWY ANYWAY.)

IONR00:;SETZB	T2,T3		;REASON,,OPTIONAL USER DATA
;	PUSHJ	P,NTNSD1##	;SEND DISCONNECT INITIATE
;	 JRST	IONR80		;HMMM. ABORT THE LINK
;	PUSHJ	P,NTNRL1##	;RELEASE THE LINK
;	 JRST	IONR80		;HMMM. ABORT THE LINK
;	JRST	IORLS7		;NETWORK SHUTDOWN, FINISH OFF THE CDB

;ABORT THE NETWORK LINK

IONR80:	PUSHJ	P,NTZAP1##	;KILL THE NETWORK CHANNEL
	 JFCL			;SIGH
	JRST	IORLS7		;AND SHUT DOWN THE CDB
	SUBTTL	IOBFA - Allocate and initialize I/O buffers

;IOBFA  --  ALLOCATE AND INITIALIZE I/O BUFFERS
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<BUFARG>
;	MOVX	T4,<RHDR>
;	PUSHJ	P,.IOBFA
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <BUFARG> is count of desired buffers in the ring structure in the left
;half and size of an individual buffer (data size only) in the right half);
;and <RHDR> is the address of the buffer ring header control block. <CDB>
;if non-zero is the I/O CDB which will own the buffers, and from which
;the buffer space may be allocated - CDB "extra" space permitting. If the
;CDB can't hold the buffers (or <CDB> = 0) the buffer space will be
;allocated from program "Managed Memory" (free space).
;
;On error return insufficient memory was available in which to construct
;even one buffer.
;
;On normal return memory needed to hold the ring structure has been
;allocated, the buffer ring structure has been linked together and
;initialized (ready for first I/O) and T2 will contain <BUFARG> as
;actually used with T3 the base address of the first buffer.
;
;Uses T1, T2, T3, and T4.

	ENTRY	.IOBFA
	INTERN	IOBFA0,	IOBFA1

.IOBFA:	PUSHJ	P,.SACIO##	;SET UP IO
IOBFA0:
IOBFA1:	PUSHJ	P,TSAV14##	;SAVE THE ARGUMENTS
	HLRZ	T1,T2		;COUNT OF BUFFERS
	ANDI	T2,-1		;SIZE OF INDIVIDUAL BUFFER
	ADDI	T2,3		;PLUS BUFFER HEADER OVERHEAD WORDS
	IMULI	T1,(T2)		;T1:=TOTAL ADDRESS SPACE NEEDED
	JUMPE	IO,IOBFA5	;IF NO CDB THEN COMES FROM MANAGED MEMORY
	SKIPN	T3,.IOXFF(IO)	;WE HAVE A CDB, ANY "EXTRA" SPACE THERE?
	JRST	IOBFA5		;NO, USE NORMAL MANAGED MEMORY
	ADD	T3,T1		;T3:=PROPOSED NEW .IOXFF
	CAMLE	T3,.IOXSZ(IO)	;WILL THIS ALLOCATION FIT IN THE EXTRA SPACE?
	JRST	IOBFA5		;NO, ALLOCATE FROM MANAGED MEMORY
	EXCH	T3,.IOXFF(IO)	;YES, GET START OFFSET (AND SET NEW FIRST FREE)
	ADD	T3,IO		;RELOCATE INTO PHYSICAL CDB
IOBFA3:	MOVEM	T3,-T3(P)	;RETURN BASE ADDRESS TO CALLER
	MOVE	T2,-T2(P)	;RE-SETUP BUFARG
	MOVE	T4,-T4(P)	;AND BUFFER RING HEADER ADDRESS
	PJRST	IOBFI2		;AND INITIALIZE THE BUFFER RING

;HERE TO ALLOCATE BUFFER SPACE FROM PROGRAM MANAGED MEMORY

IOBFA5:	PUSHJ	P,.MMGWD##	;ALLOCATE SOME WORDS OF "MANAGED MEMORY"
	 JRST	IOBFA7		;NONE AVAILABLE
	MOVE	T3,T2		;PUT START ADDRESS IN T3
	JRST	IOBFA3		;AND FINISH UP

IOBFA7:	STOPCD	<File buffer allocation failed in IOBFA>
	SUBTTL	IOBFI - Initialize I/O buffers

;IOBFI  --  INITIALIZE I/O BUFFERS
;CALL IS:
;
;	MOVX	T2,<BUFARG>
;	MOVX	T3,<ADDR>
;	MOVX	T4,<RHDR>
;	PUSHJ	P,.IOBFI
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <BUFARG> is count of desired buffers in the ring structure in the left
;half and size of an individual buffer (data size only) in the right half);
;<ADDR> is the base address of the first buffer (all buffers are assumed
;in to be in a physically-contiguous block); and <RHDR> is the address of
;the buffer ring header control block.
;
;The error return is not exercised.
;
;On normal return the buffer ring structure has been linked together and
;initialized (ready for first I/O) and T2/T3 will contain <BUFARG> and
;<ADDR> as actually used.
;
;Uses T1, T2, T3, and T4.

	ENTRY	.IOBFI
	INTERN	IOBFI0,	IOBFI1

.IOBFI:	PUSHJ	P,.SACIO##	;SET UP IO
IOBFI0:
IOBFI1:	PUSHJ	P,TSAV14##	;SAVE OUR ARGUMENTS
IOBFI2:	CAIL	T3,.JBDA	;REASONABLE ADDRESS FOR BUFFER RING?
	CAIGE	T4,.JBDA	;REASONABLE ADDRESS FOR RING HEADER?
	STOPCD	<Invalid buffer address in IOBFI2>
	MOVSI	T1,007700	;JUST THE BYTE-SIZE FIELD
	ANDM	T1,.BFPTR(T4)	;INITIALIZE BYTE POINTER
	SETZM	.BFCTR(T4)	;AND BYTE COUNTER IN RING HEADER
	HLRZ	T1,T2		;COUNT OF BUFFERS IN RING
	ANDI	T2,-1		;SIZE OF INDIVIDUAL BUFFER
	ADDI	T2,3		;PLUS BUFFER HEADER OVERHEAD WORDS
	ADDI	T3,.BFHDR	;RELOCATE TO LINK WORD OF FIRST BUFFER
	MOVE	M0,T3		;HANG ON TO COPY OF START LINK WORD
	HRRZ	T4,T3		;START OF START OF NEXT BUFFER IN RING
	TLOA	T4,-2(T2)	;SET DATA SIZE + 1 IN LH OF .BFHDR WORD
IOBFI6:	ADDI	T3,(T2)		;ADDRESS OF NEW CURRENT BUFFER
	ADDI	T4,(T2)		;ADDRESS OF NEXT POSSIBLE BUFFER IN RING
	MOVEM	T4,(T3)		;LINK CURRENT BUFFER TO NEXT BUFFER
	SOJG	T1,IOBFI6	;LOOP TILL LAST BUFFER IN RING
	HRRM	M0,(T3)		;LINK LAST BUFFER TO FIRST BUFFER
	TXO	M0,BF.VBR	;THE VIRGIN BUFFER RING BIT
	MOVEM	M0,@-T4(P)	;LINK CONTROL BLOCK TO RING STRUCTURE
	JRST	.POPJ1##	;I/O BUFFERS ALL SET FOR I/O
	SUBTTL	IOBFZ - Deallocate I/O buffers

;IOBFZ  --  FREE UP I/O BUFFERS
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<BUFARG>
;	MOVX	T3,<ADDR>
;	MOVX	T4,<RHDR>
;	PUSHJ	P,.IOBFI
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <BUFARG> is count of desired buffers in the ring structure in the left
;half and size of an individual buffer (data size only) in the right half);
;<ADDR> is the base address of the first buffer (all buffers are assumed
;in to be in a physically-contiguous block); and <RHDR> is the address of
;the buffer ring header control block. <CDB>, if supplied, is the address
;of the I/O CDB which owns the buffers (and in whose "extra" space the
;buffers may reside).
;
;The error return is not exercised.
;
;On normal return the buffer ring header is zeroed and the buffer space
;has been freed (either returned to "managed memory" or to the I/O CDB
;"extra" space as appropriate).
;
;Uses T1, T2, T3, and T4.

	ENTRY	.IOBFZ
	INTERN	IOBFZ0,	IOBFZ1

.IOBFZ:	PUSHJ	P,.SACIO##	;SET UP IO
IOBFZ0:
IOBFZ1:	PUSHJ	P,TSAV14##	;SAVE THE T'S


;DELINK THE RING HEADER FROM THE BUFFER RING ITSELF

	SETZM	.BFADR(T4)	;DELINK THE RING FROM THE HEADER
	SETZM	.BFCTR(T4)	;ZAP THE BYTE COUNTER AND
	SETZM	.BFPTR(T4)	;BYTE POINTER ON G.P.'S

;NOW FREE UP THE BUFFERS

	HLRZ	T1,T2		;COUNT OF BUFFERS
	ANDI	T2,-1		;SIZE OF AN INDIVIDUAL BUFFER
	ADDI	T2,3		;PLUS BUFFER OVERHEAD WORDS
	IMULI	T1,(T2)		;TOTAL BUFFER SPACE USED
	JUMPE	IO,IOBFZ4	;IF NO CDB THEN CAME FROM MANAGED MEMORY
	MOVE	T4,IO		;START OF CDB
	ADD	T4,.IOXSZ(IO)	;T4:= ULTIMATE END OF CDB
	CAML	T3,IO		;IS BUFFER SPACE WITHIN THE CDB?
	CAML	T3,T4		; . . .
	JRST	IOBFZ4		;NO, THEN MUST BE FROM MANAGED MEMORY

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;BUFFER SPACE FROM CDB "EXTRA" SPACE, TRY TO RECLAIM IT

	MOVE	T4,IO		;START OF CDB
	ADDI	T4,.IOMAX	;START OF "EXTRA" SPACE
	CAMGE	T3,T4		;BUFFER OVERLAP FIXED DATA?
	STOPCD	<CDB "extra" space file buffers overlap CDB data in IOBFZ>
	MOVE	T4,IO		;START OF CDB
	ADD	T4,.IOXFF(IO)	;FIRST FREE IN "EXTRA" SPACE
	ADD	T1,T3		;T1:=END (+1) OF BUFFER SPACE
	CAME	T1,T4		;THIS BUFFER LAST THING ALLOCATED?
	JRST	.POPJ1##	;NO, CAN'T FREE IT
	SUB	T1,T3		;YES, GET BACK ACTUAL SIZE OF BUFFER SPACE
	MOVNS	T1		; (NO SUB FROM MEMORY)
	ADDM	T1,.IOXFF(IO)	;RECLAIM THE BUFFER SPACE
	JRST	.POPJ1##	;RETURN

;HERE WHEN BUFFER CAME FROM MAMAGED MEMORY

IOBFZ4:	MOVE	T2,T3		;POSITION START ADDRESS
	PUSHJ	P,.MMFWD##	;FREE UP MANAGED MEMORY WORDS
	 STOPCD	<File buffer deallocation failed in IOBFZ>
	JRST	.POPJ1##	;ALL DONE
	SUBTTL	IOQAT - QUERY file-level access processor

;IOQAT  --  PROCESS /QUERY "FILE SPEC" SWITCH
;IOQAA  --  PROCESS /QUERY, LOOK ONLY FOR /QUERY:ASK, IGNORE /QUERY:TELL
;IOQTT  --  PROCESS /QUERY, LOOK ONLY FOR /QUERY:TELL, IGNORE /QUERY:ASK
;IOQET  --  ERROR-MESSAGE-LEVEL FILE "TELL"ER
;Call is:
;
;	MOVX	T1,<OUTPUT>
;	MOVX	T2,<INPUT>
;	PUSHJ	P,.IOQAT/.IOQAA/.IOQTT/.IOQET
;	 REJECTED
;	NORMAL RETURN
;
;Where <INPUT> is the address of the input I/O CDB (required); and
;<OUTPUT> is the address of the output I/O CDB. <OUTPUT> may be 0
;if there is no output side to list, or may be -1 if the "output"
;side is actually part of the input side (the "tertiary" input
;variables, as in a RENAME operation).
;
;IOQAT is the normal file-level routine to handle the /QUERY switch
;in all its variety (e.g., both ASK and TELL). IOQAT is normally used
;on input requests only, but is valid on output as well (but see below
;for IOQAA/IOQTT).
;
;IOQAA checks only /QUERY:ASK, and will skip (success) return if only
;(e.g.) /QUERY:TELL was specified. IOQAA is used for output creation to
;ask the user before the create is attempted (i.e., before the actual
;resultant file is known - what disk structure, etc.).
;
;IOQTT checks only /QUERY:TELL, and will skip (success) return always.
;IOQTT is used in conjunction with IOQAA to bracket the output creation
;attempt. IOQTT is called after the file has been created when the true
;resultant file information is known (e.g., which physical disk struc-
;ture, etc.).
;
;IOQET is used for error-message typeout to insure that whatever error
;message is being typed has been preceded by the appropriate file iden-
;tification sequence disirregardless of any /QUERY (and lack thereof)
;typed by the user.
;
;On /QUERY:ASK if the user rejects the file the REJECTED return will
;be taken with status $EFRJU in M0.
;
;On normal return the file(s) has(have) been listed if requested, and
;the file(s) is(are) acceptable if the user /QUERY:ASKed.
;
;Uses T1, T2, T3, T4.
	ENTRY	.IOQAT
	INTERN	IOQAT0,	IOQAT1

.IOQAT:	PUSHJ	P,.SACIO##	;SET UP I/O CDB INDEX
IOQAT0:	PUSHJ	P,.SAVE4##	;NEED SOME P ACS HERE
IOQAT1:	PUSHJ	P,TSAV14##	;AND THE T'S AS WELL
	MOVX	T4,FX.QRA!FX.QRT;MATCH ON EITHER /QUERY:ASK OR /QUERY:TELL
	JRST	IOQR01		;SEE IF ANYTHING TO DO



	ENTRY	.IOQAA
	INTERN	IOQAA0,	IOQAA1

.IOQAA:	PUSHJ	P,.SACIO##	;SET UP I/O CDB INDEX
IOQAA0:	PUSHJ	P,.SAVE4##	;NEED SOME P ACS HERE
IOQAA1:	PUSHJ	P,TSAV14##	;AND THE T'S AS WELL
	MOVX	T4,FX.QRA	;MATCH ONLY ON /QUERY:ASK
	JRST	IOQR01		;SEE IF ANYTHING TO DO



	ENTRY	.IOQTT
	INTERN	IOQTT0,	IOQTT1

.IOQTT:	PUSHJ	P,.SACIO##	;SET UP I/O CDB INDEX
IOQTT0:	PUSHJ	P,.SAVE4##	;NEED SOME P ACS HERE
IOQTT1:	PUSHJ	P,TSAV14##	;AND THE T'S AS WELL
	MOVX	T4,FX.QRT	;MATCH ONLY ON /QUERY:TELL, IGNORE /QUERY:ASK
	JRST	IOQR01		;SEE IF ANYTHING TO DO



	ENTRY	.IOQET
	INTERN	IOQET0,	IOQET1

.IOQET:	PUSHJ	P,.SACIO	;GET TO I/O CONTEXT
IOQET0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
IOQET1:	PUSHJ	P,TSAV14	;AND THE T'S TOO
	SKIPE	.IOQCT(T2)	;HAS THIS FILE BEEN "TELL"ED ALREADY?
	JRST	.POPJ1##	;YES, THAT'S ALL WE WANTED TO DO
	MOVX	P4,FX.QRT	;ALWAYS DO A TELL, NEVER AN ASK
	JRST	IOQT01		;LIST THE FILE
;NOW FIGURE OUT WHAT WAS PASSED US IN SO FAR AS OUT=IN IS CONCERNED
;
;SINCE .CHKTM IS ALWAYS CALLED BEFORE .IOQAT (FOR THE INPUT FILE) IT IS
;SAFE TO USE THE "CURRENT" (.IOFSC) FILE SPEC BLOCK RATHER THAN THE
;ORIGINAL (.IOFSB) FILE SPEC BLOCK, ENABLING THE USER TO INDIVIDUALLY
;/QUERY THE VARIOUS BASIC FILE SPECIFICATIONS COMPOSING THE INPUT FILE
;EXPRESSION. FOR OUTPUT THE TWO ARE ALWAYS THE SAME (SO FAR).

IOQR01:	CAIE	T1,0		;OUTPUT GIVEN?
	CAMN	T1,[-1]		;OR "FAKE" OUTPUT?
	SKIPA	P3,.IOCU3(T2)	;"FAKE", USE TERTIARY FILE SPEC BLOCK
	MOVE	P3,.IOFSC(T1)	;ADDRESS OF OUTPUT FILE SPEC BLOCK
	SKIPE	P4,T1		;NO OUTPUT /QUERY IF NO OUTPUT
	MOVE	P4,.FXCTL(P3)	;OUTPUT CONTROL FLAGS
	MOVE	T3,.IOFSC(T2)	;ADDRESS OF INPUT FILE SPEC BLOCK
	IOR	P4,.FXCTL(T3)	;MERGE IN INPUT CONTROL FLAGS
	AND	P4,T4		;MASK OUT EXTRANEOUS STUFF
	TXNN	P4,FX.QRT!FX.QRA;/QUERY:(ASK,TELL)?
	JRST	.POPJ1##	;NO, NOTHING TO DO THEN

;AT LEAST /QUERY:TELL WAS SPECIFIED SOMEWHERE (OR HERE FROM ERROR MESSAGE)

IOQT01:	DMOVE	P1,T1		;SAVE CDB POINTERS FOR FUTURE REFERENCE
	PUSHJ	P,.TSPAC##	;DON'T CONFUSE POOR OLE BATCON
	JUMPN	P1,IOQT10	;IF OUTPUT, THEN LIST IT
	MOVEI	T1,[ASCIZ\ + \]	;THE "CONCATENATION" SEPARATOR
	MOVX	T2,IM.IQC	;THE "CONCATENATION" FLAG
	TDNE	T2,.IOIOM(IO)	;IS THIS A "CONCATENATION" OPERATION?
	PUSHJ	P,.TSTRG##	;YES, PRETTY TERMINAL LISTING
	JRST	IOQT40		;NOW GO LIST THE INPUT FILE
;LIST THE "OUTPUT" SIDE

IOQT10:	XMOVEI	T4,.TOCFN	;ASSUME FULL NETWORK FILE SPEC
	SKIPE	T2,.I1NOD(P1)	;GOT A NODE SPECIFICATION?
	CAMN	T2,.MYNOD##	;YES, IS IT LOCAL HOST?
	XMOVEI	T4,.TOCFL	;JUST NEED LOCAL FILE SPECIFICATION
	SKIPL	T1,P1		;ADDRESS OF OUTPUT CDB
	JRST	IOQT17		;LIST THE FILE SPECIFICATION

;HERE FOR "TERTIARY" INPUT AS THE "OUTPUT" LISTING (E.G., RENAME)

IOQT12:	XMOVEI	T4,.TOTFS	;WE WILL SPECIFY THE FILE SPEC COMPONETS
	MOVX	T2,FX.UDR!FX.UNM!FX.UEX!FX.UGN  ;ONLY WANT THESE FIELDS
	MOVE	T1,P2		;ADDRESS OF INPUT CDB FOR TERTIARY STRINGS
IOQT17:	PUSHJ	P,0(T4)		;LIST THE FILE SPECIFICATION
	 JFCL			;???
	AOS	.IOQCT(P1)	;NOTE THIS FILE HAS BEEN "TELL"ED
IOQT19:	MOVEI	T1,[ASCIZ\ <= \]; (MATCH ANGLE BRACKETS)>
	PUSHJ	P,.TSTRG##	;SEPARATE OUTPUT FROM INPUT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;LIST INPUT SIDE

IOQT40:	MOVE	P3,.IOFSC(P2)	;GET INPUT FILE SPEC BLOCK
	XMOVEI	T4,.TOCFN	;ASSUME WANT FULL NETWORK FILE SPEC LISTED
	SKIPE	T2,.I1NOD(P2)	;INPUT NODE SPECIFIED?
	CAMN	T2,.MYNOD##	;YES, IS IT ME?
	XMOVEI	T4,.TOCFL	;JUST NEED LOCAL FILE SPEC LISTED
	MOVE	T1,P2		;ADDRESS OF INPUT CDB
	PUSHJ	P,0(T4)		;LIST APPROPRIATE FILE SPECIFICATION
	 JFCL			;???
	AOS	.IOQCT(P2)	;COUNT UP .IOQAT CALLS FOR THIS FILE

;NOW CHECK FOR /QUERY:ASK

	TXNE	P4,FX.QRA	;/QUERY:ASK ON EITHER OUTPUT OR INPUT?
	JRST	IOQT60		;YES
	PUSHJ	P,.TCRLF##	;NO, CAP OFF /QUERY:TELL OUTPUT
	JRST	.POPJ1##	;AND RETURN SUCCESSFULLY

;PROCESS /QUERY:ASK

IOQT60:	PUSHJ	P,.TSPAC##	;SPACE OVER A BIT
	MOVEI	T1,.ASKYN##	;ASSUME [Y/N]
	TXNE	P4,FX.QNY	;SOMEONE WANT [N/Y]?
	MOVEI	T1,.ASKNY##	;YES
	PUSHJ	P,(T1)		;CALL ASK ROUTINE
	 CAIA			;USER SAID "NO"
	AOSA	(P)		;SKIP RETURN SINCE USER SAID "YES"
	MOVEI	M0,$EFRJU	;EXCEPTION CODE REJECTED-BY-USER
	POPJ	P,		;RETURN AS APPROPRIATE
	SUBTTL	File-level local support routines

;FILOP  --  PERFORM GENERIC LOCAL FILE OPERATION
;Call is:
;
;	MOVX	T1,<FNC>
;	PUSHJ	P,FILOP
;	 ERROR RETURN
;	NORMAL RETURN
;
;Where <FNC> is the generic file operation to be performed (read, write,
;etc.).
;
;Register IO points to the I/O CDB.
;
;On error return M0 has an error code (protection failure, etc.).
;
;On normal return the file is OPENed for the appropriate accessibility
;and the I/O CDB is set as specified by the .IOIOC and .IOIOM control
;words (e.g., file parameters, buffer allocation, etc.).
;
;Uses registers T1, T2, T3, and T4.

	FX$UIO=FX.MCY!FX.MEY!FX.DAM!FX.IOM  ;USER SPECIFIED I/O MODE INFO

FILOP:	PUSHJ	P,.SAVE4##	;NEED SOME P'S FOR AWHILE
	PUSHJ	P,TSAV12##	;SAVE T1 AND T2 MOMENTARILY
	MOVE	P1,.IOCCF(IO)	;CHANNEL CONTROL FLAGS
	TXNE	P1,IO.NET	;ANY NETWORK ACTIVITY?
	STOPCD	<Network channel in call to FILOP>
	CAIL	T1,0		;NEGATIVE IS ILLEGAL
	CAILE	T1,.IFMAX	;FUNCTION WE KNOW ABOUT?
	JRST	[MOVX	M0,$EFIFO	;ILLEGAL FILE OPERATION
		JRST	.M0ERR##]	;SET ERROR
	SKIPN	P2,.IOFSC(IO)	;ENSURE PRESENCE OF "CURRENT" FILE SPEC BLOCK
	STOPCD	<No "current" FSB in FILOP>
	MOVE	P3,FIFNTB(T1)	;FILOP. FUNCTION AND CONTROL
	TXNN	P3,FO.UOC	;TERTIARY FUNCTION?
	JRST	FILO01		;NO, NEED A CLEAN CHANNEL

;HERE TO PERFORM A TERTIARY ACTION SUCH AS RENAME OR DELETE

FILT01:	SKIPN	T2,.IOCHN(IO)	;YES, GET ALREADY-OPENED CHANNEL
	JRST	[MOVX	M0,$EICNO	;CHANNEL NOT OPEN
		JRST	.M0ERR##]	;SET ERROR
	DPB	T2,[POINTR P3,FO.CHN]  ;SET EXTANT CHANNEL IN FUNCTION WORD
	MOVEM	P3,.I1FL3+.FOFNC(IO)  ;SET FILOP. FUNCTION WORD
	SETZM	.I1FL3+.FOIOS(IO)  ;NO I/O STATUS ('CUZ NO OPEN)
	SETZM	.I1FL3+.FODEV(IO)  ;NO I/O DEVICE ('CUZ NO OPEN)
	SETZM	.I1FL3+.FOBRH(IO)  ;NO I/O BUFFERS ('CUZ NO OPEN)
	SETZM	.I1FL3+.FONBF(IO)  ;NO I/O BUFFERS ('CUZ NO OPEN)
	XMOVEI	P1,.I1LK3(IO)	;THE TERTIARY FILE BLOCK
	HRLZM	P1,.I1FL3+.FOLEB(IO)  ;SET FILOP. RENAME/DELETE BLOCK
	PUSHJ	P,FLPA01	;SET FILE PARAMETERS/ATTRIBUTES
	 JFCL			;HUH?
	SETZM	.I1FL3+.FOPAT(IO)  ;SET FILOP. PATH BLOCK WORD
	MOVE	T2,.IOPPN(IO)	;GET ON-BEHALF-OF USER
	MOVEM	T2,.I1FL3+.FOPPN(IO)  ;SET FILOP. ON-BEHALF-OF WORD
	MOVSI	T1,.FOMAX	;SIZE OF FILOP. BLOCK
	HRRI	T1,.I1FL3(IO)	;ADDRESS OF FILOP. BLOCK
	FILOP.	T1,		;PERFORM REQUESTED ACTION
	 JRST	FILOEF		;FILOP. FAILED
	JRST	.POPJ1##	;FUNCTION SUCCEEDED
;HERE WHEN TIME TO "OPEN" A FILE

FILO01:	TXNN	P1,IO.OPN	;DOES THIS CHANNEL HAVE A FILE OPEN?
	JRST	FILO05		;NO, ALL SET
	PUSHJ	P,IOABO0	;KILL THE FILE
	 JFCL			;DUH?
	MOVE	T1,-T1(P)	;GET FUNCTION BACK AGAIN
FILO05:	MOVEM	P3,.I1FLP+.FOFNC(IO)  ;SET FILOP. FUNCTION WORD
	LDB	T4,[POINTR .IOIOC(IO),IC.MOD]  ;GET SPECIFIED FILE MODE
	CAIG	T4,.ICMAX	;ONE WE KNOW ABOUT?
	SKIPGE	T1,MOMDTB(T4)	;YES, IS IT LEGAL (IMPLEMENTED)?
	JRST	[MOVX	M0,$EFIFM	;ILLEGAL FILE MODE
		JRST	.M0ERR##]	;GO SET ERROR CONDITION
	MOVE	T2,.IOIOM(IO)	;AND GET I/O MODE WORD
	TXNE	T2,IM.CMD	;FORCED TO USE .IOIOC MODE?
	JRST	FILO09		;USE .IOIOC MODE
	DMOVE	T3,.FXCTL(P2)	;GET USER-SPECIFIED I/O CONTROL
	MOVE	T2,.IOIOC(IO)	;GET CDB I/O CONTROL
	TXNE	T3,FX.MCY	;USER SPECIFY /MACY11?
	TXO	T2,IC.MCY	;YES, NOTE IN THE CDB
	TXNE	T3,FX.MEY	;USER SPECIFY /MECY11?
	TXO	T2,IC.MCY!IC.MEY;YES, NOTE IN THE CDB
	MOVEM	T2,.IOIOC(IO)	;SET CDB I/O CONTROL
	TXNN	T3,FX$UIO	;USER SPECIFY I/O MODE INFO?
	JRST	FILO09		;NO
	LDB	T1,[POINTR T3,FX.IOM]  ;GET USER-SPECIFIED /IOMODE
	LDB	T2,[POINTR T3,FX.DAM]  ;GET USER-SPECIFIED /DATAMODE
	TXNE	T3,FX.MCY!FX.MEY;USER WANT MACY11 PACKING?
	MOVEI	T1,.IOBIN	;YES, BINARY (36-BIT WORD) I/O THEN
	CAIE	T1,0		;GOT BOTH A /IOMODE
	CAIN	T2,0		;AND A /DATAMODE?
	IORB	T1,T2		;NO, DEFAULT ONE FROM THE OTHER
	MOVE	T4,MDMOTB(T2)	;AND TRANSLATE INTO .IOIOC MODE
	DPB	T4,[POINTR .IOIOC(IO),IC.MOD]  ;SET OPERATING MODE
FILO09:	DPB	T1,[POINTR .I1FLP+.FOIOS(IO),IO.MOD]  ;SET I/O MODE
				; NOTE .LKWLD/.SCWLD MAY HAVE SET IO.DEN/ETC.
	SETZ	T1,		;INITIALLY NO OPEN FLAGS
	MOVE	T2,.IOIOM(IO)	;GET MODE CONTROL WORD
	TXNE	T2,IM.PHS	;PHYSICAL ONLY?
	TXO	T1,UU.PHS	;YES
	TXNE	T2,IM.DEL	;DISABLE ERROR LOGGING?
	TXO	T1,UU.DEL	;YES
	TXNE	T2,IM.DER	;DISABLE ERROR RETRY?
	TXO	T1,UU.DER	;YES
	TXNE	T2,IM.AIO	;ASYCHRONOUS (NON-BLOCKING) I/O?
	TXO	T1,UU.AIO	;YES
	TXNE	T2,IM.LBF	;USE GENEROUS BUFFERING?
	TXO	T1,UU.LBF	;YES
	TXO	T1,UU.SOE	;ALWAYS SYNC ON ERROR
FILO10:	IORB	T1,.I1FLP+.FOIOS(IO)  ;SET IN FILOP. DEVIOS WORD
	SKIPN	T2,.I1FLP+.FODEV(IO)  ;DEVICE NAME SET BY .LKWLD CALL
	STOPCD	<No device name in FILO10>
	SKIPN	T4,.IOCHN(IO)	;DO WE HAVE A CHANNEL OPEN?
	JRST	FILO17		;NO
	MOVE	T3,.I1FIO(IO)	;GET OLD OPEN FLAGS
	XOR	T3,T1		;CONTRAST WITH PROPOSED OPEN FLAGS
	TLNN	T3,-1		;ARE ALL OPEN FLAGS
	CAME	T2,.I1FIO+1(IO)	; AND DEVICE NAME SAME AS CURRENTLY OPEN?
	JRST	FILO17		;NO, NEW DEVICE/FLAGS, MUST DO FULL "OPEN"
	MOVE	T3,.I1FLP+.FOFNC(IO)  ;YES, GET FILOP. FUNCTION WORD
	TXZ	T3,FO.ASC	;WE DON'T WANT A NEW CHANNEL,
	TXO	T3,FO.UOC	;WE WANT TO KEEP THE OLD CHANNEL
	DPB	T4,[POINTR T3,FO.CHN]  ;SET THE CHANNEL TOO!
	MOVEM	T3,.I1FLP+.FOFNC(IO)  ;SET FILOP. MODIFIED FUNCTION WORD
	JRST	FILO20		;AND CONTINUE WITH FILOP. SETUP

FILO17:	DMOVEM	T1,.I1FIO(IO)	;SET FOR NEXT PASS THROUGH HERE
	SKIPN	.IOCHN(IO)	;GOT A "CHANNEL" IN USE
	JRST	FILO20		;NOPE
	PUSHJ	P,IORLS0	;YES, BLASTETH IT
	 JFCL			;DUH?
				; AND SETUP REST OF FILOP. BLOCK
FILO20:	MOVE	T1,-T1(P)	;RETRIEVE REQUESTED FUNCTION AGAIN
	MOVE	P1,FICFTB(T1)	;GET NIFTY (.IOCCF) FLAGS
	IORB	P1,.IOCCF(IO)	;SET IN CDB
	MOVSI	T1,.IOOBH(IO)	;OUTPUT RING HEADER CONTROL BLOCK
	HRRI	T1,.IOIBH(IO)	;INPUT RING HEADER CONTROL BLOCK
	MOVEM	T1,.I1FLP+.FOBRH(IO)  ;SET FILOP. BUFFER HEADER WORD
	SETZM	.I1FLP+.FONBF(IO)  ;SET FILOP. BUFFER COUNT WORD
				; (WE WILL BUILD BUFFERS LATER)
	XMOVEI	P1,.I1LKP(IO)	;ADDRESS OF LOOKUP BLOCK
	HRRZM	P1,.I1FLP+.FOLEB(IO)  ;SET FILOP. LOOKUP BLOCK WORD
	PUSHJ	P,FLPA01	;SET FILOP. BLOCK PARAMETERS/ATTRIBUTES
	 JFCL			;DUH?
	MOVSI	T1,.PTMAX	;LENGTH OF [RETURNED] PATH BLOCK
	HRRI	T1,.I1PT2(IO)	;ADDRESS OF [RETURNED] PATH BLOCK
	MOVEM	T1,.I1FLP+.FOPAT(IO)  ;SET FILOP. PATH BLOCK WORD
	MOVE	T1,.IOPPN(IO)	;ON-BEHALF-OF-USER WORD
	MOVEM	T1,.I1FLP+.FOPPN(IO)  ;SET FILOP. OTHER-USER WORD
FILO30:	MOVSI	T1,.FOMAX	;LENGTH OF FILOP. BLOCK
	HRRI	T1,.I1FLP(IO)	;ADDRESS OF FILOP. BLOCK
	MOVE	T2,.I1FLP+.FOFNC(IO)  ;*** THE FUNCTION/CHANNEL WORD
	MOVE	T3,.I1FLP+.FODEV(IO)  ;*** THE DEVICE TO BE USED
	TXNE	T2,FO.UOC	;*** USING ALREADY-OPENED CHANNEL?
	SETZM	.I1FLP+.FODEV(IO)  ;*** YES, MAKE SURE MONITOR NOT FOOLING US
	FILOP.	T1,		;GO BEAT ON MONITOR FILE SYSTEM
	 TDZA	M0,M0		;FLAG ERROR
	SETO	M0,		;FLAG SUCCESS
	MOVEM	T3,.I1FLP+.FODEV(IO)  ;*** RESET DEVICE WORD
	LDB	T4,[POINTR .I1FLP+.FOFNC(IO),FO.CHN]  ;GET NEW CHANNEL (IF ANY)
	MOVEM	T4,.IOCHN(IO)	;AND SET IN THE CDB
	JUMPL	M0,FILO50	;PROCEED IF FILOP. SUCCEEDED
	MOVE	T2,.IOIOM(IO)	;FAILED, GET I/O MODE CONTROL
	CAIN	T1,ERAEF%	;WAS ERROR "ALREADY EXISTING FILENAME"?
	TXNN	T2,IM.UNQ	;DID USER REQUEST A UNIQUE FILE NAME?
	JRST	FILOEF		;NO, RETURN ERROR TO USER
	PUSHJ	P,FLPUQ1	;TRY TO INCREMENT THE FILENAME
	 JRST	FILOEG		;OH WELL, WE TRIED (ERROR CODE IN M0)
	MOVX	T1,FO.ASC	;THE "ASSIGN CHANNEL NUMBER" FLAG
	ANDCAM	T1,.I1FLP+.FOFNC(IO)  ;WE WILL RE-USE THE CHANNEL
	MOVX	T1,FO.UOC	;THE "USE-OPEN-CHANNEL"
	IORM	T1,.I1FLP+.FOFNC(IO)  ;AS I SAID, . . .
	JRST	FILO30		;GO TRY AGAIN
;WE HAVE SUCCESSFULLY OPENED THE CHANNEL, NOW FIGURE OUT WHAT WE GOT

FILO50:	MOVX	P1,IO.INI!IO.DEV!IO.OPN  ;THE FILE-IS-OPEN BIT(S)
	IORB	P1,.IOCCF(IO)	;SET IN THE CDB
	MOVE	T3,.IOCHN(IO)	;FILE I/O CHANNEL
	SETZ	T2,		;JUNK WORD
	MOVE	T1,[2,,T2]	;DEVSIZ ARG POINTER TO
	DEVSIZ	T1,		;READ BUFFER SIZE
	 STOPCD	<DEVSIZ failed in FILO50>
	SUBI	T1,3		;ADJUST TO TRUE DATA SIZE
	MOVEM	T1,.I1DSZ(IO)	;SAVE FOR LATER
	MOVE	T4,.IOCHN(IO)	;FILE I/O CHANNEL
	DEVTYP	T4,		;SEE WHAT TYPE OF DEVICE WE GOT
	 STOPCD	<DEVTYP failed in FILO50>
	MOVEM	T4,.I1DTY(IO)	;SAVE IN TOPS-10 BLOCK
	LDB	T3,[POINTR T4,TY.DEV]  ;GET DEVICE TYPE CODE
	MOVEM	T3,.IODTY(IO)	;SET IN CDB
	MOVE	T2,.IOCHN(IO)	;GET CHANNEL AGAIN
	DEVCHR	T2,		;GET DEVICE CHARACTERISTICS
	MOVEM	T2,.I1DCH(IO)	;SET IN TOPS-10 BLOCK
	MOVE	T1,.I1PT2+.PTSTR(IO)  ;GET RETURNED STRUCTURE NAME
	CAIN	T3,.TYDSK	;IS RESULTANT FILE ON A TRUE DISK?
	JUMPN	T1,FILO53	;YES, RETURNED PATH BLOCK HAS STRUCTURE
				;(UNLESS NUL: IN WHICH CASE WE NEED DEVNAM)

;FIGURE OUT THE DEVICE'S REAL NAME (E.G., MTA2 RATHER THAN MT)

	MOVE	T1,.IOCHN(IO)	;I/O CHANNEL
	DEVNAM	T1,		;GET DDB DEVICE NAME
	 STOPCD	<DEVNAM failed in FILO50>
FILO53:	MOVEM	T1,.I1FLP+.FODEV(IO)  ;SET REAL DEVICE OPENED
	MOVEM	T1,.I1DEV(IO)	;SET TRUE DEVICE NAME
	MOVEI	T1,.I1PT2(IO)	;RETURNED PATH BLOCK
	MOVEM	T1,.I1LKP+.RBPPN(IO)  ;SET REAL FILE DIRECTORY PATH
	SETZM	.I1GEN(IO)	;AND NEVER A FILE GENERATION
	MOVE	T1,.MYNOD##	;PICK UP LOCAL HOST NODE NAME
	MOVEM	T1,.I1NOD(IO)	;SET FILE NODE NAME
	PUSHJ	P,FILRA		;GENERATE NAME STRINGS AS SOON AS POSSIBLE
	 JFCL			;HO HUM

;VERIFY FILE ALLOCATION (IF NEEDED)

	MOVE	T3,.IODTY(IO)	;GET COPY OF "DEVICE TYPE"
	CAIE	T3,.TYDSK	;IS THIS A TRUE DISK?
	JRST	FILO60		;NO, FILE ALLOCATION MEANINGLESS
	MOVE	T2,.FXCTL(P2)	;GET I/O CONTROL SWITCHES
	TXNN	T2,FX.ALC!FX.CTG;IS FILE ALLOCATION IMPORTANT?
	JRST	FILO60		;NO
	MOVE	T2,.FXEST(P2)	;GET /ALLOCATE VALUE
	ADDI	T2,177		;ROUND UP AND
	LSH	T2,-7		;TRUNCATE TO NUMBER OF 128(10) WORD BLOCKS
	CAMG	T2,.I1LKP+.RBALC(IO)  ;DID MONITOR GIVE US ENOUGH?
	JRST	FILO60		;YEAH, ALL SET WITH FILE THEN

;FILE HAS INSUFFICIENT PHYSICAL ALLOCATION, TRANSLATE TO ERPOA% AND ABORT
;THE FILE CREATION.  /ALLOCATE WORKS VIA AN "ESTIMATING ENTER", SO WE MUST
;ENFORCE THE ALLOCATION MANUALLY (AS CONTRASTED WITH /CONTIGUOUS WHICH IS
;THE TRUE "ALLOCATING ENTER").

	MOVEI	T1,ERPOA%	;FILOP. ERROR CODE FOR PARTIAL ALLOCATION
	HRRM	T1,.I1LKP+.RBEXT(IO)  ;ANOTHER PLACE TO HIDE IT
	PJRST	FILOEF		;TREAT AS FILOP. FAILURE . . .


;SELECT MODE BASED ON INPUT FILE, IF THE USER WANTS IT

FILO60:	LDB	P4,[POINTR .IOIOC(IO),IC.MOD]  ;GET FILE MODE
	MOVE	T1,.IOIOM(IO)	;GET MODE CONTROL FLAGS
	TXNN	T1,IM.CMD	;OVERRIDING IOC MODE?
	TXNN	T1,IM.SMD	;OR REQUESTING SELECT MODE DEFAULT?
	JRST	FILO63		;USE .IOIOC MODE AS IS
	MOVE	T1,.FXCTM(P2)	;GET FSB CONTROL MASK
	TXNE	T1,FX$UIO	;USER SPECIFY I/O MODE CONTROL?
	JRST	FILO63		;YES, NO INPUT FILE DEFAULTING
	MOVE	T1,.IODTY(IO)	;DEVICE TYPE
	CAIE	T1,.TYDSK	;IS IT A DISK?
	JRST	FILO63		;NO, LEAVE WELL ENOUGH ALONE
	LDB	P4,[POINTR .I1LKP+.RBPRV(IO),RB.MOD]  ;GET CREATED I/O MODE
	MOVE	P4,MDMOTB(P4)	;CONVERT TO OUR MODE
	DPB	P4,[POINTR .IOIOC(IO),IC.MOD]  ;AND SET IN I/O CONTROL WORD
	MOVE	T1,MOMDTB(P4)	;SELECT APPROPRIATE BUFFERED I/O MODE
	DPB	T1,[POINTR .I1FLP+.FOIOS(IO),IO.MOD]  ;AND SET AS IN OPEN
	
;SELECT PROPER I/O MODE

FILO63:	HRRZ	T3,.I1FLP+.FOIOS(IO)  ;GET I/O STATUS BITS AS IN OPEN TIME
	HRLZ	T2,.IOCHN(IO)	;GET OPENED I/O CHANNEL
	HRRI	T2,.FOSET	;FILOP. "SETSTS" FUNCTION
	MOVE	T1,[2,,T2]	;FILOP. ARG POINTER TO
	FILOP.	T1,		;SELECT ACTUAL I/O MODE AND OPTIONS
	 STOPCD	<FILOP SETSTS failed in FILO55>

;NOW SELECT BYTE SIZES

FILO65:	SETZ	T1,		;NO BYTE SIZES YET
	SKIPLE	.FXBSZ(P2)	;DID USER SPECIFY /BYTESIZE?
	HRL	T1,.FXBSZ(P2)	;YES, USE HIS BYTESIZE
	SKIPLE	.FXFSZ(P2)	;DID USER SPECIFY /FRAMESIZE?
	HRR	T1,.FXFSZ(P2)	;YES, USE HER FRAMESIZE
	TLNE	T1,-1		;LACKING A DATA SIZE?
	TRNN	T1,-1		;OR A FRAME SIZE?
	TSO	T1,T1		;YES, DEFAULT ONE FROM THE OTHER
	TLNN	T1,-1		;LACKING A DATA BYTE SIZE?
	HLL	T1,.IODBS(IO)	;YES, USE USER DEFAULT
	TRNN	T1,-1		;LACKING A FRAME BYTE SIZE?
	HRR	T1,.IODBS(IO)	;YES, USE USER DEFAULT
	MOVE	T2,.IOUBS(IO)	;GET USER-OVERRIDDING FRAME/BYTE SIZE(S)
	TLNE	T2,-1		;OVERRIDDING DATA BYTE SIZE?
	HLL	T1,T2		;YES
	TRNE	T2,-1		;OVERRIDDING FRAME SIZE?
	HRR	T1,T2		;YES
	TLNE	T1,-1		;LACKING A DATA SIZE?
	TRNN	T1,-1		;OR A FRAME SIZE?
	TSO	T1,T1		;YES, DEFAULT IT FROM THE OTHER
	CAIN	T1,0		;GOT A BYTE SIZE YET?
	MOVE	T1,MOSZTB(P4)	;GET STANDARD BYTE SIZES
	MOVE	T2,.IOIOC(IO)	;I/O CONTROL
	TXNE	T2,IC.MCY!IC.MEY;MACY11 PACKED?
	MOVE	T1,[^D08,,^D08]	;YES, 8-BIT DATA PACKED INTO 8-BIT FRAMES THEN
	HLRZM	T1,.IOBSZ(IO)	;SET LOGICAL DATA BYTE SIZE
	HRRZM	T1,.IOFSZ(IO)	;SET PHYSICAL DATA FRAME SIZE
	TXNE	T2,IC.MCY!IC.MEY;MACY11 PACKED?
	HRRI	T1,^D36		;YES, ILMCB/OLMCB WANT 36-BIT BYTE POINTERS!
	DPB	T1,[POINTR .IOIBP(IO),<<^O77>B<^D11>>]  ;SET INPUT FRAME SIZE
	DPB	T1,[POINTR .IOOBP(IO),<<^O77>B<^D11>>]  ;SET OUTPUT FRAME SIZE

;SET RECORD FORMAT AS APPROPRIATE

FILO68:	MOVE	T4,.IOIOM(IO)	;GET MODE CONTROL FLAGS
	TXNE	T4,IM.CMD	;OVERRIDING IOC MODE?
	JRST	FILO70		;YES, USE .IOIOC MODE AS IS
	TXNN	T2,IC.MCY!IC.MEY;MACY11-PACKING?
	TDZA	T1,T1		;NO, THEN NO RECORD FORMATTING
	MOVEI	T1,.ICRFV	;YES, ASSUME VARIABLE-LENGTH ON G.P.'S
	LDB	T3,[POINTR .FXCTM(P2),FX.RFM]  ;/RECFORMAT SWITCH MASK
	CAIE	T3,0		;WAS A /RECFORMAT SWITCH TYPED?
	LDB	T1,[POINTR .FXCTL(P2),FX.RFM]  ;YES, GET /RECFORMAT VALUE
	DPB	T1,[POINTR .IOIOC(IO),IC.RFM]  ;RETURN RECORD FORMAT

;SETUP RETURNED-TO-USER VALUES

FILO70:	PUSHJ	P,FILCH		;GENERATE DEVICE/FILE CHARACTERISTICS
	 JFCL			;HO HUM
	PUSHJ	P,FILPA		;GENERIC DEVICE/FILE PARAMETERS/ATTRIBUTES
	 JFCL			;HO HUM

;VERIFY BLOCKSIZE

FILO71:	MOVE	T4,.I1DTY(IO)	;DEVTYP WORD
	HRRZ	T1,.IOUBF(IO)	;USER EXERTING EXPLICIT BUFFER CONTROL?
	JUMPE	T1,FILO72	;NO
	HRRZ	T2,.I1DSZ(IO)	;MONITOR'S BLOCKSIZE
	TXNN	T4,TY.VAR	;VARIABLE BLOCK SIZE ALLOWED?
	CAIN	T1,T2		;NO, USER DIFFERENT FROM MONITOR?
	JRST	FILO72		;VARIABLE ALLOWED OR BOTH THE SAME
	CAML	T1,T2		;IS USER'S BLOCKSIZE BIGGER THAN MONITOR
	TXNE	P1,IO.OUT	;AND NOT USED FOR OUTPUT?
	JRST	FILO72		;TOO BIG IS OK ON INPUT
	MOVEI	M0,$EFVBI	;ASSUME ERROR
	JRST	.M0IOZ##	;SET ERROR AND ZAP I/O CHANNEL

;BUFFERSIZE IS OK, CHECK DIRECTION OF I/O

FILO72:	MOVEI	M0,$EFILI	;PRESET ILLEGAL TO DO INPUT
	TXNE	P1,IO.INP	;USER WANT TO DO INPUT?
	TXNE	T4,TY.IN	;YES, DOES DEVICE SUPPORT INPUT?
	CAIA			;INPUT SIDE OK
	JRST	.M0IOZ##	;SET ERROR AND ZAP I/O CHANNEL
	MOVEI	M0,$EFILO	;PRESET ILLEGAL TO DO OUTPUT
	TXNE	P1,IO.OUT	;USER WANT TO DO OUTPUT?
	TXNE	T4,TY.OUT	;YES, DOES DEVICE SUPPORT OUTPUT?
	CAIA			;OUTPUT SIDE OK
	JRST	.M0IOZ##	;SET ERROR AND ZAP I/O CHANNEL

;NOW CALCULATE BUFFERS ALLOCATION

	HRRZ	T1,.IOUBF(IO)	;USER-SPECIFIED BLOCKSIZE
	TRNN	T1,-1		;DID HE?
	HRRZ	T1,.I1DSZ(IO)	;NONE, USE MONITOR'S
	ADDI	T1,3		;ALLOW FOR INDIVIDUAL BUFFER HEADERS
	HLRZ	T2,.IOUBF(IO)	;USER-SPECIFIED BUFFER COUNT
	JUMPN	T2,FILO75	;USE HIS IF ANY GIVEN
	HLRZ	T2,.I1DSZ(IO)	;OTHERWISE USE MONITOR DEFAULTS
	SKIPN	.IODBF(IO)	;USER EXERTING CONTROL OVER ALLOCATION?
	JRST	FILO75		;NO, USE MONITOR DEFAULTS
	HRRZ	T2,.IODBF(IO)	;YES, MAXIMUM SPACE FOR IO BUFFERS
	IDIVI	T2,(T1)		;SEE HOW MANY BUFFERS FIT
	CAIG	T2,0		;AT LEAST ONE?
	MOVEI	T2,1		;NO, ALWAYS ROOM FOR ONE!
	HLRZ	T3,.IODBF(IO)	;DEFAULT MAXIMUM BUFFERS
	CAIG	T3,0		;USER GIVE COUNT MAX?
	MOVE	T3,T2		;NO
	CAILE	T2,T3		;ARE WE GENERATING TOO MANY BUFFERS?
	MOVE	T2,T3		;YES, USE USER MAXIMUM THEN
FILO75:	TXNE	P1,IO.RND	;DOING RANDOM ACCESS I/O?
	MOVEI	T2,1		;YES, ALWAYS MAXIMUM OF ONE!
	SUBI	T1,3		;REDUCE TO DATA BUFFER SIZE
	SKIPLE	.IOMBF(IO)	;MAXIMUM ALLOCATION LIMIT GIVEN?
	CAMLE	T1,.IOMBF(IO)	;YES, CAN WE FIT?
	CAIA			;OK
	JRST	[MOVEI	M0,$EFBTB	;BLOCKSIZE TOO BIG
		JRST	.M0IOZ##]	;SET ERROR AND ZAP I/O CHANNEL
	MOVEM	T1,.IOBLW(IO)	;SAVE BUFFER SIZE (36-BIT WORDS)
	MOVEM	T2,.IOBLC(IO)	;SAVE COUNT OF BUFFERS
	MOVEI	T2,^D36		;BITS PER -10 WORD
	IDIV	T2,.IOFSZ(IO)	;T2:=BYTES PER -10 WORD
	IMUL	T1,T2		;T1:=BUFFER SIZE IN TERMS OF DATA BYTES
	MOVEM	T1,.IOBLS(IO)	;SET THAT FOR INTERESTED PARTIES

;SELECT I/O SERVICE ROUTINES

FILOS:	XMOVEI	T1,.IOIIN##	;LOCAL INITIAL ISR
	TXNN	P1,IO.INP	;SET FOR INPUT?
	XMOVEI	T1,.IOIIE##	;NO, THEN SELECT ERROR ISR
	MOVEM	T1,.IOISR(IO)	;SET INPUT SERVICE ROUTINE IN CDB
	XMOVEI	T1,.IOOIN##	;LOCAL INITIAL OSR
	TXNN	P1,IO.OUT	;SET FOR OUTPUT?
	XMOVEI	T1,.IOOIE##	;NO, THEN SELECT ERROR OSR
	MOVEM	T1,.IOOSR(IO)	;SET OUTPUT SERVICE ROUTINE IN CDB

;ALL DONE

	JRST	.POPJ1##	;RETURN WITH OPEN FILE
;HERE FOR FILOP. ERROR
;
;Since we can never succeed in outguessing this and future monitors(*),
;stomp on the channel and clean it up.
;
;(*) for example, an ERNSD% (no such device) error returns a channel
;to us, but has not OPENed any device on the channel!!!

FILOEF:	ANDI	T1,-1		;IGNORE "JUNK" IN LH
	CAILE	T1,FILOEL	;ERROR CODE WITHIN KNOWN BOUNDARIES?
	SETO	T1,		;NO, PITCH IT
	SKIPA	P2,FILOET(T1)	;GET INTERNAL EXCEPTION CODE
FILOEG:	MOVE	P2,M0		;ENTER HERE WITH INTERNAL CODE IN M0
	SKIPE	T2,.I1FLP+.FODEV(IO)  ;GET MOST-RECENTLY USED DEVICE CODE
	MOVEM	T2,.I1DEV(IO)	;SET SO ERROR MESSAGES HAVE SOMETHING TO TYPE
	PUSHJ	P,FILRA		;SETUP NAME STRINGS FOR ERROR MESSAGES
	 JFCL			;HO HUM
	SKIPN	T4,.IOCHN(IO)	;GOT AN I/O CHANNEL?
	JRST	FILOE5		;IF NONE, JUST CONVERT ERROR CODE
	MOVX	T3,IO.DEV!IO.OPN;ASSUME A FILE IS OPEN
	IORM	T3,.IOCCF(IO)	; (JUST IN CASE, CLEARED AS NEEDED BELOW)
	MOVE	T1,T4		;I/O CHANNEL
	DEVTYP	T1,		;GET DEVTYP FLAGS
	 SETZ	T1,		;OH WELL, THE MONITOR IS AT IT AGAIN
	MOVEM	T1,.I1DTY(IO)	;SAVE ON G.P.'S
	LDB	T1,[POINTR T1,TY.DEV]  ;EXTRACT DEVICE TYPE
	CAIE	T1,.TYDSK	;LOOKING AT A DISK?
	JRST	FILOE2		;NO
	MOVEM	T4,.I1NSP+.DCNAM(IO)  ;YES, SET CHANNEL IN DSKCHR BLOCK
	MOVSI	T2,.I1NSL	;LENGTH (OF SCRATCH/DSKCHR BLOCK)
	HRRI	T2,.I1NSP(IO)	; AND ADDRESS OF DSKCHR BLOCK TO
	DSKCHR	T2,		;READ ABOUT THAT STRUCTURE/FILE
	 JRST	FILOE2		;FORGET IT
	CAIE	P2,$EFNRM	;WAS ERROR "NO ROOM"
	JRST	FILOE2		;NO
	MOVEI	P2,$EFQTA	;ASSUME "QUOTA EXHAUSTED"
	SKIPG	.I1NSP+.DCUNT(IO)  ;ANY ROOM LEFT ON THAT STR?
	MOVEI	P2,$EFFUL	;NO, THEN ERROR IS "DEVICE FULL"
FILOE2:	MOVX	T3,$E$LVL	;ERROR SEVERITY LEVEL
	AND	T3,P2		;EXTRACT THE SEVERITY LEVEL
	CAILE	T3,EL$FTL	;LESS THAN DEADLY (EL$FTX) ERROR?
	JRST	FILOE3		;NO, CHANNEL IN "UNSAFE" STATE, KRUMP ON IT
				;  SOME ERRORS, SUCH AS PROTECTION FAILURE,
				;  RETURN A DEVICE/CHANNEL, EVEN THOUGH THE
				;  FILOP. "FAILED" - THIS IS OK, BUT OTHER
				;  ERRORS (DEVICE-CLASS, E.G.,NO SUCH DEVICE)
				;  WILL ACTUALLY RETURN A FO.ASC CHANNEL, BUT
				;  NO DEVICE IS OPENED ON SAID CHANNEL!!!!!

;INNOCOUS ERROR, CHANNEL SHOULD STILL BE SAFE, JUST "CLOSE" AND KEEP IT

	PUSHJ	P,IOABO0	;TRY TO SIMPLY CLOSE CHANNEL (ABORT THE FILE)
	 JRST	FILOE3		;OH WELL, KILL THE CHANNEL
	JRST	FILOE5		;RETURN ERROR CODE (KEEPING THE OPEN CHANNEL)

;SEVERE ERROR, TAKE NO CHANCES, GET RID OF THE CHANNEL

FILOE3:	PUSHJ	P,IORLS0	;GET RID OF IT, WHATEVER IT IS
	 JFCL			;HO HUM
	SKIPE	.IOCHN(IO)	;SHOULDN'T HAVE A I/O CHANNEL ANYMORE
	STOPCD	<I/O channel still set in FILOE3>
FILOE5:	MOVE	M0,P2		;RETURN EXCEPTION CODE IN M0
	POPJ	P,		;NO, TAKE ERROR/EXCEPTION RETURN
;FILOP. ERROR TO INTERNAL ERROR TRANSLATION TABLE

DEFINE X(A),<EXP A>


	X	$EFXXX		;------ (--) UNTRANSLATABLE
FILOET:	X	$EFFNF		;ERFNF% (00) FILE NOT FOUND
	X	$EFDNF		;ERIPP% (01) UFD (DIRECTORY) NOT FOUND
	X	$EFPRT		;ERPRT% (02) PROTECTION FAILURE
	X	$EFFBM		;ERFBM% (03) FILE BEING MODIFIED
	X	$EFAEF		;ERAEF% (04) ALREADY EXISTING FILENAME
	X	$EFISU		;ERISU% (05) ILLEGAL SEQUENCE OF UUOS
	X	$EFRIB		;ERTRN% (06) RIB OR DIRECTORY READ ERROR
	X	$EFNSF		;ERNSF% (07) NOT A SAVE FILE
	X	$EFNEC		;ERNEC% (10) NOT ENOUGH CORE
	X	$EFDNA		;ERDNA% (11) DEVICE NOT AVAILABLE
	X	$EFNSD		;ERNSD% (12) NO SUCH DEVICE
	X	$EFILU		;ERILU% (13) ILLEGAL MONITOR CALL
	X	$EFNRM		;ERNRM% (14) NO ROOM
	X	$EFWLK		;ERWLK% (15) WRITE LOCK
	X	$EFTBL		;ERNET%	(16) NOT ENOUGH TABLE SPACE
	X	$EFPOA		;ERPOA% (17) PARTIAL ALLOCATION
	X	$EFBNF		;ERBNF% (20) BLOCK NOT FREE
	X	$EFCSD		;ERCSD% (21) CAN'T SUPERSEDE DIRECTORY
	X	$EFDNE		;ERDNE% (22) CAN'T DELETE NON-EMPTY DIRECTORY
	X	$EFSNF		;ERSNF% (23) SFD NOT FOUND
	X	$EFSLE		;ERSLE% (24) SEARCH LIST EMPTY
	X	$EFLVL		;ERLVL% (25) SFD'S NESTED TOO DEEPLY
	X	$EFNCE		;ERNCE% (26) NO-CREATE ON FOR DSK:
	X	$EFSNS		;ERSNS% (27) SEGMENT NOT ON SWAP, OR LOCKED
	X	$EFFCU		;ERFCU% (30) CAN'T UPDATE FILE
	X	$EFLOH		;ERLOH% (31) LOSEG OVERLAPS HISEG
	X	$EFNLI		;ERNLI% (32) NOT LOGGED IN
	X	$EFFLK		;ERENQ% (33) OUTSTANDING ENQ LOCKS STILL SET
	X	$EFBED		;ERBED% (34) BAD .EXE DIRECTORY
	X	$EFBEE		;ERBEE% (35) BAD .EXE EXTENSION
	X	$EFDTB		;ERDTB% (36) .EXE DIRECTORY TOO BIG
	X	$EFENC		;ERENC% (37) EXCEEDED NETWORK CAPACITY (TSK)
	X	$EFTNA		;ERTNA% (40) TASK DEVICE NOT AVAILABLE (TSK)
	X	$EFNSN		;ERUNN% (41) UNDEFINED NETWORK NODE
	X	$EFSIU		;ERSIU% (42) SFD IS IN USE (RENAME)
	X	$EFNDR		;ERNDR% (43) FILE HAS NDR LOCK (DELETE)
	X	$EFJCH		;ERJCH% (44) JOB COUNT HIGH (TOO MANY ACCESSES)
	X	$EFSSL		;ERSSL% (45) CAN'T RENAME SFD TO LOWER LEVEL
	X	$EFCNO		;ERCNO% (46) CHANNEL NOT OPEN
	X	$EFDDU		;ERDDU% (47) DEVICE "DOWN" AND UNUSEABLE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

	X	$EFDRS		;ERDRS% (50) DEVICE IS RESTRICTED
	X	$EFDCM		;ERDCM% (51) DEVICE IS CONTROLLED BY MDA
	X	$EFDAJ		;ERDAJ% (52) DEVICE ALLOCATED TO ANOTHER JOB
	X	$EFIDM		;ERIDM% (53) DEVICE DATA MODE ILLEGAL
	X	$EFUOB		;ERUOB% (54) UNDEFINED OPEN BITS
	X	$EFDUM		;ERDUM% (55) DEVICE IN USE ON MPX: CHANNEL
	X	$EFNPC		;ERNPC% (56) NO PER-PROCESS SPACE FOR CHANTAB
	X	$EFNFC		;ERNFC% (57) NO FREE CHANNELS
	X	$EFUFF		;ERUFF% (60) UNDEFINED FILOP. FUNCTION
	X	$EFCTB		;ERCTB% (61) CHANNEL TOO BIG
	X	$EFCIF		;ERCIF% (62) CHANNEL ILLEGAL FOR FUNCTION
	X	$EFACR		;ERACR% (63) ADDRESS CHECK READING ARG LIST
	X	$EFACS		;ERACS% (64) ADDRESS CHECK WRITING ARG LIST
	X	$EFNZA		;ERNZA% (65) NEGATIVE OR ZERO ARG LIST COUNT
	X	$EFATS		;ERATS% (66) ARGUMENT LIST TOO SHORT

	FILOEL==.-FILOET	;MAX KNOWN FILOP. ERROR CODE
;VARIOUS CONVERSION TABLES FOR FILO??

;FROM FILE OPERATION TO FILOP. FUNCTION CODE

FIFNTB:	FO.PRV!FO.ASC+.FORED	;.IFFND  --  FIND A FILE
	FO.PRV!FO.ASC+.FORED	;.IFRED  --  READ A FILE
	FO.PRV!FO.ASC+.FOWRT	;.IFWRT  --  WRITE A FILE
	FO.PRV!FO.ASC+.FOAPP	;.IFAPP  --  APPEND [TO] A FILE
	FO.PRV!FO.ASC+.FOSAU	;.IFSAU  --  SINGLE-ACCESS UPDATE
	FO.PRV!FO.ASC+.FOMAU	;.IFMAU  --  MULTI-ACCESS UPDATE
	FO.PRV!FO.UOC+.FODLT	;.IFDLT  --  DELETE OPEN FILE
	FO.PRV!FO.UOC+.FORNM	;.IFRNM  --  RENAME OPEN FILE


;FROM FILE OPERATION TO CHANNEL CONTROL BITS

FICFTB:	EXP	0		;.IFFND  --  OK DEFAULT MODE
	EXP	IO.INP		;.IFRED  --  OK DEFAULT, WILL WANT INPUT
	EXP	IO.OUT		;.IFWRT  --  WILL WANT OUTPUT
	EXP	IO.OUT		;.IFAPP  --  WILL WANT OUTPUT
	EXP	IO.INP!IO.OUT	;.IFSAU  --  WILL WANT INPUT AND OUTPUT
	EXP	IO.INP!IO.OUT	;.IFMAU  --  WILL WANT INPUT AND OUTPUT
	EXP	0		;.IFDLT  --  NO I/O
	EXP	0		;.IFRNM  --  NO I/O
;FILE MODE TO I/O MODE

MOMDTB:	EXP	.IOASC		;.ICDEF  --  DEFAULT (7-BIT ASCII)
	EXP	.IOASL		;.ICASC  --  ASCII (7-BIT)
	EXP	-1		;.ICAS8  --  ASCII (8-BIT) (RESERVED)
	EXP	-1		;.ICEBC  --  EBCDIC (RESERVED)
	EXP	.IOPIM		;.ICPIM  --  PACKED IMAGE (RESERVED)
	EXP	.IOIMG		;.ICIMG  --  IMAGE 36-BIT BYTES (RESERVED)
	EXP	.IOBYT		;.ICBYT  --  BINARY 8-BIT BYTES
	EXP	.IOBIN		;.ICBIN  --  BINARY 36-BIT BYTES


;FILE MODE TO BYTE AND FRAME SIZE

MOSZTB:	XWD	^D07,	^D07	;.ICDEF  --  DEFAULT (7-BIT ASCII)
	XWD	^D07,	^D07	;.ICASC  --  ASCII (7-BIT)
	XWD	^D00,	^D00	;.ICAS8  --  ASCII (8-BIT) (RESERVED)
	XWD	^D00,	^D00	;.ICEBC  --  EBCDIC (RESERVED)
	XWD	^D08,	^D08	;.ICPIM  --  PACKED IMAGE (RESERVED)
	XWD	^D36,	^D36	;.ICIMG  --  IMAGE (RESERVED)
	XWD	^D08,	^D08	;.ICBYT  --  BINARY 8-BIT BYTES
	XWD	^D36,	^D36	;.ICBIN  --  BINARY 36-BIT BYTES


;I/O MODE TO FILE MODE

MDMOTB:	EXP	.ICASC		;.IOASC  --  ASCII
	EXP	.ICASC		;.IOASL  --  ASCII
	EXP	.ICPIM		;.IOPIM  --  PACKED IMAGE
	EXP	.ICBYT		;.IOBYT  --  BYTE (8-BIT)
	EXP	.ICIMG		;******  --  RESERVED FOR DEC
	EXP	.ICIMG		;******  --  RESERVED FOR DEC
	EXP	.ICIMG		;******  --  RESERVED FOR CUSTOMER
	EXP	.ICIMG		;******  --  RESERVED FOR CUSTOMER
	EXP	.ICIMG		;.IOIMG  --  IMAGE 36-BIT BYTES
	EXP	.ICIMG		;******  --  RESERVED FOR DEC
	EXP	.ICIMG		;******  --  RESERVED FOR DEC
	EXP	.ICIMG		;.IOIBN  --  IMAGE BINARY 36-BIT BYTES
	EXP	.ICBIN		;.IOBIN  --  BINARY 36-BIT BYTES
	EXP	.ICIMG		;.IOIDP  --  IMAGE DUMP
	EXP	.ICIMG		;.IODPR  --  DUMP (RECORDS)
	EXP	.ICIMG		;.IODMP  --  DUMP
;SET FILE PARAMETERS/ATTRIBUTES/ETC.
;
;CALL WITH LOOKUP BLOCK IN P1, FSB IN P2, AND FILOP. FUNCTION WORD IN P3

FLPA01:	HRRZ	T1,P3		;GET JUST FILOP. FUNCTION
	CAIE	T1,.FORED	;IF JUST A READ
	CAIN	T1,.FODLT	; OR A DELETE
	JRST	.POPJ1##	;THEN DON'T BOTHER
	MOVE	P3,.FXCTL(P2)	;GET CONTROL FLAGS
	MOVE	P4,.FXMOD(P2)	;AND THE MOD FLAGS
	MOVE	T1,.IOIOM(IO)	;GET I/O MODE CONTROL
	MOVX	T2,RB.NSE	;THE "NON-SUPERSEDING-ENTER" FLAG
	TXNE	T1,IM.UNQ	;USER WANT A UNIQUE NAME ON CREATE?
	IORM	T2,.RBCNT(P1)	;YES

;Check for file allocation (/ESTIMATE, etc.)

FLPA03:	MOVE	T1,.FXEST(P2)	;GET THE /ESTIMATE WORD
	CAME	T1,[-1]		;NO-VALUE VALUE?
	JRST	FLPA05		;NO, EXPLICIT LENGTH QUANTITY
	MOVE	T4,.IOIOM(IO)	;GET CDB I/O MODE CONTROL
	TXNN	T4,IM.CTG	;CONTIGUOUS ALLOCATION SPECIFIED?
	TXNE	P3,FX.CTG	;OR /CONTIGUOUS TYPED?
	SKIPN	.IOALW(IO)	;CONTIGUOUS - PREFER ALLOCATED QUANTITY
	SKIPN	T1,.IOLNW(IO)	;GOT A DATA LENGTH QUANTITY?
	MOVE	T1,.IOALW(IO)	;GOT AN ALLOCATED FILE SIZE?
FLPA05:	ADDI	T1,177		;ROUND UP AND
	LSH	T1,-7		;TRUNCATE TO NUMBER OF 128(10) WORD BLOCKS
	SETZ	T2,		;T1 GOES TO .RBEST, T2 GOES TO .RBALC
	TXNN	T4,IM.CTG	;CONTIGUOUS ALLOCATION SPECIFIED?
	TXNE	P3,FX.CTG	;OR /CONTIGUOUS TYPED?
	EXCH	T1,T2		;YES NON-ZERO TO .RBALC THEN
	MOVEM	T1,.RBEST(P1)	;SET ESTIMATED ALLOCATION IN BLOCKS
	MOVEM	T2,.RBALC(P1)	;SET CONTIGUOUS ALLOCATION IN BLOCKS

;NOW CHECK DATE/TIME ATTRIBUTES

FLPA10:	SKIPN	T1,.IOCDT(IO)	;GOT A CREATION DATE/TIME?
	SKIPA	T2,T1		;NO, JUST ZERO OUT THE FIELD(S)
	PUSHJ	P,.CNTDT##	;SPLIT INTO DATE AND TIME
	DPB	T2,[POINTR .RBPRV(P1),RB.CRD]  ;SET MOST OF DATE
	LDB	T2,[POINT 3,T2,23]  ;POSITION AND
	DPB	T2,[POINTR .RBEXT(P1),RB.CRX]  ;SET REST OF DATE
	IDIVI	T1,^D60*^D1000	;CONVERT TO MINUTES
	DPB	T1,[POINTR .RBPRV(P1),RB.CRT]  ;SET CREATION TIME
	SKIPE	T1,.IOADT(IO)	;GOT AN ACCESS DATE/TIME?
	PUSHJ	P,.CNTDT##	;SPLIT INTO DATE AND TIME
	DPB	T1,[POINTR .RBEXT(P1),RB.ACD]  ;SET ACCESS DATE
	MOVE	T1,.IOEDT(IO)	;GOT A EXPIRATION DATE/TIME?
	MOVEM	T1,.RBDED(P1)	;SET IT TOO
	MOVE	T1,.IOBDT(IO)	;GOT A BACKUP DATE/TIME?
	MOVEM	T1,.RBIDT(P1)	;YES, SET IT TOO
	MOVE	T1,.IOPDT(IO)	;GOT A PHYSICAL MEDIA CREATION DATE/TIME?
	MOVEM	T1,.RBTIM(P1)	;YES, SET IT TOO (ON G.P.'S)

;Check for file protection

FLPA20:	LDB	T1,[POINTR .FXMOM(P2),FX.PRO]  ;/PROTECTION MASK
	JUMPE	T1,FLPA22	;NO /PROTECTION:NNN IF MASK IS BLANK
	LDB	T1,[POINTR P4,FX.PRO]  ;/PROTECTION:NNN VALUE
	CAIA			;SET PROTECTION CODE FROM /PROTECTION SWITCH
FLPA22:	MOVE	T1,.IOPRT(IO)	;IS PROTECTION SET?
	DPB	T1,[POINTR .RBPRV(P1),RB.PRV]  ;YES TOPS-10 LEVEL D FILE PROT

;See if account string stuff specified

FLPA25:	MOVSI	T2,.IOACT(IO)	;ADDRESS OF "ON-BEHALF-OF" ACCOUNT STRING
	HRRI	T2,.RBACT(P1)	;WHERE IT BELONGS IN THE FILE BLOCK
	SKIPE	.IOACT(IO)	;IS THERE AN "ON-BEHALF-OF" ACCOUNT STRING?
	BLT	T2,.RBAC8(P1)	;YES, COPY IT INTO THE FILE BLOCK

;Fake up "spooling" name from QUEUE JOB NAME if set (for FAL's benefit)

FLPA30:	SKIPE	T1,.IOQ6J(IO)	;GOT A QUEUE JOB NAME?
	MOVEM	T1,.RBSPL(P1)	;YES, SET FILE SPOOLING NAME THEN

;ALL DONE

	JRST	.POPJ1##	;RETURN SUCCESSFULLY
;LOOP BEATING ON FILENAME TO TRY TO CREATE A UNIQUE NAME

FLPUQ1:	MOVE	T1,.I1LKP+.RBNAM(IO)  ;GET FILE NAME
	SETZ	T3,		;CLEAR OUT NUMERIC ACCUMULATOR
FLPUQ2:	LSHC	T1,-6		;EXTRACT LOW-ORDER CHARACTER
	LSH	T2,-36		;AND RIGHT-JUSTIFY IT
	CAIL	T2,'0'		;IS IT A DIGIT?
	CAILE	T2,'9'		; . . .
	JRST	FLPUQ9		;NO - CAN'T CREATE UNIQUE NAME THEN
	ADDI	T2,1		;INCREMENT THE POOR THING
	CAIG	T2,'9'		;STILL A DIGIT?
	JRST	FLPUQ6		;YUP, GOT A NEW NUMBER THEN
	MOVEI	T2,'0'		;NOPE, OVERFLEW
	LSHC	T2,-6		;SO ACCUMULATE THIS DIGIT AND
	JRST	FLPUQ2		;AND PROPAGATE THE "CARRY" ANOTHER DECADE

FLPUQ6:	LSHC	T2,36		;LEFT-JUSTIFY AND
	LSHC	T1,6		; SLIDE THE NUMBER
	JUMPN	T2,.-1		;  BACK INTO THE NAME
	MOVEM	T1,.I1LKP+.RBNAM(IO)  ;AND PUT THE NAME BACK INTO THE FILE
	JRST	.POPJ1##	;SUCCESSFUL RETURN TO TRY AGAIN

FLPUQ9:	MOVEI	M0,$EFDIF	;"DIRECTORY IS FULL" (WELL, IT IS, SORTA)
	POPJ	P,		;AND PROPAGATE ERROR BACK TO USER
;SET UP I/O BUFFERS IF REQUESTED

FILBF:	PUSHJ	P,.SAVE4##	;PRESERVE THE P'S
FILBF1:	MOVE	P1,.IOCCF(IO)	;GET FRESH CHANNEL CONTROL FLAGS
	TXNE	P1,IO.INP	;DOING INPUT?
	TXNE	P1,IO.IBA	;YES, INPUT BUFFERS ALLOCATED?
	JRST	FILBF5		;NO INPUT OR BUFFERS ALREADY ALLOCATED
	PUSHJ	P,FILBI1	;ALLOCATE AND INITIALIZE INPUT BUFFERS
	 POPJ	P,		;BUFFER ALLOCATION FAILED
FILBF5:	TXNE	P1,IO.OUT	;DOING OUTPUT?
	TXNE	P1,IO.OBA	;YES, OUTPUT BUFFERS ALLOCATED?
	JRST	.POPJ1##	;NO OUTPUT OR BUFFERS ALREADY ALLOCATED
	PUSHJ	P,FILBO1	;ALLOCATE AND INITIALIZE OUTPUT BUFFERS
	 POPJ	P,		;BUFFER ALLOCATION FAILED
	JRST	.POPJ1##	;BUFFERS ALLOCATED



FILBI1::HRLZ	T2,.IOBLC(IO)	;GET NUMBER
	HRR	T2,.IOBLW(IO)	; AND SIZE OF BUFFERS
	MOVEI	T4,.IOIBH(IO)	;AND ADDRESS OF INPUT RING HEADER
	PUSHJ	P,IOBFA0	;ALLOCATE AND INITIALIZE BUFFER RING
	 PJRST	.M0IOZ##	;FAILED, KILL CHANNEL
	DMOVEM	T2,.IOIAC(IO)	;SAVE FOR LATER DEALLOCATION
	MOVX	P1,IO.IBA	;THE INPUT-BUFFERS-ALLOCATED BIT
	IORB	P1,.IOCCF(IO)	;SET IN THE CDB
	JRST	.POPJ1##	;SUCCESSFUL RETURN



FILBO1::HRLZ	T2,.IOBLC(IO)	;GET NUMBER
	HRR	T2,.IOBLW(IO)	; AND SIZE OF BUFFERS
	MOVEI	T4,.IOOBH(IO)	;AND ADDRESS OF OUTPUT RING HEADER
	PUSHJ	P,IOBFA0	;ALLOCATE AND INITIALIZE BUFFER RING
	 PJRST	.M0IOZ##	;FAILED, KILL CHANNEL
	DMOVEM	T2,.IOOAC(IO)	;SAVE FOR LATER DEALLOCATION
	MOVX	P1,IO.OBA	;THE OUTPUT-BUFFERS-ALLOCATED BIT
	IORB	P1,.IOCCF(IO)	;SET IN THE CDB
	JRST	.POPJ1##	;RETURN
;SETUP FILE/DEVICE CHARACTERISTICS

FILCH:	SETZ	T1,		;NO FLAGS AS YET
	MOVE	T2,.I1DCH(IO)	;GET DEVCHR WORD
	TXC	T2,DV.DSK!DV.CDR;IS BOTH A DISK AND A CARD READER?
	TXCN	T2,DV.DSK!DV.CDR; (ONLY SET IF NUL:)
	TXO	T1,IC.NUL	;YES, FLAG DEVICE IS NUL:
	TXNE	T2,DV.DSK	;DISK?
	TXO	T1,IC.FOD!IC.MDI!IC.IDV!IC.ODV!IC.RAD
	TXNE	T2,DV.DTA	;DECTAPE?
	TXO	T1,IC.FOD!IC.SDI!IC.IDV!IC.ODV
	TXNE	T2,DV.MTA	;MAGTAPE?
	TXO	T1,IC.FOD!IC.SQD!IC.IDV!IC.ODV
	TXNE	T2,DV.TTY	;TERMINAL?
	TXO	T1,IC.TRM!IC.CCL!IC.IDV!IC.ODV
	TXNE	T2,DV.LPT	;LINEPRINTER?
	TXO	T1,IC.CCL!IC.ODV
	TXNE	T2,DV.IN	;CAN DO INPUT?
	TXO	T1,IC.IDV	;YES
	TXNE	T2,DV.OUT	;CAN DO OUTPUT?
	TXO	T1,IC.ODV	;YES
	TXNE	T2,DV.AVL	;IS DEVICE AVAILABLE?
	TXO	T1,IC.AVL	;YES
	TXNE	T2,DV.DIR	;IS DEVICE A DIRECTORY DEVICE?
	TXNE	T1,IC.SDI!IC.MDI; OTHER THAN DISK OR DECTAPE?
	CAIA			;NO
	TXO	T1,IC.SDI	;ASSUME "SINGLE-DIRECTORY"

	MOVE	T2,.I1DTY(IO)	;GET DEVTYP WORD
	TXNE	T2,TY.GEN	;WAS DEVICE SPECIFICATION GENERIC?
	TXO	T1,IC.GDV	;YES
	TXNE	T2,TY.SPL	;IS DEVICE "SPOOLED"
	TXO	T1,IC.SPL	;YES

;***	MOVE	T2,.I1LKP+.RBSTS(IO)  ;GET FILE STATUS FLAGS
;***	TXNE	T2,RP.DIR	;DIRECTORY FILE?
;***	TXO	T1,IC.DRF	;YES

	MOVEM	T1,.IODCH(IO)	;SET DEVICE/FILE CHARACTERISTICS
	JRST	.POPJ1##	;SUCCESSFUL RETURN (BY DEFINITION)
;SETUP ASCII NAME INFORMATION

FILRA:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
	XMOVEI	T1,FILOTO	;OUR STRING STUFFER
	PUSHJ	P,.XTYPO##	;SET OUR TYPE-OUT ADDRESS

;GENERATE NAME COMPONETS -- NODE NAME

FILRA3:	MOVE	T2,[POINT 7,.IOSND(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSND(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1NOD(IO)	;GET FILE NODE NAME
	SETZ	T2,		;OOPS - NO NODE NAME
	MOVEM	T2,.IOFND(IO)	;SET POINTER FOR NODE NAME
	PUSHJ	P,.TSIXN##	;TYPE NODE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- DEVICE NAME

FILRA4:	MOVE	T2,[POINT 7,.IOSDV(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSDV(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1DEV(IO)	;GET DEVICE NAME
	SKIPE	T1,.I1FLP+.FODEV(IO)  ;NONE, TRY THE FILOP. BLOCK
	CAIA			;GOT A DEVICE NAME
	SETZ	T2,		;OOPS - NO DEVICE NAME
	MOVEM	T2,.IOFDV(IO)	;SET POINTER FOR DEVICE NAME
	PUSHJ	P,.TSIXN##	;TYPE DEVICE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- DIRECTORY NAME

FILRA5:	MOVE	T2,[POINT 7,.IOSDR(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSDR(IO)	;ADDRESS OF RESULTANT STRING
	XMOVEI	T1,.I1LKP+.RBPPN(IO)  ;GET DIRECTORY NAME/POINTER
	SKIPN	(T1)		;GOT A DIRECTORY/POINTER?
	SETZ	T2,		;OOPS - NO DIRECTORY NAME
	MOVEM	T2,.IOFDR(IO)	;SET POINTER FOR DIRECTORY NAME
	PUSHJ	P,.TDIRB##	;TYPE DIRECTORY NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING
	MOVE	T1,[POINT 7,.IOSDR(IO)]  ;BYTE POINTER TO DIRECTORY STRING
	MOVE	T2,T1		;COPY
	IBP	T1		;SKIP THE LEADING "[" FROM .TDIRB
	CAIA			;ENTER LOOP
	IDPB	M0,T2		;STORE IT
	ILDB	M0,T1		;DIRECTORY CHARACTER
	JUMPN	M0,.-2		;LOOP FOR WHOLE STRING
	DPB	M0,T2		;KRUMP ON TRAILING "]" FROM .TDIRB

;GENERATE NAME COMPONETS -- FILE  NAME

FILRA6:	MOVE	T2,[POINT 7,.IOSNM(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSNM(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1LKP+.RBNAM(IO)  ;GET FILE NAME
	SETZ	T2,		;OOPS - BLANK NAME
	MOVEM	T2,.IOFNM(IO)	;SET POINTER FOR FILE NAME
	PUSHJ	P,.TSIXN##	;TYPE FILE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- FILE TYPE OR EXTENSION

FILRA7:	MOVE	T2,[POINT 7,.IOSEX(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSEX(IO)	;ADDRESS OF RESULTANT STRING
	HLLZ	T1,.I1LKP+.RBEXT(IO)  ;GET FILE TYPE
	CAIN	T1,0		;ANYTHING THERE?
	SETZ	T2,		;OOPS - NO FILE TYPE
	MOVEM	T2,.IOFEX(IO)	;SET POINTER FOR FILE TYPE (EXTENSION)
	PUSHJ	P,.TSIXN##	;TYPE FILE TYPE
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- FILE GENERATION

FILRA8:	MOVE	T2,[POINT 7,.IOSGN(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOSGN(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1GEN(IO)	;IS THERE A GENERATION NUMBER?
	SETZ	T2,		;OOPS - NO GENERATION
	MOVEM	T2,.IOFGN(IO)	;SET POINTER TO GENERATION STRING
	PUSHJ	P,.TDECW##	;LIST DECIMAL GENERATION
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;***	MOVE	T2,[POINT 7,.IOSOW(IO)]  ;HOW TO STUFF THE STRING
;***	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
;***	XMOVEI	T2,.IOSOW(IO)	;ADDRESS OF RESULTANT STRING
;***	MOVEM	T2,.IOFOW(IO)	;SET POINTER FOR FILE OWNER
;***	MOVE	T1,.I1LKP+.RBPPN(IO)  ;GET DIRECTORY NAME/POINTER
;***	TLNN	T1,-1		;PPN OR ADDRESS OF PATH BLOCK?
;***	MOVE	T1,.PTPPN(T1)	;PATH BLOCK, GET PPN
;***;***	BUG: BOTH ROUTINES WILL ENCLOSE THE "OWNER" WITH "[]"
;***	JUMPLE	T1,[PUSHJ P,.TSIXN##	;TYPE OUT NAME FORMAT PPN
;***		JRST	.+2]	;CONTINUE
;***	PUSHJ	P,.TPPNW##	;TYPE OUT PPN FORMAT
;***	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;***	MOVE	T2,[POINT 7,.IOSAU(IO)]  ;HOW TO STUFF THE STRING
;***	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
;***	XMOVEI	T2,.IOSAU(IO)	;ADDRESS OF RESULTANT STRING
;***	MOVEM	T2,.IOFAU(IO)	;SET POINTER FOR FILE AUTHOR
;***	MOVE	T1,.I1LKP+.RBAUT(IO)  ;GET FILE AUTHOR
;***;***	BUG: BOTH ROUTINES WILL ENCLOSE THE "OWNER" WITH "[]"
;***	JUMPLE	T1,[PUSHJ P,.TSIXN##	;TYPE OUT NAME FORMAT PPN
;***		JRST	.+2]	;CONTINUE
;***	PUSHJ	P,.TPPNW##	;TYPE OUT PPN FORMAT
;***	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;ALL DONE

	JRST	.POPJ1##	;RETURN
;SETUP TERTIARY ASCII NAME INFORMATION (AS FOR RENAME)

FILTA:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
	XMOVEI	T1,FILOTO	;OUR STRING STUFFER
	PUSHJ	P,.XTYPO##	;SET OUR TYPE-OUT ADDRESS

;GENERATE NAME COMPONETS -- NODE NAME

FILTA3:	MOVE	T2,[POINT 7,.IOS3D(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3D(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1NOD(IO)	;GET FILE NODE NAME
	SETZ	T2,		;OOPS - NO NODE NAME
	MOVEM	T2,.IOF3D(IO)	;SET POINTER FOR NODE NAME
	PUSHJ	P,.TSIXN##	;TYPE NODE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- DEVICE NAME

FILTA4:	MOVE	T2,[POINT 7,.IOS3V(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3V(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1FL3+.FODEV(IO)  ;GET THE DEVICE NAME
	SETZ	T2,		;OOPS - NO DEVICE NAME
	MOVEM	T2,.IOF3V(IO)	;SET POINTER FOR DEVICE NAME
	PUSHJ	P,.TSIXN##	;TYPE DEVICE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- DIRECTORY NAME

FILTA5:	MOVE	T2,[POINT 7,.IOS3R(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3R(IO)	;ADDRESS OF RESULTANT STRING
	XMOVEI	T1,.I1LK3+.RBPPN(IO)  ;GET DIRECTORY NAME/POINTER
	SKIPN	(T1)		;GOT A DIRECTORY/POINTER?
	SETZ	T2,		;OOPS - NO DIRECTORY NAME
	MOVEM	T2,.IOF3R(IO)	;SET POINTER FOR DIRECTORY NAME
	PUSHJ	P,.TDIRB##	;TYPE DIRECTORY NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING
	MOVE	T1,[POINT 7,.IOS3R(IO)]  ;BYTE POINTER TO DIRECTORY STRING
	MOVE	T2,T1		;COPY
	IBP	T1		;SKIP THE LEADING "[" FROM .TDIRB
	CAIA			;ENTER LOOP
	IDPB	M0,T2		;STORE IT
	ILDB	M0,T1		;DIRECTORY CHARACTER
	JUMPN	M0,.-2		;LOOP FOR WHOLE STRING
	DPB	M0,T2		;KRUMP ON TRAILING "]" FROM .TDIRB

;GENERATE NAME COMPONETS -- FILE  NAME

FILTA6:	MOVE	T2,[POINT 7,.IOS3M(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3M(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1LK3+.RBNAM(IO)  ;GET FILE NAME
	SETZ	T2,		;OOPS - BLANK NAME
	MOVEM	T2,.IOF3M(IO)	;SET POINTER FOR FILE NAME
	PUSHJ	P,.TSIXN##	;TYPE FILE NAME
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- FILE TYPE OR EXTENSION

FILTA7:	MOVE	T2,[POINT 7,.IOS3X(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3X(IO)	;ADDRESS OF RESULTANT STRING
	HLLZ	T1,.I1LK3+.RBEXT(IO)  ;GET FILE TYPE
	CAIN	T1,0		;ANYTHING THERE?
	SETZ	T2,		;OOPS - NO FILE TYPE
	MOVEM	T2,.IOF3X(IO)	;SET POINTER FOR FILE TYPE (EXTENSION)
	PUSHJ	P,.TSIXN##	;TYPE FILE TYPE
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;GENERATE NAME COMPONETS -- FILE GENERATION

FILTA8:	MOVE	T2,[POINT 7,.IOS3N(IO)]  ;HOW TO STUFF THE STRING
	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
	XMOVEI	T2,.IOS3N(IO)	;ADDRESS OF RESULTANT STRING
	SKIPN	T1,.I1GE3(IO)	;IS THERE A GENERATION NUMBER?
	SETZ	T2,		;OOPS - NO GENERATION
	MOVEM	T2,.IOF3N(IO)	;SET POINTER TO GENERATION STRING
	PUSHJ	P,.TDECW##	;LIST DECIMAL GENERATION
	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;***	MOVE	T2,[POINT 7,.IOS3W(IO)]  ;HOW TO STUFF THE STRING
;***	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
;***	XMOVEI	T2,.IOS3W(IO)	;ADDRESS OF RESULTANT STRING
;***	MOVEM	T2,.IOF3W(IO)	;SET POINTER FOR FILE OWNER
;***	MOVE	T1,.I1LK3+.RBPPN(IO)  ;GET DIRECTORY NAME/POINTER
;***	TLNN	T1,-1		;PPN OR ADDRESS OF PATH BLOCK?
;***	MOVE	T1,.PTPPN(T1)	;PATH BLOCK, GET PPN
;***;***	BUG: BOTH ROUTINES WILL ENCLOSE THE "OWNER" WITH "[]"
;***	JUMPLE	T1,[PUSHJ P,.TSIXN##	;TYPE OUT NAME FORMAT PPN
;***		JRST	.+2]	;CONTINUE
;***	PUSHJ	P,.TPPNW##	;TYPE OUT PPN FORMAT
;***	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;***	MOVE	T2,[POINT 7,.IOS3U(IO)]  ;HOW TO STUFF THE STRING
;***	MOVEM	T2,.IOXTO(IO)	;SET FOR FILOTO TO FIND
;***	XMOVEI	T2,.IOS3U(IO)	;ADDRESS OF RESULTANT STRING
;***	MOVEM	T2,.IOF3U(IO)	;SET POINTER FOR FILE AUTHOR
;***	MOVE	T1,.I1LK3+.RBAUT(IO)  ;GET FILE AUTHOR
;***;***	BUG: BOTH ROUTINES WILL ENCLOSE THE "OWNER" WITH "[]"
;***	JUMPLE	T1,[PUSHJ P,.TSIXN##	;TYPE OUT NAME FORMAT PPN
;***		JRST	.+2]	;CONTINUE
;***	PUSHJ	P,.TPPNW##	;TYPE OUT PPN FORMAT
;***	PUSHJ	P,FILOTZ	;TERMINATE THE STRING

;ALL DONE

	JRST	.POPJ1##	;RETURN
;FILRA/FILTA HELPER FOR TEXT OUTPUT

FILOTO:	IDPB	T1,.IOXTO(IO)	;STASH CHARACTER AWAY IN STRING
	POPJ	P,		;AND THAT'S IT

FILOTZ:	MOVE	T2,.IOXTO(IO)	;FETCH COPY OF BYTE STUFFER
	SETZ	T1,		;A NULL TO TERMINATE THE STRING
	IDPB	T1,T2		;CLEAR END OF STRING
	TLNE	T2,760000	;TO WORD BOUNDRY?
	JRST	.-2		;NOT YET
	POPJ	P,		;RETURN READY FOR MORE FILOTO
;RETURN FILE PARAMETERS, IF NEEDED

FILPA:	MOVE	T1,.I1LKP+.RBSIZ(IO)  ;FILE LENGTH (-10 WORDS)
	MOVEM	T1,.IOLNW(IO)	;SET IN THE CDB
	MOVEI	T2,^D36		;BITS PER WORD
	IDIV	T2,.IOFSZ(IO)	;LOGICAL DATA BYTES PER WORD
	IMULI	T1,(T2)		;DATA BYTES WRITTEN IN FILE
	MOVEM	T1,.IOLNB(IO)	;SET IN THE CDB
	MOVE	T1,.I1LKP+.RBALC(IO)  ;FILE ALLOCATION (-10 BLOCKS)
	IMULI	T1,^D128	;FILE ALLOCATION (-10 WORDS)
	MOVEM	T1,.IOALW(IO)	;SET IN THE CDB
	IMULI	T1,(T2)		;FILE ALLOCATION IN BYTES
	MOVEM	T1,.IOALB(IO)	;SET IN THE CDB
	DMOVE	T1,.IOLNW(IO)	;WRITTEN LENGTH (WORDS, BYTES)
	DMOVEM	T1,.IOLSW(IO)	;SET LAST WRITTEN WORD, BYTE

;SETUP DATE/TIME WORDS

	LDB	T1,[POINTR .I1LKP+.RBPRV(IO),RB.CRT]  ;CREATION TIME
	IMULI	T1,^D60*^D1000	;(.CNVDT WANTS MILLISECONDS)
	LDB	T2,[POINTR .I1LKP+.RBPRV(IO),RB.CRD]  ;CREATION DATE
	LDB	T4,[POINTR .I1LKP+.RBEXT(IO),RB.CRX]  ;CREATION DATE EXTENSION
	DPB	T4,[POINT 3,T2,23]  ;REST OF CREATION DATE
	PUSHJ	P,.CNVDT##	;CONVERT TO UNIVERSAL DATE/TIME
	MOVEM	T1,.IOCDT(IO)	;SET DATA CREATION DATE/TIME
	SETZ	T1,		;NO ACCESS TIME KNOWN
	LDB	T2,[POINTR .I1LKP+.RBEXT(IO),RB.ACD]  ;ACCESS DATE (NO TIME)
	PUSHJ	P,.CNVDT##	;CONVERT TO UNIVERSAL DATE/TIME
	MOVEM	T1,.IOADT(IO)	;SET IN THE CDB
	MOVE	T1,.I1LKP+.RBTIM(IO)  ;INTERNAL (PHYSICAL) CREATION DATE/TIME
	MOVEM	T1,.IOPDT(IO)	;SET IN THE CDB
	MOVE	T1,.I1LKP+.RBDED(IO)  ;FILE EXPIRATION DATE/TIME
	TLNN	T1,700000	;*** LOOK REASONABLE?
	SETZ	T1,		;*** NO (WATCH OUT FOR BOGUS VALUES)
	MOVEM	T1,.IOEDT(IO)	;SET EXPIRATION DATE/TIME IN THE CDB
	MOVE	T1,.I1LKP+.RBIDT(IO)  ;INCREMENTAL BACKUP DATE/TIME
	TLNN	T1,700000	;*** LOOK REASONABLE?
	SETZ	T1,		;*** NO (WATCH OUT FOR BOGUS VALUES)
	MOVEM	T1,.IOBDT(IO)	;SET BACKUP DATE/TIME IN THE CDB
	SETZM	.IOUDT(IO)	;WE DON'T KNOW ABOUT UPDATE TIME(S)

;NOW THE PROTECTION (EASY CASE)

	LDB	T1,[POINTR .I1LKP+.RBPRV(IO),RB.PRV]  ;GET THE PROTECTION
	HRROM	T1,.IOPRT(IO)	;SET FILE PROTECTION VALUE

;ALL DONE

	JRST	.POPJ1##	;SUCCESSFUL RETURN
	SUBTTL	File-level remote support routines

;DPINI  --  INITIALIZE DAP COMMUNICATIONS LINK
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<NOD>
;	PUSHJ	P,DPINI
;	 error return
;	normal return
;
;Where <NOD> is the 6-bit format node name with whom file access is desired.
;
;On error return M0 contains a reason why communications could not be
;established.
;
;On normal return, a communications channel has been established with a
;FAL process on the specified node, and configuration messages have been
;exchanged. The link is ready for normal DAP protocol interchange.
;
;Uses T1 - T4.

	ENTRY	.DPINI
	INTERN	DPINI0,DPINI1

.DPINI:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPINI0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S HERE
DPINI1:	PUSHJ	P,TSAV14##	;SAVE THE NODE NAME INPUT

;ENSURE THAT WE HAVE A CLEAN "CHANNEL"

	MOVE	T2,.IOCCF(IO)	;GET CONTROL FLAGS
	TXNN	T2,IO.OPN	;A FILE KNOWN TO BE OPEN?
	SKIPE	.IOCHN(IO)	;OR A CHANNEL LEFT LYING AROUND?
	JRST	[PUSHJ	P,IOABO1	;STOMP ON THE FILE
		 JFCL			;HMMM
		JRST	.+1]		;CONTINUE

DPINI2:	SKIPN	.IONCH(IO)	;HAVE A NETWORK CHANNEL?
	JRST	DPINI4		;NO, ALL SET TO OPEN NEW NETWORK LINK
	SETZ	T2,T3		;NO OPTIONAL DISCONNECT DATA
	PUSHJ	P,NTZAP1##	;YES, STOMP ON IT TOO
	 JFCL			;HMMM

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;SETUP SOURCE AND DESTINATION PROCESS DESCRIPTOR BLOCKS

DPINI4:	SETZM	.IONSF(IO)	;CLAIM NO SPECIAL SOURCE FORMAT//OBJECT
	SETZM	.IONSP(IO)	;NOR PPN
	SETZM	.IONSN(IO)	;NOR NAME
	MOVX	T3,<0,,345>	;*** GENERIC INNOCUOUS UNPRIVILEGED JUNK
	MOVEM	T3,.IONSF(IO)	;*** VAX WANTS THIS NON-ZERO,
				;*** BUT OTHERWISE IGNORES IT!

REPEAT 0,<			;*** WHEN NO LONGER WORRIED ABOUT THE DCP

	MOVX	T3,<2,,0>	;FORMAT 2 (= [P,PN]NAME)
	MOVEM	T3,.IONSF(IO)	;TELL "FAL" WE ARE IDENTIFYING OURSELF
	MOVE	T3,.MYPPN##	;MY PPN
	MOVEM	T3,.IONSP(IO)	;SET IN SOURCE PPN WORD
	MOVE	P3,[^D12,,.IONSN]  ;<N8P> "BYTE POINTER" FOR N6XO8
	DMOVE	T2,.MYNAM##	;FETCH USER NAME
	PUSHJ	P,.N6XO8##	;CONVERT SIXBIT (2-WORDS) TO EIGHTBIT
	 POPJ	P,		;DIED
	HRLI	P3,4		;MAXIMUM STRING BLOCK LENGTH
	MOVSM	P3,.IONSN(IO)	;SET NAME BLOCK
> ;END REPEAT 0

;AND NOW THE DESTINATION PROCESS DESCRIPTOR BLOCK

NIPOBJ:!MOVX	T3,<0,,21>	;GENERIC DAP FAL SPECIFICATION
	MOVEM	T3,.IONDF(IO)	;SELECT DESTINATION TASK
	SETZM	.IONDP(IO)	;NO SPECIAL PPN
	SETZM	.IONDN(IO)	;NOR NAME

;SET USER FOR "ON BEHALF OF" REMOTE STUFF

	SKIPN	P1,.IOFSC(IO)	;ADDRESS OF FILE SPEC BLOCK
	STOPCD	<No "current" FSB in DPINI>
	XMOVEI	T2,.FXUID(P1)	;/USERID USERID STRING (IF ANY)
	MOVE	P3,[^D39,,.IONUS]  ;8-BIT FORMAT POINTER
	PUSHJ	P,.N7TO8##	;CONVERT FROM ASCIZ TO 8-BIT
	 STOPCD	</USERID string too long in DPINI>
	HRLZM	P3,.IONUS(IO)	;SET BYTE COUNT
	XMOVEI	T2,.FXUAC(P1)	;/USERID ACCOUNT STRING (IF ANY)
	MOVE	P3,[^D39,,.IONAC]  ;8-BIT FORMAT POINTER
	PUSHJ	P,.N7TO8##	;CONVERT FROM ASCIZ TO 8-BIT
	 STOPCD	</UACCOUNT string too long in DPINI>
	HRLZM	P3,.IONAC(IO)	;SET BYTE COUNT
	XMOVEI	T2,.FXUPW(P1)	;/USERID PASSWORD STRING (IF ANY)
	MOVE	P3,[^D39,,.IONPW]  ;8-BIT FORMAT POINTER
	PUSHJ	P,.N7TO8##	;CONVERT FROM ASCIZ TO 8-BIT
	 STOPCD	</UPASSWORD string too long in DPINI>
	HRLZM	P3,.IONPW(IO)	;SET BYTE COUNT

;EXPLICIT USERID STUFF SET, CALL "NODE DEFAULTER" FOR LAST DITCH ATTEMPT

	MOVE	T1,IO		;SET CDB ADDRESS IN T1 FOR GLOBAL CALL
	PUSHJ	P,.DFLND##	;SEE IF ANYONE WANTS TO CHANGE/ADD ETC.
	 POPJ	P,		;??? OH WELL, PASS THE EXCEPTION/ERROR ON

;TRY TO CONNECT TO A REMOTE FAL

	MOVEI	T4,5		;*** THE RETRY COUNTER
	MOVEM	T4,-T4(P)	;*** SAVE IT SOMEWHERE
DPINI6:	MOVE	T2,-T2(P)	;RESTORE THE NODE NAME
	PUSHJ	P,NTNIA1##	;ISSUE CONNECT REQUEST
	 JRST	DPINIE		;FAILED - CHECK IT OUT

;WAIT FOR COMPLETION

	PUSHJ	P,NTNCW1##	;WAIT FOR CONNECT CONFIRM
	 JRST	DPINIE		;FAILED - CHECK IT OUT

;NETWORK LINK ESTABLISHED AND ACTIVE, INITIALIZE BUFFERS ETC

	PUSHJ	P,NTINI1##	;INITIALIZE NETWORK BUFFERS, ETC.
	 POPJ	P,		;SIGH

;EXCHANGE CONFIGURATION MESSAGES

	PJRST	DPICM1		;SETUP AND EXCHANGE CONFIG MESSAGES



;ERROR ESTABLISHING LINK TO REMOTE

DPINIE:	CAIE	M0,$EFURO	;UNKNOWN OBJECT?
	CAIN	M0,$EFOTB	;OBJECT BUSY?
	JRST	DPINIW		;YES, WAIT AND TRY AGAIN
	POPJ	P,		;NO OTHERS, DIE

DPINIW:	SOSG	-T4(P)		;READY TO GIVE UP YET?
	POPJ	P,		;YES, CONNECT INIT FAILED
	MOVEI	T1,1		;NO, PERSIST A FEW TIMES
	SLEEP	T1,		;GIVE THE OTHER SIDE A CHANCE
	JRST	DPINI6		;TO RECYCLE ITSELF, AND TRY AGAIN
;DPICM - SETUP AND EXCHANGE CONFIGURATION MESSAGES
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPICM
;	 error return
;	normal return
;
;Where <CDB> is the address of the networked I/O "channel" data block.
;
;DPICM first sets up a configuration message reflecting this library's
;capabilities, then calls DPXCM to actually exchange configuration messages
;with the remote FAL process.
;
;On error return communications could not successfully be established with
;the remote FAL process, an error code will be returned in M0.
;
;On normal return a communications channel has been established with a
;remote FAL process, and configuration messages have been exchanged. The
;link is ready for DAP-level traffic.
;
;Uses T1 - T4.

	ENTRY	.DPICM
	INTERN	DPICM0,	DPICM1

.DPICM:	PUSHJ	P,.SACIO##	;SETUP CDB INDEX
DPICM0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPICM1:	MOVDII	T3,MSZ,0	;NO EXPLICIT DAP MESSAGE SIZE LIMIT

;**************************************************************
;
;The DAP message size value was a real trouble spot in the early NFT-10
;development period - different systems behaved quite differently with
;respect to my sending a "0" (= unlimited buffering capability) for
;the "MSZ" field. Some early VAXen, lacking a specific limit, just kept
;accumulating the data until they choked on it. At least one flavor of
;TOPS-20 sent me ^D256, but would refuse to talk to me in return if I
;sent it the same value! Empirically I have determined that ^O1040
;(enough for 512 byte-records plus DAP overhead) seemed to keep everyone
;happy.
;
;If you ever come across a system that for no apparent reason simply
;refuses to cooperate, try patching DPICM1 to set 1040 into the MSZ
;field.
;
;**************************************************************

	MOVDM	T3,MSZ		;SET CONFIGURATION MESSAGE SIZE FIELD
	MOVDII	T3,OST,$DVOT1	;WE ARE A TOPS-10 SYSTEM
	MOVDM	T3,OST		;SET CONFIGURATION OPERATING SYSTEM FIELD
	MOVDII	T3,FST,$DVFT1	;FILE SYSTEM IS ALSO TOPS-10
	MOVDM	T3,FST		;SET CONFIGURATION FILE SYSTEM FIELD
	MOVDII	T3,DVR,7	;DAP MAJOR VERSION
	MOVDM	T3,DVR		;SET IN CDB
	MOVDII	T3,DVE,0	;DAP "ECO" (OR MINOR) VERSION
	MOVDM	T3,DVE		;SET IN CDB
	MOVDII	T3,DVU,0	;DAP "USER" OR "CUSTOMER" VERSION
	MOVDM	T3,DVU		;SET IN CDB
	MOVDII	T3,DVS,0	;DAP "SOFTWARE" VERSION
	MOVDM	T3,DVS		;SET IN CDB
	MOVDII	T3,DVT,0	;DAP "USER SOFTWARE" VERSION
	MOVDM	T3,DVT		;SET IN CDB
	MOVDII	T3,CNF,<SFO,SFT,APN,CMF,BLR,C25,FCK,AEA,DIR,TEA,PEA,SPO,CMS,FDE,BTC,WST,REN,WLD,CGN,NAM,DSG,CFA,CFD,CFP,CFN,N3D,CRA,CRD,CRP>
	MOVDM	T3,CNF		;SET CONFIGURATION CAPABILITIES FLAGS FIELD
	PJRST	DPXCM1		;NOW EXCHANGE THE CONFIGURATION MESSAGES
;DPXCM - EXCHANGE DAP CONFIGURATION MESSAGES
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPXCM
;	 error return
;	normal return
;
;Where <CDB> is the address of the associated I/O channel data block
;which has been linked to a remote FAL process.
;
;DPXCM will first transmit a configuration message to the remote FAL
;process (the caller is responsible for correctly setting the initial
;configuration message to be sent to the remote), then receive the
;remote FAL's configuration message.
;
;On error return M0 will contain an error code indicating why the DAP
;configuration messages could not be exchanged (network died, etc.).
;
;On normal return the DAP link is ready for normal DAP-level traffic.
;
;Uses T1 - T4.

	ENTRY	.DPXCM
	INTERN	DPXCM0,DPXCM1

.DPXCM:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPXCM0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPXCM1:	MOVD1	T2,MSZ		;GET MAXIMUM MESSAGE SIZE WE SET
	MOVEM	T2,.I1DSZ(IO)	;STASH IT FOR AWHILE
	MOVEI	T2,$DHCFG	;MESSAGE TYPE = CONFIGURATION
	PUSHJ	P,XDDAP1##	;GENERATE CONFIGURATION MESSAGE
	 JRST	[CAIN	M0,$EINMP	;GOT INPUT MESSAGE PENDING?
		JRST	.+1		;YES, PROCESS IT
		JRST	DPXCME]		;NO, NETWORK ERROR (CHECK FOR $EINLA)
				; (NOTE THAT XDDAP WILL AUTOMATICALLY FLUSH
				;  CONFIGURATION MESSAGES).

;CLEAN UP IN CASE A RESTART OR THE LIKE

	SETZM	.IOBZD(IO)	;START OFF WITH A FRESH SLATE
	MOVSI	T1,.IOBZD(IO)	;START OF DAP TO-BE-ZEROED AREA
	HRRI	T1,.IOBZD+1(IO)	;BLT POINTER TO
	BLT	T1,.IOEZD-1(IO)	;CLEAR DAP TO-BE-CLEARED AREA

;NOW RECEIVE THE REMOTE'S INITIAL RESPONSE

	PUSHJ	P,RDMSG1##	;GET MESSAGE TYPE
	 JRST	DPXCME		;NET DIED - CHECK FOR $EINLA
	JSP	T4,.CDISP##	;DISPATCH ON DAP MESSAGE TYPE
		DPXCM3,,$DHCFG	;CONFIGURATION
		DPXCM7,,$DHSTS	;STATUS (??)
		0		;THAT'S IT
	STOPCD	<First received DAP message not configuration>
;HERE TO READ REMOTE'S DAP CONFIGURATION MESSAGE

DPXCM3:	PUSHJ	P,RDDAP1##	;READ IN THE REMOTE'S CONFIGURATION MESSAGE
	 POPJ	P,		;DUH?
	MOVD1	T1,DVR		;DAP PROTOCOL VERSION
	MOVD1	T2,DVE		;DAP PROTOCOL ECO LEVEL
	LSH	T1,^D9		;POSITION AND
	IOR	T1,T2		;CONCOCT A "VERSION" VALUE
	MOVEM	T1,.IODPV(IO)	;SET DAP "VERSION"
	MOVX	T1,IO.DAP	;WE ARE TALKING DAPESE
	IORM	T1,.IOCCF(IO)	;SET APPROPRIATE FLAGS IN CHANNEL CONTROL
	SKIPN	T1,.I1DSZ(IO)	;GET THE MAXIMA WE GENERATED
	MOVEI	T1,777777	;UNLIMITED
	SKIPN	T2,.IDMSZ(IO)	;GET REMOTE'S MAXIMA
	MOVEI	T2,777777	;UNLIMITED
	CAMLE	T1,T2		;IS OUR LIMIT BIGGER THAN THE REMOTE?
	MOVE	T1,T2		;YES, USE REMOTE'S MESSAGE LIMIT THEN
	CAMLE	T1,.IONLB(IO)	;BIGGER THAN OUR NSP SEGMENT SIZE?
	MOVE	T1,.IONLB(IO)	;YES, LIMIT IT TO FIT NSP BUFFER
	MOVEM	T1,.IONLM(IO)	;SET OUTPUT NETWORK MESSAGE-LIMITED SIZE
	SUB	T1,.IONLB(IO)	;GET DIFFERENCE IN MESSAGE AND BUFFER SIZE
	ADDM	T1,.IONOC(IO)	;ADJUST OUTPUT BYTES REMAINING

;ALL SET

	JRST	.POPJ1##	;CONNECTED WITH A REMOTE FAL



;HERE WHEN LINK STARTS WITH A STATUS RATHER THAN CONFIGURATION

DPXCM7:	PUSHJ	P,RDSTS0##	;READ AND TRANSLATE THE STATUS
	 JFCL			;HO HUM
	MOVE	P1,M0		;PRESERVE ERROR CODE
	PUSHJ	P,NTZAP0##	;ABORT THE LINK
	 JFCL
	MOVE	M0,P1		;REPOSITION ERROR CODE
	POPJ	P,		;PROPAGATE ERROR



;HERE ON I/O ERROR - CHECK FOR $EINLA (SORT OF A DEFERRED ERROR FROM
;TSK. - IT HAS NO WAY OF REJECTING THE (E.G.,) PPN/PASSWORD UNTIL *AFTER*
;THE LINK IS ACTUALLY CONNECTED, SO MUST LOOK FOR A IMMEDIATE "DISCONNECT"
;AT THIS STAGE - SEE NARXS IN NN.MAC)

DPXCME:	CAIE	M0,$EINLA	;GENERIC "LINK ABORTED" ERROR?
	POPJ	P,		;BACK TO CALLER
	MOVE	T2,.IOER2(IO)	;YES, RETRIEVE REAL ERROR HERE
	MOVEI	T4,[$EFURO,,$EIURO	;NO SUCH OBJECT
		$EFRES,,$EIRES		;NO RESOURCES/TOO MANY CONNECTS
		$EFOTB,,$EIOTB		;OBJECT BUSY
		$EFLNS,,$EILNS		;NODE SHUTTING DOWN
		$EFABM,,$EIABM		;ABORTED BY DIALOG
		$EFUID,,$EIUID		;INVALID USERID/PASSWORD
		$EFUAC,,$EIUAC		;INVALID USER ACCOUNT STRING
		$EFIMG,,$EIIMG		;ERROR IN IMAGE FIELD/STRING
		0]			;END OF TABLE
	PUSHJ	P,.CFIND##	;READILY-TRANSLATABLE ERROR?
	 POPJ	P,		;NO, PROPAGATE $EINLA
	MOVE	M0,T1		;YES, PICK TRANSLATION THEN
	POPJ	P,		;AND USE IT (PRETTIER MESSAGE)
;DPRNM  --  PROCESS RECEIVED NAME STRING
;CALL IS:
;
;	PUSHJ	P,DPRNM
;	 error return
;	normal return
;
;On error return the received resultant name string could not be parsed.
;M0 has an error code.
;
;On successful return the name string has been parsed and the appropriate
;file information fields set.
;
;Uses T1 - T4.

	ENTRY	.DPRNM
	INTERN	DPRNM0,	DPRNM1

.DPRNM:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPRNM0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPRNM1:	MOVD1	T1,FST		;GET REMOTE FILE SYSTEM TYPE
	CAIE	T1,$DVF32	;TALKING TO A VAX (RMS-32)?
	CAIN	T1,$DVF11	;OR TO A RSTS/E (ALSO GETS RSX/ETC)?
	CAIA			;YES
	JRST	DPRNM4		;NO

;VAXII LIKE TO PREFIX THEIR RESULTANT FILE NAME STUFF WITH AN "_" CHARACTER.
;NEEDLESS TO SAY, THIS DOES NOT PLEASE SCAN! THEREFORE OVERWRITE THE "_"
;WITH A SPACE AND HOPE FOR THE BEST.
;
;I SEE RSTS/E ALSO DOES THIS. I WONDER WHY? IT SEEMS LIKE SOMEONE IS GOING
;TO AN AWFUL LOT OF TROUBLE TO MAKE THINGS COMPLICATED . . .

	MOVE	T1,[POINT 7,.IDNMS(IO)]  ;PROTOTYPE NAME STRING BYTE POINTER
	MOVEI	T3," "		;INNOCUOUS ASCII CHARACTER
	ILDB	T2,T1		;FIRST BYTE OF NAME STRING
	CAIE	T2,"_"		;IS VAX DOING ITS THING?
	JRST	DPRNM2		;NO (OR AT LEAST NOT HERE)
	DPB	T3,T1		;YES, UNDO IT!
	ILDB	T2,T1		;SECOND (!!) BYTE OF NAME STRING
	CAIN	T2,"_"		;IS VAX DOING EVEN MORE OF ITS THING?
	DPB	T3,T1		;YES, UNDO IT!
DPRNM2:	MOVEI	T3,"-"		;MORE-PALATABLE CHARACTER THAN "_"
DPRNM3:	ILDB	T2,T1		;NEXT NAME CHARACTER
	CAIN	T2,"_"		;UNDESIRABLE CHARACTER?
	DPB	T3,1		;YES, CLEAN IT UP
	JUMPN	T2,DPRNM3	;CHECK THE ENTIRE STRING

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

DPRNM4:	PUSHJ	P,DPGAAT	;GET FILE SPEC CONTROL FLAGS IN T2
	TXNN	T2,FX.SGN	;DOES GENERATION GET SEMICOLON?
	JRST	DPRN00		;NO
	MOVD	T1,NTY		;YES (E.G., RSX, VAX), GET NAME TYPE
	TFNN	T1,NFN		;IF A FILE NAME TYPE
	TFNE	T1,NFS		;OR A FILE SPEC TYPE
	CAIA			;THEN KRUMP ON SEMICOLONS
	JRST	DPRN00		;ELSE LEAVE THE NAME MESSAGE ALONE

;HERE FOR (E.G.) RSX/VAX FILE NAME - CONVERT ";" PRECEDING GENERATION INTO
;OUR "." FOR THE FILE SPEC PARSER.

DPRNM5:	MOVE	T1,[POINT 7,.IDNMS(IO)]  ;POINTER TO NAME STRING
	MOVEI	T3,"."		;PREFERED GENERATION CHARACTER
DPRNM6:	ILDB	T2,T1		;GET FIRST CHARACTER, ENTER LOOP
	CAIN	T2,";"		;SEMICOLON PRECEDING GENERATION?
	DPB	T3,T1		;YES, CONVERT ;GENERATION TO .GENERATION
	JUMPN	T2,DPRNM6	;LOOP FOR WHOLE NAME STRING

;HERE TO DISPATCH TO NAME-TYPE-SPECIFIC HANDLING

DPRN00:	MOVD	T1,NTY		;GET NAME TYPE FIELD
	TFNE	T1,NVN		;VOLUME NAME?
	JRST	DPRN20		;YES
	TFNE	T1,NDN		;DIRECTORY NAME?
	JRST	DPRN30		;YES
	TFNE	T1,NFN		;FILE NAME (INC EXTENSION AND GENERATION)?
	JRST	DPRN51		;YES
	TFNE	T1,NFS		;FULL FILE SPECIFICATION?
	JRST	DPRN50		;YES
	STOPCD	<Unknown NAME message type in DPRNM>

;HERE ON VOLUME NAME

DPRN20:	PUSHJ	P,DPRNN1	;GOBBLE UP THE NAME
	 STOPCD	<DPRNN1 failed reading device NAME message in DPRN20>
DPRN24:	SKIPN	T1,F.BLK##+.FXDEV  ;PICK UP THE DEVICE NAME
	SKIPE	T1,F.BLK##+.FXNAM  ;NO ":", USE UNQUALIFIED NAME INSTEAD
	CAIA			;GOT A NAME, USE IT
	STOPCD	<Null returned device name in DPRN20>
	MOVEM	T1,.I1FLP+.FODEV(IO)  ;SET FOR SCWLD, IOQAT, ETC.
	MOVEM	T1,.I1DEV(IO)	;PUT IN "REAL" DEVICE NAME FIELD
	MOVEM	T1,.I1PT2(IO)	;ALSO PUT IT IN RETURNED PATH BLOCK
	SKIPN	T1,F.BLK##+.FSDEV  ;PICK UP THE DEVICE STRING
	MOVE	T1,F.BLK##+.FSNAM  ;USE UNQUALIFIED NAME INSTEAD
	XMOVEI	T2,.IOSDV(IO)	;ADDRESS OF DEVICE STRING NAME BLOCK
	MOVEM	T2,.IOFDV(IO)	;SET POINTER TO DEVICE STRING
	PUSHJ	P,DPRNS1	;AND COPY THE STRING OVER
	 JFCL			;JUNK
	JRST	.POPJ1##	;BACK FOR MORE
;DIRECTORY NAME

DPRN30:	MOVE	T4,[POINT 7,.IDNMS(IO)]  ;POINTER TO ASCIZ STRING
	ILDB	T1,T4		;GET THE FIRST CHARACTER
	CAIE	T1,"["		;A DIRECTORY DELIMITER?
	CAIN	T1,"<"		;(> MATCH ANGLE BRACKETS)
	JRST	DPRN33		;YES, ALL SET
	SKIPA	T2,["["]	;NO, PRESET NORMAL DELIMITER
DPRN31:	ILDB	T1,T4		;NEXT CHARACTER OF NAME
	DPB	T2,T4		;PUT BACK ONE
	SKIPE	T2,T1		;END OF STRING YET?
	JRST	DPRN31		;NO
DPRN33:	PUSHJ	P,DPRNN1	;NOW READ IN THE STRING
	 STOPCD	<DPRNN1 failed reading directory NAME message in DPRN33>
DPRN34:	MOVE	T3,[-.FXLND,,F.BLK##+.FXDIR]  ;RESULTANT DIRECTORY
	MOVEI	T4,.I1PT2+.PTPPN(IO)  ;WHERE TO PUT IT
DPRN36:	MOVE	T1,(T3)		;GET NEXT DIRECTORY NAME
	MOVEM	T1,(T4)		;STASH IT IN PATH BLOCK
	ADDI	T3,1		;FIRST HALF OF BIWORD
	ADDI	T4,1		;NEXT PATH BLOCK WORD
	AOBJN	T3,DPRN36	;LOOP FOR ENTIRE PATH
	MOVEI	T1,.I1PT2(IO)	;ADDRESS OF RESULTANT PATH BLOCK
	MOVEM	T1,.I1LKP+.RBPPN(IO)  ;SET FOR SCWLD, IOWAT, ETC.
	MOVE	T1,F.BLK##+.FSDIR  ;ADDRESS OF DIRECTORY STRING
	XMOVEI	T2,.IOSDR(IO)	;ADDRESS OF DIRECTORY STRING NAME BLOCK
	MOVEM	T2,.IOFDR(IO)	;SET POINTER TO DIRECTORY STRING
	PUSHJ	P,DPRNS1	;AND COPY THE STRING OVER
	 JFCL			;JUNK
	SKIPE	F.BLK##+.FXDEV	;GOT A DEVICE?
	JRST	DPRN24		;YES, GO SET IT UP TOO
	JRST	.POPJ1##	;BACK FOR MORE
;HERE FOR FULL FILE SPECIFICATION

DPRN50:

;HERE FOR FILE NAME

DPRN51:	PUSHJ	P,DPRNN1	;READ IN THE FILE NAME/SPEC
	 STOPCD	<DPRNN1 failed reading file name/spec NAME message in DPRN51>
DPRN54:	SKIPE	T1,F.BLK##+.FXDEV  ;GET DEVICE IF ANY
	JRST	[MOVEM	T1,.I1FLP+.FODEV(IO)  ;SET FOR SCWLD, IOQAT, ETC.
		MOVEM	T1,.I1DEV(IO)	;PUT IN "REAL" DEVICE NAME FIELD
		MOVEM	T1,.I1PT2(IO)	;ALSO PUT IT IN RETURNED PATH BLOCK
		JRST	.+1]		;CONTINUE
	MOVE	T1,F.BLK##+.FXNAM  ;GET FILE NAME IF ANY
	MOVEM	T1,.I1LKP+.RBNAM(IO)  ;AND SET FOR SCWLD, IOQAT, ETC.
	MOVE	T1,F.BLK##+.FSNAM  ;GET FILE NAME STRING, IF ANY
	XMOVEI	T2,.IOSNM(IO)	;ADDRESS OF NAME STRING NAME BLOCK
	MOVEM	T2,.IOFNM(IO)	;SET POINTER TO NAME STRING
	PUSHJ	P,DPRNS1	;AND COPY THE STRING OVER
	 JFCL			;JUNK
	MOVE	T1,F.BLK##+.FXEXT  ;GET FILE TYPE IF ANY
	HLLZM	T1,.I1LKP+.RBEXT(IO)  ;AND SET FOR SCWLD, IOQAT, ETC.
	MOVE	T1,F.BLK##+.FSEXT  ;GET FILE EXTENSION STRING
	XMOVEI	T2,.IOSEX(IO)	;ADDRESS OF EXTENSION STRING NAME BLOCK
	MOVEM	T2,.IOFEX(IO)	;SET POINTER TO EXTENSION STRING
	PUSHJ	P,DPRNS1	;AND COPY THE STRING OVER
	 JFCL			;JUNK
	MOVE	T1,F.BLK##+.FXGEN  ;GET FILE GENERATION IF ANY
	MOVEM	T1,.I1GEN(IO)	;AND SET FOR INTERESTED PARTIES
	MOVE	T1,F.BLK##+.FSGEN  ;GET GENERATION NAME STRING
	XMOVEI	T2,.IOSGN(IO)	;ADDRESS OF GENERATION STRING NAME BLOCK
	MOVEM	T2,.IOFGN(IO)	;SET POINTER TO GENERATION STRING
	PUSHJ	P,DPRNS1	;AND COPY THE STRING OVER
	 JFCL			;JUNK
	SKIPE	F.BLK##+.FXDIR	;GOT A DIRECTORY?
	JRST	DPRN34		;YES, GO SET IT UP TOO
	SKIPE	F.BLK##+.FXDEV	;GOT A DEVICE?
	JRST	DPRN24		;YES, GO SET IT UP TOO
	JRST	.POPJ1##	;BACK FOR MORE
;HELPER FOR DPRNM NAME PROCESSING

	ENTRY	.DPRNN
	INTERN	DPRNN0,	DPRNN1

.DPRNN:	PUSHJ	P,.SACIO	;SET UP I/O CONTEXT
DPRNN0:
DPRNN1:	PUSHJ	P,.SAVE4##	;SCAN'S CH AND NM ARE OUR P3 AND P4 !!!
	SETZM	.IOXTO(IO)	;USE IOXTO AS COUNTER/FLAG HERE
	XMOVEI	T1,DPRNNI	;OUR VERY OWN INPUT TYPER
	PUSHJ	P,.XTYPI##	;INTERCEPT "COMMAND" INPUT
	XMOVEI	T1,DPRNNO	;OUR VERY OWN OUTPUT TYPER
	PUSHJ	P,.XTYPO##	;INTERCEPT "COMMAND" OUTPUT
	MOVE	T1,[POINT 7,[0]];A DUMMY STRING
	MOVEM	T1,.IOXTI(IO)	;SET IN CASE .CLRTI NEEDS SOMETHING
	PUSHJ	P,.CLRTI##	;SETUP LOWLEVEL COMMAND INPUT ROUTINES
	MOVE	T1,[POINT 7,.IDNMS(IO)]  ;BYTE POINTER TO NAME STRING
	MOVEM	T1,.IOXTI(IO)	;SET FOR DPRNNI

;NOW PARSE THE NAME MESSAGE

	PUSHJ	P,.FILSP##	;LET SCAN DO ITS THING
	 JRST	DPRNN7		;ERROR - DIE
	SKIPE	.IOXTO(IO)	;IT BETTER NOT HAVE COMPLAINED
	JRST	DPRNN7		;OOPS - SHOULDN'T HAPPEN
	LDB	T1,[POINTR F.BLK##+.FXMOD,FX.TRM]  ;GET FILE SPEC TERMINATOR
	CAIN	T1,.FXTRZ	;BETTER HAVE BEEN "NORMAL" TERMINATION
	JUMPL	CH,.POPJ1##	;IF READ TO "EOL" THEN COMPLETED SAFELY
DPRNN7:	STOPCD	<Error in parsing received NAME message in DPRNN>



;THE "COMMAND" INPUT ROUTINE

DPRNNI:	ILDB	CH,.IOXTI(IO)	;GET NEXT CHARACTER FROM NAME STRING
	JUMPN	CH,.POPJ##	;RETURN IT
	MOVEI	CH,.CHLFD	;END OF STRING, RETURN EOL TO SCAN
	POPJ	P,		; . . .


;THE "COMMAND" OUTPUT ROUTINE

DPRNNO:	OUTCHR	T1		;OH WELL
	AOS	.IOXTO(IO)	;COUNT OCCURENCES
	POPJ	P,		;RETURN TO SCAN
;DPRNS - HELPER FOR DPRNM

DPRNS1:	CAIE	T1,0		;DO WE HAVE A SOURCE STRING?
	HRLI	T1,(POINT 7,)	;YES, MAKE IT A BYTE POINTER
	HRLI	T2,(POINT 7,)	;AND A DESTINATION BYTE POINTER TOO
DPRNS3:	ILDB	M0,T1		;READ ANOTHER BYTE
DPRNS4:	IDPB	M0,T2		;AND STUFF IT AWAY
	JUMPN	M0,DPRNS3	;LOOP FOR WHOLE STRING
	TLNE	T2,760000	;WORD ZERO'ED OUT YET?
	JRST	DPRNS4		;NO
	JRST	.POPJ1		;YES
;DPIAF  --  SETUP FILE INFORMATION FROM DAP ATTRIBUTES
;CALL IS:
;
;	PUSHJ	P,DPIAF
;	 error return
;	normal return
;
;On error return a serious incompatibility exists and could not be
;converted.
;
;On normal return, all possible DAP attributes have been converted and
;set into the corresponding file information fields within the CDB.
;
;Uses T1 - T4.

	ENTRY	.DPIAF
	INTERN	DPIAF0,	DPIAF1

.DPIAF:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPIAF0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPIAF1:	SKIPE	.IDNMS(IO)	;WAS SOME SORT OF NAME MESSAGE SEEN?
	JRST	DPIA10		;YES, ASSUME FILE NAME STUFF OK FOR IOQAT

;NO NAME MESSAGES SEEN FOR THIS FILE, ASSUME A NON-WILDCARDED FILE ACCESS
;AND SET UP THE OPEN/LOOKUP/PATH BLOCKS FROM THE ORIGINAL FILE SPECIFICATION
;(ISN'T DAP WONDERFUL?)

DPIA00:	MOVE	T1,.IOFSY(IO)	;ADDRESS OF FILE SPEC BLOCK FROM LKWLN
	MOVE	P1,.FXNOD(T1)	;PRESERVE COPY OF NODE NAME
	SETZM	.FXNOD(T1)	;DON'T OFFEND .STOPB
	MOVEI	T2,.I1OPN(IO)	;ADDRESS OF RESULTANT OPEN BLOCK
	MOVEI	T3,.I1LKP(IO)	;ADDRESS OF RESULTANT LOOKUP BLOCK
	MOVEI	T4,.I1PT2(IO)	;ADDRESS OF RESULTANT PATH BLOCK
	PUSHJ	P,.STOPB##	;FAKE OUT THE FILE RESULTS
	 STOPCD	<STOPB failed in DPIA00: wildcarded spec but no names returned>
	MOVE	T1,.IOFSY(IO)	;RESTORE ADDRESS OF FILE SPEC BLOCK
	MOVEM	P1,.FXNOD(T1)	;RESTORE ACTUAL NODE SPECIFICATION
;	MOVEM	P1,.I1NOD(IO)	;ALSO SET NODE WORD (SHOULD ALREADY BE SET)
	MOVE	T1,.I1FLP+.FODEV(IO)  ;GET SPECIFIED DEVICE
	MOVEM	T1,.I1DEV(IO)	;FOR THOSE WHO CARE
	SETZM	.I1GEN(IO)	;AND IGNORE THE GENERATION NUMBER FOR NOW
	AOS	.CTDVS##	;COUNT AS AT LEAST ONE DEVICE SEEN
	AOS	.CTDRS##	; AND A DIRECTORY SEEN
	AOS	.CTDRF##	;  AND A DIRECTORY FOUND
	AOS	.CTFLS##	;   AND A FILE SEEN
	AOS	.CTFLF##	;    AND A FILE FOUND TOO

;HANDLE THE MAIN ATTRIBUTES
;
;WHEN SETTING THE FILE-LEVEL PARAMETERS FROM THE CORRESPONDING DAP-LEVEL
;DATA THE MENU IS IGNORED. THIS IS SINCE MULTIPLE FILES CAN COME FROM A
;SINGLE "FILE ACCESS". DAP DOES NOT REQUIRE THAT ALL ATTRIBUTES BE SENT
;WITH EVERY FILE - THE FIELD(S) MAY BE LEFT BLANK (UNTRANSMITTED, AND SO
;NOT IN THE MENU) IF UNCHANGED. THEREFORE WE BLINDLY TRUST THE VARIOUS
;FIELDS, ASSUMING THAT FIRST DPWAF SET THEM UP RIGHT, AND THEY WILL BE
;OVERRIDDEN BY THE REMOTE FAL IF NEEDED.

DPIA10:	MOVE	P4,.IOIOM(IO)	;CARRY I/O MODE CONTROL IN P4
	MOVD	P1,M02		;MAIN ATTRIBUTES MENU
	PUSHJ	P,DPID00	;TRY TO MAKE SENSE OF DTY/RFM/RAT/BSZ
	 STOPCD			;CAN'T GET HERE
	SKIPN	.IOBSZ(IO)	;ENSURE A DATA BYTE SIZE IS AVAILABLE
	STOPCD	<No logical data bytesize in DPIA10>
	MOVEI	T4,^D36		;-10 WORD SIZE
	IDIV	T4,.IOBSZ(IO)	;T4:=BYTES PER -10 WORD
	LDB	P3,[POINTR .IOIOC(IO),IC.RFM]  ;GET RECORD FORMAT
	CAIN	P3,.ICRF3	;36PACK'ED PDP-10 WORDS?
	MOVEI	T4,^D09		;YES, SCREWS UP ALL THE CALCULATIONS
	MOVD1	T1,BLS		;GET RETURNED DAP DATA BLOCK SIZE
	MOVEM	T1,.IOBLS(IO)	;AND SET FILE PARAMETER
	CAIN	P3,.ICRF3	;36PACK'ED PDP-10 WORDS?
	LSH	T1,1		;YES, SCREWS UP ALL THE CALCULATIONS
	IDIV	T1,T4		;T1:=BLOCKSIZE (36-BIT WORDS)
	CAIE	T2,0		;EXACT FIT?
	ADDI	T1,1		;NO, NEED ONE MORE [PARTIAL] WORD
	MOVEM	T1,.IOBLW(IO)	;SET THAT FILE PARAMETER TOO
	MOVD1	T1,MRS		;GET RETURNED DAP RECORDSIZE
	MOVEM	T1,.IORSZ(IO)	;AND SET FILE PARAMETER
	MOVD1	T1,ALQ		;GET RETURNED DAP ALLOCATION ("BLOCKS")
	IMUL	T1,.IOBLS(IO)	;CONVERT TO DATA BYTES
	MOVEM	T1,.IOALB(IO)	;SET ALLOCATION IN BYTES FILE PARAMETER
	MOVEM	T1,.IOLNB(IO)	; FAKE LENGTH FROM ALQ UNTIL TOLD OTHERWISE
	CAIN	P3,.ICRF3	;36PACK'ED PDP-10 WORDS?
	LSH	T1,1		;YES, SCREWS UP ALL THE CALCULATIONS
	IDIV	T1,T4		;T1:=FILE ALLOCATION IN -10 WORDS
	CAIE	T2,0		;EXACT FIT?
	ADDI	T1,1		;NO, NEED ONE MORE [PARTIAL] WORD
	MOVEM	T1,.IOALW(IO)	;SET ALLOCATION IN WORDS FILE PARAMETER
	MOVE	T2,T1		;FILE ALLOCATION IN WORDS
	ADDI	T2,177		;ROUND UP AND
	LSH	T2,-7		;TRUNCATE TO 128(10) WORD BLOCKS
	MOVEM	T2,.I1LKP+.RBALC(IO)  ;SET IN LOOKUP BLOCK TOO
DPIA16:	TMNN	P1,EBK		;GOT EXPLICIT END OF FILE BLOCK NUMBER?
	JRST	DPIA19		;NO, FAKE FROM ALLOCATION THEN
	MOVD1	T1,EBK		;END OF FILE BLOCK NUMBER
	IMUL	T1,.IOBLS(IO)	;T1:=END OF FILE IN BYTES (UPPER LIMIT)
	MOVE	T2,.IOBLS(IO)	;DATA BYTES PER BLOCK
	MOVD1	T3,FFB		;FIRST FREE BYTE IN END OF FILE BLOCK
	TMNN	P1,FFB		;DO WE KNOW WHERE FFB IS?
	TDZA	T2,T2		;NO
	SUB	T2,T3		;YES, T2:=UNUSED BYTES WITHIN EBK
	SUB	T1,T2		;T1:=FILE LENGTH IN DATA BYTES
	MOVEM	T1,.IOLNB(IO)	;SET LENGTH IN BYTES FILE PARAMETER
	CAIN	P3,.ICRF3	;36PACK'ED PDP-10 WORDS?
	LSH	T1,1		;YES, SCREWS UP ALL THE CALCULATIONS
	IDIV	T1,T4		;T1:=FILE LENGTH IN -10 WORDS
	CAIE	T2,0		;ANY TRAILING BYTES?
	ADDI	T1,1		;ALLOW FOR TRAILING PARTIAL WORD
DPIA19:	MOVEM	T1,.IOLNW(IO)	;SET FILE LENGTH IN WORDS PARAMETER
	MOVEM	T1,.I1LKP+.RBSIZ(IO)  ;ALSO SIMULATE LOOKUP BLOCK

;FAKE UP AN I/O MODE FOR THE LOOKUP BLOCK

DPIA20:	SETO	T1,		;NOTHING YET
	MOVE	T2,.IOBSZ(IO)	;LOGICAL DATA BYTESIZE
	MOVD	T3,DTY		;DATA TYPE FIELD
	TFNN	T3,<ASC,IMG>	;ENSURE SOMETHING WE KNOW ABOUT
	STOPCD	<No (or unknown) data type in DPIA20>
	TFNE	T3,ASC		;ASCII DATA?
	MOVEI	T1,.ICASC	;YES, ASCII FILE DATA MODE
	TFNE	T3,IMG		;IMAGE (BINARY) DATA?
	MOVEI	T1,.ICBIN	;YES, BINARY FILE DATA MODE

;***	CAIN	T1,.ICBIN	;BINARY OR OTHERWISE?
;***	CAIE	T2,^D08		;BINARY, 8-BIT BYTES OR OTHERWISE?
;***	CAIA			;OTHERWISE
;***	MOVEI	T1,.ICBYT	;8-BIT BINARY, CALL IT BYTE MODE
;***
;***	Don't use .ICBYT as a default, since on a COPY-type command
;***	from remote (-11, etc.) to local disk the output file ends up
;***	being defaulted to .IOBYT, which wins "Ill data mode" . . .
;***	so just leave it as /BINARY/BYTE:8, use "BYTE" as special mode.

	DPB	T1,[POINTR .IOIOC(IO),IC.MOD]  ;SET FILE DATA MODE
	MOVE	T1,MOMDTB(T1)	;CONVERT TO TOPS-10 I/O DATA MODE
	DPB	T1,[POINTR .I1LKP+.RBPRV(IO),RB.MOD]  ;FAKE OUT I/O MODE

;AND THE ASSOCIATED RECORD-FORMAT AS APPROPRIATE

	MOVD	T2,DTY		;GET DATA TYPE
	TFNN	T2,IMG		;IMAGE (BINARY) DATA?
	TDZA	T1,T1		;NO, MUST BE CHARACTER (ASCII), BYTE MODE
	MOVD1	T1,RFM		;YES, GET REMOTE RECORD FORMAT FIELD
	LDB	T2,[POINTR .IOIOC(IO),IC.RFM]  ;GET SELECTED RFM
	TXNE	P4,IM.CMD	;DOES .IOIOC MODE OVERRIDE?
	JRST	[CAIN	T2,.ICRF3	;/RECFORMAT:36PACK ?
		CAIE	T1,.ICRFV	;YES, THEN REMOTE MUST BE "VARIABLE"
		CAMN	T1,T2		;RESULTANT RFM WHAT WAS SPECIFIED?
		JRST	DPIA30		;YES, RFM IS OK
		STOPCD	<Resultant RFM different from specified RFM>]
	CAIE	T2,.ICRF3	;LEAVE "FAKED-OUT" IF /RECFORMAT:36PACK
	DPB	T1,[POINTR .IOIOC(IO),IC.RFM]  ;SET RECORD FORMAT FIELD

;HANDLE FILE/DEVICE CHARACTERISTICS

DPIA30:	PUSHJ	P,DPDCH1	;CONVERT DAP DCH INTO I/O CDB DCH
	 JFCL			;HUM
	MOVEM	T2,.IODCH(IO)	;SET FILE/DEVICE CHARACTERISTICS

;HANDLE DATE/TIME ATTRIBUTES

DPIA60:	MOVD	P1,M13		;DATE/TIME ATTRIBUTES MENU
	TMNN	P1,CDT		;GOT A CREATION DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVD1	T1,CDT		;GET RETURNED LOGICAL CREATION DATE/TIME
	MOVEM	T1,.IOCDT(IO)	;SET FILE PARAMETER
	SKIPE	T2,T1		;ANYTHING THERE TO CONVERT?
	PUSHJ	P,.CNTDT##	;SPLIT INTO DATE AND TIME
	DPB	T2,[POINTR .I1LKP+.RBPRV(IO),RB.CRD]  ;SET MOST OF DATE
	LDB	T2,[POINT 3,T2,23]  ;POSITION AND
	DPB	T2,[POINTR .I1LKP+.RBEXT(IO),RB.CRX]  ;SET REST OF DATE
	IDIVI	T1,^D60*^D1000	;CONVERT TO MINUTES
	DPB	T1,[POINTR .I1LKP+.RBPRV(IO),RB.CRT]  ;SET CREATION TIME
	TMNN	P1,UDT		;GOT UPDATE DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVD1	T1,UDT		;GET RETURNED UPDATE DATE/TIME
	MOVEM	T1,.IOUDT(IO)	;SET UPDATE TIME FILE PARAMETER
	TMNN	P1,EDT		;GOT EXPIRATION DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVD1	T1,EDT		;GET RETURNED EXPIRATION DATE/TIME
	MOVEM	T1,.IOEDT(IO)	;SET EXPIRATION DATE/TIME FILE PARAMETER
	MOVEM	T1,.I1LKP+.RBDED(IO)  ;SET TOPS-10 EXPIRATION DATE/TIME
	TMNN	P1,BDT		;GOT BACKUP DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVD1	T1,BDT		;GET RETURNED BACKUP DATE/TIME
	MOVEM	T1,.IOBDT(IO)	;SET BACKUP DATE/TIME FILE PARAMETER
	MOVEM	T1,.I1LKP+.RBIDT(IO)  ;SET INCREMENTAL BACKUP DATE/TIME
	TMNN	P1,PDT		;GOT A PHYSICAL DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVD1	T1,PDT		;GET PHYSICAL MEDIA CREATION DATE/TIME
	MOVEM	T1,.IOPDT(IO)	;SET PHYSICAL CREATION FILE PARAMETER
	MOVEM	T1,.I1LKP+.RBTIM(IO)  ;SET TOPS-10 PHYSICAL MEDIA TIME
	TMNN	P1,ADT		;GOT ACCESS DATE/TIME?
	TDZA	T1,T1		;NO, BLANK THE FIELD
	MOVEM	T1,.IOADT(IO)	;SET ACCESS TIME FILE PARAMETER
	CAIE	T1,0		;ANYTHING THERE TO CONVERT?
	PUSHJ	P,.CNTDT##	;SPLIT INTO DATE AND TIME
	DPB	T1,[POINTR .I1LKP+.RBEXT(IO),RB.ACD]  ;SET ACCESS DATE

;HANDLE PROTECTION ATTRIBUTES
;
;DPIA ASSUMES THAT THE PROTECTION FIELDS ARE ALL ONE WORD LONG. AS THIS
;IS NOT REALLY GUARANTEED, CAUSE ASSEMBLY ERROR IF IT EVER CHANGES

	IFN	$DLPSY-1,<PRINTX ?PSY field not one word long in DPIA70>
	IFN	$DLPOW-1,<PRINTX ?POW field not one word long in DPIA70>
	IFN	$DLPGR-1,<PRINTX ?PGR field not one word long in DPIA70>
	IFN	$DLPWL-1,<PRINTX ?PWL field not one word long in DPIA70>

DPIA70:	MOVD	P1,M14		;PROTECTION ATTRIBUTES MENU
	SETZ	T2,		;DEFAULT FOR INPUT
	MOVD	T1,PWL		;GET RETURNED "WORLD" PROTECTION
	TMNE	P1,PWL		;GOT A "WORLD" PROTECTION?
	PUSHJ	P,DPFPXL	;TRANSLATE INTO TOPS-10 LEVEL-D DISK PROTECTION
DPIA72:	LSHC	T2,-3		;SAVE VALUE SO FAR
	SETZ	T2,		;DEFAULT FOR INPUT
	MOVD	T1,PGR		;GET RETURNED "GROUP" PROTECTION
	TMNE	P1,PGR		;GOT A "GROUP" PROTECTION?
	PUSHJ	P,DPFPXL	;TRANSLATE INTO TOPS-10 LEVEL-D DISK PROTECTION
DPIA73:	LSHC	T2,-3		;ACCUMULATE THIS "GROUP" FIELD TOO
	SETZ	T2,		;DEFAULT FOR INPUT
	MOVD	T1,POW		;GET RETURNED "OWNER" PROTECTION
	TMNE	P1,POW		;GOT "OWNER" PROTECTION?
	PUSHJ	P,DPFPXO	;TRANSLATE INTO TOPS-10 LEVEL-D DISK PROTECTION
DPIA74:	LSHC	T2,6		;T2:=NINE-BIT TOPS-10 LEVEL-D DISK PROTECTION
	ANDI	T2,777		;REDUCE TO KNOWN SIZE
	DPB	T2,[POINTR .I1LKP+.RBPRV(IO),RB.PRV]  ;SET FILE PROTECTION
	HRROM	T2,.IOPRT(IO)	;SET IN FILE PARAMETERS BLOCK TOO
	TMNN	P1,<PWL,PGR,POW>;GOT A VIABLE PROTECTION CODE?
	SETZM	.IOPRT(IO)	;NO, NOT REALLY

DPIA99:	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPID - HELPER TO DPIAF TO TRY TO OUTGUESS DAP/FAL

DPID00:	MOVD	T1,DTY		;GET DAP DATA TYPE
	TFNE	T1,EBC		;EBCDIC?
	STOPCD	<EBCDIC returned data type in DPID00>
	TFNE	T1,<ASC,IMG>	;EITHER ASCII OR BINARY?
	JRST	DPID30		;YES, DATA TYPE ALL SET
	JUMPE	T1,DPID10	;ANYTHING TO GUESS FROM HERE?
	TFNE	T1,<EXE,PRV>	;IF EXECUTABLE AND/OR PRIVILEGED CODE
	JRST	DPID27		;THEN BINARY DATA TYPE
DPID10:	MOVD1	T2,BSZ		;GET DAP DATA BYTE SIZE
	MOVD	T3,RAT		;DAP RECORD ATTRIBUTES
	MOVD1	T4,RFM		;DAP RECORD FORMAT
	CAIE	T4,$DVFST	;IF ASCII STREAM RECORDS
	TFNE	T3,<FCC,ILC,PRN,EFC,CCC,LSA>  ;OR IF "CHAR"ISH ATTRIBUTES
	JRST	DPID28		;ASSUME ASCII CHARACTERS

;NO DATA TYPE, AND CAN'T GUESS FROM RECORD FORMAT/ATTRIBUTES

DPID20:	JUMPE	T2,DPID28	;NO IDEA WHATSOEVER IF NO BYTE SIZE
	CAIN	T2,^D08		;IF OTHER THAN 8-BITS
	JRST	DPID28		; (8-BITS, WILDLY GUESS ASCII)
DPID27:	TFO	T1,IMG		;NOT 8-BITS, ASSUME BINARY
	WARNCD	<Wildly guessing binary data>
	JRST	DPID29		;GO DO IT
DPID28:	TFO	T1,ASC		;ASSUME ASCII DATA
	WARNCD	<Wildly guessing ASCII data>
DPID29:	MOVDM	T1,DTY		;SET DEFAULTED DATA TYPE

;NOW TRY FOR A DATA BYTE SIZE

DPID30:	MOVD1	T2,BSZ		;DAP DATA BYTE SIZE
	MOVD1	T3,OST		;REMOTE OPERATING SYSTEM TYPE
	JUMPN	T2,DPID37	;GO WITH DAP'S FRAME SIZE IF PRESENT
	TFNN	T1,ASC		;LOOKING AT ASCII DATA TYPE?
	JRST	DPID33		;NO, MUST BE BINARY
	MOVE	T2,[^D07,,^D07]	;DEFAULT ASCII DATA AND FRAME SIZES
;***	This happens so often that I got tired of the message - am I the
;***	the only one who sends the byte size???? RSX, VAX, and even the
;***	-20 doesn't!!! Jeez!!!!!
;***	WARNCD	<Wildly defaulting ASCII data byte size in DPID30>
	JRST	DPID38		;GO SET FILE PARAMETERS

;BINARY DATA TYPE

DPID33:	CAIE	T3,$DVOT1	;IF EITHER TOPS-10
	CAIN	T3,$DVOT2	;OR TOPS-20
	SKIPA	T2,[^D36,,^D36]	;THEN BINARY DATA COMES IN 36-BIT BYTES
	MOVE	T2,[^D08,,^D08]	;ALL OTHERS TALK TWEENY WEENY 8-BIT BYTES
	WARNCD	<Wildly defaulting binary data byte size in DPID30>
	JRST	DPID38		;GO SET FILE PARAMETERS

DPID37:	TFNE	T1,ASC		;ASCII CHARACTER DATA?
	SKIPA	T2,[^D07,,^D07]	;YES, 7-BIT DATA THEN
	TSO	T2,T2		;NO, ARBITRARY DATA BYTE SIZE
DPID38:	LDB	T1,[POINTR .IOIOC(IO),IC.RFM]  ;GET RECORD FORMAT
	CAIN	T1,.ICRF3	;36PACK'ED PDP-10 WORDS?
	MOVE	T2,[^D36,,^D36]	;YES, THEN ULTIMATELY DEALING IN 36-BIT WORDS
	HLRZM	T2,.IOBSZ(IO)	;SET LOGICAL DATA BYTE SIZE
	HRRZM	T2,.IOFSZ(IO)	;SET PHYSICAL FRAME BYTE SIZE

;NOW CHECK OUT RECORD FORMAT

DPID40:	MOVD	T1,M02		;MAIN ATTRIBUTES MENU FIELD
	TMNE	T1,RFM		;GOT A RECORD FORMAT?
	JRST	DPID50		;YEAH, SET HERE
	MOVD1	T1,RFM		;GET CURRENT SOMETHING-OR-OTHER
	JUMPN	T1,DPID50	;IF SOMETHING THERE, JUST KEEP IT
	MOVEI	T1,$DVFFX	;NO, DEFAULT IS FIXED-LENGTH RECORDS
	MOVD1M	T1,RFM		; (TOPS-10/20 ALWAYS SENDS RFM FIELD)

DPID50:	JRST	.POPJ1##	;HO HUM
;DPWAF  --  SETUP DAP ATTRIBUTES FROM LOCAL FILE INFORMATION
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPWAF
;	 error return
;	normal return
;
;Where <CDB> is the address of the I/O channel data block controlling
;the DAP-level remote file access link.
;
;DPWAF sets the DAP area(s) from the file- and command-level parameters
;preparatory to a DAP "read" file access. All attributes fields will be
;set/defaulted/cleared as needed. Even fields not to be sent will be
;set/defaulted/cleared so that the field may be referenced (since DAP
;leaves this rather vague).
;
;On error return, a serious incompatibility exists and could not be
;converted (such as an item too big to fit in its DAP field).
;
;On normal return all possible file attributes have been DAPed and
;are ready to be sent to the remote. The file specification as set
;in .IOFSY has also been DAPed.
;
;Uses T1 - T4.

	ENTRY	.DPWAF
	INTERN	DPWAF0,	DPWAF1

.DPWAF:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPWAF0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPWAF1:

;SETUP ATTRIBUTES

DPWA00:	MOVE	P3,.IOFSC(IO)	;GET ADDRESS OF FILE SPEC BLOCK
	MOVE	P4,.IOIOM(IO)	;GET I/O MODE FLAGS

;MAIN ATTRIBUTES

DPWA10:	SETZB	P1,P2		;INITIAL MAIN ATTRIBUTES MENU
	LDB	T1,[POINTR .IOIOC(IO),IC.MOD]  ;GET FILE DATA MODE
	TXNE	P4,IM.CMD	;DOES .IOIOC MODE OVERRIDE?
	JRST	DPWA11		;YUP, USE .IOIOC AS IS
	MOVE	T3,.FXCTM(P3)	;GET CONTROL SWITCH MASKS
	TXNE	T3,FX.IOM	;WAS /IOMODE GIVEN?
	LDB	T2,[POINTR .FXCTL(P3),FX.IOM]  ;YES, GET /IOMODE VALUE
	TXNE	T3,FX.DAM	;WAS /DATAMODE GIVEN?
	LDB	T2,[POINTR .FXCTL(P3),FX.DAM]  ;YES, GET /DATAMODE VALUE
	TXNE	T3,FX.DAM!FX.IOM;IF USER SPECIFYING MODE
	MOVE	T1,MDMOTB(T2)	;THEN PICK UP INTERNAL FILE MODE TRANSLATION
	DPB	T1,[POINTR .IOIOC(IO),IC.MOD]  ;SET SELECTED FILE MODE
DPWA11:	JUMPN	T1,DPWA12	;IF SET, BELIEVE IT
	TXNN	P4,IM.SMD	;NO MODE GIVEN, ALLOWED TO SELECT FILE DEFAULT?
	JRST	DPWA12		;NO, DEFAULT TO ASCII
	SETZB	T3,T4		;INITIALLY 0
	MOVDM	T3,DTY		;NO DATA TYPE SET
	JRST	DPWA13		;LET REMOTE TELL US WHAT MODE TO USE

DPWA12:	SETZB	T3,T4		;INITIALLY 0
	CAIN	T1,.ICDEF	;DEFAULT (UNSPECIFIED)?
	TFO	T3,ASC		;YES, ASCII CHARACTER DATA
	CAIE	T1,.ICASC	;ASCII?
	CAIN	T1,.ICAS8	;ASCII 8-BIT?
	TFO	T3,ASC		;YES, ASCII CHARACTER DATA
;	CAIN	T1,.ICEBC	;EBCDIC?
;	TFO	T3,EBC		;YES, EBCDIC CHARACTER DATA
	CAIE	T1,.ICPIM	;PACKED IMAGE?
	CAIN	T1,.ICIMG	;REGULAR IMAGE?
	TFO	T3,IMG		;YES, IMAGE DATA
	CAIE	T1,.ICBYT	;8-BIT BYTE DATA?
	CAIN	T1,.ICBIN	;BINARY DATA?
	TFO	T3,IMG		;YES, IMAGE DATA
	TFNN	T3,<ASC,IMG>	;WAS SOME DATA TYPE SELECTED?
	STOPCD	<No (or unknown) file data type in DPWA11>
	MOVDM	T3,DTY		;SET DAP FILE DATA TYPE
	TMO	P1,DTY		;MARK DATA TYPE FIELD TO BE SENT

DPWA13:	MOVDII	T3,ORG,$DVOSQ	;ALL FILE ACCESSES ARE SEQUENTIAL
	MOVDM	T3,ORG		;SET MAIN ATTRIBUTES FILE ORGANIZATION
	TMO	P1,ORG		;MARK FILE ORGANIZATION TO BE SENT

DPWA15:	LDB	T3,[POINTR .IOIOC(IO),IC.RFM]  ;GET .IOIOC RECORD FORMAT
	TXNE	P4,IM.CMD	;DOES .IOIOC MODE OVERRIDE?
	JRST	DPWA16		;MUST USE .IOIOC AS IT STANDS
	LDB	T2,[POINTR .FXCTM(P3),FX.RFM]  ;/RECFORMAT MASK
	JUMPN	T2,[LDB	T3,[POINTR .FXCTL(P3),FX.RFM]  ;GET /RECFORMAT TYPE
		JRST	DPWA16]		;AND SET RECORD FORMAT FIELD
	TXNN	P4,IM.SMD	;NO /RECFORMAT, ALLOWED TO SELECT DEFAULT?
DPWA16:	TMO	P1,RFM		;SET RECORD FORMAT IN MENU
DPWA17:	DPB	T3,[POINTR .IOIOC(IO),IC.RFM]  ;SET .IOIOC RECORD FORMAT
	CAIN	T3,.ICRF3	;/RECFORMAT:36PACK?
	JRST	[MOVEI	T3,.ICIMG	;YES, IMAGE/BINARY DATA THEN
		DPB	T3,[POINTR .IOIOC(IO),IC.MOD]  ;SET NEW DATA MODE
		MOVD	T3,DTY		;RETRIEVE DATATYPE FIELD
		TFZ	T3,<ASC,EBC>	;NOT CHARACTER DATA
		TFO	T3,IMG		;BUT RATHER IMAGE DATA
		MOVDM	T3,DTY		;RESET DATATYPE FIELD
		TMO	P1,DTY		;MAKE SURE IT GOES OUT
		MOVEI	T3,.ICRFV	;TELL REMOTE "VARIABLE" RFM
		JRST	.+1]		;CONTINUE ONWARDS
	MOVD1M	T3,RFM		;SET MAIN ATTRIBUTES RECORD FORMAT

DPWA18:	SETZB	T3,T4		;NO-VALUE VALUE
	MOVE	T1,.IOIOC(IO)	;GET I/O CONTROL FLAGS
	TXNE	T1,IC.LSN	;WANT LINE-SEQUENCED ASCII?
	TFO	T3,LSA		;YES
	TXNE	T1,IC.MCY!IC.MEY;IS DATA MACY11-FORMATTED?
	TFO	T3,MCY		;YES
	MOVDM	T3,RAT		;SET MAIN ATTRIBUTES RECORD ATTRIBUTES
	TMO	P1,RAT		;SET RECORD ATTRIBUTES IN MENU

DPWA20:	SKIPG	T3,.FXBLS(P3)	;GOT A BLOCKSIZE SET?
	TDZA	T3,T3		;NO, NO VALUE
	TMO	P1,BLS		;YES, MARK BLOCKSIZE FIELD TO BE SENT
	MOVD1M	T3,BLS		;SET MAIN ATTRIBUTES BLOCKSIZE FIELD

DPWA21:	SKIPG	T3,.FXRSZ(P3)	;GOT A RECORDSIZE SET?
	TDZA	T3,T3		;NO, NO VALUE
	TMO	P1,MRS		;YES, MARK RECORDSIZE TO BE SENT
	MOVD1M	T3,MRS		;SET MAIN ATTRIBUTES RECORDSIZE FIELD

DPWA22:	SETZ	T3,		;NO BYTE SIZE(S) YET
	SKIPLE	.FXBSZ(P3)	;USER SPECIFY /BYTESIZE?
	HRL	T3,.FXBSZ(P3)	;YES
	SKIPLE	.FXFSZ(P3)	;USER SPECIFY /FRAMESIZE?
	HRR	T3,.FXFSZ(P3)	;YES
	MOVE	T4,.IOUBS(IO)	;OVERRIDING BYTE SIZE(S) - IF ANY
	TLNE	T4,-1		;OVERRIDING DATA BYTE SIZE?
	HLL	T3,T4		;YES
	TRNE	T4,-1		;OVERRIDING FRAME SIZE?
	HRR	T3,T4		;YES
	TLNE	T3,-1		;LACKING A DATA SIZE?
	TRNN	T3,-1		;OR A FRAME SIZE?
	TSO	T3,T3		;YES, DEFAULT ONE FROM THE OTHER
	LDB	T4,[POINTR .IOIOC(IO),IC.RFM]  ;GET RECORD FORMAT TYPE
	CAIN	T4,.ICRF3	;36PACK'ED PDP-10 WORDS?
	MOVE	T3,[^D36,,^D36]	;YES, THEN REALLY 36-BIT WORDS
	HLRZM	T3,.IOBSZ(IO)	;SET LOGICAL DATA BYTE SIZE
	HRRZM	T3,.IOFSZ(IO)	;SET PHYSICAL FRAME BYTE SIZE
	ANDI	T3,-1		;REDUCE TO JUST FRAME SIZE
	CAIN	T4,.ICRF3	;36PACK'ED WORDS?
	MOVEI	T3,^D08		;YES, FAKE OUT REMOTE WITH 8-BIT BYTES
	MOVD1M	T3,BSZ		;SET MAIN ATTRIBUTES BYTESIZE FIELD
	JUMPE	T3,DPWA25	;DON'T SEND A BLANK BYTE SIZE
	TMO	P1,BSZ		;MARK BYTESIZE FIELD TO BE SENT

DPWA25:	SETZB	T3,T4		;NO VALUE
	MOVDM	T3,ALQ		;NO ALLOCATION YET
	MOVDM	T3,FSZ		;NO FIXED HEADER SIZE
	MOVEM	T3,.IDRTS(IO)	;NO RUNTIME SYSTEM NAME
	MOVDM	T3,DEQ		;NO DEFAULT EXTENSION QUANTITY
	MOVDM	T3,FOP		;NO OPTIONS NEEDED ON READ ACCESS
	MOVDM	T3,DEV		;NO DEVICE CHARACTERISTICS YET
	MOVDM	T3,SDC		;NO SPOOLING CHARACTERISTICS EITHER
	MOVDM	T3,LRL		;NO LONGEST RECORD LENGTH
	MOVDM	T3,HBK		;NO HIGHEST BLOCK ALLOCATED YET
	MOVDM	T3,EBK		;NO END-OF-FILE BLOCK NUMBER YET
	MOVDM	T3,FFB		;NO FIRST FREE BYTE WITHIN EBK YET
	MOVDM	T3,SBN		;NO STARTING BLOCK NUMBER ON MEDIA YET
	MOVDM	P1,M02		;SET MAIN ATTRIBUTES MENU FIELD

;CLEAR OUT KEY DEFINITION ATTRIBUTES

DPWA40:	SETZB	T3,T4		;NO VALUE
	MOVDM	T3,M10		;NO FIELDS IN KEY DEFINITIONS

;CLEAR OUT ALLOCATION ATTRIBUTES

	MOVDM	T3,M11		;NO FIELDS IN ALLOCATION ATTRIBUTES
	MOVDM	T3,VOL		;NO RELATIVE VOLUME NUMBER
	MOVDM	T3,ALN		;NO ALIGNMENT OPTIONS
	MOVDM	T3,ALP		;NO ALLOCATION OPTIONS
	MOVDM	T3,LOC		;NO ALLOCATION LOCATION
	MOVDM	T3,AAL		;NO FILE ALLOCATION
	MOVDM	T3,AEQ		;NO DEFAULT EXTENSION QUANTITY

;CLEAR OUT SUMMARY ATTRIBUTES

	MOVDM	T3,M12		;NO FIELDS IN SUMMARY ATTRIBUTES

;CLEAR OUT DATE/TIME ATTRIBUTES

DPWA60:	SETZB	T3,T4		;NO VALUE
	MOVDM	T3,M13		;NO FIELDS IN DATE/TIME ATTRIBUTES
	MOVDM	T3,CDT		;NO CREATION DATE/TIME
	MOVDM	T3,UDT		;NO UPDATE DATE/TIME
	MOVDM	T3,EDT		;NO DELETE DATE/TIME
	MOVDM	T3,RVN		;NO REVISION NUMBER
	MOVDM	T3,BDT		;NO BACKUP DATE/TIME
	MOVDM	T3,PDT		;NO PHYSICAL DATE/TIME
	MOVDM	T3,ADT		;NO ACCESS DATE/TIME

;CLEAR OUT PROTECTION ATTRIBUTES

	MOVDM	T3,M14		;NO FIELDS IN PROTECTION ATTRIBUTES
	DMOVEM	T3,.IDPNM(IO)	;NO OWNER NAME STRING
	MOVDM	T3,PSY		;NO SYSTEM PROTECTION CODE YET
	MOVDM	T3,POW		;NO OWNER PROTECTION CODE YET
	MOVDM	T3,PGR		;NO GROUP PROTECTION CODE YET
	MOVDM	T3,PWL		;NO WORLD PROTECTION CODE YET

DPWA99:	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPWAA  --  SETUP DAP ACCESS MESSAGE FROM [WILD INPUT] FILE SPECIFICATION
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPWAA
;	 error return
;	normal return
;
;Where <CDB> is the address of the controlling I/O CDB.
;
;DPWAA will clear out the ACCESS message data area (excepting the function
;field which is left untouched), then fill in the file specification and
;password fields from the CDB's file spec block pointer (.IOFSC). If the
;remote supports file data checksumming then DPWAA will set the ACCESS
;options field to request same.
;
;On error return the ACCESS message could not be translated (the file
;specification was too big, etc.). An error code is in M0.
;
;On normal return the ACCESS message is ready to be sent (XDDAP), excepting
;the access function field, which must be correctly set by the caller.
;
;Uses T1 - T4.

	ENTRY	.DPWAA
	INTERN	DPWAA0,	DPWAA1

.DPWAA:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPWAA0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPWAA1:	XMOVEI	T1,DTYPO	;OUR OWN PRIVATE TYPER
	PUSHJ	P,.XTYPO##	;INTERCEPT AND SETUP TYPEOUT

;FIRST INITIALIZE THE ACCESS MESSAGE FIELDS

	SETZB	T1,T2		;INITIAL (NO VALUE) VALUE
	MOVDM	T1,AFC		;CLEAR ACCESS FUNCTION FIELD
	MOVDM	T1,FAC		;CLEAR ACCESS OPERATIONS
	MOVDM	T1,SHR		;CLEAR SHARED OPERATIONS
	MOVDM	T1,ADS		;CLEAR ACCESS DISPLAY

;TRY FOR FILE DATA CHECKSUMMING

	MOVDII	T1,AOP,ACK	;ASSUME (HOPE) REMOTE SUPPORTS CHECKSUMMING
	MOVD	T3,CNF		;REMOTE'S CONFIGURATION FLAGS
	TFNN	T3,FCK		;DOES REMOTE SUPPORT FILE DATA CHECKSUMMING?
	TFZ	T1,ACK		;NO (BOO HISS), THEN DON'T REQUEST IT
	MOVDM	T1,AOP		;SET BASIC ACCESS OPTIONS

;CONVERT FILE SPECIFICATION INTO DAP ACCESS MESSAGE FILE SPEC FIELD

	MOVE	P3,[$DBFIL,,.IDFIL]  ;7-BIT BYTE STUFFER PROTOTYPE
	PUSHJ	P,DP3P4		;SETUP .IODP3/.IODP4 AS COUNTER/POINTER
	 STOPCD	<DP3P4 failed in DPWAA1>
	SKIPN	T1,.IOFSY(IO)	;ADDRESS OF FILE SPEC BLOCK FROM LKWLN
	STOPCD	<No FSB for filespec in DPWAA>
	PUSHJ	P,DPGAAT	;GET FILE SPEC CONTROL FLAGS IN T2
	TXNE	T2,FX.UDV	;WANT TO DO A DEVICE FIELD?
	SKIPA	T3,.FSDEV(T1)	;YES, ADDRESS OF DEVICE SPECIFICATION STRING
	SETZ	T3,		;NO
	MOVEM	T3,.IOFDV(IO)	;SET DEVICE NAME IN CASE OF PREMATURE ERROR
	TXNE	T2,FX.UDR	;WANT TO DO A DIRECTORY FIELD?
	SKIPA	T3,.FSDIR(T1)	;YES, ADDRESS OF DIRECTORY SPECIFICATION STRING
	SETZ	T3,		;NO
	MOVEM	T3,.IOFDR(IO)	;SET DIRECTORY NAME IN CASE OF PREMATURE ERROR
	TXNE	T2,FX.UNM	;WANT TO DO A FILE NAME FIELD?
	SKIPA	T3,.FSNAM(T1)	;YES, ADDRESS OF FILE NAME SPECIFICATION STRING
	SETZ	T3,		;NO
	MOVEM	T3,.IOFNM(IO)	;SET FILE NAME IN CASE OF PREMATURE ERROR
	TXNE	T2,FX.UEX	;WANT TO DO A EXTENSION FIELD?
	SKIPA	T3,.FSEXT(T1)	;YES, ADDRESS OF EXTENSION SPECIFICATION STRING
	SETZ	T3,		;NO
	MOVEM	T3,.IOFEX(IO)	;SET EXTENSION NAME IN CASE OF PREMATURE ERROR
	TXNE	T2,FX.UGN	;WANT TO DO A GENERATION FIELD?
	SKIPA	T3,.FSGEN(T1)	;YES, ADDRESS OF GENERATION SPECIFICATION STRING
	SETZ	T3,		;NO
	MOVEM	T3,.IOFGN(IO)	;SET GENERATION NAME IN CASE OF PREMATURE ERROR
	PUSHJ	P,.TOFSB##	;SET THE FILE SPEC INTO THE DAP AREA
	DMOVE	P3,.IODP3(IO)	;GET TERMINAL BYTE COUNTER/POINTER
	AOBJP	P3,DPWAE1	;ERROR IF OVERFLOWED
	MOVEI	T1,0		;A NULL
	IDPB	T1,P4		;TO ASCIZIZE THE FILE SPEC STRING

;PASS ALONG ANY PASSWORD SUPPLIED

	MOVE	P3,[$DBPSW,,.IDPSW]  ;7-BIT BYTE STUFFER PROTOTYPE
	PUSHJ	P,DP3P4		;SETUP .IODP3/.IODP4 AS COUNTER/STUFFER
	 STOPCD	<DP3P4 failed in DPWAA1>
	SKIPN	T1,.IOFSC(IO)	;ADDRESS OF USER'S CURRENT FILE SPEC BLOCK
	STOPCD	<No FSB for password in DPWAA>
	ADDI	T1,.FXPSW	;POINT TO THE PASSWORD STRING
	PUSHJ	P,.TSTRG##	;PUT IT INTO THE PASSWORD FIELD
	DMOVE	P3,.IODP3(IO)	;GET TERMINAL BYTE COUNTER/POINTER
	AOBJP	P3,DPWAE2	;ERROR IF OVERFLOWED
	MOVEI	T1,0		;A NULL
	IDPB	T1,P4		;TO ASCIZIZE THE PASSWORD STRING

;ACCESS MESSAGE ALL SET AND READY

	JRST	.POPJ1##	;SUCCESSFUL RETURN


;FILE SPEC STRING TOO BIG

DPWAE1:	MOVEI	M0,$EFRFB	;FILE SPECIFICATION (STRING) TOO BIG
	POPJ	P,		;ERROR RETURN


;FILE PASSWORD STRING TOO BIG

DPWAE2:	MOVEI	M0,$EFRSB	;GENERIC STRING TOO BIG ERROR
	POPJ	P,		;ERROR RETURN
;DPWAN  --  SETUP DAP NAME MESSAGE FROM TERTIARY FILE SPECIFICATION
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPWAN
;	 error return
;	normal return
;
;Where <CDB> is the address of the controlling I/O CDB.
;
;DPWAN will set the NAME message fields with the tertiary file
;specification as used in a (e.g.) rename command.
;
;On error return the NAME message could not be translated (the file
;specification was too big, etc.). An error code is in M0.
;
;On normal return the NAME message is ready to be sent (XDDAP).
;
;Uses T1 - T4.

	ENTRY	.DPWAN
	INTERN	DPWAN0,	DPWAN1

.DPWAN:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPWAN0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPWAN1:	MOVEI	T1,DTYPO	;OUR OWN PRIVATE TYPER
	PUSHJ	P,.XTYPO##	;INTERCEPT AND SETUP TYPEOUT

;CONVERT FILE SPECIFICATION INTO DAP NAME MESSAGE FILE SPEC FIELD

	MOVE	P3,[$DBNMS,,.IDNMS]  ;7-BIT BYTE STUFFER PROTOTYPE
	PUSHJ	P,DP3P4		;SETUP .IODP3/.IODP4 AS COUNTER/POINTER
	 STOPCD	<DP3P4 failed in DPWAN1>
	MOVE	T1,.IOFS3(IO)	;ADDRESS OF TERTIARY FILE SPEC BLOCK
	PUSHJ	P,DPGAAT	;GET FILE SPEC CONTROL FLAGS IN T2
	TXZ	T2,FX.UFS	;DON'T WANT ANY SWITCHES HERE!
	PUSHJ	P,.TOFSB##	;SET THE FILE SPEC INTO THE DAP AREA
	DMOVE	P3,.IODP3(IO)	;GET TERMINAL BYTE COUNTER/POINTER
	AOBJP	P3,DPWAE1	;ERROR IF OVERFLOWED
	MOVEI	T1,0		;A NULL
	IDPB	T1,P4		;TO ASCIZIZE THE FILE SPEC STRING

;SET FULL FILE SPECIFICATION NAME TYPE

	MOVDII	T1,NTY,NFS	;FULL FILE SPECIFICATION
	MOVDM	T1,NTY		;SET NAME MESSAGE TYPE

;NAME MESSAGE ALL SET AND READY

	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPOAF  --  SETUP DAP ATTRIBUTES FROM LOCAL FILE INFORMATION
;CALL IS:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPOAF
;	 error return
;	normal return
;
;Where <CDB> is the address of the I/O channel data block controlling
;the DAP-level remote file access link.
;
;DPOAF sets the DAP area(s) from the file- and command-level parameters
;preparatory to a DAP "write" file access. All attributes fields will be
;set/defaulted/cleared as needed. Even fields not to be sent will be
;set/defaulted/cleared so that the field may be referenced (since DAP
;leaves this rather vague). Additionally the file and password fields
;of the access message are set, and all other access fields are cleared.
;
;On error return, a serious incompatibility exists and could not be
;converted (such as an item too big to fit in its DAP field).
;
;On normal return, all possible file attributes have been DAPed and
;are ready for whatever DAP attributes messages need to be sent.
;
;Uses T1 - T4.

	ENTRY	.DPOAF
	INTERN	DPOAF0,	DPOAF1

.DPOAF:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPOAF0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPOAF1:

;NOW SETUP ATTRIBUTES

DPOA00:	MOVE	P3,.IOIOC(IO)	;I/O CONTROL
	MOVE	P4,.IOIOM(IO)	;I/O MODE

;MAIN ATTRIBUTES FIELDS

DPOA10:	LDB	T1,[POINTR P3,IC.MOD]  ;PICKUP INTERNAL DATA MODE
	SETZB	T3,T4		;INITIALIZE FLAGS
	CAIE	T1,.ICDEF	;NONE (?) - DEFAULT IS ASCII
	CAIN	T1,.ICASC	;7-BIT ASCII?
	TFO	T3,ASC		;YES
	CAIN	T1,.ICAS8	;8-BIT ASCII?
	TFO	T3,ASC		;YES
	CAIN	T1,.ICEBC	;EBCDIC?
	TFO	T3,EBC		;YES
	CAIE	T1,.ICPIM	;PACKED IMAGE?
	CAIN	T1,.ICIMG	;OR NORMAL IMAGE?
	TFO	T3,IMG		;YES
	CAIE	T1,.ICBYT	;BYTE MODE?
	CAIN	T1,.ICBIN	;OR BINARY MODE?
	TFO	T3,IMG		;YES
	TFNN	T3,<ASC,EBC,IMG>;HAS A MODE BEEN SELECTED?
	STOPCD	<No (or unknown) DAP file data mode in DPOA10>
	TXNE	P4,IM.ZOD	;ZERO ON DELETE?
	TFO	T3,ZOD		;YES
	MOVDM	T3,DTY		;SET MAIN ATTR DATA TYPE FIELD

DPOA12:	MOVE	P1,.IOFSC(IO)	;ADDRESS OF FILE SPEC BLOCK
	SETZ	T2,		;NO BYTESIZES YET
	TFNE	T3,ASC		;ASCII DATA?
	MOVE	T2,[^D07,,^D08]	;YES, CHARACTER DATA ALWAYS 8-BIT FRAMES
	SKIPLE	.FXBSZ(P1)	;USER SUPPLY A DATA BYTESIZE?
	HRL	T2,.FXBSZ(P1)	;YES, USE IT
	SKIPLE	.FXFSZ(P1)	;USER SUPPLY A FRAME BYTESIZE?
	HRR	T2,.FXFSZ(P1)	;YES, USE IT
	TLNE	T2,-1		;GOT BOTH A DATA
	TRNN	T2,-1		;AND A FRAME SIZE?
	TSO	T2,T2		;NO, DEFAULT ONE FROM THE OTHER
	TLNN	T2,-1		;GOT A DATA BYTESIZE?
	HLL	T2,.IODBS(IO)	;NO, PICK UP PROGRAM DEFAULT, IF ANY
	TRNN	T2,-1		;GOT A FRAME BYTESIZE?
	HRR	T2,.IODBS(IO)	;NO, PICK UP PROGRAM DEFAULT, IF ANY
	MOVE	T3,.IOUBS(IO)	;GET USER OVERRIDING <DATA,,FRAME> SIZES
	TLNE	T3,-1		;GOT OVERRIDING DATA BYTE SIZE?
	HLL	T2,T3		;YES, USE HIS DATA BYTE SIZE
	TRNE	T3,-1		;GOT OVERRIDING FRAME BYTE SIZE?
	HRR	T2,T3		;YES, USE HER FRAME BYTE SIZE
	TLNE	T2,-1		;GOT A DATA BYTESIZE?
	TRNN	T2,-1		;AND A FRAME BYTESIZE TOO?
	TSO	T2,T2		;NO, DEFAULT ONE FROM THE OTHER
	CAIN	T2,0		;STILL HAVE NO BYTESIZE?
	MOVE	T2,MOSZTB(T1)	;GET I/O-MODE DATA AND FRAME BYTE SIZES
	HLRZM	T2,.IOBSZ(IO)	;SET LOGICAL DATA BYTE SIZE
	HRRZM	T2,.IOFSZ(IO)	;SET PHYSICAL FRAME SIZE
	TLNN	T2,-1		;MUST HAVE A DATA BYTE SIZE
	STOPCD	<No byte size in DPOA12>
	SKIPN	T3,.IOFSZ(IO)	;GET PHYSICAL FRAME SIZE
	MOVE	T3,.IOBSZ(IO)	;NONE, USE LOGICAL DATA BYTE SIZE
	MOVD1M	T3,BSZ		;SET MAIN ATTR BYTE SIZE FIELD

DPOA15:	MOVDII	T3,ORG,$DVOSQ	;ALL FILE ACCESSES ARE SEQUENTIAL
	MOVDM	T3,ORG		;SET MAIN ATTR FILE ORGANIZATION FIELD

	MOVD1	T2,OST		;REMOTE (FAL) OPERATING SYSTEM TYPE
	CAILE	T2,$DVOMX	;IS THIS A SYSTEM WE KNOW ABOUT?
	JRST	[OUTSTR	[ASCIZ\[Unknown OS type, defaulting to RSX-11M]
\]
		MOVEI	T2,$DVORM	;RSX-11M
		JRST	.+1]		;MAKE A WILD GUESS AT IT
	MOVD	T3,DTY		;RETRIEVE DATA TYPE FLAGS
	TFNN	T3,ASC		;DEALING IN ASCII CHARACTER DATA?
	JRST	DPOA17		;NO, BINARY

;SELECT RECORD FORMAT AND ATTRIBUTES FOR ASCII DATA

DPOA16:	MOVE	T3,DARFTB(T2)	;ASCII, GET APPROPRIATE RECORD FORMAT
	MOVD1M	T3,RFM		;SET MAIN ATTR RECORD FORMAT FIELD
	MOVE	T3,DARATB(T2)	;ASCII, GET APPROPRIATE RECORD ATTRIBUTES
	SETZ	T4,		;FINISH OFF INITIAL FLAGS POTENTIAL WORDS
	TXNE	P3,IC.LSN	;WANT LINE-SEQUENCED ASCII?
	TFO	T3,LSA		;YES, THE POOR DUMB FOOL
	TXNE	P3,IC.CCC	;COBOL CARRIAGE CONTROL?
	TFO	T3,CCC		;YES
	TXNE	P3,IC.FCC	;FORTRAN CARRIAGE CONTROL?
	TFO	T3,FCC		;YES
	MOVDM	T3,RAT		;SET MAIN ATTR RECORD ATTRIBUTES FIELD
	JRST	DPOA19		;CONTINUE WITH REST OF MAIN ATTR

;SELECT RECORD FORMAT AND ATTRIBUTES FOR IMAGE (BINARY) DATA

DPOA17:	MOVE	T1,.IOFSC(IO)	;ADDRESS OF FILE SPEC BLOCK
	LDB	T3,[POINTR .IOIOC(IO),IC.RFM]  ;GET RECORD FORMAT SPEC
	TXNE	P4,IM.CMD	;DOES .IOIOC OVERRIDE?
	JRST	DPOA18		;YES, DISREGARD /RECFORMAT THEN
	MOVE	T4,.FXCTM(T1)	;CONTROL SWITCHES MASK
	TXNN	T4,FX.RFM	;USER SPECIFY /RECFORMAT?
	SKIPA	T3,DBRFTB(T2)	;NO, DEFAULT AN APPROPRIATE RECORD FORMAT
	LDB	T3,[POINTR .FXCTL(T1),FX.RFM]  ;YES, USE HIS RECORD FORMAT
	DPB	T3,[POINTR .IOIOC(IO),IC.RFM]  ;SET SELECTED RECORD FORMAT
DPOA18:	CAIN	T3,.ICRF3	;/RECFORMAT:36PACK?
	JRST	[MOVE	T3,[^D36,,^D36]	;YES, THEN DATA IS 36-BIT WORDS
		HLRZM	T3,.IOBSZ(IO)	;SET LOGICAL DATA BYTE SIZE
		HRRZM	T3,.IOFSZ(IO)	;SET PHYSICAL FRAME SIZE
		MOVEI	T3,^D08		;DEAL WITH REMOTE IN 8-BIT BYTES
		MOVD1M	T3,BSZ		;SET MAIN ATTR BYTE SIZE FIELD
		MOVD	T3,DTY		;RETRIEVE DATA TYPE
		TFZ	T3,<ASC,EBC>	;NOT CHARACTER DATA
		TFO	T3,IMG		;BUT RATHER IMAGE/BINARY DATA
		MOVDM	T3,DTY		;TELL REMOTE THAT TOO
		MOVEI	T3,.ICRFV	;TELL REMOTE "VARIABLE" RFM
		JRST	.+1]		;SO MUCH FOR TRUTH-IN-ADVERTISING
	CAIN	T3,$DVFVF	;VARIABLE WITH FIXED CONTROL?
	STOPCD	<Record format not supported at DPOA18>
	MOVD1M	T3,RFM		;SET MAIN ATTR RECORD FORMAT FIELD
	MOVE	T3,DBRATB(T2)	;APPROPRIATE RECORD ATTRIBUTES
	MOVE	T4,.FXCTL(T1)	;CONTROL SWITCHES
	TXNN	P4,IM.CMD	;IGNORE USER SPEC IF .IOIOC OVERRIDES
	TXNN	T4,FX.MCY!FX.MEY;USER SPECIFY /MACY11 OR /MECY11?
	TXNE	P3,IC.MCY!IC.MEY;OR OTHERWISE WANT MACY11-PACKING?
	TFO	T3,MCY		;YES
	SETZ	T4,		;OTHER HALF OF POTENTIAL WORDS
	MOVDM	T3,RAT		;SET MAIN ATTR RECORD ATTRIBUTES FIELD

;NOW START UP THE MAIN ATTRIBUTES MENU

DPOA19:	MOVDII	P1,M02,<DTY,ORG,RFM,RAT,BSZ>  ;ALWAYS-SENT FIELDS
	MOVD1	T2,FST		;*** GET REMOTE FILE SYSTEM
	CAIN	T2,$DVFF1	;*** FCS-11?
	TMZ	P1,BSZ		;*** YES, WON'T ACCEPT BYTE SIZE FIELD!
				;*** (IT ALSO WON'T SEND IT BACK TO US)

;SELECT BLOCKSIZE

DPOA20:	MOVE	T1,.IOFSC(IO)	;ADDRESS OF CURRENT FILE SPEC BLOCK
	SKIPG	T3,.FXBLS(T1)	;USER SPECIFY /BLOCKSIZE?
	MOVE	T3,.IOBLS(IO)	;NO, USE PROGRAM-SUPPLIED BLOCKSIZE (IF ANY)
	MOVEM	T3,.IOBLS(IO)	;SET BLOCKSIZE (BEST GUESS ANYWAY) FOR DPOA24
	JUMPE	T3,DPOA22	;DON'T BOTHER WITH BLOCKSIZE IF NOTHING THERE
	MOVD1M	T3,BLS		;SET MAIN ATTR BLOCKSIZE FIELD
	TMO	P1,BLS		;AND FLAG IT IN THE MENU

;SELECT RECORD SIZE

DPOA22:	SKIPG	T3,.FXRSZ(T1)	;USER SPECIFY /RECSIZE?
	SKIPLE	T3,.IORSZ(IO)	;NO, GOT A PROGRAM-SPECIFIED RECORDSIZE?
	JRST	DPOA23		;YES, TRUST IT
	LDB	T4,[POINTR .IOIOC(IO),IC.RFM]  ;RECORD FORMAT
	CAIN	T4,.ICRF3	;36PACK'ED WORDS?
	MOVEI	T3,<<<^D256-10>/^D09>*^D09>  ;YES, WORDS INTO 256-BYTE RECORDS
DPOA23:	MOVEM	T3,.IORSZ(IO)	;SET RECORDSIZE (BEST GUESS ANYWAY)
	JUMPE	T3,DPOA24	;DON'T BOTHER WITH RECORDSIZE IF NULL
	MOVD1M	T3,MRS		;YES, SET MAIN ATTR RECORD SIZE FIELD
	TMO	P1,MRS		;AND FLAG IT IN THE MENU

;SELECT FILE ALLOCATION

DPOA24:	SKIPG	T3,.FXEST(T1)	;USER SPECIFY /ALLOCATE OR /ESTIMATE?
	JRST	DPOA25		;NO, TRY PROGRAM-SPECIFIED VALUES
	ADDI	T3,177		;YES, ROUND UP AND
	LSH	T3,-7		;TRUNCATE TO "BLOCKS" (SO TO SPEAK)
	JRST	DPOA26		;SET ALLOCATION IN BLOCKS

DPOA25:	SKIPG	.IOBLS(IO)	;HAVE WE GOT A BLOCKING SIZE?
	JRST	DPOA30		;NO, THEN CAN'T COMPUTE AN ALLOCATION SIZE
	SKIPG	T3,.IOALB(IO)	;GET PROGRAM-SPECIFIED ALLOCATION (BYTES)
	MOVE	T3,.IOLNB(IO)	;OR FALL BACK TO ACTUAL WRITTEN LENGTH (BYTES)
	IDIV	T3,.IOBLS(IO)	;CONVERT TO BLOCKS
	CAILE	T4,0		;ANY REMAINDER?
	ADDI	T3,1		;YEAH, ALLOW FOR PARTIAL BLOCK
DPOA26:	JUMPE	T3,DPOA30	;SKIP ALLOCATION IF NULL
	MOVD1M	T3,ALQ		;SET MAIN ATTR ALLOCATION QUANTITY FIELD
	TMO	P1,ALQ		;AND FLAG IT IN THE MENU TOO

;SELECT FILE "OPTIONS"

DPOA30:	MOVDII	T3,FOP,<TEF>	;ASSUME TRUNCATE TO EOF ON CLOSE
	SETZB	T3,T4		;*** OLD RSX IN THE FIELD DOESN'T LIKE TEF
	MOVE	T2,.FXCTL(T1)	;GET USER-SPECIFIED CONTROL FLAGS
	TXNN	T2,FX.ALC	;USER SPECIFY /ALLOCATE?
	TXNE	P4,IM.CBT	;OR PROGRAM SPECIFY "BEST TRY"
	TFO	T3,CBT		;YES, FLAG "CONTIGUOUS BEST TRY"
	TXNN	T2,FX.CTG	;USER SPECIFY /CONTIGUOUS?
	TXNE	P4,IM.CTG	;OR PROGRAM SPECIFY CONTIGUOUS?
	TFO	T3,CTG		;YES, FLAG "CONTIGUOUS"
	TFNE	T3,CTG		;CONTIGUOUS ALLOCATION REQUIRED?
	TFZ	T3,CBT		;YES, THEN NO "BEST TRY OK"
	MOVE	T2,.FXMOD(T1)	;FILE MODS
	TXNN	T2,FX.SUP	;/ERSUPERSEDE?
	TFO	T3,SUP		;NO, OK TO SUPERSEDE
	MOVDM	T3,FOP		;SET MAIN ATTR FILE ACCESS OPTIONS FIELD
	TMO	P1,FOP		;AND FLAG IT IN THE MENU TOO

	MOVDM	P1,M02		;SET MAIN ATTTRIBUTES MENU FIELD


;ALLOCATION ATTIBUTES

DPOA50:	SETZB	P1,P2		;INIT ALLOCATION ATTR MENU
	MOVD	T3,ALQ		;MAIN ATTR ALLOCATION QUANTITY
	MOVDM	T3,AAL		;COPY INTO ALLOC ATTR ALLOCATION QUANTITY
	MOVD	T3,M02		;MAIN ATTR MENU
	TMNN	T3,ALQ		;AN ALLOCATION QUANTITY?
	TMO	P1,AAL		;YES
	SETZB	T3,T4		;INIT FLAGS
	MOVD	T1,FOP		;MAIN ATTR FILE ACCESS OPTIONS
	TFNE	T1,CBT		;CONTIGUOUS BEST TRY?
	TFO	T3,ACB		;YES, MARK IN ALLOCATION OPTIONS
	TFNE	T1,CTG		;CONTIGUOUS ALLOCATION REQUIRED?
	TFO	T3,ACT		;YES, MARK IN ALLOCATION OPTIONS
	MOVDM	T3,ALP		;SET ALLOC ATTR ALLOCATION OPTIONS FIELD
	TFNE	T3,<ACB,ACT>	;ANYTHING IN OPTIONS?
	TMO	P1,ALP		;YES, MARK IT IN THE MENU
	SKIPN	T3,.I1LKP+.RBPOS(IO)  ;ALLOCATION ADDRESS SUPPLIED?
	JRST	DPOA56		;NO
	MOVD1M	T3,LOC		;SET ALLOC ATTR ALLOCATION ADDRESS FIELD
	MOVDII	T3,ALN,ALB	;THE ALIGN-TO-SPECIFIED-BLOCK BIT
	MOVDM	T3,ALN		;SET ALLOC ATTR ALIGNMENT CONTROL FIELD
	TMO	P1,<ALN,LOC>	;MARK FIELDS PRESENT IN MENU
DPOA56:	MOVDM	P1,M11		;SET ALLOCATION ATTRIBUTES MENU


;DATE/TIME ATTRIBUTES

DPOA70:	SETZB	P1,P2		;INITIALIZE MENU SELECTION
	MOVE	T4,.IODPV(IO)	;GET PROTOCOL VERSION
DPOA71:	SKIPE	T3,.IOCDT(IO)	;DO WE HAVE A CREATION DATE/TIME?
	TMO	P1,CDT		;YES, FLAG THE MENU ACCORDINGLY
	MOVD1M	T3,CDT		;SET DATE/TIME ATTR CREATION FIELD
	SKIPE	T3,.IOUDT(IO)	;DO WE HAVE AN UPDATE DATE/TIME?
	TMO	P1,UDT		;YES, FLAG THE MENU ACCORDINGLY
	MOVD1M	T3,UDT		;SET DATE/TIME ATTR UPDATE FIELD
	SKIPE	T3,.IOEDT(IO)	;DO WE HAVE AN EXPIRATION DATE/TIME?
	TMO	P1,EDT		;YES, FLAG THE MENU
	MOVD1M	T3,EDT		;SET DATE/TIME ATTR EXPIRATION FIELD
DPOA74:	CAIGE	T4,006000	;VERSION 6.0 OR LATER PROTOCOL?
	JRST	DPOA79		;NOPE, NOTHING MORE CAN BE SENT
	SKIPE	T3,.IOBDT(IO)	;DO WE HAVE A BACKUP DATE/TIME?
	TMO	P1,BDT		;YES, FLAG THE MENU
	MOVD1M	T3,BDT		;SET DATE/TIME ATTR BACKUP FIELD
	SKIPE	T3,.IOPDT(IO)	;GOT A PHYSICAL MEDIA CREATION DATE/TIME?
	TMO	P1,PDT		;YES, FLAG THE MENU
	MOVD1M	T3,PDT		;SET DATE/TIME ATTR PHYSICAL CREATE FIELD
	SKIPE	T3,.IOADT(IO)	;GOT AN ACCESS DATE/TIME?
	TMO	P1,ADT		;YES, FLAG THE MENU APPROPRIATELY
	MOVD1M	T3,ADT		;SET DATE/TIME ATTR ACCESS FIELD

DPOA79:	MOVDM	P1,M13		;SET DATE/TIME ATTRIBUTES MENU


;PROTECTION ATTRIBUTES
;
;DPOA8? ASSUMES PROTECTION FLAGS FIELDS ARE ONLY ONE WORD LONG. AS THIS
;IS NOT GUARANTEED, AT LEAST CAUSE ASSEMBLY ERROR IF IT EVER CHANGES

	IFN	$DLPSY-1,<PRINTX ?PSY field not one word long in DPOA80>
	IFN	$DLPOW-1,<PRINTX ?POW field not one word long in DPOA80>
	IFN	$DLPGR-1,<PRINTX ?PGR field not one word long in DPOA80>
	IFN	$DLPWL-1,<PRINTX ?PWL field not one word long in DPOA80>

DPOA80:	SETZB	P1,P2		;INITIAL MENU FLAGS
	MOVE	T2,.IOFSC(IO)	;ADDRESS OF CURRENT FILE SPEC BLOCK
	LDB	T3,[POINTR .FXMOM(T2),FX.PRO]  ;DID USER SUPPLY /PROT:?
	JUMPE	T3,DPOA81	;NO
	LDB	T3,[POINTR .FXMOD(T2),FX.PRO]  ;YES, FETCH /PROTECTION VALUE
	JRST	DPOA82		;AND SEND IT TO THE REMOTE

DPOA81:	SKIPN	T3,.IOPRT(IO)	;OR IS PROTECTION AVAILABLE VIA THE CDB?
	JRST	DPOA88		;SKIP IF NO PROTECTION FIELD
DPOA82:	LSHC	T3,-6		;REDUCE TO OWNER PROTECTION
	ANDI	T3,7		;AND ONLY THE OWNER PROTECTION
	MOVE	T2,FPDPTO(T3)	;TRANSLATE TO DAPISH PROTECTION FLAGS
	MOVDM	T2,POW		;SET PROTECTION ATTR OWNER FIELD
	LSHC	T3,3		;GET GROUP CODE
	ANDI	T3,7		;AND ONLY THE GROUP CODE
	MOVE	T2,FPDPTB(T3)	;TRANSLATE TO DAPISH PROTECTION FLAGS
	MOVDM	T2,PGR		;SET PROTECTION ATTR GROUP FIELD
	LSHC	T3,3		;GET WORLD ACCESS FIELD
	ANDI	T3,7		;AND ONLY WORLD ACCESS FIELD
	MOVE	T2,FPDPTB(T3)	;TRANSLATE TO DAPISH PROTECTION FLAGS
	MOVDM	T2,PWL		;SET PROTECTION ATTR WORLD FIELD
	TMO	P1,<POW,PGR,PWL>;SELECT MENU FIELDS
DPOA88:	MOVDM	P1,M14		;SET PROTECTION ATTRIBUTES MENU FIELD

;ALL DONE CONVERTING FILE ATTRIBUTES TO DAP ATTRIBUTES

DPOA99:	JRST	.POPJ1##
;FILE SPEC STRING TOO BIG

DPOAE1:	MOVEI	M0,$EFRFB	;FILE SPECIFICATION (STRING) TOO BIG
	JRST	.M0ERR##	;MARK ERROR AND RETURN


;FILE PASSWORD STRING TOO BIG

DPOAE2:	MOVEI	M0,$EFRSB	;GENERIC STRING TOO BIG ERROR
	JRST	.M0ERR##	;MARK ERROR AND RETURN
;DPOAA  --  SETUP DAP ACCESS MESSAGE FROM [OUTPUT] FILE SPECIFICATION
;Call is:
;
;	MOVX	T1,<CDB>
;	PUSHJ	P,DPOAA
;	 error return
;	normal return
;
;Where <CDB> is the address of the controlling I/O CDB.
;
;On error return the ACCESS message could not be translated (the file
;specification was too big, etc.). An error code is in M0.
;
;On normal return the ACCESS message is ready to be sent (XDDAP), excepting
;the access function field, which must be correctly set by the caller.
;
;DPOAA will clear out the ACCESS message data area (excepting the function
;field which is left untouched), then fill in the file specification and
;password fields from the CDB as set by SCWLD (output spec). If the
;remote supports file data checksumming then DPOAA will set the ACCESS
;options field to request same.
;
;DPOAA also generates the file componet strings (.IOFxx) such that if
;the remote doesn't return any name messages telling what actually
;happened, then at least the CDB can still say what we tried to do. DPRNM
;will update the file componet strings to reflect any received name
;messages.
;
;Uses T1 - T4.

	ENTRY	.DPOAA
	INTERN	DPOAA0,	DPOAA1

.DPOAA:	PUSHJ	P,.SACIO##	;SETUP I/O CDB INDEX
DPOAA0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPOAA1:	XMOVEI	T1,DTYPO	;OUR OWN PRIVATE TYPER
	PUSHJ	P,.XTYPO##	;INTERCEPT AND SETUP TYPEOUT

;FIRST INITIALIZE THE ACCESS MESSAGE FIELDS

	SETZB	T1,T2		;INITIAL (NO VALUE) VALUE
	MOVDM	T1,AFC		;CLEAR ACCESS FUNCTION FIELD
	MOVDM	T1,FAC		;CLEAR ACCESS OPERATIONS
	MOVDM	T1,SHR		;CLEAR SHARED OPERATIONS
	MOVDM	T1,ADS		;CLEAR ACCESS DISPLAY

;TRY FOR FILE DATA CHECKSUMMING

	MOVDII	T1,AOP,ACK	;ASSUME (HOPE) REMOTE SUPPORTS CHECKSUMMING
	MOVD	T3,CNF		;REMOTE'S CONFIGURATION FLAGS
	TFNN	T3,FCK		;DOES REMOTE SUPPORT FILE DATA CHECKSUMMING?
	TFZ	T1,ACK		;NO (BOO HISS), THEN DON'T REQUEST IT
	MOVDM	T1,AOP		;SET BASIC ACCESS OPTIONS

;CONVERT FILE SPECIFICATION INTO DAP ACCESS MESSAGE FILE SPEC FIELD

	PUSHJ	P,DPOFS1	;GENERATE FILE COMPONET STRINGS (.IOFXX)
	 STOPCD	<DPOFS failed in DPOAA1>
	MOVE	P3,[$DBFIL,,.IDFIL]  ;7-BIT BYTE STUFFER PROTOTYPE
	PUSHJ	P,DP3P4		;SETUP .IODP3/.IODP4 AS COUNTER/POINTER
	 STOPCD	<DP3P4 failed in DPOAA>
	PUSHJ	P,DPGAAT	;GET FILE SPEC CONTROL FLAGS IN T2
	PUSHJ	P,TOCFS1	;GENERATE FILE SPECIFICATION STRING
	 STOPCD	<TOCFS1 failed in DPOAA>
	DMOVE	P3,.IODP3(IO)	;GET TERMINAL BYTE COUNTER/POINTER
	AOBJP	P3,DPOAE1	;ERROR IF OVERFLOWED
	MOVEI	T1,0		;A NULL BYTE
	IDPB	T1,P4		;TO TERMINATE THE ASCIZ FILE SPEC STRING

;PASS ALONG ANY FILE PASSWORD TOO

	MOVE	P3,[$DBPSW,,.IDPSW]  ;7-BIT BYTE STUFFER PROTOTYPE
	PUSHJ	P,DP3P4		;SETUP BYTE COUNTER/POINTER
	 STOPCD	<DP3P4 failed in DPOAA>
	SKIPN	T1,.IOFSC(IO)	;ADDRESS OF USER'S CURRENT FILE SPEC
	STOPCD	<No FSB for password in DPOAA>
	MOVEI	T1,.FXPSW(T1)	;ADDRESS OF ASSOCIATED PASSWORD STRING
	PUSHJ	P,.TSTRG##	;PUT PASSWORD STRING INTO DAP BLOCK
	DMOVE	P3,.IODP3(IO)	;GET TERMINAL BYTE COUNTER/POINTER
	AOBJP	P3,DPOAE2	;ERROR IF OVERFLOWED
	MOVEI	T1,0		;A NULL BYTE
	IDPB	T1,P4		;TO TERMINATE THE ASCIZ PASSWORD STRING

;ACCESS MESSAGE ALL SET

	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPOFS - GENERATE "OUTPUT" FILE SPEC STRING FOR DAP ACCESS MESSAGE
;CALL IS:
;
;	PUSHJ	P,DPOFS
;	 error return
;	normal return
;
;The error return is not exercised
;
;On normal return the "file specification" has been generated in terms
;of the file componet strings (.IOF?? - TOCFL/N can be used to generate
;the full file spec string).
;
;Uses T1, T2, T3, T4, P1, P2, P3, P4.

DPOFS1:	XMOVEI	T1,FILOTO	;OUR LITTLE TYPER
	PUSHJ	P,.XTYPO##	;DIRECT STRING OUTPUT
	MOVE	P1,.IOFSB(IO)	;ADDRESS OF "OUTPUT" FSB
	MOVE	P2,.FXFLD(P1)	;"OUTPUT" FIELDS FLAGS
	MOVE	P3,.IOSCD(IO)	;ADDRESS OF "INPUT" CDB
	MOVE	P4,.IOFSB(P3)	;ADDRESS OF "INPUT" FSB

;START WITH DEVICE NAME/STRING

DPOF20:	MOVE	T1,[POINT 7,.IOSDV(IO)]  ;DEVICE STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WDV	;DEVICE WILDCARDS?
	JRST	DPOF22		;YES
	SKIPN	T1,.FSDEV(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOF29		;NO DEVICE SPECIFIED
	JRST	DPOF24		;TYPE DEVICE NAME

DPOF22:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXDEV(P1)	;DID USER TYPE "*:"?
	JRST	DPOF26		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFDV(P3)	;YES, USE CORRESPONDING INPUT DEVICE NAME
DPOF24:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOF29		;CAP OFF DEVICE

DPOF26:	MOVE	T1,.I1OPN+.OPDEV(IO)  ;SCWILD'S DEVICE NAME
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT DEVICE NAME
DPOF29:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOSDV(IO)	;WAS A DEVICE NAME GENERATED?
	XMOVEI	T1,.IOSDV(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOFDV(IO)	;SET ADDRESS OF DEVICE STRING

;NOW DO DIRECTORY NAME

DPOF30:	MOVE	T1,[POINT 7,.IOSDR(IO)]  ;DIRECTORY STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WDR	;DIRECTORY WILDCARDS?
	JRST	DPOF32		;YES
	SKIPN	T1,.FSDIR(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOF39		;NO DIRECTORY SPECIFIED
	JRST	DPOF34		;TYPE DIRECTORY STRING

DPOF32:	MOVSI	T1,(ASCIZ\*\)	;FULL-WILD STRING
	CAME	T1,@.FSDIR(P1)	;DID USER TYPE "[*]"?
	JRST	DPOF36		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFDR(P3)	;YES, USE CORRESPONDING INPUT DIRECTORY NAME
DPOF34:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOF39		;CAP OFF DIRECTORY

DPOF36:	MOVE	T1,.I1LKP+.RBPPN(IO)  ;SCWILD'S DIRECTORY NAME
	PUSHJ	P,.TDIRB##	;TYPE PATH BLOCK
	MOVE	T1,[POINT 7,.IOSDR(IO)]  ;BYTE POINTER TO DIRECTORY STRING
	MOVE	T2,T1		;COPY
	IBP	T1		;SKIP THE LEADING "[" FROM .TDIRB
	CAIA			;ENTER LOOP
	IDPB	M0,T2		;STORE IT
	ILDB	M0,T1		;DIRECTORY CHARACTER
	JUMPN	M0,.-2		;LOOP FOR WHOLE STRING
	DPB	M0,T2		;KRUMP ON TRAILING "]" FROM .TDIRB
DPOF39:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOSDR(IO)	;WAS A DIRECTORY NAME GENERATED?
	XMOVEI	T1,.IOSDR(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOFDR(IO)	;SET ADDRESS OF DIRECTORY STRING

;TYPE FILE NAME NEXT

DPOF40:	MOVE	T1,[POINT 7,.IOSNM(IO)]  ;FILE NAME STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WNM	;NAME WILDCARDS?
	JRST	DPOF42		;YES
	SKIPN	T1,.FSNAM(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOF49		;NO NAME SPECIFIED
	JRST	DPOF44		;TYPE FILE NAME

DPOF42:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXNAM(P1)	;DID USER TYPE "*"?
	JRST	DPOF46		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFNM(P3)	;YES, USE CORRESPONDING INPUT DEVICE NAME
DPOF44:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOF49		;CAP OFF NAME

DPOF46:	MOVE	T1,.I1LKP+.RBNAM(IO)  ;SCWILD'S FILE NAME
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT NAME
DPOF49:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOSNM(IO)	;WAS A FILE NAME GENERATED?
	XMOVEI	T1,.IOSNM(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOFNM(IO)	;SET ADDRESS OF FILE NAME STRING

;FOLLOW UP WITH THE FILE TYPE/EXTENSION

DPOF50:	MOVE	T1,[POINT 7,.IOSEX(IO)]  ;EXTENSION STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WEX	;EXTENSION WILDCARDS?
	JRST	DPOF52		;YES
	SKIPN	T1,.FSEXT(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOF59		;NO EXTENSION SPECIFIED
	JRST	DPOF54		;TYPE EXTENSION

DPOF52:	HRLZI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXEXT(P1)	;DID USER TYPE ".*"?
	JRST	DPOF56		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFEX(P3)	;YES, USE CORRESPONDING INPUT EXTENSION
DPOF54:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOF59		;CAP OFF EXTENSION

DPOF56:	HLLZ	T1,.I1LKP+.RBEXT(IO)	;SCWILD'S FILE EXTENSION
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT DEVICE NAME
DPOF59:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOSEX(IO)	;WAS A EXTENSION NAME GENERATED?
	XMOVEI	T1,.IOSEX(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOFEX(IO)	;SET ADDRESS OF EXTENSION STRING

;FINISH OFF WITH THE GENERATION

DPOF60:	MOVE	T1,[POINT 7,.IOSGN(IO)]  ;GENERATION STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WGN	;GENERATION WILDCARDS?
	JRST	DPOF62		;YES
	SKIPN	T1,.FSGEN(P1)	;NO, USE GENERATION AS TYPED BY USER
	JRST	DPOF69		;NO GENERATION SPECIFIED
	JRST	DPOF64		;TYPE GENERATION STRING

DPOF62:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXGEN(P1)	;DID USER TYPE ".*"?
	JRST	DPOF66		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFGN(P3)	;YES, USE CORRESPONDING INPUT GENERATION
DPOF64:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOF69		;CAP OFF GENERATION

DPOF66:	SKIPE	T1,.I1GEN(IO)	;LOOK FOR A GENERATION
	PUSHJ	P,.TDECW##	;TYPE OUT DECIMAL GENERATION

DPOF69:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOSGN(IO)	;WAS A GENERATION NAME GENERATED?
	XMOVEI	T1,.IOSGN(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOFGN(IO)	;SET ADDRESS OF GENERATION STRING

;ALL DONE WITH "OUTPUT" FILE SPECIFICATION COMPONETS

DPOF70:	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPOTN - BUILD TERTIARY NAME COMPONETS FOR RENAME
;Call is:
;
;	PUSHJ	P,DPOTN
;	 error return
;	normal return
;
;DPOTN is used to build the DAP NAME message containing the full file
;specification to be used in a RENAME operation (presumably via the
;version 7.0 and later ACCOMP(RENAME) sequence. The name is generated
;in a manner analguous to DPOAA, only the controlling spec is the .IOCU3
;"tertiary" file spec block, and the "input" and "output" CDBs are one
;and the same.
;
;The error return is taken if the file spec cannot be built (e.g., the
;file spec string is too big, etc.)
;
;On normal return the NAME message is ready to be shipped, containing
;the tertiary (RENAME) file spec a la .IOCU3 and .SCWLD's results.
;The tertiary string componets (.IOF3?) are also setup.
;
;Uses T1, T2, T3, T4.

	ENTRY	.DPOTN
	INTERN	DPOTN0,	DPOTN1

.DPOTN:	PUSHJ	P,.SACIO##	;SWITCH TO I/O CONTEXT
DPOTN0:	PUSHJ	P,.SAVE4##	;PROTECT THE P'S
DPOTN1:	XMOVEI	T1,DTYPO	;CHARACTER "TYPEOUT" ROUTINE
	PUSHJ	P,.XTYPO##	;INTERCEPT AND SPECIFY CHARACTER HANDLING

;SPECIFY NAME TYPE

	MOVDII	T1,NTY,NFS	;WE ARE BUILDING FULL FILE SPEC
	MOVDM	T1,NTY		;SET IN NAME TYPE FIELD

;CONVERT FILE SPECIFICATION INTO DAP NAME MESSAGE FIELD

	PUSHJ	P,DPOTS1	;GENERATE FILE COMPONET STRINGS (.IOF3?)
	 STOPCD	<DPOTS failed in DPOTN1>
	MOVE	P3,[$DBNMS,,.IDNMS]  ;7-BIT BYTE PROTOTYPE STUFFER
	PUSHJ	P,DP3P4		;SETUP .IODP3/.IODP4 AS COUNTER/POINTER
	 STOPCD	<DP3P4 failed in DPOTN1>
	PUSHJ	P,DPGAAT	;GET FILE SPEC CONTROL FLAGS IN T2
	TXZ	T2,FX.UND!FX.UDV;IGNORE/SUPPRESS NODE AND DEVICE FIELDS
	PUSHJ	P,TOTFS1	;GENERATE TERTIARY FILE SPEC STRING
	 STOPCD	<TOTFS1 failed in DPOTN1>
	DMOVE	P3,.IODP3(IO)	;GET FINAL COUNTER/POINTER
	AOBJP	P3,DPOAE1	;ERROR IF OVERFLOWED STRING BUFFER
	MOVEI	T1,0		;A TERMINATING <NUL>
	IDPB	T1,P4		;TO ASCIZIZE THE FILE SPEC STRING

;NAME MESSAGE COMPLETE

	JRST	.POPJ1##	;SUCCESSFUL RETURN READY FOR XDDAP
;DPOTS - GENERATE TERTIARY "OUTPUT" FILE SPEC STRING FOR DAP NAME MESSAGE
;CALL IS:
;
;	PUSHJ	P,DPOTS
;	 error return
;	normal return
;
;The error return is not exercised
;
;On normal return the "file specification" has been generated in terms
;of the tertiary file componet strings (.IOF3?).
;
;Uses T1, T2, T3, T4, P1, P2, P3, P4.

DPOTS1:	XMOVEI	T1,FILOTO	;OUR LITTLE TYPER
	PUSHJ	P,.XTYPO##	;DIRECT STRING OUTPUT
	MOVE	P1,.IOCU3(IO)	;ADDRESS OF "OUTPUT" FSB
	MOVE	P2,.FXFLD(P1)	;"OUTPUT" FIELDS FLAGS
	MOVE	P4,.IOFSB(IO)	;ADDRESS OF "INPUT" FSB

;START WITH DEVICE NAME/STRING

DPOT20:	MOVE	T1,[POINT 7,.IOS3V(IO)]  ;DEVICE STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WDV	;DEVICE WILDCARDS?
	JRST	DPOT22		;YES
	SKIPN	T1,.FSDEV(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOT29		;NO DEVICE SPECIFIED
	JRST	DPOT24		;TYPE DEVICE NAME

DPOT22:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXDEV(P1)	;DID USER TYPE "*:"?
	JRST	DPOT26		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFDV(IO)	;YES, USE CORRESPONDING INPUT DEVICE NAME
DPOT24:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOT29		;CAP OFF DEVICE

DPOT26:	MOVE	T1,.I1OP3+.OPDEV(IO)  ;SCWILD'S DEVICE NAME
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT DEVICE NAME
DPOT29:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOS3V(IO)	;WAS A DEVICE NAME GENERATED?
	XMOVEI	T1,.IOS3V(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOF3V(IO)	;SET ADDRESS OF DEVICE STRING

;NOW DO DIRECTORY NAME

DPOT30:	MOVE	T1,[POINT 7,.IOS3R(IO)]  ;DIRECTORY STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WDR	;DIRECTORY WILDCARDS?
	JRST	DPOT32		;YES
	SKIPN	T1,.FSDIR(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOT39		;NO DIRECTORY SPECIFIED
	JRST	DPOT34		;TYPE DIRECTORY STRING

DPOT32:	MOVSI	T1,(ASCIZ\*\)	;FULL-WILD STRING
	CAME	T1,@.FSDIR(P1)	;DID USER TYPE "[*]"?
	JRST	DPOT36		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFDR(IO)	;YES, USE CORRESPONDING INPUT DIRECTORY NAME
DPOT34:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOT39		;CAP OFF DIRECTORY

DPOT36:	MOVE	T1,.I1LK3+.RBPPN(IO)  ;SCWILD'S DIRECTORY NAME
	PUSHJ	P,.TDIRB##	;TYPE PATH BLOCK
	MOVE	T1,[POINT 7,.IOS3R(IO)]  ;BYTE POINTER TO DIRECTORY STRING
	MOVE	T2,T1		;COPY
	IBP	T1		;SKIP THE LEADING "[" FROM .TDIRB
	CAIA			;ENTER LOOP
	IDPB	M0,T2		;STORE IT
	ILDB	M0,T1		;DIRECTORY CHARACTER
	JUMPN	M0,.-2		;LOOP FOR WHOLE STRING
	DPB	M0,T2		;KRUMP ON TRAILING "]" FROM .TDIRB
DPOT39:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOS3R(IO)	;WAS A DIRECTORY NAME GENERATED?
	XMOVEI	T1,.IOS3R(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOF3R(IO)	;SET ADDRESS OF DIRECTORY STRING

;TYPE FILE NAME NEXT

DPOT40:	MOVE	T1,[POINT 7,.IOS3M(IO)]  ;FILE NAME STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WNM	;NAME WILDCARDS?
	JRST	DPOT42		;YES
	SKIPN	T1,.FSNAM(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOT49		;NO NAME SPECIFIED
	JRST	DPOT44		;TYPE FILE NAME

DPOT42:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXNAM(P1)	;DID USER TYPE "*"?
	JRST	DPOT46		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFNM(IO)	;YES, USE CORRESPONDING INPUT DEVICE NAME
DPOT44:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOT49		;CAP OFF NAME

DPOT46:	MOVE	T1,.I1LK3+.RBNAM(IO)  ;SCWILD'S FILE NAME
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT NAME
DPOT49:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOS3M(IO)	;WAS A FILE NAME GENERATED?
	XMOVEI	T1,.IOS3M(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOF3M(IO)	;SET ADDRESS OF FILE NAME STRING

;FOLLOW UP WITH THE FILE TYPE/EXTENSION

DPOT50:	MOVE	T1,[POINT 7,.IOS3X(IO)]  ;EXTENSION STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WEX	;EXTENSION WILDCARDS?
	JRST	DPOT52		;YES
	SKIPN	T1,.FSEXT(P1)	;NO, USE NAME AS TYPED BY USER
	JRST	DPOT59		;NO EXTENSION SPECIFIED
	JRST	DPOT54		;TYPE EXTENSION

DPOT52:	HRLZI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXEXT(P1)	;DID USER TYPE ".*"?
	JRST	DPOT56		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFEX(IO)	;YES, USE CORRESPONDING INPUT EXTENSION
DPOT54:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOT59		;CAP OFF EXTENSION

DPOT56:	HLLZ	T1,.I1LK3+.RBEXT(IO)	;SCWILD'S FILE EXTENSION
	PUSHJ	P,.TSIXN##	;TYPE SIXBIT DEVICE NAME
DPOT59:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOS3X(IO)	;WAS A EXTENSION NAME GENERATED?
	XMOVEI	T1,.IOS3X(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOF3X(IO)	;SET ADDRESS OF EXTENSION STRING

;FINISH OFF WITH THE GENERATION

DPOT60:	MOVE	T1,[POINT 7,.IOS3N(IO)]  ;GENERATION STRING BLOCK BYTE POINTER
	MOVEM	T1,.IOXTO(IO)	;SETUP FOR FILOTO
	TXNE	P2,FX.WGN	;GENERATION WILDCARDS?
	JRST	DPOT62		;YES
	SKIPN	T1,.FSGEN(P1)	;NO, USE GENERATION AS TYPED BY USER
	JRST	DPOT69		;NO GENERATION SPECIFIED
	JRST	DPOT64		;TYPE GENERATION STRING

DPOT62:	MOVSI	T1,'*  '	;FULL-WILD STRING
	CAME	T1,.FXGEN(P1)	;DID USER TYPE ".*"?
	JRST	DPOT66		;NO, USE SCWILD'S RESULT
	MOVE	T1,.IOFGN(IO)	;YES, USE CORRESPONDING INPUT GENERATION
DPOT64:	PUSHJ	P,.TSTRG##	;AND TYPE IT OUT
	JRST	DPOT69		;CAP OFF GENERATION

DPOT66:	SKIPE	T1,.I1GE3(IO)	;LOOK FOR A GENERATION
	PUSHJ	P,.TDECW##	;TYPE OUT DECIMAL GENERATION

DPOT69:	PUSHJ	P,FILOTZ	;TERMINATE ASCIZ STRING
	SKIPE	T1,.IOS3N(IO)	;WAS A GENERATION NAME GENERATED?
	XMOVEI	T1,.IOS3N(IO)	;YES, ADDRESS OF STRING
	MOVEM	T1,.IOF3N(IO)	;SET ADDRESS OF GENERATION STRING

;ALL DONE WITH "OUTPUT" FILE SPECIFICATION COMPONETS

DPOT70:	JRST	.POPJ1##	;SUCCESSFUL RETURN
;DPDCH - TRANSLATE DAP DEVICE CHARACTERISTICS INTO FILE CHARACTERISTICS
;CALL IS:
;
;	PUSHJ	P,DPDCH
;	 error return
;	normal return
;
;The error return is not utilized.
;
;On normal return, the DAP device characteristics (predominantly the "DEV"
;field of the main attributes) are translated into the I/O CDB file/device
;characteristics (.IODCH/IC.xxx), returned in T2.
;
;Uses T1, T2, T3.

	ENTRY	.DPDCH
	INTERN	DPDCH0,	DPDCH1

.DPDCH:	PUSHJ	P,.SACIO##	;SWITCH TO I/O CONTEXT
DPDCH0:				;DON'T USE THE P'S HERE
DPDCH1:	SETZ	T1,		;INITIALLY NO FLAGS
	MOVD	T2,DEV		;GET MAIN ATTRIBUTES DEVICE CHARACTERISTICS
	TFNE	T2,REC		;"RECORD-ORIENTED"?
	TXO	T1,IC.REC	;YES
	TFNE	T2,CCL		;CARRIAGE-CONTROL?
	TXO	T1,IC.CCL	;YES
	TFNE	T2,TRM		;TERMINAL?
	TXO	T1,IC.TRM	;YES
	TFNE	T2,MDI		;MULTIPLE DIRECTORIES?
	TXO	T1,IC.MDI	;YES
	TFNE	T2,SDI		;SINGLE-DIRECTORY?
	TXO	T1,IC.SDI	;YES
	TFNE	T2,SQD		;SEQUENTIAL BLOCK ORIENTED?
	TXO	T1,IC.SQD	;YES
	TFNE	T2,NUL		;NUL DEVICE?
	TXO	T1,IC.NUL	;YES
	TFNE	T2,FOD		;FILE-ORIENTED DEVICE?
	TXO	T1,IC.FOD	;YES
	TFNE	T2,DSH		;SHARABLE?
	TXO	T1,IC.DSH	;YES
	TFNE	T2,SPL		;SPOOLED DEVICE?
	TXO	T1,IC.SPL	;YES
	TFNE	T2,MNT		;MOUNTED?
	TXO	T1,IC.MNT	;YES
	TFNE	T2,DMT		;MARKED FOR DISMOUNT?
	TXO	T1,IC.DMT	;YES
	TFNE	T2,ALL		;DEVICE ALLOCATED?
	TXO	T1,IC.ALL	;YES
	TFNE	T2,IDV		;CAN DEVICE DO INPUT?
	TXO	T1,IC.IDV	;YES
	TFNE	T2,ODV		;CAN DEVICE DO OUTPUT?
	TXO	T1,IC.ODV	;YES
	TFNE	T2,SWL		;IS DEVICE SOWTWARE-WRITE-LOCKED?
	TXO	T1,IC.SWL	;YES
	TFNE	T2,AVL		;IS DEVICE AVAILABLE?
	TXO	T1,IC.AVL	;YES
	TFNE	T2,ELG		;ERROR-LOGGING ENABLED?
	TXO	T1,IC.ELG	;YES
	TFNE	T2,MBX		;A MAILBOX?
	TXO	T1,IC.MBX	;YES
	TFNE	T2,RTM		;REAL-TIME DEVICE?
	TXO	T1,IC.RTM	;YES
	TFNE	T2,RAD		;RANDOM-ACCESS?
	TXO	T1,IC.RAD	;YES
	TFNE	T2,DRC		;READ-CHECKING ENABLED?
	TXO	T1,IC.DRC	;YES
	TFNE	T2,DWC		;WRITE-CHECKING ENABLED?
	TXO	T1,IC.DWC	;YES
	TFNE	T2,FRN		;FOREIGN DEVICE?
	TXO	T1,IC.FRN	;YES
	TFNE	T2,NDV		;NETWORK DEVICE?
	TXO	T1,IC.NDV	;YES
	TFNE	T2,GDV		;GENERIC DEVICE?
	TXO	T1,IC.GDV	;YES

	MOVD	T2,ALP		;GET ALLOCATION OPTIONS (IF ANY)
	TFNE	T2,ACT		;ALLOCATED CONTIGUOUSLY?
	TXO	T1,IC.CTG	;YES

	MOVE	T2,T1		;POSITION MASK IN T2
	JRST	.POPJ1##	;RETURN WITH IC.??? FLAGS IN T2
;DPSII - DAP INPUT INITIALIZATION - SEND CONTROL(CONNECT/GET)
;CALL IS:
;
;	PUSHJ	P,DPSII
;	 error return
;	normal return
;
;On error return the input data stream could not be started up (M0
;contains an error code).
;
;On normal return the network stream is ready for DAP DATA messages to
;be received from the remote.
;
;Uses T1 - T4

	ENTRY	.DPSII
	INTERN	DPSII0,	DPSII1

.DPSII:	PUSHJ	P,.SACIO##	;SETUP I/O CDB ADDRESS
DPSII0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPSII1:;SETZM	.IODIS(IO)	;SELECT STREAM ID "0"

;SETUP CONTROL MESSAGE FOR SEQUENTIAL FILE TRANSFER

	MOVEI	T3,$DVCSF	;SEQUENTIAL FILE ACCESS MODE
	MOVD1M	T3,RAC		;SET RECORD ACCESS CONTROL FIELD
	SETZB	T3,T4		;CLEAR FLAGS
	MOVDM	T3,ROP		;SET RECORD-LEVEL OPERATIONS FIELD
	SETZB	T3,T4		;CLEAR FLAGS
	MOVDM	T3,CDS		;SET CONTROL-DISPLAY-REQUESTED FIELD
;	MOVDII	T3,M04,<RAC,ROP,CDS>  ;CONTROL MENU FLAGS
	MOVDII	T3,M04,<RAC,ROP>;CONTROL MENU FLAGS (VAX HATES CDS)
	MOVDM	T3,M04		;SET CONTROL MENU FIELD
	MOVEI	T3,$DVCON	;CONTROL(CONNECT) INIT DATA STREAM FUNCTION
	MOVD1M	T3,CFC		;SET CONTROL FUNCTION FIELD
	MOVEI	T2,$DHCTL	;CONTROL MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND A CONTROL(CONNECT) MESSAGE
	 CAIA			;HMMM
	JRST	DPSI20		;SET FOR DATA TRANSMISSION
	STOPCD	<Control(connect) xmit failed>

;INDICATE DESIRE TO RECEIVE DATA

DPSI20:	MOVD	T3,M04		;RETRIEVE COPY OF CONTROL MENU
	TMZ	T3,CDS		;DON'T NEED DISPLAY-REQUESTED FIELD ANYMORE
				; (BUT KEEP RAC/ROP OUT OF PARANOIA)
	MOVDM	T3,M04		;SET SHRUNKEN CONTROL MENU
	MOVEI	T3,$DVCGT	;CONTROL(GET) READ FUNCTION
	MOVD1M	T3,CFC		;SET CONTROL FUNCTION FIELD
	MOVEI	T2,$DHCTL	;CONTROL MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND A CONTROL(GET) MESSAGE
	 CAIA			;HMMM
	JRST	DPSI30		;GET REMOTE'S ACKNOWLEDGEMENT
	STOPCD	<Control(get) xmit failed>

;WAIT FOR REMOTE TO ACKNOWLEDGE OUR DESIRE TO READ DATA

DPSI30:	PUSHJ	P,XDFLS1##	;ENSURE MESSAGES SENT TO REMOTE
	 POPJ	P,		;OOPS

DPSI40:	PUSHJ	P,RDMSG1##	;GET A DAP MESSAGE CODE
	 POPJ	P,		;NETWORK MUST HAVE DIED
	JSP	T4,.CDISP##	;DISPATCH ON RECEIVED MESSAGE TYPE
		DPSI42,,$DHSTS	;STATUS, PROBABLY AN ERROR
		DPSI49,,$DHACK	;ACKNOWLEDGEMENT
		0		;NO MORE
	JRST	.RDEOS##	;MESSAGE OUT OF SEQUENCE

;STATUS RECEIVED, CHECK IT OUT

DPSI42:	PUSHJ	P,RDSTS1##	;READ IN THE STATUS MESSAGE
	 POPJ	P,		;OOPS
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"?
	CAIN	M0,$EGAOK	;"A-OK"?
	JRST	DPSI40		;YES (DUH?) TRY FOR THE ACK AGAIN
	POPJ	P,		;PROPAGATE ERROR

;ACKNOWLEDGEMENT RECEIVED

DPSI49:	PUSHJ	P,RDDAP1##	;EAT REST OF ACK MESSAGE
	 POPJ	P,		;NETWORK DIED
	MOVX	T1,IO.DCC	;THE DAP-CONTROL(CONNECT) BIT
	IORM	T1,.IOCCF(IO)	;SET IN THE CDB

;OPTIMIZE BUFFER ALLOCATION FOR INPUT

	SETO	T2,		;NO LINK QUOTA DIDDLING
	MOVEI	T3,^D75		;75% OF QUOTA FOR INPUT OPERATIONS
;***	PUSHJ	P,NTNSQ1##	;BEND LINK QUOTAS TOWARD INPUT
	 JFCL			;HO HUM

	JRST	.POPJ1##	;ALL SET FOR I/O (READ) OPERATIONS
;DPSOI - DAP OUTPUT INITIALIZATION - SEND CONTROL(CONNECT/PUT)
;CALL IS:
;
;	PUSHJ	P,DPSOI
;	 error return
;	normal return
;
;On error return the output data stream could not be started up (M0
;contains an error code).
;
;On normal return the network stream is ready for DAP DATA messages to
;be transmitted to the remote.
;
;Uses T1 - T4

	ENTRY	.DPSOI
	INTERN	DPSOI0,	DPSOI1

.DPSOI:	PUSHJ	P,.SACIO##	;SETUP I/O CDB ADDRESS
DPSOI0:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
DPSOI1:;SETZM	.IODOS(IO)	;SELECT STREAM ID "0"

;SETUP CONTROL MESSAGE FOR SEQUENTIAL FILE TRANSFER

	MOVEI	T3,$DVCSF	;SEQUENTIAL FILE ACCESS MODE
	MOVD1M	T3,RAC		;SET RECORD ACCESS CONTROL FIELD
	SETZB	T3,T4		;CLEAR FLAGS
	MOVE	T1,.IOFOP(IO)	;RETRIEVE FILE OPERATION
	CAIN	T1,.IFAPP	;APPEND FUNCTION?
	TFO	T3,EOF		;YES, SET "POSITION TO EOF"
	MOVDM	T3,ROP		;SET RECORD-LEVEL OPERATIONS FIELD
	SETZB	T3,T4		;CLEAR FLAGS
	MOVDM	T3,CDS		;SET CONTROL-DISPLAY-REQUESTED FIELD
;	MOVDII	T3,M04,<RAC,ROP,CDS>  ;CONTROL MENU FLAGS
	MOVDII	T3,M04,<RAC,ROP>;CONTROL MENU FLAGS (VAX HATES CDS)
	MOVDM	T3,M04		;SET CONTROL MENU FIELD
	MOVEI	T3,$DVCON	;CONTROL(CONNECT) INIT DATA STREAM FUNCTION
	MOVD1M	T3,CFC		;SET CONTROL FUNCTION FIELD
	MOVEI	T2,$DHCTL	;CONTROL MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND A CONTROL(CONNECT) MESSAGE
	 CAIA			;HMMM
	JRST	DPSO20		;SET FOR DATA TRANSMISSION
	STOPCD	<Control(connect) xmit failed>

;INDICATE DESIRE TO TRANSMIT DATA

DPSO20:	MOVD	T3,M04		;RETRIEVE COPY OF CONTROL MENU
	TMZ	T3,CDS		;DON'T NEED DISPLAY-REQUESTED FIELD ANYMORE
				; (BUT KEEP RAC/ROP OUT OF PARANOIA)
	MOVDM	T3,M04		;SET SHRUNKEN CONTROL MENU
	MOVEI	T3,$DVCPT	;CONTROL(PUT) WRITE FUNCTION
	MOVD1M	T3,CFC		;SET CONTROL FUNCTION FIELD
	MOVEI	T2,$DHCTL	;CONTROL MESSAGE CODE
	PUSHJ	P,XDDAP1##	;SEND A CONTROL(PUT) MESSAGE
	 CAIA			;HMMM
	JRST	DPSO30		;GET REMOTE'S ACKNOWLEDGEMENT
	STOPCD	<Control(put) xmit failed>

;WAIT FOR REMOTE TO ACKNOWLEDGE OUR DESIRE TO WRITE DATA

DPSO30:	PUSHJ	P,XDFLS1##	;ENSURE MESSAGES SENT TO REMOTE
	 POPJ	P,		;OOPS

DPSO40:	PUSHJ	P,RDMSG1##	;GET A DAP MESSAGE CODE
	 POPJ	P,		;NETWORK MUST HAVE DIED
	JSP	T4,.CDISP##	;DISPATCH ON RECEIVED MESSAGE TYPE
		DPSO42,,$DHSTS	;STATUS, PROBABLY AN ERROR
		DPSO49,,$DHACK	;ACKNOWLEDGEMENT
		0		;NO MORE
	JRST	.RDEOS##	;MESSAGE OUT OF SEQUENCE

;STATUS RECEIVED, CHECK IT OUT

DPSO42:	PUSHJ	P,RDSTS1##	;READ IN THE STATUS MESSAGE
	 POPJ	P,		;OOPS
	CAIE	M0,$EGOIP	;"OPERATION IN PROGRESS"?
	CAIN	M0,$EGAOK	;"A-OK"?
	JRST	DPSO40		;YES (DUH?) TRY FOR THE ACK AGAIN
	POPJ	P,		;PROPAGATE ERROR

;ACKNOWLEDGEMENT RECEIVED

DPSO49:	PUSHJ	P,RDDAP1##	;EAT REST OF ACK MESSAGE
	 POPJ	P,		;NETWORK DIED
	MOVX	T1,IO.DCC	;THE DAP-CONTROL(CONNECT) BIT
	IORM	T1,.IOCCF(IO)	;SET IN THE CDB

;OPTIMIZE QUOTA ALLOCATION FOR OUTPUT

	SETO	T2,		;NO QUOTA DIDDLING
	MOVEI	T3,^D25		;75% OF BUFFER QUOTA FOR OUTPUT
;***	PUSHJ	P,NTNSQ1##	;BEND BUFFER ALLOCATION TOWARDS OUTPUT
	 JFCL			;HO HUM

	JRST	.POPJ1##	;ALL SET FOR I/O (WRITE) OPERATIONS
;DP3P4 - SETUP .IODP3/.IODP4 AS BYTE COUNT/BYTE POINTER
;CALL IS:
;
;	MOVX	P3,<7BP>
;	PUSHJ	P,DP3P4
;	 error return
;	normal return
;
;Where <7BP> is the prototype 7-bit format pointer in the form count,,offset
;where "count" is the maximum byte count of the string and "offset" is the
;byte string offset into the .IODAP area within the I/O CDB.
;
;On error return the specified index was outside of all possible CDB offsets
;
;On normal return .IODP3 will contain an AOBJN counter of the form -max,,0 and
;.IODP4 will contain the byte pointer for IDPBs.
;
;Preserves all acs

DP3P4:	HRRZ	P4,P3		;WORD OFFSET INTO THE CDB
	ANDCMI	P3,-1		;MAXIMUM COUNT,,0
	CAILE	P4,.IOMAX	;WITHIN RANGE?
	STOPCD	<DAP ASCII string index outside of CDB>
	HRLI	P4,(POINT 7,(IO))  ;CONVERT TO 7-BIT BYTE POINTER
	TLC	P3,-1		;MAKE COUNT INTO AOBJN POINTER
	DMOVEM	P3,.IODP3(IO)	;SETUP COUNTER AND POINTER FOR DTYPO
				; (THIS WAY THE RH(.IODP3) IS AN UP-TO-DATE
				;  COUNT OF BYTES ACTUALLY STORED,
				;  WHILE LH IS NEGATIVE IF NOT OVERFLOWED)
	JRST	.POPJ1##	;READY FOR CALLS TO DTYPO



;DTYPO - HELPER FOR DP???

DTYPO:	EXCH	P3,.IODP3(IO)	;GET COUNTER WHERE IT IS ACCESSIBLE
	AOBJP	P3,.+2		;ROOM FOR ANOTHER 7-BIT BYTE?
	IDPB	T1,.IODP4(IO)	;YES
	EXCH	P3,.IODP3(IO)	;RESTORE CALLER'S P3
	POPJ	P,		;RETURN
;DPGOST - GET DAP OPERATING SYSTEM TYPE

DPGOST:	MOVD1	T2,OST		;REMOTE OPERATING SYSTEM TYPE
	CAIG	T2,$DVOMX	;WITHIN LIMITS THAT WE KNOW OF?
	JRST	.POPJ1##	;YES, ALL SET, RETURN HAPPILY
	OUTSTR	[ASCIZ\[Unknown remote operating system, assuming RSX-11M]
\]				;TELL USER OF WOES
	MOVEI	T2,$DVORM	;DEFAULT TO RSX-11M
	POPJ	P,		;AND THAT IS THAT



;DPGFST - GET DAP FILE SYSTEM TYPE

DPGFST:	MOVD1	T2,FST		;REMOTE FILE SYSTEM TYPE
	CAIG	T2,$DVFMX	;WITHIN LIMITS THAT WE KNOW OF?
	JRST	.POPJ1##	;YES, ALL SET, RETURN HAPPILY
	OUTSTR	[ASCIZ\[Unknown remote file system type, assuming RMS-11]
\]				;TELL USER OF WOES
	MOVEI	T2,$DVF11	;DEFAULT TO RSX-11 RMS-11
	POPJ	P,		;AND THAT IS THAT



;DPGAAT - GET DAP FILE SPEC CONTROL FLAGS BASED ON FILE SYSTEM TYPE

DPGAAT:	PUSHJ	P,DPGFST	;GET FILE SYSTEM TYPE
	 JFCL			;IGNORE ERRORS
	MOVE	T2,DPWAAT(T2)	;FETCH FLAGS
	POPJ	P,		;RETURN



;FILE-SYSTEM-SPECIFIC FILE SPEC CONTROL FLAGS

	FXFWAA==FX.UDV!FX.UDR!FX.UNM!FX.UEX

DPWAAT:	FXFWAA				;00 - UNKNOWN
	FXFWAA!FX.UGN!FX.SGN		;01 - RMS-11
	FXFWAA!FX.UGN			;02 - RMS-20
	FXFWAA!FX.UGN!FX.SND!FX.SGN	;03 - RMS-32
	FXFWAA!FX.UGN!FX.SGN		;04 - FCS-11
	FXFWAA				;05 - RT-11
	FXFWAA				;06 - NO FILE SYSTEM
	FXFWAA!FX.UGN			;07 - TOPS-20
	FXFWAA!FX.UGN!FX.UFS		;08 - TOPS-10
	FXFWAA				;09 - OS-8
	FXFWAA!FX.UGN!FX.SND!FX.SGN	;10 - RMS-32S

IFN	<$DVFMX-<.-DPWAAT>+1>,<IF1,<
	PRINTX ? DPWAAT table out of sync with protocol maximum>>
;MORE CONVERSION TABLES

;ASCII TO DAP RECORD FORMAT BASED ON OPERATING SYSTEM TYPE

DARFTB::0				;00 -
	$DVFVR				;01 - RT-11
	$DVFVR				;02 - RSTS/E
	$DVFVR				;03 - RSX-11S
	$DVFVR				;04 - RSX-11M
	$DVFVR				;05 - RSX-11D
	$DVFVR				;06 - IAS
	$DVFVR				;07 - VAX/VMS
	$DVFNR				;08 - TOPS-20
	$DVFNR				;09 - TOPS-10
	$DVFNR				;10 - RTS-8
	$DVFNR				;11 - OS-8
	$DVFVR				;12 - RSX-11M+
	$DVFVR				;13 - COPOS/11
	$DVFVR				;14 - P/OS
	$DVFVR				;15 - VAX/ELAN

IFN	<$DVOMX-<.-DARFTB>+1>,<IF1,<
	PRINTX ? DARFTB table out of sync with protocol maximum>>


;ASCII TO DAP RECORD ATTRIBUTES BASED ON OPERATING SYSTEM TYPE

DARATB::0				;00 -
	DPFLG1 (<ILC>)			;01 - RT-11
	DPFLG1 (<ILC>)			;02 - RSTS/E
	DPFLG1 (<ILC>)			;03 - RSX-11S
	DPFLG1 (<ILC>)			;04 - RSX-11M
	DPFLG1 (<ILC>)			;05 - RSX-11D
	DPFLG1 (<ILC>)			;06 - IAS
	DPFLG1 (<ILC>)			;07 - VAX/VMS
	0				;08 - TOPS-20
	0				;09 - TOPS-10
	0				;10 - RTS-8
	0				;11 - OS-8
	DPFLG1 (<ILC>)			;12 - RSX-11M+
	DPFLG1 (<ILC>)			;13 - COPOS/11
	DPFLG1 (<ILC>)			;14 - P/OS
	DPFLG1 (<ILC>)			;15 - VAX/ELAN

IFN	<$DVOMX-<.-DARATB>+1>,<IF1,<
	PRINTX ? DARATB table out of sync with protocol maximum>>

;IMAGE (BINARY) TO DAP RECORD FORMAT BASED ON OPERATING SYSTEM TYPE

DBRFTB::0				;00 -
	$DVFVR				;01 - RT-11
	$DVFVR				;02 - RSTS/E
	$DVFVR				;03 - RSX-11S
	$DVFVR				;04 - RSX-11M
	$DVFVR				;05 - RSX-11D
	$DVFVR				;06 - IAS
	$DVFVR				;07 - VAX/VMS
	$DVFNR				;08 - TOPS-20
	$DVFNR				;09 - TOPS-10
	$DVFNR				;10 - RTS-8
	$DVFNR				;11 - OS-8
	$DVFVR				;12 - RSX-11M+
	$DVFVR				;13 - COPOS/11
	$DVFVR				;14 - P/OS
	$DVFVR				;15 - VAX/ELAN

IFN	<$DVOMX-<.-DBRFTB>+1>,<IF1,<
	PRINTX ? DBRFTB table out of sync with protocol maximum>>


;IMAGE (BINARY) TO DAP RECORD ATTRIBUTES BASED ON OPERATING SYSTEM TYPE

DBRATB::0				;00 -
	0				;01 - RT-11
	0				;02 - RSTS/E
	0				;03 - RSX-11S
	0				;04 - RSX-11M
	0				;05 - RSX-11D
	0				;06 - IAS
	0				;07 - VAX/VMS
	0				;08 - TOPS-20
	0				;09 - TOPS-10
	0				;10 - RTS-8
	0				;11 - OS-8
	0				;12 - RSX-11M+
	0				;13 - COPOS/11
	0				;14 - P/OS
	0				;15 - VAX/ELAN

IFN	<$DVOMX-<.-DBRATB>+1>,<IF1,<
	PRINTX ? DBRATB table out of sync with protocol maximum>>
;CONVERT FROM DAP PROTECTION CODES TO LOCAL FILE PROTECTION CODES
;CALL IS:
;
;	MOVD	T1,<DPRT>
;	PUSHJ	P,DPFPXL/DPFPXO
;	return
;
;Where <DPRT> is the DAPISH file protection mask.
;
;Call DPFPXL for group and world protections, DPFPXO for owner protection
;
;On return, the local TOPS-10 LEVEL-D disk system protection code is
;in T2.
;
;Uses T1 - T2.

DPFPXL::SETZ	T2,		;ASSUME UNLIMITED ACCESS
	TFZE	T1,PCP		;DENY PROTECTION CHANGE?
	MOVEI	T2,1		;YES
	TFZE	T1,PDE		;DENY DELETE/RENAME?
	MOVEI	T2,2		;YES
	TFZE	T1,PWR		;DENY WRITE?
	MOVEI	T2,3		;YES
	TFZE	T1,PUP		;DENY UPDATE?
	MOVEI	T2,4		;YES
	TFZE	T1,<PAP,PXT>	;DENY APPEND OR EXTEND?
	MOVEI	T2,5		;YES
	TFNE	T1,<PRD,PDI>	;DENY READ OR DIRECTORY ACCESS?
	MOVEI	T2,6		;YES
	TFNE	T1,PEX		;DENY EXECUTE?
	JRST	[TFNE	T1,PRD		;YES - BUT STILL ALLOW READ?
		MOVEI	T2,7		;NO, DISALLOW ALL ACCESS
		JRST	.+1]		;CONTINUE
	TFZ	T1,<PRD,PDI,PEX>;BLAST SOME BITS
	JUMPE	T1,.POPJ##	;RETURN DATA FILE PROTECTION IN T2
	STOPCD	<Excess DAP protection mask bits in DPFPXL>


DPFPXO::SETZ	T2,		;ASSUME UNLIMITED ACCESS
	TFZE	T1,PCP		;DENY PROTECTION CHANGE?
	MOVEI	T2,1		;YES
	TFZE	T1,<PDE,PWR,PUP,PAP,PXT>  ;DENY DELETE!WRITE!ETC.?
	MOVEI	T2,2		;YES
	TFZE	T1,<PRD,PDI,PEX>;DENY READ, DIRECTORY, OR EXECUTE ACCESS?
	MOVEI	T2,3		;YES
	POPJ	P,		;RETURN FILE PROTECTION IN T2
;CONVERT FROM LOCAL FILE PROTECTION CODES TO DAP PROTECTION FLAGS

FPDPTB::0				;0 - ALL ACCESSES
	DPFLG1 (<PCP>)			;1 - DENY PROTECTION CHANGE
	DPFLG1 (<PCP,PDE>)		;2 - DENY RENAME
	DPFLG1 (<PCP,PDE,PWR>)		;3 - DENY WRITE
	DPFLG1 (<PCP,PDE,PWR,PUP>)	;4 - DENY UPDATE
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT>)  ;5 - DENY APPEND
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT,PRD,PDI>)  ;6 - DENY READ, DIRECTORY
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT,PRD,PDI,PEX>)  ;7 - DENY ALL ACCESSES


;FOR OWNER PROTECTION (HIGH BIT IS FILDAE BIT)

FPDPTO::0				;0 - ALL ACCESSES
	DPFLG1 (<PCP>)			;1 - DENY PROTECTION CHANGE
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT>)  ;2 - DENY APPEND
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT,PRD,PDI,PEX>)  ;3 - DENY ALL ACCESSES
	0				;4 - ALL ACCESSES
	DPFLG1 (<PCP>)			;5 - DENY PROTECTION CHANGE
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT>)  ;6 - DENY APPEND
	DPFLG1 (<PCP,PDE,PWR,PUP,PAP,PXT,PRD,PDI,PEX>)  ;7 - DENY ALL ACCESSES
	SUBTTL	"TYPEOUT" SUPPORT ROUTINES

;TOTFL  --  TYPE OUT TERTIARY "LOCAL FILE SPECIFICATION" FROM CDB
;TOTFN  --  TYPE OUT TERTIARY "NETWORK FILE SPECIFICATION" FROM CDB
;TOTFS  --  TYPE OUT TERTIARY GENERIC FILE SPECIFICATION FROM CDB
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<FLGS>	;TOTFS ONLY
;	PUSHJ	P,TOTFL/TOTFN/TOTFS
;	 error return
;	normal return
;
;Where <CDB> is the address of an I/O CDB; and <FLG> are file spec control
;flags (governing output form) a la .TOFSB.
;
;.TOTFL types out the file specification sans node name (i.e., the
;"local" file spec), while .TOTFN types out the file specification
;including the node name (the "network" file spec). The file spec is
;in "standard" format - nod::dev:[dir]nam.ext.gen.
;
;.TOTFS types out the file specification as per the control flags passed
;in register T2 (see .TOFSB for details of the file spec control flags).
;
;The error return is not exercised.
;
;On normal return the currently-active tertiary file specification
;is "typed out" via .TCHAR.
;
;Uses T1, T2, T3, T4.

	ENTRY	.TOTFN
	INTERN	TOTFN0,	TOTFN1

.TOTFN:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOTFN0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOTFN1:	MOVX	T2,FX.UND!FXFWAA!FX.UGN  ;WANT NODE::DEV:[DIR]NAM.TYP.GEN
	JRST	TOTFS1		;TYPE REST OF FILE SPEC



	ENTRY	.TOTFL
	INTERN	TOTFL0,	TOTFL1

.TOTFL:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOTFL0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOTFL1:	MOVX	T2,FXFWAA!FX.UGN;WANT DEV:[DIR]NAM.TYP.GEN
	JRST	TOTFS1		;GO TYPE OUT THE FILE SPEC
	ENTRY	.TOTFS
	INTERN	TOTFS0,	TOTFS1

.TOTFS:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOTFS0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOTFS1:	PUSH	P,.IOFND(IO)	;NODE
	PUSH	P,.IOFDV(IO)	; DEVICE
	PUSH	P,.IOFDR(IO)	;  DIRECTORY
	PUSH	P,.IOFNM(IO)	;   NAME
	PUSH	P,.IOFEX(IO)	;    EXTENSION
	PUSH	P,.IOFGN(IO)	;     GENERATION
	MOVSI	T1,.IOF3D(IO)	;ADDRESS OF TERTIARY NODE NAME ADDRESS
	HRRI	T1,.IOFND(IO)	;ADDRESS OF NORMAL NODE NAME ADDRESS
	BLT	T1,.IOFGN(IO)	;COPY TERTIARY BLOCK ONTO NORMAL BLOCK
	PUSHJ	P,TOCFS1	;TYPE OUT FILE SPEC AS DIRECTED
	 JFCL			;HO HUM
	POP	P,.IOFGN(IO)	;     GENERATION
	POP	P,.IOFEX(IO)	;    EXTENSION
	POP	P,.IOFNM(IO)	;   NAME
	POP	P,.IOFDR(IO)	;  DIRECTORY
	POP	P,.IOFDV(IO)	; DEVICE
	POP	P,.IOFND(IO)	;NODE
	JRST	.POPJ1##	;RETURN WITH USER NONE-THE-WISER
;TOCFL  --  TYPE OUT "LOCAL FILE SPECIFICATION" FROM CDB
;TOCFN  --  TYPE OUT "NETWORK FILE SPECIFICATION" FROM CDB
;TOCFS  --  TYPE OUT GENERIC FILE SPECIFICATION FROM CDB
;CALL IS:
;
;	MOVX	T1,<CDB>
;	MOVX	T2,<FLGS>	;TOCFS ONLY
;	PUSHJ	P,TOCFL/TOCFN/TOCFS
;	 error return
;	normal return
;
;Where <CDB> is the address of an I/O CDB; and <FLG> are file spec control
;flags (governing output form) a la .TOFSB.
;
;.TOCFL types out the file specification sans node name (i.e., the
;"local" file spec), while .TOCFN types out the file specification
;including the node name (the "network" file spec). The file spec is
;in "standard" format - nod::dev:[dir]nam.ext.gen.
;
;.TOCFS types out the file specification as per the control flags passed
;in register T2 (see .TOFSB for details of the file spec control flags).
;
;The error return is not exercised.
;
;On normal return the currently-active file's file specification
;is "typed out" via .TCHAR.
;
;Uses T1, T2, T3, T4.

	ENTRY	.TOCFN
	INTERN	TOCFN0,	TOCFN1

.TOCFN:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOCFN0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOCFN1:	MOVX	T2,FX.UND!FXFWAA!FX.UGN  ;WANT NODE::DEV:[DIR]NAM.TYP.GEN
	JRST	TOCFS1		;TYPE REST OF FILE SPEC



	ENTRY	.TOCFL
	INTERN	TOCFL0,	TOCFL1

.TOCFL:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOCFL0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOCFL1:	MOVX	T2,FXFWAA!FX.UGN;WANT DEV:[DIR]NAM.TYP.GEN
	JRST	TOCFS1		;GO TYPE OUT THE FILE SPEC
	ENTRY	.TOCFS
	INTERN	TOCFS0,	TOCFS1

.TOCFS:	PUSHJ	P,.SACIO##	;SETUP I/O CONTEXT
TOCFS0:	PUSHJ	P,.SAVE4##	;SAVE THE P ACS
TOCFS1:	MOVE	P1,T2		;PRESERVE FILE SPEC TYPEOUT CONTROL
	TXNN	P1,FX.UND	;WANT THE NODE NAME TYPED?
	JRST	TOCFS2		;NO
	SKIPE	T1,.IOFND(IO)	;GOT A NODE STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS2		;NO
	PUSHJ	P,.TSTRG##	;YES, TYPE NODE NAME
	PUSHJ	P,.TCOLN##	;FOLLOWED BY A "::"
	PUSHJ	P,.TCOLN##	; . . .
TOCFS2:	TXNN	P1,FX.UDV	;WANT DEVICE NAME TYPED?
	JRST	TOCFS3		;NO
	SKIPE	T1,.IOFDV(IO)	;GOT A DEVICE STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS3		;NO
	PUSHJ	P,.TSTRG##	;YES, TYPE DEVICE NAME
	PUSHJ	P,.TCOLN##	;FOLLOWED BY A ":"
TOCFS3:	TXNN	P1,FX.UDR	;WANT DIRECTORY NAME TYPED?
	JRST	TOCFS4		;NO
	SKIPE	T1,.IOFDR(IO)	;GOT A DIRECTORY STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS4		;NO
	PUSHJ	P,.TLBRK##	;PRECEDE WITH A "["
	MOVE	T1,.IOFDR(IO)	;ADDRESS OF DIRECTORY STRING
	PUSHJ	P,.TSTRG##	;TYPE DIRECTORY NAME
	PUSHJ	P,.TRBRK##	;CAP OFF WITH A "]"
TOCFS4:	TXNN	P1,FX.UNM	;WANT FILE NAME TYPED?
	JRST	TOCFS5		;NO
	SKIPE	T1,.IOFNM(IO)	;GOT A FILE NAME STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS5		;NO
	PUSHJ	P,.TSTRG##	;YES, TYPE FILE NAME
TOCFS5:	TXNN	P1,FX.UEX	;WANT THE EXTENSION TYPED?
	JRST	TOCFS6		;NO
	SKIPE	T1,.IOFEX(IO)	;GOT AN EXTENSION STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS6		;NO
	PUSHJ	P,.TDOT##	;PREFIX WITH A DOT
	MOVE	T1,.IOFEX(IO)	;ADDRESS OF FILE EXTENSION STRING
	PUSHJ	P,.TSTRG##	;TYPE FILE EXTENSION
	TXO	P1,FX.SEX	;NOTE EXTENSION TYPED
TOCFS6:	TXNN	P1,FX.UGN	;WANT GENERATION TYPED?
	JRST	TOCFS7		;NO
	SKIPE	T1,.IOFGN(IO)	;GOT A GENERATION STRING?
	SKIPN	0(T1)		;PROBABLY, ANY TEXT IN STRING?
	JRST	TOCFS7		;NO
	TXNN	P1,FX.SEX	;HAS EXTENSION BEEN OUTPUT YET?
	PUSHJ	P,.TDOT##	;NO, NEED A FIRST DOT THEN
	TXNN	P1,FX.SGN	;WANT GENERATION PRECEDED BY SEMICOLON?
	PUSHJ	P,.TDOT##	;NO, PRECEDE GENERATION WITH A DOT
	TXNE	P1,FX.SGN	;WANT GENERATION PRECEDED BY SEMICOLON?
	PUSHJ	P,.TSEMI##	;YES, PRECEDE GENERATON WITH A SEMICOLON
	MOVE	T1,.IOFGN(IO)	;ADDRESS OF GENERATION STRING
	PUSHJ	P,.TSTRG##	;TYPE FILE GENERATION
TOCFS7:	JRST	.POPJ1##	;RETURN
	END