.TITLE SRDOPR-OPEN & READ .ident -5.0- ; 19-Nov-79 ;+ ; ;**SRD--SORT DIRECTORY ; ;THIS MODULE OPENS THE UFD AND READS IT INTO MEMORY ; ; ; THIS TASK WILL SORT A RSX11M DIRECTORY ;THEN CREATE A LISTING WITH SEVERAL SELECTION OPTIONS ; ;THIS IS THE MAIN ROUTINE, AND IS PURE. ; ; MODIFICATIONS: ; ; HLC001 -- FIX BUG ON SYSTEMS WITH EXTEND TASK AND NO DYNAMIC ; CHECKPOINT ALLOCATION. ; ; DUKE002 -- FIXED PROBLEM WITH SRD ABORTING WHEN DIRECTORY TOO ; BIG. ALSO MODIFIED LOGIC THAT READS IN THE DIRECTORY ; SO THAT IF THE DIRECTORY IS TOO BIG, THEN SRD ; WILL READ IN AS MUCH OF THE DIRECTORY AS IT CAN FIT, ; COMPRESS THE DIRECTORY, THEN TRY TO READ SOME MORE. ; THIS IS DONE SO THAT IF SRD ENCOUNTERS A LARGE ; DIRECTORY FILE THAT IS NOT EXTREMELY DENSE, THEN ; IT MAY ACTUALLY SUCCEED IN SOME CASES. ; ; ;- ; ;SYSTEM MACRO CALLS ; .MCALL OFNB$,QIOW$S .GLOBL SRDOPR .IF DF R$$11M&D$$CAL ; .MCALL EXTK$S ; .ENDC ;R$$11M&D$$CAL SRDOPR: OFNB$ #UFDFDB ; OPEN THE DIRECTORY BCC 10$ ; THIS SHOULD WORK! CMPB #IE.PRI,F.ERR(R0) ; WAS ERROR A PRIVILEGE VIOLATION BEQ 5$ ; FERR OPNI ; 5$: FERR PRIV ; ; Preserve the directory file ID, Device, and unit number 10$: MOV F.FNB+N.FID(R0),SAVDID ; SAVE DIRECTORY ID MOV F.FNB+N.FID+2(R0),SAVDID+2 MOV F.FNB+N.DVNM(R0),SAVDVN ; ---AND DEVICE NAME MOV F.FNB+N.UNIT(R0),SAVUNM ; ALSO UNIT NUMBER ; Derive the total number of blocks to read in. MOV F.EFBK+2(R0),R1 ; GET LENGTH OF FILE TST F.FFBY(R0) ; END OF TOP OF BLOCK? BNE 20$ ; BR IF NO DEC R1 ; DONT COUNT EMPTY BLOCK ; Check for directories > 255 blocks in length. 20$: CMP R1,#255. ; MORE THAN 255. BLOCKS IN DIRECTORY? BLOS 22$ ; NO -- KEEP GOING. FERR DIRB ; YES -- FATAL ERROR. ; Calculate total number of bytes to read 22$: SWAB R1 ; MULT BY 256 ASL R1 ; FIND SIZE OF BUFFER NEEDED IN BYTES MOV R1,R3 ; SAVE THAT FOR IO OPERATION BEQ 99$ ; BR ON ZERO LENGTH DIRECTORY ; Initialize buffer pointer and block number MOV DIRBF$,R4 ; SAVE BEGINNING OF BUFFER. MOV #1,R5 ; REMEMBER CURRENT BLOCK NUMBER. .IF DF R$$11M&D$$CAL ; IF ON RSX11M AND DYNAMIC ... CLR DIRIC$ ; ... THEN CLEAR EXTENSION INCREMENT. .ENDC ;R$$11M&D$$CAL 30$: MOV DIRBE$,R0 ; GET TOP OF EXISTING BUFFER SUB R4,R0 ; FIND SIZE OF EXISTING BUFFER .IF DF R$$11M&D$$CAL ; IF RSX11M AND DYNAMIC ALLOCATION... BIC #^O77,R0 ; REDUCE BUFFER TO 64 BYTES. .ENDC ;R$$11M&D$$CAL ; MOV R3,R1 ; GET REMAINING BYTES TO READ IN. SUB R0,R1 ; GET NEEDED - BUFFERSIZE .IF DF R$$11M ; IF ON RSX11M ... BEQ 40$ ; BR IF NO ADJUSTMENT NEEDED. MOV R1,R0 ; GET ACTUAL NUMBER OF BYTES TO ADJUST. .REPT 6 ; ASR R0 ; CONVERT TO 64 BYTE BLOCK .ENDR ;6 .IF NDF D$$CAL ; IF NO DYNAMIC ALLOCATION... BMI 40$ ; THEN DON'T TRY TO DECREASE. .ENDC ;D$$CAL EXTK$S R0 ; ASK FOR MORE OR LESS SPACE BCS 35$ ; SKIP ON ERROR IN EXTEND. ADD R1,DIRBE$ ; INCREMENT BUFFER POINTER. .IF DF D$$CAL ; IF DYNAMIC ALLOCATION ... ADD R0,DIRIC$ ; ACCUM AMOUNT GOTTEN. .ENDC ;D$$CAL ; BR 40$ ; AND READ IN THE DIRECTORY. 35$: EXTK$S #10 ; EXTEND BY 1000 (8) BCS 40$ ; SKIP IF NO MORE SPACE. .IF DF D$$CAL ; ADD #10,DIRIC$ ; ACCOUNT FOR SPACE. .ENDC ;D$$CAL ; ADD #1000,DIRBE$ ; AND ADD INTO THE END OF BUFFER. BR 35$ ; AND TRY FOR MORE SPACE. .ENDC ;R$$11M ; ; Loop, reading in as much of the file ; as possible, compressing the buffer, ; then re-reading again. If we're unable to ; fit all the directory file into the buffer, ; then we'll quit with a fatal DIRB error. ; R0 - Used to calculate how many blocks read ; R1 - Points to the end of the buffer (For SRDCOM) ; R2 - Number of bytes to read ; R3 - Total size of directory in bytes ; R4 - Points to buffer to read into. ; R5 - Contains starting block number of read. 40$: MOV DIRBE$,R2 ; Get pointer to buffer end ; Check to see if buffer is large enough to ; read entire directory file into memory. SUB R4,R2 ; COMPUTE SIZE OF BUFFER. BLOS 41$ ; LOS - error, die BIC #777,R2 ; Block align CMP R2,#1000 ; Is there at least a block ? BHIS 42$ ; HIS - yes 41$: FERR DIRB ; Else die with fatal error 42$: CMP R2,R3 ; Is there enough space ? BLO 47$ ; LO - then enough space ; Buffer is large enough. Zero R3 so as to indicate ; that another read is not required. 45$: MOV R3,R2 ; Set length of read CLR R3 ; Show no more to read BR 48$ ; Set up the read to fill the buffer, then compress, ; and try again. 47$: SUB R2,R3 ; Adjust what's left ; Now read the directory buffer into memory. 48$: QIOW$S #IO.RVB,#UFDLUN,#DSKEFN,,#IOSB$,, TSTB IOSB$ ; IO WORK? BPL 50$ ; BR IF YES FERR REDE ; FATAL ERROR READING DIRECTORY ; Adjust pointers and set up to compress the ; dictionary. ; 50$: MOV R2,R0 ; GET AMOUNT JUST READ INTO R0 CLRB R0 ; CLEAN OUT LOW ORDER SWAB R0 ; ASR R0 ; COMPUTE NUMBER OF BLOCKS READ ADD R0,R5 ; ADJUST BLOCK POINTER. MOV R3,-(SP) ; SAVE R3 MOV R5,-(SP) ; SAVE R5 ; Now compress the directory buffer MOV R2,R1 ; GET END OF BUFFER ... ADD R4,R1 ; INTO R1. MOV R4,R2 ; GET BEGINNING INTO R2 CALL SRDCOM ; COMPRESS THE BUFFER. MOV R1,R4 ; RECOVER LAST ADDRESS IN BUFFER MOV (SP)+,R5 ; RECOVER BLOCK NUMBER MOV (SP)+,R3 ; RECOVER NUMBER OF BYTES TO BE READ BNE 30$ ; LOOP UNTIL WHOLE DIRECTORY READ ; OR UNTIL RUN OUT OF MEMORY. 80$: MOV R4,F.BKDS+2+UFDFDB ; SAVE END OF DIRECTORY. RETURN ; RETURN TO MAIN 99$: JMP LSTNX$ ; PROCEED TO NEXT DIRECTORY .END