	.TITLE	STD_RMS - Routines to allow FORTRAN program to use RMS.
	.IDENT	/2-001/	
				

	.SBTTL	Declarations

MAXLUN = 100	; Maximum logical unit number supported.

	.MCALL 	$RABDEF,$FABDEF

	$RABDEF
	$FABDEF

; ========================================================================
; These declarations are to allow access into the OTS LUB structue.
; These definitions seem to be nowhere on the VMS distruibution.  
; The fiche claims that these values will not be changed.  I hope so.
;
	LUB$W_UNIT_ATTR = -4	; Offset from RAB.
	LUB$V_OLD_FILE  = 3	; Bit to indicate OPEN(...STATUS='OLD')
;=========================================================================

	.SBTTL	LOCAL DATA
	.PSECT	_STD_DATA	PIC,USR,CON,REL,LCL,NOSHR,NOEXE,RD,WRT,LONG
;+
; STD_AA_RAB_TABLE.  
; This table is used by the RMS routines to translate lun to RAB address.
;-

STD_AA_RAB_TABLE:.REPT	MAXLUN
		 .LONG	 0	; Initial value=0
		 .ENDM

	.PSECT	_STD_CODE	PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT,LONG


	.SBTTL	STD_SEQ_USEROPEN - USEROPEN subroutine for sequential access.
;++
; FUNCTIONAL DESCRIPTION:
;
;	STD_RFA_USEROPEN is called as a FORTRAN USEROPEN subroutine.  It
;	is used if access to the file using the STD_SEQ_GET and STD_SEQ_PUT
;	subroutines is desired.
;
;
; CALLING SEQUENCE:
;
;	EXTERNAL STD_SEQ_USEROPEN
;
;	OPEN (..., USEROPEN=STD_SEQ_USEROPEN,...)
;
; FORMAL PARAMETERS:
;
;	4.(AP)  - address of FAB for file.
;	8.(AP)  - address of RAB for file.
;	12.(AP) - address of LUN for file.
;
; IMPLICIT INPUTS:
;
;	None.
;
; IMPLICIT OUTPUTS:
;
;	RAB address stored in STD_AA_RAB_TABLE.
;
; COMPLETION STATUS: 
;
;	From $OPEN or $CONNECT.
;
; SIDE EFFECTS:
;
;	Locate mode bit in RAB is cleared.
;
;--

	.ENTRY	STD_SEQ_USEROPEN,^M<R2>	
USEROPEN:					; Local label.
	MOVL	8(AP),R0			; Get address of RAB.
	BICL	#1@RAB$V_LOC,RAB$L_ROP(R0)	; Clear locate mode bit.
;
; If STATUS = 'OLD' do an $OPEN.  Otherwise (NEW,SCRATCH,UNKNOWN) do a 
; $CREATE.
;
	BBC	#LUB$V_OLD_FILE,LUB$W_UNIT_ATTR(R0),5$
;
	$OPEN	FAB=@4(AP)			; Perform the open.
	BRB	7$
;
5$:	$CREATE FAB=@4(AP)			; Perform the create.
7$:	BLBC	R0,10$				; Return immediately if error.

	$CONNECT RAB=@8(AP)			; Connect stream to file.
	BLBC	R0,10$				; Return immediately if error.
	MOVL	@12.(AP),R2			; Get the lun.
	MOVL	8(AP),STD_AA_RAB_TABLE[R2]	; Set rab address in table.
10$:	RET

	.SBTTL	STD_RFA_USEROPEN - USEROPEN subroutine for RFA access.
;++
; FUNCTIONAL DESCRIPTION:
;
;	STD_RFA_USEROPEN is called as a FORTRAN USEROPEN subroutine.  It
;	is used if access to the file using the STD_RFA_GET subroutine
;	is desired.  If a file is opened with STD_RFA_USEROPEN, sequential
;	access is also permitted with STD_SEQ_GET and STD_SEQ_PUT.
;
; CALLING SEQUENCE:
;
;	EXTERNAL STD_RFA_USEROPEN
;
;	OPEN (..., USEROPEN=STD_RFA_USEROPEN,...)
;
; FORMAL PARAMETERS:
;
;	4.(AP)  - address of FAB for file.
;	8.(AP)  - address of RAB for file.
;	12.(AP) - address of LUN for file.
;
; IMPLICIT INPUTS:
;
;	None.
;
; IMPLICIT OUTPUTS:
;
;	RAB address stored in STD_AA_RAB_TABLE.
;
; COMPLETION STATUS: 
;
;	From $OPEN or $CONNECT.
;
; SIDE EFFECTS:
;
;	Locate mode bit in RAB is cleared.
;	Sequential only bit in FAB is cleared.
;
;--

	.ENTRY	STD_RFA_USEROPEN,^M<R2>	
	MOVL	4(AP),R0			; Get address of FAB.
	BICL	#1@FAB$V_SQO,FAB$L_FOP(R0)	; Clear sequential only bit.
	BRB	USEROPEN

	.SBTTL	STD_SEQ_PUT - Sequential RMS put subroutine.
