.TITLE BLKWRK .IDENT /V1.0/ .IF EQ DEBUG .PSECT BLKWRK,RO .IFF .PSECT BLKWRK,RW .ENDC ;+ ; MACHINE/SYSTEM - PDP-11/70 / IAS V3.0 ; AUTHOR - JOHN GUIDI ; DATE - 22-SEPTEMBER-80 ; RESIDENCE - LB:[?,?]BLKWRK.MAC ; LANGUAGE - MACRO-11 D1113 ; ; ROUTINE FUNCTION ; ---------- ------------------------------------------------------ ; OPNSYS OPENS STORAGE BITMAP OR FCS INDEX FILE ; RDSYS READS VBN FROM EITHER STORAGE BITMAP OR FCS INDEX FILE ; LBNBIT DETERMINES IF GIVEN LBN IS ALLOCATED TO A FILE ; FILWRK FILLS THE WORK AREA WITH LBN'S TO LOOK FOR ;- .MCALL OPEN$R .MCALL READ$,WAIT$ .MCALL FDOF$L,HMBOF$ .MCALL GET$S FDOF$L ; DEFINE FILE DESCRIPTOR BLOCK (FDB) OFFSETS HMBOF$ ; DEFINE FCS INDEX FILE HOME BLOCK OFFSETS .EVEN .NLIST BEX AVAMSG: .ASCII /THE FOLLOWING LBN IS NOT CURRENTLY IN USE: / AVASIZ=.-AVAMSG .LIST BEX .EVEN .SBTTL OPNSYS -> OPENS EITHER STORAGE BITMAP OR FCS INDEX FILE OPNSYS:: ;+ ; ROUTINE: OPNSYS ; ; EFFECT: OPENS SYSFDB WITH THE FILE DESCRIBED BY THE DATASET ; DESCRIPTOR WHICH IS IN SYSPTR. SYSPTR WILL POINT TO EITHER ; THE BITMAP DATASET, OR THE INDEX FILE DATASET. ; (NOTE: SYSPTR IS NOT VERIFIED TO POINT TO BITDSP OR INXDSP) ; ; INPUTS: 1. SYSFDB (SYSFDB IS EITHER UNUSED, OR HAS BEEN CLOSED) ; 2. SYSPTR (POINTS TO EITHER BITDSP OR INXDSP) ; ; OUTPUTS: 1. SYSFDB (OPENED TO EITHER BITMAP OR INDEX FILE) ; 2. SYSSTB (STATISTICS BLOCK FOR SYSFDB) ; 3. C-BIT CLEAR IF FILE POINTED BY SYSPTR IS OPENED ; C-BIT SET IF FILE IS NOT OPENED ; 4. SYSPTR (UNCHANGED) ; 5. ALL REGISTERS PRESERVED (ONLY R0 AND R1 USED) ; 6. MAXLBN (MAXIMUM LBN FOR THIS DEVICE) ; - OR- ; IBITSZ (INDEX FILE BITMAP SIZE) ; 7. PRESERVES REGISTERS R0-R1 ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ; 2. RDSYS ; ;- ; ; 1. LINK A STATISTICS BLOCK TO THE FDB, THEN OPEN THE FCS APPROPRIATE ; SYSTEM FILE. ; PUSH ; SAVE R0,R1 ON STACK MOV #SYSSTB, ; LINK IN STAT BLOCK OPEN$R #SYSFDB,,SYSPTR ; OPEN SYSTEM FILE BCC 30$ ; OPEN$R OK? YES. CMP #BITDSP,SYSPTR ; NO. WAS IT BITMAP ATTEMPT? BNE 10$ ; NO. GO DISPLAY INDEX FILE ERROR ERROR BOPNXX ; YES. REPORT BITMAP FILE ERROR BR 20$ ; GO INDICATE FAILURE 10$: ERROR XOPNXX ; REPORT INDEX FILE OPEN FAILED 20$: SEC ; INDICATE FAILURE JMP 999$ ; AND EXIT ; ; 2. IT IS THEN NECESSARY TO UPDATE INFO IN THE OPENED FDB, AS SYSTEM ; FILE INDEX FILE HEADERS CONTAIN NO INFO IN THE USER ATTRIBUTE AREA. ; THE FILE SIZE LEFT IN THE STATISTICS BLOCK IS USED TO UPDATE THE ; F.HIBK AND F.EFBK LOCATIONS IN SYSFDB. ; ; R0 -> SYSFDB (FROM OPEN$R) 30$: MOV #SYSSTB,R1 ; R1 -> STAT BLOCK FOR SYSTEM FILE MOV 4(R1),F.HIBK(R0) ; SET HIGH VBN MOV 6(R1),(R0) ; (DOUBLE WORD) MOV 4(R1),F.EFBK(R0) ; SET EOF VBN MOV 6(R1),(R0) ; (DOUBLE WORD) ADD #1,(R0) ; DOUBLE PRECISION INCREMENT OF EOF ADC F.EFBK(R0) ; ; ; 3A. IF SYSFDB IS BEING OPENED TO THE STORAGE BITMAP FILE, READ VBN 1 ; (STORAGE CONTROL BLOCK) AND FILL THE MAXLBN VARIABLE WITH THE ; MAXIMUM LBN FOR THIS DEVICE. ; CMP #BITDSP,SYSPTR ; DID WE OPEN STORAGE BITMAP FILE? BNE 40$ ; NO. GO FETCH INDEX FILE STUFF CLR SYSVBN ; SET SYSVBN TO 1 MOV #1, ; (DOUBLE WORD) CALL RDSYS ; READ VBN 1 OF BITMAP FILE BCS 999$ ; EXIT IF ERROR MOV #SYSBUF,R0 ; R0 -> SYSBUF ADD #3,R0 ; R0 -> NUM OF STORAGE BITMAP BLOCKS MOVB (R0)+,R1 ; R0 -> FIRST GARBAGE WORD PAIR ; R1 = NUM OF STORAGE BITMAP BLOCKS BIC #^B1111111100000000,R1 ; (CLEAR HIGH BYTE OF R1) ASL R1 ; R1 = NUMBER OF GARBAGE WORDS TO SKIP ; (2 WORDS FOR EACH STORAGE BIT BLOCK) ASL R1 ; R1 = NUMBER OF GARBAGE BYTES TO SKIP ADD R1,R0 ; R0 -> SIZE OF DEVICE IN LBN'S MOV (R0)+,MAXLBN ; MAXLBN = SIZE OF DEVICE IN LBN'S MOV (R0), ; (DOUBLE WORD) DEC ; MAXLBN = MAXIMUM LBN ON DEVICE SBC MAXLBN ; (REMEMBER, LBN'S START AT 0) BR 50$ ; GO INDICATE SUCCESS AND EXIT ; ; - OR - ; ; 3B. SYSFDB IS OPENED TO THE FCS INDEX FILE. FETCH THE INDEX FILE BITMAP ; SIZE AND STORE IT IN THE VARIABLE IBITSZ. ; 40$: CLR SYSVBN ; SET SYSVBN TO 2 MOV #2, ; (DOUBLE WORD) CALL RDSYS ; READ VBN 1 OF BITMAP FILE BCS 999$ ; EXIT IF ERROR MOV ,IBITSZ ; SAVE INDEX FILE BITMAP SIZE 50$: CLC ; INDICATE SUCCESS 999$: ; LABEL FOR ERROR POP ; RESTORE R1,R0 FROM STACK RETURN .SBTTL RDSYS -> READS VBN FROM BITMAP STORAGE OR FCS INDEX FILE RDSYS:: ;+ ; ROUTINE: RDSYS ; ; EFFECT: READS THE VBN SPECIFIED IN SYSVBN INTO THE BUFFER SYSBUF ; ; INPUTS: 1. SYSFDB (OPENED TO EITHER BITMAP OR INDEX FILE) ; 2. SYSPTR (CONTAINS EITHER THE VALUE BITDSP OR INXDSP,DEPENDING ; ON WHICH FILE IS PRESENTLY USING SYSFDB). ; 3. SYSVBN (VBN DESIRED TO BE READ) ; ; OUTPUTS: 1. SYSBUF (CONTAINS THE VBN READ) ; 2. C-BIT CLEAR INDICATES THAT SYSVBN BLOCK WAS READ OK ; C-BIT SET INDICATES ERROR DURING READ ; 3. ALL REGISTERS PRESERVED (ONLY R0 IS USED) ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ;- PUSH R0 ; SAVE R0 ON STACK READ$ #SYSFDB,#SYSBUF,#SYSSIZ,#SYSVBN ; READ VBN SPECIFIED IN SYSVBN BCS 10$ ; READ$ OK? NO. GO REPORT ERROR WAIT$ #SYSFDB ; YES. WAIT FOR READ$ TO COMPLETE BCS 10$ ; ERROR DURING READ, GO REPORT IT BR 999$ ; OTHERWISE - EXIT 10$: ; DETERMINE WHICH FILE WAS BEING READ CMP #BITDSP,SYSPTR ; WAS THIS AN ATTEMPT TO READ BITMAP? BNE 20$ ; NO. GO REPORT INDEX FILE ERROR ERROR BREDXX ; REPORT BITMAP FILE READ ERROR SEC ; INDICATE FAILURE BR 999$ ; THEN EXIT 20$: ERROR XREDXX ; REPORT INDEX FILE READ ERROR SEC ; INDICATE FAILURE ; THEN EXIT 999$: ; LABEL TO EXIT ROUTINE POP R0 ; RESTORE R0 RETURN .SBTTL LBNBIT -> DETERMINES IF SPECIFIED LBN IS ALLOCATED TO A FILE LBNBIT:: ;+ ; ROUTINE: LBNBIT ; ; EFFECTS: DETERMINES FROM THE STORAGE BITMAP FILE WHETHER THE ; LBN REFERED TO BY THE LBNVAL VARIABLE IS IN USE. ; ; INPUTS: 1. SYSFDB (OPENED TO THE FCS STORAGE BITMAP FILE) ; 2. SYSPTR (CONTAINS BITDSP VALUE) ; 3. SYSVBN (CONTAINS VBN OF BITMAP CURRENTLY IN SYSBUF) ; 4. LBNVAL (LBN VALUE TO CHECK BITMAP AGAINST) ; ; OUTPUTS: 1. SYSVBN (CONTAINS NEW VBN IF IT WAS NECCESSARY TO PAGE SYSBUF ; TO OBTAIN BLOCK CONTAINING BIT FOR LBNVAL) ; 2. R0 = 0 IF LBNVAL IS IN USE ; R0 = 1 IF LBNVAL IS AVAILABLE ; 3. C-BIT CLEAR IF ROUTINE IS SUCCESSFUL ; C-BIT SET IF ERROR OCCURS ; 4. REGISTERS R1-R5 PRESERVED (R0-R3 ARE USED) ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ; 2. RDSYS ; 3. $DDIV ;- ; ; 1. OBTAIN THE STORAGE MAP BLOCK FOR THE LBN IN LBNVAL. THIS IS GIVEN ; BY THE FOLLOWING EQUATION: ; ; [ LBNVAL ] ; BITMAP VBN FOR LBNVAL = INT [ ------ ] + 2 ; [ 4096. ] ; ; [ LBNVAL ] ; BITS INTO VBN FOR LBNVAL = MOD [ ------ ] ; [ 4096. ] ; PUSH ; SAVE R1,R2,R3 ON THE STACK MOV #4096.,R0 ; R0 = 4096. (NUMBER BITS/BLOCK) MOV LBNVAL,R1 ; R1 = HIGH ORDER LBN MOV ,R2 ; R2 = LOW ORDER LBN CALL $DDIV ; R0 = BIT WITHIN VBN ; R1 = HIGH ORDER QUOTIENT VBN ; R2 = LOW ORDER QUOTIENT VBN MOV R0,R3 ; R3 = BIT WITHIN VBN ADD #2,R2 ; ADD 2 TO LOW ORDER VBN ADC R1 ; ADD CARRY TO HIGH ORDER VBN ; ; 2. SEE IF THIS VBN HAS ALREADY BEEN READ INTO SYSBUF BY COMPARING ; THE DESIRED VBN WITH SYSVBN. IF NOT ALREADY PRESENT, THEN READ ; THIS VBN INTO SYSBUF. ; 20$: CMP SYSVBN,R1 ; HIGH ORDER VBN'S MATCH? BNE 30$ ; NO. NEED TO READ VBN CMP ,R2 ; LOW ORDER MATCH? BEQ 40$ ; YES. 30$: MOV R1, ; PLACE LBNVAL'S VBN INTO SYSVBN MOV R2, ; (DOUBLE WORD) CALL RDSYS ; READ THIS VBN INTO SYSBUF BCC 40$ ; ALL IS WELL - CONTINUE SEC ; NOPE. INDICATE FAILURE BR 999$ ; THEN EXIT ; ; 3. NOW WE FIND THE WORD WITHIN SYSBUF WHICH IS ASSOCIATED WITH LBNVAL. ; THIS IS GIVEN BY THE FOLLOWING EQUATION: ; ; [ BITS INTO VBN FOR LBNVAL ] ; WORD WITHIN SYSBUF FOR LBNVAL = INT [ ------------------------ ] ; [ 16. ] ; ; AND THE BIT WITHIN THE WORD WHICH IS ASSOCIATED WITH LBNVAL. THIS IS ; GIVEN BY THE FOLLOWING EQUATION: ; ; [ BITS INTO VBN FOR LBNVAL ] ; BIT WITHIN SYSBUF WORD FOR LBNVAL = MOD [ ------------------------ ] ; [ 16. ] ; ; R3 = BITS INTO VBN FOR VBNVAL 40$: MOV #16.,R0 ; R0 = # BITS PER BYTE CLR R1 ; R1 = 0 MOV R3,R2 ; R2 = BITS INTO SYSBUF FOR VBNVAL CALL $DDIV ; DOUBLE PRECISION DIVIDE ; R0 = BIT WITHIN WORD WITH VBNVAL BIT ; R1 OUGHT TO BE CLEAR ; R2 = WORD WITH VBNVAL BIT IN SYSBUF ASL R2 ; R2 = BYTE WITH VBNVAL BIT IN SYSBUF ADD #SYSBUF,R2 ; R2 -> WORD WITH VBNVAL BIT INDICATOR MOV (R2),R2 ; R2 = WORD WITH VBNVAL BIT INDICATOR MOV R0,R1 ; R1 = VBNVAL BIT WITHIN WORD INC R1 ; R1 = VBNVAL BIT WITHIN WORD +1 NEG R1 ; R1 = SHIFT NEEDED TO SHIFT VBNVAL ; BIT INTO C-BIT. ; ; 4. SHIFT THE STORAGE BITMAP BIT ASSOCIATED WITH THIS LBNVAL INTO THE ; C-BIT. IF THE BIT IS CLEAR, THEN THE LBN IS ALLOCATED TO A FILE. ; IF THE BIT IS SET, THE LBN IS AVAILABLE. R0 = 0 IF BIT CLEAR, ; R0 = 1 IF BIT IS SET. ; CLR R0 ; SET INDICATOR TO LBN USED ASH R1,R2 ; SHIFT DESIRED LBNVAL BIT INTO C-BIT BCC 50$ ; C-BIT CLEAR? GO RETURN R0 CLEAR INC R0 ; NO. SET INDICATOR TO LBN AVAILABLE 50$: CLC ; SET ROUTINE STATUS TO SUCCESS 999$: ; LABEL FOR ERRORS POP ; RESTORE R3,R2,R1 FROM THE STACK RETURN .SBTTL FILWRK -> FILLS THE WORK BUFFER WITH LBN'S TO BE SEARCHED FOR FILWRK:: ;+ ; ROUTINE: FILWRK ; ; EFFECT: THIS ROUTINE WILL TRANSLATE EACH ENTRY IN THE INPUT FILE ; INTO THE CORRESPONDING DOUBLE WORD INTERNAL FORM LBN ; VALUE, AND FILL THE LBN VALUES INTO WRKBUF UNTIL EITHER ; A) THERE IS A GET$S ERROR, B) INPUT FILE EOF, OR C) THE ; WRKBUF IS FULL. IF THE WORK BUFFER IS FILLED UP, THEN ; THE BIT WRKMOR IS SET IN WRKFLG TO PERMIT ANOTHER BUFFER ; TO BE FILLED AFTER THIS ONE IS PROCESSED. ; ; INPUTS: 1. WRKFLG (BIT WRKMOR MUST BE CLEAR EACH TIME THIS ROUTINE IS ; USED TO READ THE FIRST LBN INTO THE WORK BUFFER. THIS IS USED ; ALONG WITH NUMLBN TO INDICATE THAT THE FIRST CONVERTED LBN IS ; ACCEPTABLE.) ; 2. LSTLBN (CONTAINS THE VALUE OF THE LAST LBN PLACED INTO WRKBUF) ; 3. INPFDB (INPUT FILE OPENED) ; 4. MAXLBN (MAXIMUM LBN FOR THIS DEVICE) ; ; OUTPUTS: 1. WRKFLG (IF BIT WRKMOR SET, THERE IS POTENTIAL FOR ANOTHER ; WORK BUFFER TO BE FILLED) ; 2. WRKBUF (CONTAINS THE LIST OF ORDERED, UNDUPLICATED LBN'S) ; 3. NUMLBN (NUMBER OF LBN'S IN WRKBUF) ; 4. LSTLBN (VALUE OF THE LAST LBN IN WRKBUF) ; 5. ALL REGISTERS PRESERVED (R0-R5) ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ; 2. .DD2CT ; 3. LBNBIT ;- ; ; 1. INITIALIZE VARIABLES ; PUSH ; SAVE R0-R5 ONTO THE STACK MOV #WRKBUF,NXTWRK ; RESET NXTWRK TO START OF WORK BUFFER CLR NUMLBN ; INITIALIZE NUMBER OF LBN'S IN BUFFER ; ; 2. READ NEXT SEQUENTIAL RECORD FROM UTILITY INPUT FILE ; 20$: GET$S #INPFDB ; READ INPUT FILE RECORD BCC 30$ ; GET$S OK? YES. MOVB ,-(SP) ; NO. PUSH ERROR BYTE ONTO STACK CMPB #IE.EOF,(SP)+ ; WERE WE AT END OF FILE? BNE 25$ ; NO. GO SHOW ERROR BIC #WRKMOR,WRKFLG ; YES. SET WRKFLG TO NO MORE BUFFERS CLC ; SET ROUTINE STATUS TO SUCCESS JMP 999$ ; THEN RETURN 25$: ERROR IREDXX ; DISPLAY ERROR MESSAGE SEC ; INDICATE FAILURE JMP 999$ ; THEN EXIT ; ; 3. TRANSLATE ASCII TO INTERNAL DOUBLE WORD LBN VALUE AND STORE THIS ; VALUE IN LBNVAL. ; 30$: MOV #LBNVAL,R3 ; R3 -> ADDRESS FOR CONVERTED NUMBER MOV ,R4 ; R4 = NUMBER OF CHARACTERS TO CONVERT MOV ,R5 ; R5 = ADDRESS OF STRING 35$: CMPB #40,(R5)+ ; IS THIS A BLANK? BNE 37$ ; NO. BACK OVER THIS CHARACTER SOB R4,35$ ; CHECK ENTIRE STRING BR 39$ ; STRING IS EMPTY, GO REPORT ERROR 37$: CMPB #'-,-(R5) ; IS FIRST CHARACTER "-"? BEQ 39$ ; YES. REPORT ERROR ; R4 = SIZE AFTER BLANKS STRIPPED ; R5 -> FIRST CHARACTER TO CONVERT CALL .DD2CT ; CONVERT DECIMAL STRING TO BINARY BCC 40$ ; CONVERSION OK? YES - CONTINUE 39$: ERROR LCNVXX ; DISPLAY LBN CONVERSION ERROR PRINT , ; DISPLAY OFFENDER BR 20$ ; TRY ANOTHER RECORD ; ; 4. ENSURE THAT THE VALUE IN LBNVAL IS LESS THAN OR EQUAL TO THE ; MAXLBN VALUE. ; 40$: CMP MAXLBN,LBNVAL ; HIGH ORDER CMP WITH MAXLBN BHI 50$ ; HIGHER - OK BLO 45$ ; LOWER - GO REPORT ERROR CMP , ; LOW ORDER CMP (IF HIGH ORDER SAME) BHIS 50$ ; HIGHER/SAME - ALL IS WELL 45$: ERROR BLBNXX ; DISPLAY EXCESSIVE LBN ERROR PRINT R5,R4 ; DISPLAY OFFENDER BR 20$ ; TRY ANOTHER RECORD ; ; 5. IF THIS IS THE FIRST POTENTIAL LBN OF THE FIRST WORK BUFFER, THEN ; SIMPLY GO SEE IF THE LBN IS ALLOCATED TO A FILE BEFORE PLACING IT ; IN THE WORK BUFFER. OTHERWISE, ENSURE THAT THIS LBN IS LARGER THAN ; THE LAST ONE ENTERED IN THE WORK BUFFER, AND THAT THIS LBN IS NOT ; A DUPLICATE. ; 50$: TST NUMLBN ; IS THIS THE FIRST LBN? BNE 51$ ; NO. CHECK FOR ORDER, DUPLICATES BIT #WRKMOR,WRKFLG ; IS THIS THE FIRST WORK BUFFER? BEQ 60$ ; YES (WRKMOR CLEAR). THEN PLACE INTO ; WRKBUF. FIRST LBN IS ALWAYS OK. 51$: CMP LBNVAL,LSTLBN ; HIGH ORDER LBN COMPARED TO PRECEDING BHI 60$ ; THIS ONE IS HIGHER, ALL IS WELL BLO 55$ ; THIS ONE IS LOWER - GO REPORT ERROR CMP , ; LOW ORDER LBN COMPARE BHI 60$ ; THIS ONE IS HIGHER, ALL IS WELL BLO 55$ ; THIS IS LOWER -GO REPORT ORDER ERROR ERROR LDUPXX ; IT'S THE SAME. DUPLICATION ERROR PRINT R5,R4 ; DIPLAY OFFENDING LBN BR 20$ 55$: ERROR LORDXX ; DISPLAY LBN ORDER ERROR PRINT R5,R4 ; DISPLAY OFFENDING LBN BR 20$ ; TRY ANOTHER RECORD ; ; 6. SEE IF THIS LBN IS ACTUALLY IN USE BY CHECKING THE BITMAP FILE ; 60$: CALL LBNBIT ; SEE IF THIS BIT IS AVAILABLE BCS 999$ ; IF ERROR FROM LBNBIT - EXIT TST R0 ; IS LBN AVAILABLE? BEQ 70$ ; NO. GO STUFF LBN IN WORK BUFFER PRINT #AVAMSG,#AVASIZ,#44 ; YES. TELL THE WORLD LBN IS AVAILABLE PRINT R5,R4 ; AS WELL AS WHICH LBN IT IS JMP 20$ ; THEN GO TRY ANOTHER RECORD ; ; 7. LBN IN LBNVAL VARIABLE IS OK. PLACE THIS LBN IN THE WORK BUFFER WRKBUF ; AT THE LOCATION INDICATED BY NXTWRK. THEN UPDATE THE VARIABLES LSTLBN, ; NUMLBN,NXTWRK, AND WRKFLG. ; 70$: MOV LBNVAL,LSTLBN ; SAVE LBNVAL AS LSTLBN MOV , INC NUMLBN ; INCREMENT NUMBER LBN'S COUNTER MOV NXTWRK,R0 ; R0 -> NEXT AVAIL WORK BUFFER SPACE MOV LBNVAL,(R0)+ ; PUSH LBNVAL INTO WORK BUFFER MOV ,(R0)+ ; (R0 -> NEXT AVAIL SPACE) MOV R0,NXTWRK ; UPDATE WORK SPACE POINTER CMP #WRKEND,R0 ; IS THE WORK BUFFER FULL? ; (WRKEND -> END OF WORK BUFFER) BLOS 75$ ; YES. GO SET WRKFLG STATUS JMP 20$ ; NO. READ NEXT RECORD 75$: BIS #WRKMOR,WRKFLG ; INDICATE THAT WRKBUF HAS BEEN FILLED ; ONCE, AND THAT POTENTIAL EXISTS FOR ; MORE BUFFERS TO BE FILLED. CLC ; SET ROUTINE STATUS TO SUCCESS ; THEN RETURN 999$: POP ; RESTOR R5-R0 FROM THE STACK RETURN .END