.TITLE SCNIDX - SCANS INDEXF.SYS .SBTTL SUBROUTINE DESCRIPTION ; ; SCANS INDEX FILE ON A DEVICE ; FOR A FILE CONTAINING LOGICAL BLOCK NUMBER (LBN) ; SPECIFIED IN PARAMETER BLOCK AS FOLLOWS ; R5 = ADDRESS OF PARAMETER BLOCK ; ; 2(R5) = ADDRESS OF HI 8 BITS OF SEARCH LBN ; 4(R5) = ADDRESS OF LO 16 BITS OF SEARCH LBN ; 6(R5) = ADDRESS OF DEVICE NAME STRING ; ; FORTRAN CALLABLE AS FOLLOWS: ; ; INTEGER*4 USRLBN ! WHEN PROMPTING FOR LBN READ IT AS I*4 ; INTEGER TMPLBN(2) ; INTEGER LOLBN ; BYTE HILBN(2) ; BYTE DEVUNT(4) ; EQUIVALENCE (USRLBN,TMPLBN) ; EQUIVALENCE (LOLBN,TMPLBN) ; EQUIVALENCE (HILBN,TMPLBN(2)) ; ; ; CALL SCNIDX(HILBN,LOLBN,DEVUNT) ; ;C ETC.... ;C ; .PAGE .SBTTL MACRO DEFINITIONS .MCALL FHDOF$,HMBOF$L .MCALL QIOW$S,DIR$,ALUN$S .MCALL $GNCAL,$FBCAL,$RBCAL ; RMS GENERAL CALLS $GNCAL $FBCAL $RBCAL FHDOF$ DEF$L ; DEFINE FILE HEADER OFFSETS LOCALLY HMBOF$L DEF$L ; DEFINE HOME BLOCK OFFSETS LOCALLY .PAGE .SBTTL DATA DEFINITIONS .SBTTL D LOCAL DATA SECTIONS .PSECT LCDATA,RW,D,REL,LCL .NLIST BEX PROJ: .BLKB 1 PROG: .BLKB 1 .EVEN HILBN: .BLKB 1 .EVEN FMTBUF: .ASCIZ /%2NLBN %B,%P ALLOCATED TO FILE(S): %2N/ FNMFMT: .ASCIZ /%4A[%B,%B]%X/ FIDFMT: .ASCIZ / FILE ID=(%O,%O)%N/ DATFMT: .ASCIZ /CREATED ON %15A VBN IN FILE:%M%N/ DATSTR: .BLKB 15. OUTBUF: .BLKB 160. .EVEN LSTREC: .BLKW 1 ; ARGLST: .WORD HILBN LOLBN: .BLKW 1 ; LBN TO SEARCH FOR ; FNMARG: .BLKW 1 ; ADDRESS OF DEVICE NAME SPEC .WORD PROJ .WORD PROG ; OWNING UIC FNAME: .BLKW 5 ; FILE NAME.EXT;VER OF "FOUND" FILE FNMADR: .BLKW 1 ; FILE NAME STRING ADDRESS FOR VALIDF CALL FNMLEN: .BLKW 1 ; LENGTH OF CONVERTED FILE SPEC ; FIDARG: U.FNUM: .BLKW 1 ; FID FROM HEADER U.FSEQ: .BLKW 1 DATARG: .WORD DATSTR ; DATE CONVERT ARG BLOCK FILVBN: .WORD 0 ; VBN OF CURRENT FILE BEING SCANNED ; MSGLEN: .BLKW 1 PRMBLK: ; PARAMETER BLOCK FOR OPNIDX CALL .WORD 2 ; NUMBER OF ARGUMENTS DEVNAM: .BLKW 1 ; SPACE FOR ADDRESS OF DEVNAME STRING BUFADR: .WORD FILHDR ; BUFFER ADDRESS FAB: .BLKW 1 ; FAB RETURNED FROM OPNIDX RAB: .BLKW 1 ; RAB RETURNED FROM OPNIDX MAXHDR: .BLKW 1 RV.PTR: ; CURRENT RETRIEVAL POINTER RV.HBN: .BLKB 1 ; HI LBN OF CURRENT POINTER RV.CNT: .BLKB 1 ; BLOCK COUNT RV.LBN: .BLKW 1 ; LO LBN OF CURRENT POINTER MAPOFF: .BLKW 1 ; ADDRESS OF BEGINING OF MAP AREA .PAGE .SBTTL D GLOBAL DATA SECTIONS ; .PSECT FILHDR,RW,D,GBL,REL,OVR FILHDR: .BLKB 512. ; FILE HEADER DATA FROM INDEX FILE ; .PSECT BITMAP,RW,D,GBL,REL,OVR BITMAP: .BLKB 512.*4 ; BITMAP FOR FILE HEADERS ; .PSECT HDRCNT,RW,D,GBL,REL,OVR GHDRS: .WORD 0 ; NUMBER OF GOOD HEADERS BHDRS: .WORD 0 ; NUMBER OF BAD HEADERS BMSIZ: .BLKW 1 ; BITMAP SIZE AS STORED IN HOME BLOCK FMAX: .BLKW 1 ; MAXIMUM NUMBER OF FILE HEADERS ; ; .PAGE .SBTTL MAIN LINE CODE .SBTTL I SUBROUTINE INITIALIZATION .EVEN .ENABLE LSB .PSECT SCNIDX,RW,I,REL SCNIDX:: MOVB @2(R5),HILBN ; STORE LBN MOV @4(R5),LOLBN ; TO SEARCH FOR (24 BITS) MOV 6(R5),DEVNAM ; MOVE ADDRESS OF DEVNAME TO PARM BLOCK MOV 6(R5),FNMARG ; COPY ADDRESS FOR OUTPUT CONVERSION LATER MOV #OUTBUF,R0 ; R0 = OUTPUT BUFFER ADDRESS MOV #FMTBUF,R1 ; R1 = FMT CNV STRING ADDR (.ASCIZ) MOV #ARGLST,R2 ; R2 = ADDRESS OF VALUES TO CONVERT CALL $EDMSG MOV R1,MSGLEN QIOW$S #IO.WVB,#5,#1,,,,<#OUTBUF,MSGLEN> ; OUTPUT INTRO MSG MOV #PRMBLK,R5 ; LOAD R5 FOR SUBROUTINE CALL CALL OPNIDX ; OPEN THE INDEX FILE ; RETURNS WITH FAB IN RO ; RAB IN R1 MOV R0,FAB ; SAVE THE VALUES MOV R1,RAB ; RETURNED $FETCH MAXHDR,ALQ,R0 ; FIND OUT HOW MANY FILE HEADERS THERE ARE MOV #2,R2 ; POINT TO HOME BLOCK'S VBN CLR R3 ; CLEAR OUT HIGH HALF VBN $STORE R2,BKT,R1 ; STORE VBN FOR READ $READ R1,#RABERR ; READ THE HOME BLOCK IN MOV #FILHDR,R4 ; ADDRESS OF FILE HEADER MOV H.FMAX(R4),FMAX ; SAVE MAXIMUM FILES ALLOWED FOR LATER USE MOV H.IBSZ(R4),R2 ; SIZE OF INDEX FILE BIT MAP IN BLOCKS MOV R2,BMSIZ ; SAVE IT FOR LATER SWAB R2 ; CONVERT TO BYTE COUNT ASL R2 ; BY MUMBO JUMBO MATH $STORE R2,USZ,R1 ; STORE BYTE COUNT TO READ IN THE RAB $STORE #BITMAP,UBF,R1 ; READ INTO BITMAP BUFFER CLR R3 MOV #3,R2 ; POINT TO VBN OF BITMAP $STORE R2,BKT,R1 ; STORE VBN FOR READ $READ R1,#RABERR $STORE #512.,USZ,R1 ; RESTORE THE BYTE COUNT TO 1 BLOCK $STORE #FILHDR,UBF,R1 ; AND THE BUFFER MOV BMSIZ,R2 ; NOW RESTORE THE BMSIZ VALUE ADD #2,R2 ; OFFFSET FOR BOOT,HOME INC R2 ; NOW INCREMENT FOR 1ST VBN .PAGE .SBTTL I READ A FILE HEADER RDHDR: MOV RAB,R1 ; PICK UP THE RAB ADDRESS CLR R3 ; CLEAR OUT HIGH HALF VBN $STORE R2,BKT,R1 ; STORE VBN TO READ MOV R2,LSTREC ; SAVE FOR LATER READIT: $READ R1,#RABERR ; READ THE FILE HEADER IN .SBTTL I SEE IF IT'S A VALID HEADER CALL VALHDR ; IS IT A VALID FILE HEADER BCC 15$ ; SIMULATE A LONG BRANCH JMP 355$ ; NO, SKIP, NOT USED AS A FILE HEADER YET .SBTTL I HEADER IS VALID 15$: CLR R3 ; VALID FILE HEADER MOV #FILHDR,R4 ; FIND START OF FILE HEADER MOVB H.MPOF(R4),R3 ; CALCULATE ADDRESS OF MAP AREA ASL R3 ; CONVERT TO BYTE OFFSET ADD R3,R4 ; R4 = ADDRESS OF BEG OF MAP AREA IN HEADER MOV R4,MAPOFF ; SAVE ADDRESS FOR LATER USE 20$: CLR R0 BISB M.USE(R4),R0 ; WORDS OF RETRIEVAL POINTERS USED BNE 25$ ; IF THERE ARE ANY POINTERS COINTINUE JMP 355$ ; IF NOT JUMP TO CLEANUP 25$: CLC ; CLEAR OUT FOR SHIFT ASR R0 ; 2 WORDS FOR EACH POINTER ; R0 = # OF RETRIEVAL POINTERS ADD #M.RTRV,R4 ; R4 = ADDRESS OF FIRST RETRIEVAL POINTER .PAGE .SBTTL I CHECK RETRIEVAL POINTERS WITHIN HEADER NXTPTR: MOV (R4)+,RV.PTR ; COPY THIS POINTER MOV (R4)+,RV.LBN ; TO TEMP STORAGE CLR R1 ; CLEAR OUT R1 BISB RV.CNT,R1 ; ADD COUNT TO POINTER ADD R1,FILVBN ; ADD TO FILE'S VBN ADD #1,FILVBN ; NOW ADJUST FOR LBN TO VBN CMPB HILBN,RV.HBN ; TEST THE HIGH LBN'S BNE 50$ ; NOT EQUAL CHECK NEXT MOV RV.LBN,R1 ; GET THE STARTING BLOCK # CMP R1,LOLBN ; POINTER < LOLBN ? BHI 50$ ; NO, TRY NEXT CLR R1 ; CLEAR OUT R1 BISB RV.CNT,R1 ; ADD COUNT TO POINTER ADD RV.LBN,R1 ; NOW ADD THE BASE LBN CMP R1,LOLBN ; POINTER >= LOLBN ? BEQ 100$ ; YES, THEN THIS IS THE FILE BHI 100$ ; YES ALSO .SBTTL I LBN OUT OF RANGE, CHECK NEXT RETRIEVAL POINTER 50$: SOB R0,NXTPTR ; GET NEXT POINTER IF ANY MOV MAPOFF,R4 ; SEE IF THERE IS AN EXTENSION FILE HEADER MOV M.EFNU(R4),R2 ; BEQ 355$ ; NO EXTENSION HEADER GET NEW FILE HEADER MOV RAB,R1 ; PICK UP THE RAB ADDRESS ADD BMSIZ,R2 ; ADD OFFSET FOR BITMAP SIZE & ADD #2,R2 ; BOOT,HOME BLOCK TO CONVERT FID TO VBN CLR R3 ; CLEAR OUT HIGH HALF VBN $STORE R2,BKT,R1 ; STORE VBN OF EXTENSION FILE HEADER JMP READIT .PAGE .SBTTL I LBN IN RANGE .SBTTL I EXTRACT FILE HEADER INFO FOR OUTPUT 100$: ; R1 = CNT + RV.LBN SUB LOLBN,R1 ; CALCULATE THE OFFSET IN THIS POINTER SUB R1,FILVBN ; ADJUST FILVBN ACCORDINGLY MOV R2,LSTREC ; SAVE VBN, NEED R2 FOR WORK MOV #FILHDR,R4 ; PICK UP BEGINNING OF FILE HEADER MOVB H.PROG(R4),PROG ; GET THE UIC MOVB H.PROJ(R4),PROJ ; GET THE UIC MOV H.FNUM(R4),U.FNUM ; COPY FILE ID MOV H.FSEQ(R4),U.FSEQ ; AND SEQUENCE NUMBER CLR R3 BISB H.IDOF(R4),R3 ; CALCULATE ADDRESS OF ID AREA CLC ; CLEAR OUT CARRY BIT ASL R3 ; CONVERT TO BYTE OFFSET ADD R3,R4 ; R4 = ADDRESS OF BEG OF ID AREA IN HEADER MOV R4,R3 ; R3 = DITTO ; ADD #I.FNAM,R3 ; PICK UP RAD50 FILE NAME MOV #FNAME,R2 MOV (R3)+,(R2)+ ; COPY NAME WD 1 MOV (R3)+,(R2)+ ; COPY NAME WD 2 MOV (R3)+,(R2)+ ; COPY NAME WD 3 MOV (R3)+,(R2)+ ; COPY EXTENSION MOV (R3)+,(R2)+ ; COPY VERSION MOV #OUTBUF,R0 ; R0 = OUTPUT BUFFER ADDRESS MOV #FNMFMT,R1 ; OUTPUT FILE SPEC MOV #FNMARG,R2 CALL $EDMSG MOV R1,MSGLEN ; SAVE MSGLEN FOR QIO MOV #OUTBUF,R2 ; PUT ADDRESS OF FILSPC IN R2 ADD #I.CRDT,R4 ; POINT TO CREATION DATE MOV #DATSTR,R2 ; POINT TO DATE STRING MOVB (R4)+,(R2)+ ; PICK UP DAY MOVB (R4)+,(R2)+ MOVB #'-,(R2)+ MOVB (R4)+,(R2)+ ; PICK UP MONTH MOVB (R4)+,(R2)+ MOVB (R4)+,(R2)+ MOVB #'-,(R2)+ MOVB (R4)+,(R2)+ ; PICK UP YEAR MOVB (R4)+,(R2)+ MOVB #40,(R2)+ ; SPACE MOVB (R4)+,(R2)+ ; PICK UP HOURS MOVB (R4)+,(R2)+ MOVB #':,(R2)+ MOVB (R4)+,(R2)+ ; AND MINUTES MOVB (R4)+,(R2)+ MOV #FIDFMT,R1 MOV #FIDARG,R2 CALL $EDMSG ; FORMAT FILE ID FOR QIO ADD R1,MSGLEN MOV #DATFMT,R1 ; FORMAT CREATION DATE & TIME MOV #DATARG,R2 CALL $EDMSG ADD R1,MSGLEN QIOW$S #IO.WVB,#5,#1,,,,<#OUTBUF,MSGLEN> 300$: MOV LSTREC,R2 INC R2 JMP RDHDR .PAGE .SBTTL I HEADER IS NOT VALID .SBTTL I TEST FOR EOF INDEX FILE 355$: CLR FILVBN ; CLEAR OUT VBN COUNTER MOV LSTREC,R2 ; GET LAST SAVED (NON-EXTENSION) FILE HEADER INC R2 ; INCREMENT VBN COUNTER CMP R2,MAXHDR ; OUT OF FILE HEADERS? BGE RTN ; READ NEXT FILE HEADER JMP RDHDR ; READ NEXT FILE HEADER RTN: RETURN ; RETURN TO MAIN .END