.TITLE SRDOPR-OPEN & READ .ident -6.0- ; 28-Nov-80 ;+ ; ;**SRD--SORT DIRECTORY ; ;THIS MODULE OPENS THE UFD AND READS IT INTO MEMORY ;SYSTEM MACRO CALLS ; .MCALL OFNB$,QIOW$S .GLOBL SRDOPR BUFSZ: .WORD 0 ; Real Size of Buffer .IF DF R$$11M&D$$CAL ; .MCALL EXTK$S ; .ENDC ;R$$11M&D$$CAL SRDOPR: TST F.BDB+UFDFDB ; DIRECTORY ALREADY OPEN (FROM LAST PIECE)?? BNE 10$ ; YES MOVB #FO.RD!FA.SHR,F.FACC+UFDFDB ;ASSUME ONLY READ ACCESS BIT #WBSW,SWMS2$ ;DOES HE WANT IT WRITTEN BACK? BEQ 5$ ;BR IF NO MOVB #FO.MFY,F.FACC+UFDFDB ;REQUEST ACCESS OF FILE FOR MODIFY 5$: OFNB$ #UFDFDB ;OPEN THE DIRECTORY BCC 7$ ;THIS SHOULD WORK! CMPB #IE.PRI,F.ERR+UFDFDB ; PRIV ERROR ??? BEQ 6$ FERR DOERR ; NO--SOME OTHER ERROR 6$: FERR DPRIV ; YES ; 7$: MOV UFDFDB+F.FNB+N.FID,SAVDID ; Save Directory ID MOV UFDFDB+F.FNB+N.FID+2,SAVDID+2 ; 10$: MOV DIRBF$,F.BKDS+2+UFDFDB ;POINT AT START OF BUFFER CLR @DIRBF$ MOV F.EFBK+2+UFDFDB,R1 ; IS BUFFER LARGE ENOUGH ? SUB F.BKVB+2+UFDFDB,R1 INC R1 BEQ 15$ TST F.FFBY+UFDFDB BNE 15$ DEC R1 15$: CMP R1,#127. ; Will it overflow on the calculation? BLOS 16$ ; If LOS no - carry on MOVB #127.,R1 ; Yes - use a smaller value ; (we'll get the rest later) ; 16$: SWAB R1 ASL R1 ; R1 = DIRECTORY SIZE IN BYTES MOV R1,R3 ; SAVE THAT FOR IO OPERATION BEQ 99$ ; BR ON ZERO LENGTH DIRECTORY MOV R3,BUFSZ ; Save real buffer size CMP R3,MINSZ$ ; Less than minimum size? BHIS 17$ ; If HIS no - carry on MOV MINSZ$,R3 ; Yes - use minimum ; 17$: ; Initialize buffer pointer and block number MOV DIRBF$,R4 ; SAVE BEGINNING OF BUFFER. MOV UFDFDB+F.BKVB+2,R5 ; REMEMBER CURRENT BLOCK NUMBER. BNE 20$ ; If NE OK - carry on INC R5 ; Else set to 1 ; 20$: .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$: BR 80$ ; Use what we've got 42$: MOV BUFSZ,R3 ; Restore real size required 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$,, MOVB IOSB$,UFDFDB+F.ERR ; IO WORK? BPL 50$ ; BR IF YES CMPB #IE.EOF,F.ERR+UFDFDB ;END-OF FILE??? BEQ 60$ ;CONTINUE IF YES! FERR REDE ;READ ERROR OF INPUT FILE ; 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 R5,UFDFDB+F.BKVB+2 ; Store it MOV R3,-(SP) ; SAVE R3 MOV R5,-(SP) ; Save R5 ; Now compress the directory buffer MOV IOSB$+2,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. 60$: MOVB #IE.EOF,F.ERR+UFDFDB 80$: MOV R4,F.BKDS+2+UFDFDB ; SAVE END OF DIRECTORY. RETURN ; RETURN TO MAIN 99$: JMP LSTNX$ ; PROCEED TO NEXT DIRECTORY .END