.TITLE DIROPR - OPEN AND READ DIRECTORY FILE .IDENT /18APR82/ ; .IDENT /V5.0/ ; UPDATE AUDIT CONTROL-13 NOV 1979 12:09:12 ;**V5.0 ; EDIT # 0021 2 NOV 1979 14:37:58 DK1:[300,3]SRDOPR.MAC;31 ;**V5.0 ; PREVIOUS EDIT 2 NOV 1979 14:22:38 DK1:[300,3]SRDOPR.MAC;30 ;**V5.0 ;+ ;**-1 ; ; DIROPR.MAC - COMPOSITE OF TWO SRD V5.0 MODULES: SRDOPR, SRDSRT. ; THIS ROUTINE WILL READ IN THE DIRECTORY FILE, AND COMPRESS ENTRIES ; AS THE DIRECTORY BLOCKS ARE READ. IF NECESSARY, THE TASK WILL ; EXTEND ITSELF TO ACCOMODATE LARGE DIRECTORIES (FUNCTIONS PERFORMED ; BY SRDOPR). ONCE THE DIRECTORY ; IS IN AND COMPRESSED, THE ENTRIES WILL BE SORTED AND WRITTEN BACK ; IF SO DIRECTED (FUNCTIONS PERFORMED BY SRDSRT). ; ;***** ; ; UPDATE 2/16/82 -- PRS; ADD CODE TO COPY CURRENT DIRECTORY FILENAME ; BLOCK TO ANOTHER AREA...USED BY SELECTIVE DELETE AND OUTPUT ; LISTING HEADER ROUTINES ; ; UPDATE 4/18/82 -- PRS; CHANGE MODULE NAME TO REFLECT MAJOR CHANGE TO ; "SRDOPR". INCLUDE SRDSRT FUNCTIONS AND SRD V6.0 COMPRESSION ; OF DIRECTORY AS ITS READ IN. CHANGE EXTEND TASK TO ONLY ; EXTEND 4 BLOCKS (1KW) AT A TIME, OR 1 BLOCK IF 4 BLOCKS ; WON'T WORK. TRUNCATE DIRECTORY FILE AFTER WRITE-BACK ; ; UPDATE 5/9/82 -- PRS; CONDITIONALIZE DIAGNOSTIC MESSAGE FOR EXTENDING ; TASK LIMITS WITH TKB GLOBAL DEFINITION OF $DIEXT. $DIEXT =0, ; FOR NO DIAGNOSTIC; $DIEXT >/< 0, ISSUES DIAGNOSTIC. ; ;***** ;- ; ;SYSTEM MACRO CALLS ; .MCALL OFNB$,READ$,WRITE$,WAIT$,CLOSE$,FDOF$L FDOF$L .PSECT $CODE1,RO,I,LCL,CON,REL .DROPR:: ;CHANGE MODULE ENTRY POINT NAME MOV #UFDFDB,R0 TST F.BDB(R0) ; DIRECTORY ALREADY OPEN (FROM LAST PIECE)?? BNE 10$ ; YES MOV #,R1 ;COPY CURRENT DIRECTORY FILENAME BLOCK TO ; ANOTHER AREA 3$: MOV UFDFDB+F.FNB(R1),SAVFNB(R1) SUB #2,R1 ;ADJUST OFFSET INTO FILENAME BLOCK BGE 3$ ;LOOP TIL DONE MOVB #FO.RD!FA.SHR,F.FACC(R0) ;ASSUME ONLY READ ACCESS BIT #WBSW,SWMSK$ ;WRITING BACK ? BEQ 5$ ;BRANCH IF NO MOVB #FO.MFY,F.FACC(R0) ;REQUEST ACCESS OF FILE FOR MODIFY 5$: OFNB$ R0 ;OPEN THE DIRECTORY BCC 10$ ;THIS SHOULD WORK! CMPB #IE.PRI,F.ERR(R0) ; PRIV ERROR ??? BEQ 6$ ;BRANCH IF YES FERR DOERR ; NO--SOME OTHER ERROR 6$: FERR DPRIV 10$: MOV F.EFBK+2(R0),R1 ;DETERMINE # BLOCKS IN DIRECTORY FILE SUB F.BKVB+2(R0),R1 INC R1 BEQ 13$ TST F.FFBY(R0) BNE 13$ DEC R1 13$: MOV DIRBF$,R2 ;FETCH START ADDRESS OF BUFFER CLR (R2) ;SHOW NOTHING THERE YET TST R1 ;CHECK # BLOCKS TO READ BEQ 40$ ;BRANCH IF 0, ALL DONE 15$: MOV R2,F.BKDS+2(R0) ;SAVE CURRENT BUFFER POINTER ADD #512.,R2 ;ENOUGH ROOM FOR 1 BLOCK ? 16$: CMP R2,DIRBE$ BLOS 20$ ;BRANCH IF YES, READ IT EXTK$S #040 ;TRY TO EXTEND 4 BLOCKS (1KW) BCS 18$ ;BRANCH IF FAILED ADD #04000,DIRBE$ ;UPDATE SPACE AVAILABLE BR 19$ ; AND PROCEED TO READ 1 BLOCK 18$: EXTK$S #010 ;TRY TO EXTEND 1 BLOCK BCS 41$ ;BRANCH IF CAN'T EVEN GET 1 BLOCK ADD #01000,DIRBE$ ;UPDATE SPACE AVAILABLE 19$: TST #$DIEXT ;ISSUE DIAGNOSTIC ? BEQ 20$ ; BRANCH IF NO DIAG EXTNDT ;NOTIFY USER 20$: READ$ R0 ;READ BLOCK FROM DIRECTORY BCS 25$ ;BRANCH ON PROBLEMS WAIT$ R0 ;WAIT FOR COMPLETION BCC 30$ ;BRANCH IF OK 25$: CMPB #IE.EOF,F.ERR(R0) ;END-OF FILE??? BEQ 41$ ;CONTINUE IF YES! FERR REDE ;READ ERROR OF INPUT FILE 30$: MOV F.BKDS+2(R0),R2 ;RECOVER START ADDRESS OF DATA BLOCK CALL CMPRES ;COMPRESS ENTRIES IN PLACE DEC R1 ;ADJUST # BLOCKS LEFT TO READ BNE 15$ ;BRANCH IF MORE TO DO MOV R2,F.BKDS+2(R0) ;SAVE CURRENT BUFFER POINTER ; *** NOTE: DIRECTORY LIST RUNS FROM DIRBF$ TO F.BKDS+2(R0) 40$: MOVB #IE.EOF,F.ERR(R0) 41$: BIT #SRSW,SWMSK$ ;SORTING ENTRIES ? BEQ 50$ ;BRANCH IF NO CALL SORT ;SORT ENTRIES 50$: BIT #WBSW,SWMSK$ ;DIRECTORY WRITE BACK SELECTED ? BEQ 60$ ;BRANCH IF NO CMPB #IE.EOF,F.ERR(R0) ; GOT ENTIRE DIRECTORY?? BEQ 55$ ; BRANCH IF YES FERR WBCAN ; NO, CANCEL WRITE BACK 55$: CALL WRTBCK ;WRITE BACK COMPRESSED LIST RETURN ;ONLY RETURN FROM WRTBCK IS SUCCESS 60$: CMPB #IE.EOF,F.ERR(R0) ; DONE WITH DIRECTORY ?? BEQ 70$ ; BRANCH IF YES DIAG BIGDIR ;SHOW PROBLEM GETTING ENTIRE DIRECTORY BIT #PUSW,SWMSK$ ;DOING A PURGE? BEQ 100$ ;BRANCH IF NO DIAG PURGER ;SHOW PROBLEM WITH PURGE BR 100$ ; AND CONTINUE 70$: CLOSE$ R0 ;CLOSE THE UFD 100$: RETURN ; ;+ ;***** ; ; LOCAL SUBROUTINE SECTION ; ; CMPRES - COMPRESSES ONE BLOCK (512. BYTES) OF DIRECTORY ENTRIES ; IN PLACE. ADAPTED FROM SRDCMP V 6.0. ; ; REGISTER USAGE -- ; ON ENTRY ; R2 - POINTS TO START OF DATA BLOCK ; ON RETURN ; R2 - POINTS TO 1ST OPEN SPACE IN BUFFER, THIS WORD IS CLEARED ; ; R3-R5, ASSUMED FREE FOR USE ; ;***** ;- ; CMPRES: MOV #<512./D.SIZ>,R5 ;SET # ENTRIES TO SCAN 2$: TST (R2) ;LOOK FOR 1ST NULL FID BEQ 8$ ;BRANCH IF FOUND ADD #D.SIZ,R2 ;ADJUST POINTER SOB R5,2$ ;LOOP TIL DONE BR 30$ ; 8$: MOV R2,R3 ;COPY CURRENT POINTER BR 20$ ; AND SKIP THIS ENTRY 10$: TST (R3) ;CHECK FID BEQ 20$ ;BRANCH IF NULL MOV #,R4 ;SET # WORDS IN ENTRY 15$: MOV (R3)+,(R2)+ ;COPY ENTRY SOB R4,15$ CLR -D.SIZ(R3) ;CLEAR FID OF ENTRY JUST COPIED BR 21$ 20$: ADD #D.SIZ,R3 ;ELSE, ADJUST POINTER 21$: SOB R5,10$ ; AND LOOK AGAIN 30$: CLR (R2) ;FORCE NULL WORD AT END OF BUFFER RETURN ;RETURN TO CALLER ; ;+ ;***** ; ; SORT DIRECTORY JUST READ IN -- ADAPTED FROM SRDSRT V5.0 ; ;***** ;- ; ;LOCAL MACRO ; .ENABL LSB .MACRO C$MP ARG CMP ARG(R3),ARG(R4) ;SEE WHICH IS BIGGER BHI EXCHNG ;IF HI EXCHANGE POINTERS BLO CONTIN ;IF LO-CONINTUE .ENDM SORT: ;ENTRY POINT MOV F.BKDS+2(R0),R1 ;FETCH TOP OF DIRECTORY LIST MOV DIRBF$,R2 ;FETCH START OF DIRECTORY LIST 10$: MOV R2,R3 ;COPY ADDRESS OF CURRENT TOP MOV R3,R4 ;AGAIN 20$: ADD #D.SIZ,R4 ;POINT AT NEXT ITEM CMP R4,R1 ;WATCH FOR END BHIS 40$ ;BR WHEN ALL DONE BIT #NASW,SWMSK$ ;SORT BY NAME ? BNE 30$ ;BR IF YES C$MP D.TYP ;CK FOR FILE TYPE 30$: C$MP D.FNAM ;NOW FIRST PART OF NAME C$MP D.FNAM+2 ;SECOND PART C$MP D.FNAM+4 ;AND THIRD C$MP D.TYP ;DO TYPE INCASE WE'RE GOING BY NAME ; ; FALL THROUGH FOR NAME MATCH ; ... NOW CHECK FOR HIGHEST VERSION ; CMP D.VER(R3),D.VER(R4) BHI CONTIN EXCHNG: MOV R4,R3 CONTIN: BR 20$ ; ; COME HERE AFTER A SCAN COMPLETE ; 40$: CMP R2,R3 ;MAKE SURE IT CHANGED BNE 45$ ;BR IF EXCHANGE REQUIRED ADD #D.SIZ,R2 BR 60$ 45$: MOV #8.,R4 ;SET LOOP COUNT 50$: MOV (R2),-(SP) ;PUSH 1 MOV (R3),(R2)+ ;COPY NEW OVER OLD MOV (SP)+,(R3)+ ;NOW PUT SOB R4,50$ ; 60$: CMP R2,R1 ;SEE IF DONE BLO 10$ ;BR IF MORE TO DO 63$: RETURN .DSABL LSB ; ;+ ;***** ; ; WRTBCK -- WRITES BACK DIRECTORY BUFFER TO UFD ; ;***** ;- ; WRTBCK: MOV #WBTRY,R4 ;FETCH RE-TRY LOOP COUNT MOV F.BKDS+2(R0),R1 ;FETCH TOP OF DIRECTORY MOV R1,R2 ;COPY IT SUB DIRBF$,R2 ;ADJUST FOR OFFSET BIC #177000,R2 ;CLEAR OUT EVEN # OF BLOCKS BEQ 5$ ;BRANCH IF ON AN EVEN BLOCK SUB #512.,R2 ;DETERMINE # BYTES TO CLEAR NEG R2 ASR R2 ;MAKE IT WORDS 3$: CLR (R1)+ ;ZERO OUT REMAINDER OF LAST BLOCK SOB R2,3$ 5$: CLR R5 MOV #1,F.EFBK+2(R0) ;RESET END-OF-FILE MOV DIRBF$,F.BKDS+2(R0) ;POINT I-O BUFFER TO TOP MOV #1,F.VBN+2(R0) ;AND ALSO VIRT. BLK NUMBER 10$: WRITE$ R0 ;WRITE OUT A BLOCK BCS 15$ ; BRANCH ON ERROR WAIT$ R0 ;WAIT FOR COMPLETION BCC 20$ 15$: DIAG WBERR ; ISSUE DIAGNOSTIC, WILL RETRY INC R5 20$: ADD #512.,F.BKDS+2(R0) ;ADJ. BUFFER TO NEXT BLK CMP F.BKDS+2(R0),R1 ;SEE IF WE'RE PAST END OF DATA BLO 10$ ;BRANCH IF NO ; ; CHECK FOR ERROR & RETRY IF NEEDED ; TST R5 ; ANY ERRORS ? BEQ 30$ ; BRANCH IF NO SOB R4,5$ ; RETRY FERR WBERR ; RETRIES FAILED, FATAL THIS TIME 30$: CALL .TRNCL ;TRUNCATE AND CLOSE DIRECTORY FILE RETURN ;ONLY RETURN IS SUCCESS .END