; Macro subroutines which do I/O for an input file.
;	The record is either the next in the sequential file, or the one
;	pointed to by the supplied RFA.
;
; Calling Sequences:
;	status := open_in (filename);
;	status := close_in;
;	status := get_in (line);
;

	.psect	data, wrt, noexe
in_fab:		$fab	fnm=<test.spd>		; file access block
in_rab:		$rab	fab=in_fab, rac=seq

	.psect	code, nowrt, exe
; OPEN_IN - open the input file
;
; Calling Sequence:
;	status := open_in (filename);
;
; Where:
;	filename - pascal string variable, containing filename.
;	status	- status returned by $open ($connect assumed to work)
;

	.entry  open_in,^m<r3,r4>
	movl	4(ap), r2		; point to first argument descriptor
	cmpb	dsc$b_dtype(r2), #dsc$k_dtype_vt
					; varying string data?
	bnequ	10$			; 	no, return error code in status
	cmpb	dsc$b_class(r2), #dsc$k_class_vs
					; varying string descriptor?
	bnequ	10$			; 	no, return error code in status
	movab	in_fab, r4
	movl	dsc$a_pointer(r2), r3	; get pointer to filename curlen/string
	movb	0(r3), fab$b_fns(r4)	; move curlen into fab
	movab	2(r3), fab$l_fna(r4)	; move address of string into fab

	$open	fab=in_fab		; open file
	movl	r0, r4			; save open error status 
	$connect	rab=in_rab	; connect to file
	movl	r4, r0			; restore open error status 
	ret				; all done now

; Force an error of invalid class/data type combination in descriptor
10$:	movl	#lib$_invcladty, r0	; move error status into return code
	ret


; CLOSE_IN - read a record from the input file (either sequentially or RFA).
;
; Calling Sequence:
;	status := close_in;
;
; Where:
;	status - status returned by $CLOSE
;

	.entry	close_in,^m<>
	$close	fab=in_fab		; close file
	ret

; GET_IN - read a record from the input file (either sequentially or RFA).
;
; Calling Sequence:
;	status := get_in (buffer);
;
; Where:
;	buffer	- pascal string variable: user buffer for read.
;	status	- status returned by $GET
;

	.entry	get_in,^m<r2,r3,r6,r7>


; Move maximum length and buffer pointer into RAB
	movl	4(ap), r2		; point to first argument descriptor
	cmpb	dsc$b_dtype(r2), #dsc$k_dtype_vt
					; varying string data?
	bnequ	10$			; 	no, return error code in status
	cmpb	dsc$b_class(r2), #dsc$k_class_vs
					; varying string descriptor?
	bnequ	10$			; 	no, return error code in status
	movab	in_rab, r7
	movw	dsc$w_maxstrlen(r2), rab$w_usz(r7)
					; move maximum record length to rab
	movl	dsc$a_pointer(r2), r3	; get pointer to buffer curlen/string
	movab	2(r3), rab$l_ubf(r7)	; move buffer pointer to rab

; Read the record
	$get	rab=in_rab

; Move data to LINE parameter
	movw	rab$w_rsz (r7), (r3)	; move length of record into curlen

	ret

; Force an error of invalid class/data type combination in descriptor
10$:	movl	#lib$_invcladty, r0	; move error status into return code
	ret

	.end
