	.TITLE	FID2FSPEC
;
;----	Purpose:	Retrieve the directory + file specification
;			from the input device specification and file ID
;
;----	Arguments:
;
D_DEVICE=4	;Input	C*(*)		Device spec. descriptor
FID=8		;Input	3*(I*2)		File ID
D_FSPEC=12	;Output	C*(*)		Filespec descriptor
;
;----	Note that if FSPEC is not sufficiently large to hold the filespec,
;----	the filespec is truncated on the right. If FSPEC is sufficiently
;----	large, it is blank-filled on the right.
;
;----	Equates:
;
B_HEADER = 512		; Byte length of header record
B_DEVICE = 16		; Maximum byte length of device specification
F.FID = 8		; File ID offset in file header
;
	.PSECT	FNDATA,WRT,NOEXE,LONG

INDEX_FAB:	$FAB	FNA=INDEX_NAME,RFM=FIX,NAM=INDEX_NAM,MRS=B_HEADER,
INDEX_NAM:	$NAM
INDEX_RAB:	$RAB	FAB=INDEX_FAB,UBF=HEADER,USZ=B_HEADER,-
			RAC=KEY,KBF=IREC,KSZ=4

INDEX:		.ASCII	'[0,0]INDEXF.SYS;1'
B_INDEX = 	.-INDEX
INDEX_NAME:	.BLKB	B_DEVICE + B_INDEX
IREC:		.LONG	0
OFFSET:		.LONG	0
HEADER:		.BLKB	B_HEADER

FSPEC_ARG:	.LONG	6
	.ADDRESS	HEADER		; File header buffer
	.ADDRESS	INDEX_RAB	; INDEXF RAB
	.ADDRESS	.-.		; Filespec descriptor
	.ADDRESS	HEADER		; Buffer used to read .DIR headers
	.ADDRESS	IREC		; Directory file header VBN
	.ADDRESS	OFFSET		; OFFSET+FID=VBN of file header

	.PSECT	CODE,NOWRT,EXE
	.ENTRY	FID2FSPEC,^M<R2,R3,R4,R5,R6,R7,R8>
;
;----	Combine the device and INDEXF.SYS into a complete file spec
;

	MOVAL	@D_DEVICE(AP),R6	; R6 points to device descr.
	MOVAL	@D_FSPEC(AP),R7		; R7 points to filespec descr.
	MOVL	R7,FSPEC_ARG+<3*4>
	MOVC5	#0,.-.,#^A' ',(R7),@4(R7)	;Init fspec to ' '

	CLRL	R1			; R1 counts file spec bytes
	MOVAL	@4(R6),R2
P5:
	MOVB	(R2)+,INDEX_NAME(R1)	; Move device spec to INDEX file spec
	CMPB	#^A' ',INDEX_NAME(R1)
	BEQLU	P10			; Stop on first blank
	INCB	R1
	CMPB	R1,(R6)
	BGEQU	P10			; Stop if no more characters
	CMPB	R1,#B_DEVICE
	BLSSU	P5			; Stop if no more room
P10:
	ADDB3	R1,#B_INDEX,INDEX_FAB+FAB$B_FNS	; length of INDEX spec
	MOVC3	#B_INDEX,INDEX,INDEX_NAME(R1)	; rest of INDEX spec
;
;----	Open and connect the Index file
;
	$OPEN	FAB=INDEX_FAB		; Open INDEXF.SYS
	BLBS	R0,P15
	BRW	ERROR2
P15:
	$CONNECT	RAB=INDEX_RAB
	BLBC	R0,ERROR1
;
;----	Determine the Index file OFFSET such that:
;----	Index file VBN of file header = OFFSET + File ID
;----	by retrieving the FID from VBN 100
;
	MOVW	#100,IREC
	$GET		RAB=INDEX_RAB
	SUBW3	HEADER+F.FID,#100,OFFSET	; 100 - FID from VBN 100
	MOVAL	@FID(AP),R2		; R2 points to file ID
	ADDW3	OFFSET,(R2),IREC	; Offset + FID = INDEXF record #
	$GET		RAB=INDEX_RAB
	BLBC	R0,ERROR1
	CMPL	(R2),HEADER+F.FID	; Compare MS 2 words of file ID
	BNEQU	ERROR1
	CMPW	4(R2),HEADER+F.FID+4	; Compare LS word of file ID
	BNEQU	ERROR1
;
;----	Use FSPEC to generate the file specification from the file header
;
	CALLG	FSPEC_ARG,G^FSPEC
	JSB	CLOSE
	BRB	RETURN
	
ERROR1:
	JSB	CLOSE
ERROR2:
	MOVL	#SS$_BADPARAM,R0
RETURN:
	RET
;
;----	CLOSE:	Internal subroutine to close INDEX.SYS
;
CLOSE:
	$CLOSE	FAB=INDEX_FAB
	RSB
	.END
