.TITLE CNT ;+ ; CNT -- PROGARM TO DETERMINE FROM "BITMAP.SYS" A SUMMARY ; OF THE CONTIGUOUS DISK SPACE AVAILABLE. ; ; ; >CNT DM0:/CO:N ; ; WILL LIST THE "N" LARGEST CONTIGUOUS SPACES ON DM0: ; ; DEFAULTS: SY0:/CO:3 ; ;- ; ; EVENT FLAGS ; TTIEVF= 1 FILEVF= 2 ; ; LOGICAL UNITS ; TTILUN= 1 FILLUN= 2 GCLUN= 3 ; .MCALL TINIT,TTYOUT,PCRLF,PSTR,PDEC,POCT,PTAB .MCALL FINIT$,OPEN$R,READ$,WAIT$,CLOSE$,FSRSZ$ .MCALL ENTER,LEAVE,RECALL .MCALL FDBDF$,FDRC$A,FDBK$A,FDOP$A,NMBLK$ .MCALL GCML,RCML$,GCMLB$ .MCALL CSI$,CSI1G,CSI2,CSI$SW,CSI$SV,CSI$ND .MCALL ALUN$S,EXIT$S,MVADR .MCALL POCT2,PDEC2 ; ; .MACRO INC2,A ADD #1,A+2 ADC A .ENDM ; .MACRO CLR2,A CLR A CLR A+2 .ENDM .SBTTL >INITIALIZATIONS START: MOV SP,SPSAVE ;SAVE SP FOR ERROR RESTART FINIT$ ;INIT FCS TINIT TTILUN,TTIEVF ;INIT FOR TERMINAL OUTPUT ALUN$S #GCLUN,#"TI,#0 ;ASSIGN GCML TO TI: BR GOTOIT ;AND GO TO IT ; ; TERMIN: EXIT$S ;RETURN TO RSX ; ; ERRPFX::PSTR ^*/CNT -- /* RETURN ; DIE:: RCML$ #GCBLK ;RECLAIM FOR RESTART MOV SPSAVE,SP ;AND SP RESTORED BR START ;AND START OVER ; SPSAVE: .WORD 0 ;SAVE SP HERE FOR ERROR REC. .SBTTL >COMMAND LINE INPUT GOTOIT: GCML #GCBLK,,,TERMIN,GCERR ;GET A COMMAND LINE CSI1G #CSBLK,GCBLK,CS1ERR ;INITIAL PARSE CSI2 #CSBLK,OUTPUT,#SWTAB,CS2ERR ;GET IT ALL ; ; BIT #COSWF,CSBLK+C.MKW1 ;A SWITCH GIVEN? BNE 1$ ;YES BY GOLLY MOV #LSTDEF,NUML ;NO, GET DEFAULT BR 2$ 1$: TST NUML ;CHECK IF BIG ENUFF BLE 15$ ;NO, FORCE DEFAULT CMP #LSTMAX,NUML ;IS HE ASKING FOR TOO MUCH? BGT 2$ ;NO, IT'S OKAY 15$: MOV #LSTMAX,NUML ;FORCE IT 2$: ; ; NOW READY TO OPEN THE FILE AND START READING. CALL OPEN ;OPEN THE FILE ; ; WITH THE FILE OPEN, GO AHEAD AND READ IT. ; MOV #TOTFRE,R1 ;CLEAR... MOV NUML,R2 ;...ALL ASL R2 ; ... OF THE ADD #6,R2 ; ...COUNTERS 3$: CLR (R1)+ SOB R2,3$ CALL COUNT ;COUNT THE BITS IN FILE ; ; CLOSE THE FILE, SINCE WE'RE DONE WITH IT ; CALL CLOSE ;CLOSE THE FILE ; ; AND THEN PRINT OUT THE RESULTS ; CALL PRINT ; ; WITH ALL THAT DONE, GO BACK AND SEE IF WE HAVE ; TO DO MORE. ; JMP START .SBTTL >>OPEN THE BITMAP FILE ; ; OPEN -- ROUTINE WHICH OPENS THE BITMAP.SYS FILE, ; AND PREPARES IT FOR READING. THIS ROUTINE ; INITIALIZES: ; ; R3 = # OF BLOCKS LEFT TO BE READ ; R4 = # OF BITS IN THE LAST BLOCK ; (R4=0 => LAST BLOCK FULL) ; ; OPEN: ENTER R0,R1 ;SAVE R0 FROM FCS MOV #LDIRNM,CSBLK+C.DSDS+4 ;SET THE UIC MOV #DIRNM,CSBLK+C.DSDS+6 ;TO [0,0] ; OPEN$R #BITFDB,,,,,,IOERR ; ; FORCE READING TO BEGIN FROM BLOCK 2 ; CLR F.VBN(R0) ;CLEAR HIGH WORD MOV #2,F.VBN+2(R0) ;AND SET LOW WORD ; ; THE FILE IS OPEN, BUT WE DON'T KNOW HOW BIG IT IS. ; SO, GO AHEAD AND ... ; CALL GETSZ ;DETERMINE FILE SIZE ; ; THE NUMBER OF BLOCKS TO READ+BLOCK #1+AN EOF BLOCK => ; ; F.EFBK=R3+2 ; MOV R3,R1 ;A TEMP WORK REG INC R1 INC R1 MOV R1,F.EFBK(R0) LEAVE RETURN .SBTTL >>GET THE FILE SIZE ; ; GETSZ -- ROUITNE TO DETERMINE THE BITMAP FILE SIZE ; FROM THE DEVICE VOLUME SIZE. ; ; INPUTS: R0 = # FDB ; ; OUTPUTS: R3 = # OF BLOCKS TO BE READ ; R4 = # OF BITS IN THE LAST BLOCK ; (R4=0 => LAST BLOCK FULL) ; ; DIVAL =16.*256. GETSZ: ENTER R1,R2,R5 ;WORK REGS. MVADR F.FNB+N.DVNM,R0,R1 ;GET DEVICE NAME MOV #TABSIZ,R2 ;TABLE SIZE FOR LOOP 1$: CMPB TABLE(R2),(R1) ;CHECK FIRST CHARACT BNE 10$ ;NOT IT, BRANCH CMPB TABLE+1(R2),1(R1) ;SECOND CHARACTER? BEQ 20$ ;WE GOT IT, BRANCH 10$: DEC R2 ;GO TO NEXT NAME.. DEC R2 ; ...UP THE TABLE BGE 1$ ;THERE ARE MORE. BR 50$ ;WE ASSUME ITS PROPERLY SET.?? ; ; WE'RE POINTING TO THE DEVICE, SO GET THE VOLUME SIZE ; 20$: ASL R2 ;(VOLUME SIZES ARE 2-WORD.) MOV TVAL(R2),R4 ;GET VOLUME SIZE MOV TVAL+2(R2),R5 ; IN R4-R5 COMBIN. DIV #DIVAL,R4 ;DIVIDE TO GET BLOCKS AND BITS MOV R4,R3 ;MOVE IN THE BLOCKS, MOV R5,R4 ; AND THE BITS BEQ 50$ INC R3 ; 50$: LEAVE RETURN .SBTTL >>COUNT BITS IN BLOCK ; ; COUNT -- ROUTINE TO COUNT UP THE NUMBER ; OF SET BITS IN THE BITMAP. ; ; INPUTS: R3 = # OF BLOCKS TO BE READ ; R4 = # OF BITS IN THE LAST BLOCK ; (R4=0 => LAST BLOCK FULL) ; COUNT: ENTER R0,R1,R2,R5 CLR R0 ;PREPARE MASK WORD ; MOV #GETWD,-(SP) ;OH-OH ; ; PUTTING A ROUTINE ADDRESS ON THE STACK CAN MEAN ; ONLY ONE THING: COROUTINUS A' ABSCURUS. ; 1$: RECALL ;TAT'S IT ALRIGHT BCS 10$ ;AND THIS IS THE WAY OUT ; TST R5 ;CHECK THAT WORD BEQ 5$ ;THERE'S NOTHING IN IT CMP #-1,R5 ;ARE THEY ALL USED? BEQ 6$ ;DON'T WASTE TIME TESTING EACH ; SEC ;THE TESTING BIT 4$: CALL CTEST ;TEST THE WORD FROM BCC 4$ ; GETWD TILL IT IS DONE. BR 1$ ;THEN GET SOME MORE ; 5$: ADD #16.,TOTSPC+2 ;16. MORE BLOCKS ON THIS DEV ADC TOTSPC ;TO ADD IN. CALL LASTST ;DOES THIS END A CONT. CHUNK? BR 1$ ;GO FOR MORE ; 6$: ADD #16.,TOTFRE+2 ;ADD TO TOTAL FREE SPACE ADC TOTFRE ; ADD #16.,CCBC+2 ;AND TO CONT. BLOCK COUNT ADC CCBC ; ADD #16.,TOTSPC+2 ;AND TO THE TOTAL SPACE ADC TOTSPC ; BR 1$ ;GO FOR MORE ; ; THE CO-ROUTINE IS EFFECTIVELY FLUSHED (TRUST ME). ; THE WORD LEFT TO DO (IN R5) IS EITHER #_"BLANK" OR ; IT HAS ONLY R3 # OF BITS TO DO. ; 10$: TST R3 ;IS THERE ANYTHING? BEQ 20$ ;NO SEC ;THE TESTING BIT 15$: CALL CTEST ;YES, SO TEST SOB R3,15$ ; THAT MANY TIMES 20$: CALL LASTST ;DOES THIS END A CONT CHUNK. ; 25$: LEAVE RETURN .SBTTL >>TEST A BIT IN THE WORD ; ; CTEST -- ROUTINE TO TEST A BIT IN THE WORD AND ; INCREMENT THE COUNTS IF THE BIT I SET. ; ; INPUTS: R0= MASK ; R5= WORD ; ; CTEST: ROL R0 ;POSITION BIT BCS 11$ ;GONE FULL CIRCUIT INC2 TOTSPC ;INCREMENT TOTAL SPACE BIT R0,R5 ;CHECK OUT BIT BNE 5$ ;SET!! ; CALL LASTST ;DOES THIS END A CONT. CHUNK BR 10$ ; 5$: INC2 TOTFRE ;ONE MORE FREE BLOCK INC2 CCBC ;INC OR RESTART COUNT 10$: CLC 11$: RETURN .SBTTL >>IS CONTIGUOUS COUNT ACTIVE? ; ; LASTST -- ROUTINE WHICH IS CALLED WHENEVER THE LAST BIT ; WAS FOUND TO BE CLEAR, I.E. NOT FREE. IN THIS CASE, ; THE PRVIOUS FREE SPACE WAS CONTIGUOUS (OR ITSELF WAS ; NOT FREE) ; LASTST: TST CCBC ;SEE IF THERE IS BNE 1$ ; A COUNT LEFT TO TST CCBC+2 ; INSERT IN THE LIST. BEQ 5$ ;NO. 1$: CALL INSERT ;YES, SO INSERT 5$: RETURN .SBTTL >>GET A WORD TO TEST ; ; GETWD -- ROUTINE TO GET A WORD TO TEST. THIS IS ; A COROUTINE WITH COUNT, IN THAT AFTER IT GETS THE ; WORD, IT "RECALLS" COUNT TO PROCESS. ; ; INPUTS: R3 = # OF BLOCKS TO BE READ ; R4 = # OF BITS IN THE LAST BLOCK ; (R4=0 => LAST BLOCK FULL) ; ; OUTPUTS: R3 = # OF BLOCKS LEFT TO READ ; IF LAST BLOCK WAS READ, ; R3 = # OF BITS IN THE LAST WORD ; R5 = THE WORD READ ; GETWD: MOV #BLKBUF,R1 ;THE READ BUFFER MOV #BLKSIZ,R2 ;AND ITS SIZE ; MOV R0,-(SP) ;SAVE R0 FROM FCS READ$ #BITFDB,R1,R2,,,,,IOERR ;READ A BLOCK WAIT$ R0,,,IOERR ;AND WAIT FOR IT MOV (SP)+,R0 ; ; ASR R2 ;# OF WORDS DEC R3 ;ONE LESS BLOCK BLE 10$ ;IT WAS THE LAST ; 2$: MOV (R1)+,R5 ;GET A WORD CLC RECALL ;SEND IT BACK SOB R2,2$ ;GET THE NEXT BR GETWD ;GO READ MORE ; ; WE HAVE JUST READ IN THE LAST BLOCK. IF R4=0, ; THEN THE BLOCK IS FULL, OTHERWISE R4 HOLDS THE ; NUMBER OF BITS IN THE BLOCK. ; 10$: MOV R4,R3 ; BEQ 14$ ;IT'S FULL, DO AS IS CLR R2 ;PREPARE FOR DIVIDE DIV #16.,R2 ;TO FIND OUT HOW MANY WORDS. ; ; R2=# OF WORDS ; R3=# OF BITS LEFT OVER ; TST R2 ; BEQ 15$ ;NO WORDS 14$: MOV (R1)+,R5 ;GET THE WORD CLC RECALL ;PROCESS IT SOB R2,14$ ; 15$: MOV (R1)+,R5 ;GET THE LAST WORD SEC ;INDICATE IT RETURN ;FLUSH CO ROUT .SBTTL >>INSERT COUNT IN ORDERED LIST ; ; ; ROUTINE TO "INSERT" THE CURRENT CONTIGUOUS BLOCK ; COUNT INTO THE LIST OF CONTIGUOUS BLOCK COUNTS. ; ; INSERT: ENTER R1,R2 MOV #LIST,R1 ;GET LIST POINTER MOV NUML,R2 ;AND SIZE 1$: CMP CCBC,(R1)+ ;HOW DOES IT RATE? BGT 14$ ;CAN'T BE SMALLER BLT 13$ ;CAN'T BE BIGGER CMP CCBC+2,(R1) ;THE LOW WORD? BHI 14$ ;IS GREATER 13$: TST (R1)+ ; BR 2$ ;NOT GOOD ENOUGH 14$: MOV (R1),-(SP) ;GREAT, SWAP US FOR MOV -(R1),-(SP) ; MOV CCBC,(R1)+ ;WHAT WAS THERE MOV CCBC+2,(R1)+ ; MOV (SP)+,CCBC ; MOV (SP)+,CCBC+2 ; 2$: SOB R2,1$ ; CLR2 CCBC ;AND RESET COUNTER LEAVE RETURN .SBTTL >>CLOSE THE FILE ; ; CLOSE -- ROUTINE TO CLOSE THE BITMAP FILE. ; CLOSE: CLOSE$ #BITFDB,IOERR RETURN .SBTTL >>OUTPUT THE RESULTS ; ; PRINT -- ROUTINE TO PRINT OUT ALL THE RESULTS ; .SBTTL >OUTPUT RESULTS ; ; PRINT -- ROUTINE TO OUTPUT THE RESULTS OF THE ; COUNT TO THE TERMINAL ; PRINT: PCRLF ;SPACE THINGS TTYOUT #BITFDB+F.FNB+N.DVNM,#2 ;OUTPUT DEVICE NAME POCT BITFDB+F.FNB+N.UNIT ;AND NUMBER PSTR ^*/: HAS /* PDEC2 TOTFRE ;BLOCKS FREE PSTR ^*/ OUT OF /* PDEC2 TOTSPC ;TOTAL BLOCKS READ PSTR ^*/ BLOCKS FREE./* PCRLF ;NEXT LINE MOV #LIST,R0 ;LIST OF NUMBERS MOV NUML,R1 ;AND ITS SIZE PSTR ^*/THE /* PDEC R1 PSTR ^*/ LARGEST CONTIGUOUS SPACE(S) ARE:/* PCRLF DEC R1 BEQ 12$ ;ONLY ONE TO PRINT 10$: MOV R0,-(SP) CALL QUTDP2 ADD #4,R0 PSTR ^*/, /* SOB R1,10$ PSTR ^*/AND /* 12$: MOV R0,-(SP) CALL QUTDP2 PSTR ^*/ BLOCKS EACH./* RETURN .SBTTL >>FCS AND GCML STUFF ; ; ; FCS AND GCML STUFF ; ; ; THE FDB ; BITFDB: FDBDF$ FDRC$A FD.RWM FDBK$A BLKBUF,BLKSIZ,,FILEVF,IOSTAT FDOP$A FILLUN,CSBLK+C.DSDS,DFNBLK,FO.RD ; IOSTAT: .BLKW 2 ;READ STATUS ; DFNBLK: NMBLK$ BITMAP,SYS,,SY,0 ; BLKSIZ =512. BLKBUF: .BLKB BLKSIZ ; ; DIRNM: .ASCII /[0,0]/ LDIRNM =.-DIRNM .EVEN ; ; ; GCML AND CSI ; GCBLK: GCMLB$ ,CNT,,GCLUN ; ; CSI$ CSBLK: .BLKB C.SIZE .EVEN ; COSWF =1 ;SWITCH FLAG WORD ; SWTAB: CSI$SW CO,COSWF,,,,COVAL CSI$ND ; COVAL: CSI$SV DECIMAL,NUML,2 CSI$ND ; .SBTTL >>MISCELLANEOUS STUFF ; ; TABLE OF ASCII DEVICE NAMES. ; EACH ENTRY MUST HAVE A MATCHING TWO WORD ; ENTRY IN TVAL. ; TABLE: .ASCII /DK/ .ASCII /DM/ ; TABSIZ= .-TABLE-2 ; ; TVAL IS THE EOF BLOCK NUMBER FOR THE ; RESPECTIVE DEVICE IN TABLE. ; TVAL: .WORD 0,4800. .WORD 0,27126. ; ; ; MISC STUFF ; NUML: .WORD 0 ;NUMBER OF CONTIG SPACES TO DETERMINE TOTFRE: .WORD 0,0 ;TOTAL FREE SPACE TOTSPC: .WORD 0,0 ;TOTAL SPACE CCBC: .WORD 0,0 ;CURRENT CONTIGUOUS BLOCK COUNTER ; ; LSTMAX =10. ;MAX LIST SIZE LSTDEF =3. ;DEFAULT LIST SIZE ; LIST: .BLKW LSTMAX*2 ; ; FSRSZ$ 1 .END START