$BEGIN DSCBT,0003, ; ; COPYRIGHT (C) 1976 BY DIGITAL EQUIPMENT CORPORATION, ; MAYNARD, MASSACHUSETTS ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE IN- ; CLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ; ANY OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE ; MADE AVAILABLE TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH ; SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE ; TO AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN ; IN DIGITAL. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITH- ; OUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ; DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY FOR ; THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT WHICH IS ; NOT SUPPLIED BY DIGITAL. ; ; ANDREW C. GOLDSTEIN 11-AUG-76 4:32 ;+ ; ; THIS ROUTINE INITIALIZES THE CONTENTS OF THE OUTPUT DISK'S ; STORAGE BITMAP FILE. FUNCTIONALLY, IT SETS ALL BITS TO 1 (FREE) ; AND THEN ALLOCATES ALL OF THE REGIONS LISTED IN THE ALLOCATION ; TABLE, AS WELL AS CLEARING THE DEAD SPACE AT THE END OF THE LAST ; BITMAP BLOCK. ; ; INPUTS: ; ; OUTLUN ASSIGNED TO DISK ; DATA IN ALLOCATION TABLE ; ; OUTPUTS: ; ; STORAGE MAP FILE WRITTEN TO DISK ; ;- $DSCBT:: ; ; FIRST MAKE UP AN ALLOCATION POINTER FOR THE NON-EXISTENT BLOCKS ; FROM THE END OF THE VOLUME UP TO THE NEXT STORAGE MAP BLOCK ; BOUNDARY. ; $CALL $DDIV <$CLF,$VOLSZ+2,$VOLSZ> ; REDUCE VOLUME SIZE BY CLF $CALL $DDIV <#4096.,R1,R2> ; R0 = # CLUSTERS IN LAST BLOCK LET R1 := #4096. - R0 ; NUMBER OF NONEXISTENT CLUSTERS $CALL $MUL <$CLF,R1> ; NUMBER OF CLUSTERS LET R2 := #$VOLND ; POINT TO TABLE ENTRY LET (R2)+ := R1 ; STORE IN TABLE ENTRY LET (R2)+ := R0 LET (R2)+ := $VOLSZ ; (STARTING LBN) LET (R2)+ := $VOLSZ+2 ; ; NOW INITIALIZE THE STORAGE CONTROL BLOCK. SINCE ONLY VFY LOOKS AT ; THIS, A VAGUE FACSIMILE IS ALL THAT IS NEEDED. ; LET R0 := #.SMBUF ; POINT TO STORAGE MAP BUFFER LET (R0)+ := #0 LET R1 := $SBM - #1 ; GET SIZE OF STORAGE MAP FILE IF R1 GT #126. THEN LET R1 := #1 ; TOUGH LUCK, FELLAS LET (R0)+ :B= #0 LET (R0)+ :B= R1 ; PUT IN BLOCK THRU R1 LET (R0)+ := #4096. ; 4096 DISK BLOCK PER MAP BLOCK LET (R0)+ := #0 END LOOP LET (R0)+ := $CW2 ; VOLUME SIZE LET (R0)+ := $CW3 WHILE R0 LO #.SMBUF+512. LET (R0)+ := #0 ; CLEAR REST OF BUFFER END LOOP LET .SMVBN := #0 ; THIS BLOCK PRECEDES REAL MAP LET .SMFLG := .SMFLG + #1 ; MARK BUFFER DIRTY ; WILL BE FLUSHED BELOW ; ; NOW FIND THE ENTRIES IN THE ALLOCATION TABLE IN ORDER BY LBN. ; MARK OFF EACH ENTRY IN THE STORAGE MAP BUFFER. WHEN WE PASS THE ; END OF THE BUFFER, FLUSH IT AND RE-INIT TO ALL ONES. ; LET $LBN := #0 ; START WITH BLOCK 0 LET $LBN+2 := #0 $CALL NXB ; INIT BUFFER FIRST REPEAT ; LOOP FOR ALL TABLE ENTRIES LET R1 := #-1 ; HIGHEST LBN LET R2 := R1 FOR.ABS R5 := #$BOOTB+4 TO #$VOLND+12. BY #8. ; SEARCH FOR NEXT AREA IF -4(R5) NE #0 OR -2(R5) NE #0 ; IGNORE NULL AREAS DCOMP 2(R5),(R5), $LBN+2,$LBN IF RESULT IS HIS ; LOOK FOR BLOCKS GREATER THAN CURRENT DCOMP 2(R5),(R5), R1,R2 ; AND LESS THAN LOWEST SO FAR IF RESULT IS LO LET R1 := 2(R5) ; SET NEW LOWEST LET R2 := (R5) LET R3 := R5 ; MARK THE SPOT END END END END LOOP IF R1 EQ #-1 AND R2 EQ R1 LEAVE LOOP ; DONE THEM ALL LET $LBN := R2 + #01 ; SAVE LBN FOR NEXT ENTRY LET $LBN+2 := R1 + CARRY ; ; FOUND NEXT GROUP OF BLOCKS. COMPUTE NUMBER OF BITS TO CLEAR ; AND THE BITMAP LOCATION WHERE THEY START. ; $CALL $DDIV <$CLF,-2(R3),-4(R3)> ; REDUCE BY CLUSTER FACTOR IF R0 NE #0 FATAL END PUSH R1,R2 ; SAVE COUNT $CALL $DDIV <$CLF,2(R3),(R3)> ; REDUCE LBN BY CLUSTER FACTOR $CALL $DDIV <#4096.,R1,R2> ; COMPUTE MAP BLOCK LET R2 := R2 + #1 ; MAKE REAL VBN IF R2 LO .SMVBN ; IF BEFORE WHERE WE ARE FATAL END WHILE .SMVBN LO R2 ; IF PAST CURRENT BUFFER $CALL NXB ; GO TO NEXT BLOCK END LOOP ; ; CORRECT MAP BLOCK IS NOW IN BUFFER. MARK OFF BITS. ; BEGIN MARKS $CALL $DIV ; COMPUTE WORD NUMBER IN BLOCK LET R0 := R0 L.SHIFT 1 + #.SMBUF ; WORD ADDRESS LET R1 := R1 + #1 LET R2 := #0 SEC THRU R1 LET R2 := R2 L.ROTATE 1 ; POSITION TO INITIAL BIT END LOOP REPEAT ; LOOP FOR BLOCKS REPEAT ; LOOP FOR WORDS REPEAT ; LOOP FOR BITS LET (R0) := (R0) OFF.BY R2 ; CLEAR A BIT LET (SP) := (SP) - #01 ; COUNT THE BIT LET 2(SP) := 2(SP) - CARRY IF (SP) EQ #0 AND 2(SP) EQ #0 LEAVE MARKS LET R2 := R2 L.ROTATE 1 ; AND ADVANCE UNTIL RESULT IS CS LET R2 := #1 ; RE-INIT BIT TST (R0)+ ; NEXT WORD UNTIL R0 HIS #.SMBUF+512. ; UNTIL END OF BUFFER $CALL NXB ; MOVE TO NEXT BLOCK LET R0 := #.SMBUF ; POINT TO START OF BUFFER END LOOP END MARKS ; DONE MARKING THIS CLUSTER CMP (SP)+,(SP)+ ; CLEAN THE STACK END LOOP LET R4 := $OUDEV ; GET DEVICE TABLE ENTRY WHILE .SMVBN LO V.SBSZ(R4) ; ZERO OUT REMAINING BLOCKS $CALL NXB ; IN THE STORAGE MAP FILE LET R0 := #.SMBUF ; THAT ARE THERE DUE TO THRU R1 := #256. ; CLUSTER ROUND UP LET (R0)+ := #0 END LOOP END LOOP $CALL .SMRVB <,,,#0,R4> ; FLUSH LAST BUFFER RETURN ;+ ; ; SUBROUTINE TO FLUSH THE BUFFER AND INIT FOR THE NEXT BLOCK. ; ; R3 & R5 CLOBBERED ; ;- NXB: $CALL .SMRVB <,,,#0,$OUDEV> ; FLUSH THE BUFFER LET R3 := #.SMBUF THRU R5 := #256. LET (R3)+ := #-1 ; RE-INIT TO ONES END LOOP LET .SMFLG := .SMFLG + #1 ; MARK DIRTY LET .SMVBN := .SMVBN + #1 ; AND BUMP TO NEXT BLOCK RETURN .END