;++
; FUNCTIONAL DESCRIPTION:
;
;	Performs a sequential put operation using RMS.  Optionally returns
;  	RFA of record to caller.
;
; CALLING SEQUENCE:
;
;	INTEGER*4 STD_SEQ_PUT,ret_status
;
;	ret_status = STD_SEQ_PUT ( lun ,  recsiz , buffer [, rfa] )
;
; FORMAL PARAMETERS:
;
;	LUN    - address of FORTRAN logical unit number to do I/O to.
;	RECSIZ - address of size of record in bytes.
;	BUFFER - address of array containing data to be written.
;	RFA    - address of 3 word array to recieve RFA of record written.
;
; IMPLICIT INPUTS:
;
;	RAB address from STD_AA_RAB_TABLE.
;
; IMPLICIT OUTPUTS:
;
;	None.
;
; COMPLETION STATUS: 
;
; 	Standard RMS-32 status values. 
;
; SIDE EFFECTS:
;
;	None.
;
;--
	.ENTRY STD_SEQ_PUT,^M<R2>
	MOVZWL	@4(AP),R2			; Get LUN.
	MOVL	STD_AA_RAB_TABLE[R2],R2		; Convert to RAB address.
;
; Store buffer address and record length in RAB.
;
	$RAB_STORE RAB=R2, RAC=SEQ, RBF=@12.(AP), RSZ=@8(AP)
;
; Write the record.
;
	$PUT	RAB=R2
;
; Check if RFA was requested
;
	CMPB	(AP),#4			; Were there 4 parameters?
	BLSSU	10$			; If not, caller did not want RFA.
;
; Move RFA into users array.
;
	MOVL	16.(AP),R1		; Get address of array.
	MOVL	RAB$W_RFA(R2),(R1)	; Move first two words.
	MOVw	RAB$W_RFA+4(R2),4(R1)	; Move last word.
;
; Return to caller with status from $PUT
;
10$:	RET		

	.SBTTL	STD_SEQ_GET - Sequential RMS GET subroutine.
;++
; FUNCTIONAL DESCRIPTION:
;
;	Performs a sequential get operation using RMS.  Optionally returns
;  	RFA of record to caller.
;
; CALLING SEQUENCE:
;
;	INTEGER*4 STD_SEQ_GET,ret_status
;
;	ret_status = STD_SEQ_GET(lun,bufsiz,buffer,recsiz[,rfa])
;
; FORMAL PARAMETERS:
;
;	LUN    - address of FORTRAN logical unit number to do I/O to.
;	BUFSIZ - address of word containing size of buffer in bytes.
;	BUFFER - address of array to receive data.
;	RECSIZ - address of word to receive size of record in bytes.
;	RFA    - address of 3 word array to recieve RFA of record read.
;
; IMPLICIT INPUTS:
;
;	RAB address from STD_AA_RAB_TABLE.
;
; IMPLICIT OUTPUTS:
;
;	None.
;
; COMPLETION STATUS: 
;
; 	Standard RMS-32 status values. 
;
; SIDE EFFECTS:
;
;	None.
;
;--
	.ENTRY STD_SEQ_GET,^M<R2>
	MOVZWL	@4(AP),R2			; Get LUN.
	MOVL	STD_AA_RAB_TABLE[R2],R2		; Convert to RAB address.
;
; Store buffer address and record length in RAB.
;
	$RAB_STORE RAB=R2, RAC=SEQ, UBF=@12.(AP), USZ=@8.(AP)
;
; Read the record.
;
	$GET	RAB=R2
;
; Return lenght of record
;
	MOVW	RAB$W_RSZ(R2),@16.(AP)
;
; Check if RFA was requested
;
	CMPB	(AP),#5			; Were there 5 parameters?
	BLSSU	10$			; If not, caller did not want RFA.
;
; Move RFA into users array.
;
	MOVL	20.(AP),R1		; Get address of array.
	MOVL	RAB$W_RFA(R2),(R1)	; Move first two words.
	MOVw	RAB$W_RFA+4(R2),4(R1)	; Move last word.
;
; Return to caller with status from $GET.
;
10$:	RET		

	.SBTTL	STD_RFA_GET - RMS Record's file address GET subroutine.
;++
; FUNCTIONAL DESCRIPTION:
;
;	Performs a RMS get operation by RFA (record's file address).
;
; CALLING SEQUENCE:
;
;	INTEGER*4 STD_RFA_GET,ret_status
;
;	ret_status = STD_RFA_GET(lun,bufsiz,buffer,recsiz,rfa)
;
; FORMAL PARAMETERS:
;
;	LUN    - address of FORTRAN logical unit number to do I/O to.
;	BUFSIZ - address of word containing size of buffer in bytes.
;	BUFFER - address of array to receive data.
;	RECSIZ - address of word to receive size of record in bytes.
;	RFA    - address of 3 word array containing RFA of record to be read.
;
; IMPLICIT INPUTS:
;
;	RAB address from STD_AA_RAB_TABLE.
;
; IMPLICIT OUTPUTS:
;
;	None.
;
; COMPLETION STATUS: 
;
; 	Standard RMS-32 status values. 
;
; SIDE EFFECTS:
;
;	None.
;
;--
	.ENTRY STD_RFA_GET,^M<R2>
	MOVZWL	@4(AP),R2			; Get LUN.
	MOVL	STD_AA_RAB_TABLE[R2],R2		; Convert to RAB address.
;
; Store buffer address, buffer length, and RFA in RAB.
;
	MOVL	20.(AP),R1
	$RAB_STORE RAB=R2, RAC=RFA, UBF=@12.(AP), USZ=@8(AP), RFA=0(R1)
;
; Read the record.
;
	$GET	RAB=R2
;
; Return lenght of record
;
	MOVW	RAB$W_RSZ(R2),@16.(AP)
;
; Return to caller with status from $GET.
;
	RET		
       .END
