.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 HEADER: .BLKB B_HEADER FSPEC_ARG: .LONG 5 .ADDRESS HEADER ; File header .ADDRESS INDEX_RAB ; INDEXF RAB .ADDRESS .-. .ADDRESS HEADER ; Buffer used to read .DIR headers .ADDRESS IREC .PSECT CODE,NOWRT,EXE .ENTRY FID2FSPEC,^M ; ;---- 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 BLBC R0,ERROR2 $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,R0 ; 100 - FID from VBN 100 MOVAL @FID(AP),R2 ; R2 points to file ID ADDW3 R0,(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