.TITLE BLKMAP .IDENT /V1.0/ .IF EQ DEBUG .PSECT BLKMAP,RO .IFF .PSECT BLKMAP,RW .ENDC ;+ ; MACHINE/SYSTEM - PDP-11/70 / IAS V3.0 ; AUTHOR - JOHN GUIDI ; DATE - 22-SEPTEMBER-80 ; RESIDENCE - LB:[?,?]BLKMAP.MAC ; LANGUAGE - MACRO-11 D1113 ; ; ROUTINE FUNCTION ; -------- ------------------------------------------------------ ; NXTFIL FINDS NEXT FILE MATCHING [0,0] OR [*,*]*.*;*. ; ; GETMAP GET MAP AREA INFO FOR FILE IN EXMFDB AND SEARCH ; WORK BUFFER FOR ANY MATCHING LBN'S. ; ; CHKLBN DETERMINE IF LBN'S ASSOCIATED WITH MAP RETRIEVAL ; POINTER ARE IN THE WORK BUFFER. ; ; ALLLBN PRINTS INFO FOR LBN OBTAINED FROM BINARY SEARCH ; AND CHECKS LBN'S SURROUNDING THIS LBN AGAINST ; MAP RETRIEVAL POINTER. ; ; PRTLBN PRINTS THE LBN,VBN, AND FILENAME ; ; GETFIL OBTAIN THE FILE DESCRIPTION FOR THE FILE WHOSE ; MAP RETRIEVAL POINTER JUST MATCHED AN LBN IN ; THE WORK BUFFER FOR THE FIRST TIME. ; ; WRKREM DISPLAYS ANY REMAINING LBN'S IN THE WORK BUFFER ; AFTER ALL [0,0] AND [*,*]*.*;* FILES HAVE BEEN ; CHECKED AND LBN'S ARE UNACCOUNTED FOR. ;- .MCALL HMBOF$,FHDOF$,PUT$S,CLOSE$,C$C HMBOF$ ; FCS INDEX FILE HOME BLOCK OFFSETS FHDOF$ ; FCS INDEX FILE FILE HEADER OFFSETS C$C ; DEFINE CARRIAGE CONTROL OFFSETS .NLIST BEX FNDMSG: .ASCIZ /LBN=%7<%T%7>%7J. VBN=%7<%T%7>%7J. %VA/ REMMSG: .ASCII /THE FOLLOWING LBN(S) ARE UNACCOUNTED FOR:/ REMSIZ=.-REMMSG LBNMSG: .ASCIZ /%T/ .LIST BEX .EVEN .SBTTL NXTFIL -> FINDS NEXT FILE MATCHING [0,0] OR [*,*]*.*;* NXTFIL:: ;+ ; ROUTINE: NXTFIL ; ; EFFECT: NXTFIL OBTAINS THE NEXT FILE FOR THE GIVEN WILDCARD ; FILE SPECIFICATION AND FILLS IN EXMFDB WITH THE ; FILE IDENTIFICATION INFO. WE START OUT LOOKING FOR ; THE NEXT MATCH TO [0,0]*.*;* , AND THEN WE LOOK FOR ; [*,*]*.*;* MATCHES. THIS IS NECESSARY BECAUSE THE .FNDNX ; ROUTINE WILL NOT FIND [0,0] FILES UNLESS AN EXPLICIT UIC ; IS GIVEN. ; ; INPUTS: 1. EXMFLG (IF CLEAR, THIS ROUTINE LOADS EXMPTR WITH MSTDSP ; AND FINDS MATCHING FILE) ; 2. EXMPTR (IF EXMFLG HAS EXMFND SET, THEN EXMPTR CONTAINS ; THE ADDRESS OF THE DATASET DESCRIPTOR CURRENTLY BEING ; USED (IE MSTDSP ! WLDDSP)) ; 3. WLDBLK+N.WNM2 (CONTAINS THE ASCII DIRECTORY STRING OF LAST ; FILE FOUND) ; 4. NUMLBN (NUMLBN SHOULD BE >0 - OTHERWISE WE'RE WASTING TIME) ; ; OUTPUTS: 1. EXMFLG (EXMFND SET INDICATES ROUTINE HAS BEEN ENTERED AT ; LEAST ONCE. EXMEND INDICATES THAT NO MORE FILES ARE TO BE ; FOUND) ; 2. EXMFDB (FILLED IN BY .WPARS AND .FNDNX OF NEXT FILE IF AVAIL.) ; 3. C-BIT (SET INDICATES ERROR, CLEAR - ROUTINE SUCCESSFUL) ; 4. EXMPTR (CONTAINS ADDRESS OF DATASET LAST USED ; (MSTDSP ! WLDDSP)) ; 5. REGISTERS R0-R4 PRESERVED ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ; 2. .WPARS ; 3. .FNDNX ;- ; ; 1. SEE IF THIS ROUTINE HAS ALREADY BEEN ENTERED. IF NOT, EXMFND BIT ; IN EXMFLG WILL BE CLEAR. IN THIS CASE, SET THE EXMPTR VARIABLE ; WITH THE ADDRESS OF THE DATASET [0,0]*.*;*. ; PUSH ; SAVE R0-R4 ON THE STACK TST EXMFLG ; EXMFND NOT SET YET? BNE 20$ ; NO. THIS ROUTINE ALREADY ENTERED MOV #MSTDSP,EXMPTR ; YES. INITIALIZE EXMPTR WITH THE ; MASTER DIRECTORY FILESPEC DATASET BIS #EXMFND,EXMFLG ; SET FLAG TO INDICATE ROUTINE ENTERED ; ; 2. COPY THE DATASET WHOSE ADDRESS IS IN EXMPTR INTO EXMDSP. SET UP THE ; DIRECTORY STRING STORAGE AREA IN WLDBLK. THEN PARSE THE EXMDSP DATASET. ; 10$: MOV EXMPTR,R4 ; R4 = WLDDSP ! MSTDSP ADDRESS MOV #6,R0 ; R0 = NUMBER OF WORDS IN A DATSET MOV #EXMDSP,R1 ; R1 -> EXMDSP 12$: MOV (R4)+,(R1)+ ; TRANSFER THE APPROPRIATE (MSTDSP, SOB R0,12$ ; OR WLDDSP) DATASET INTO EXMDSP. ; NEED TO COPY DIRECTORY STRING INTO ; WLDBLK AREA. MOV #EXMDSP,R4 ; R4 -> EXMDSP MOV N.DIRD(R4),R0 ; R0 = LENGTH OF DIRECTORY STRING BEQ 17$ ; SKIP THIS IF NO DIR STRING MOV (R4),R1 ; R1 -> DIRECTORY STRING MOV #,R2 ; R2 -> DIR STRING STORAGE IN WLDBLK MOV R2,(R4) ; DATASET DIR ADDRESS IS RESET TO ; POINT TO WLDBLK STRING STORAGE AREA 15$: MOVB (R1)+,(R2)+ ; COPY DIR STRING INTO WLDBLK STORAGE SOB R0,15$ ; USE .WPARS TO PARSE EXMDSP 17$: MOV #EXMFDB,R0 ; R0 -> EXAMINATION FILE FDB MOV #,R1 ; R1 -> EXMFDB FILE NAME BLOCK MOV #EXMDSP,R2 ; R2 -> DATA SET DESCRIPTOR CLR R3 ; (NO DEFAULT NAME BLOCK) MOV #WLDBLK,R4 ; R4 -> WILDCARD UIC BLOCK CALL .WPARS ; PARSE THIS FILE SPECIFICATION BCC 20$ ; .PARSE OK? YES. ERROR EPARXX ; NO. REPORT ERROR SEC ; SET STATUS TO INDICATE FAILURE JMP 999$ ; EXIT ; ; 3. TRY TO FIND THE NEXT FILE WHICH MATCHES EITHER [0,0]*.*;* OR [*,*]*.*;* ; (DEPENDING ON WHETHER EXMPTR = ADDRESS OF MSTDSP OR WLDDSP RESPECTIVELY). ; 20$: MOV #,R1 ; R1 -> EXMFDB FILE NAME BLOCK MOV N.FVER(R1),EXMVER ; SAVE ORIGINAL VERSION NUMBER MOV #EXMFDB,R0 ; R0 -> EXAMINATION FILE FDB MOV #WLDBLK,R2 ; R2 -> WILDCARD UIC BLOCK MOV N.FVER(R1),N.FID+4(R1) ; COPY OLD VERSION TO UNUSED FID SLOT BIS #NB.WLV,N.STAT(R1) ; SET WILD VERSION INPUT FLAG MOV EXMVER,N.FVER(R1) ; RESTORE ORIGINAL VERSION ; .FNDNX REQUIRES THAT: ; R0 -> FDB ; R1 -> FILE NAME BLOCK ; R2 -> SCRATCH WILDCARD BLOCK ;------------------------------------- CALL .FNDNX ; FIND NEXT MATCHING FILE BCC 50$ ; .FNDNX OK? YES. ; ; 4. .FNDNX HAS FAILED. ; IF WLDDSP IS THE ADDRESS IN EXMPTR (EXMDSP WAS [*,*]*.*;*), THEN WE ; HAVE EXHAUSTED ALL FILE CHOICES. IN THIS CASE SET EXMEND IN EXMFLG. ; OTHERWISE, WE HAVE JUST FINISHED WITH EXMDSP BEING [0,0]*.*;*. ; NOW RESET EXMDSP WITH WLDDSP TO PICK UP ALL REMAINING FILES, THEN ; GO PARSE THE [*,*]*.* DATASET. ; CMP #WLDDSP,EXMPTR ; NO. WAS DATASET WLDDSP? BNE 30$ ; NO. GO RESET EXMPTR TO WLDDSP BIS #EXMEND,EXMFLG ; YES. INDICATE NO MORE FILES POSSIBLE BR 50$ ; GO EXIT 30$: MOV #WLDDSP,EXMPTR ; SET EXMPTR WITH WLDDSP BR 10$ ; GO PARSE THIS 50$: CLC ; SET INDICATOR TO SUCCESS 999$: POP ; RESTORE R4-R0 FROM THE STACK RETURN .SBTTL GETMAP -> GET MAP AREA INFO FOR FILE IN EXMFDB AND SEARCH .SBTTL GETMAP WORK BUFFER FOR ANY MATCHING LBN'S. GETMAP:: ;+ ; ROUTINE: GETMAP ; ; EFFECTS: THE FILE HEADER FOR THE FILE IN EXMFDB IS READ INTO SYSBUF. ; FOR EACH MAP RETRIEVAL POINTER (INCLUDING EXTENSION FILE ; HEADER MAP RETRIEVAL POINTERS) THE WORK BUFFER WRKBUF IS ; SEARCHED FOR MATCHING LBN'S. THIS ROUTINE IS EXITED EITHER ; WHEN ALL RETRIEVAL POINTERS FOR THIS FILE HAVE BEEN CHECKED ; AGAINST THE WORK BUFFER, OR IF THE LAST LBN IN THE WORK ; BUFFER HAS BEEN MATCHED. ; ; INPUTS: 1. EXMFDB (EXMFDB FILLED IN VIA .FNDNX ROUTINE) ; 2. SYSFDB (OPENED TO THE FCS INDEX FILE) ; 3. IBITSZ (EQUALS THE FCS INDEX FILE BITMAP SIZE) ; 4. NUMLBN (NUMBER OF LBN'S IN WORK BUFFER) ; 5. WRKBUF (WORK BUFFER CONTAINING LBN'S TO BE SEARCHED FOR) ; ; OUTPUTS: 1. NUMLBN (NUMBER OF LBN'S LEFT IN WORK BUFFER) ; 2. WRKBUF (WORK BUFFER AS INPUT LESS THOSE LBN'S ACCOUNTED ; FOR BY THE FILE IN EXMFDB) ; 3. REGISTERS R0-R3 PRESERVED ; 4. EXMFLG (BIT EXMNAM CLEARED TO INDICATE FILENAME NOT OBTAINED) ; ; ROUTINES ; CALLED: 1. BLKTRP (THROUGH ERROR MACRO) ; 2. RDSYS ; 3. CHKLBN ;- ; ; 1. INITIALIZE BOTVBN TO 1, CLEAR EXMNAM IN EXMFLG TO INDICATE THAT THE ; ASCII FILE NAME IS NOT YET AVAILABLE. THEN OBTAIN THE FILE HEADER ; FROM FCS INDEX FILE FOR THE FILE CONTAINED IN EXMFDB. ; PUSH ; SAVE R0-R3 ON THE STACK CLR BOTVBN ; SET BOTVBN VARIABLE TO 1 MOV #1, BIC #EXMNAM,EXMFLG ; INDICATE FILENAME NOT AVAILABLE CLR SYSVBN ; SYSVBN = SIZE FCS INDEX FILE BITMAP MOV IBITSZ, ; (DOUBLE WORD) ADD #2, ; SYSVBN = BIT MAP SIZE + 2 ADC SYSVBN ; (OVERFLOW) ADD , ; BIT MAP SIZE ; + 2 ; + FILE ID ; ------------ ; INDEX FILE VBN FOR FILE ID ADC SYSVBN ; (OVERFLOW) CALL RDSYS ; READ THE APPROPRIATE INDEX FILE VBN BCS 999$ ; IF ERROR EXIT MOV #,R2 ; R2 -> FILE ID IN EXMFDB CMP (R2)+, ; FILE NUMBER MATCH? BNE 10$ ; NO. GO REPORT ERROR CMP (R2), ; FILE SEQUENCE NUMBER MATCH? BEQ 15$ ; YES. WE HAVE THE PROPER VBN 10$: ERROR XCMPXX ; REPORT FCS INDEX FILE COMPARE ERROR SEC ; SET FAILURE INDICATOR BR 999$ ; THEN EXIT ; ; 2. PICK UP THE NUMBER OF MAP RETRIEVAL POINTERS USED FROM THE MAP AREA ; OF THIS FILE HEADER. IF NO RETRIEVAL POINTERS HAVE YET BEEN ASSIGNED, ; A LEGITAMITE SITUATION, THEN SIMPLY EXIT THIS ROUTINE. ; 15$: MOV #SYSBUF,R0 ; R0 -> SYSBUF MOVB H.MPOF(R0),R1 ; R1 = WORDS TO MAP AREA FROM SYSBUF BIC #^B1111111100000000,R1 ; CLEAR OFF HIGH ORDER BYTE ASL R1 ; R1 = BYTE OFFSET OF MAP AREA ADD R1,R0 ; R0 -> MAP AREA MOV R0,R1 ; R1 -> MAP AREA ADD #S.MPHD,R1 ; R1 -> FIRST MAP RETRIEVAL POINTER MOVB M.USE(R0),R2 ; R2 = RETRIEVAL POINTER WORDS USED BNE 17$ ; ANY RETRIEVAL POINTERS USED? YES CLC ; NO. INDICATE ROUTINE SUCCESS BR 999$ ; THEN EXIT 17$: BIC #^B1111111100000000,R2 ; (CLEAR OFF HIGH BYTE) ASL R2 ; R2 = RETRIEVAL POINTER BYTES USED ; ; 3. ENSURE THAT THE LAYOUT OF THE RETRIEVAL POINTERS IS SUCH THAT EACH ; MAP POINTER CONSISTS OF 4 BYTES ARRANGED AS FOLLOWS: ; ; ----------------- ; : COUNT : HIGH : ; ----------------- ; : LOW ORDER LBN : ; ----------------- CMPB #1,M.CTSZ(R0) ; IS COUNT FIELD SIZE=1? BNE 20$ ; NO. GO REPORT CONSTERNATION CMPB #3,M.LBSZ(R0) ; IS LBN FIELD SIZE =3? BEQ 30$ ; YES. 20$: ERROR MRETXX ; REPORT MAP AREA ERROR SEC ; INDICATE FAILURE BR 999$ ; THEN EXIT ; ; 4. FILL THE COUNT AND BOTLBN VARIABLES WITH THE CORRESPONDING INFO ; FROM THE MAP RETRIEVAL POINTER POINTED TO BY R1. ; 30$: ; R1 -> MAP RETRIEVAL POINTER CLR COUNT ; CLEAR LBN COUNT VARIABLE MOV #BOTLBN,R3 ; R3 -> BOTLBN MOVB (R1)+,(R3)+ ; FILL IN BOTLBN VARIABLE CLRB (R3)+ ; - AND - MOVB (R1)+,COUNT ; COUNT VARIABLE FROM MOVB (R1)+,(R3)+ ; THIS MAP RETRIEVAL POINTER MOVB (R1)+,(R3) ; ; ; 5. GO SEE IF ANY OF THE LBN'S ASSOCIATED WITH THIS MAP POINTER ARE ; IN THE WORK BUFFER. ANY LBN'S IN THE WORK BUFFER THAT MATCH WILL ; HAVE BEEN REMOVED FROM THE WORK BUFFER. THE WORK BUFFER WRKBUF ; WILL BE REORGANIZED, AND THE VARIABLE NUMLBN UPDATED. IF THERE ARE ; NO LBN'S LEFT IN THE WORK BUFFER, WE'RE DONE HERE. ; CALL CHKLBN ; GO MATCH LBN'S IN WRKBUF TST NUMLBN ; ANY LBN'S LEFT IN WORK BUFFER? BNE 35$ ; YES. GET NEXT RETRIEVAL POINTER CLC ; NO. NO NEED TO CONTINUE. SET SUCCESS BR 999$ ; THEN EXIT ; ; 6. SETUP BOTVBN VARIABLE FOR NEXT RETRIEVAL POINTER (IN CASE THERE IS ONE). ; THEN SEE IF THERE ARE ANY MORE RETRIEVAL POINTERS IN THIS FILE HEADER. ; IF THERE ARE, GO PROCESS THE NEXT ONE. ; 35$: ADD COUNT, ; ACCUMULATE VBN'S SUCH THAT ADC BOTVBN ; BOTVBN = FIRST VBN ASSOCIATED WITH INC ; NEXT RETRIEVAL POINTER ADC BOTVBN ; (IF ONE EXISTS). SUB #4,R2 ; R2 = RETREIVAL POINTER BYTES LEFT BLE 40$ ; NONE LEFT. ANY EXTENSION HEADERS? JMP 30$ ; GO LOOK AT NEXT RETRIEVAL POINTER ; ; 7. WE'VE LOOKED AT ALL THE RETRIEVAL POINTERS FOR THIS FILE HEADER. SEE IF ; THERE IS AN EXTENSION FILE HEADER ASSOCIATED WITH THIS FILE. IF SO ; PLACE THE EXTENSION FILE HEADER IN SYSBUF AND GO PROCESS IT. IF NOT, ; WE'RE DONE HERE. ; 40$: TST M.EFNU(R0) ; IS THERE AN EXTENSION FILE NUMBER? BNE 45$ ; YES. GO FETCH EXTENSION FILE HEADER CLC ; NO. ALL DONE HERE. SET STATUS BEQ 999$ ; THEN EXIT 45$: MOV M.EFSQ(R0),-(SP) ; YES. SAVE THE SEQUENCE NUMBER MOV M.EFNU(R0),-(SP) ; AS WELL AS THE EXTENSION FILE NUMBER CLR SYSVBN ; CLEAR HIGH ORDER VBN MOV IBITSZ, ; FCS INDEX FILE BITMAP SIZE ADD #2, ; + 2 ADC SYSVBN ; (OVERFLOW) ADD M.EFNU(R0), ; + FILE ID ADC SYSVBN ; (OVERFLOW) CALL RDSYS BCS 999$ ; ENSURE THAT WE HAVE THE PROPER ; EXTENSION HEADER. ; THE STACK IS: ; ------------------ ; : FILE ID NUMBER : ; ------------------ ; : FILE SEQUENCE : ; ------------------ ;------------------------------------- 50$: CMP (SP)+, ; FILE NUMBER MATCH? BNE 60$ ; NO. GO REPORT ERROR CMP (SP)+, ; FILE SEQUENCE NUMBER MATCH BEQ 70$ ; YES. 60$: INC SP ERROR XCMPXX ; NO. REPORT ERROR SEC ; INDICATE FAILURE BR 999$ ; AND RETURN 70$: JMP 15$ ; GOT EXTENSION HEADER. GO PROCESS IT. 999$: ; LABEL FOR EXIT POP ; RESTORE R3-R0 FROM THE STACK RETURN .SBTTL CHKLBN -> DETERMINE IF LBN'S ASSOCIATED WITH MAP RETRIEVAL .SBTTL CHKLBN POINTER ARE IN THE WORK BUFFER. CHKLBN:: ;+ ; ROUTINE: CHKLBN ; ; EFFECTS: FOR THE MAP RETRIEVAL POINTER SPECIFIED IN THE VARIABLES ; COUNT AND BOTLBN, THE WORK BUFFER IS BINARY SEARCHED FOR ; THE FIRST LBN WHICH FALLS INTO THE RANGE OF THE MAP ; RETRIEVAL POINTER. IF A MATCH IS FOUND, THE ALLLBN ROUTINE ; IS CALLED TO PRINT THIS LBN, AS WELL AS TO SCAN PRECEDING ; AND FOLLOWING LBN'S TO SEE IF THEY ALSO FALL IN THE RANGE ; OF LBN'S REPRESENTED BY THIS POINTER. ; ; INPUTS: 1. COUNT (NUMBER OF LBN'S REPRESENTED BY MAP RETRIEVAL POINTER) ; 2. BOTLBN (LOW LBN REPRESENTED BY MAP RETRIEVAL POINTER) ; 3. WRKBUF (CONTAINS ORDERED UNDUPLICATED LBN'S TO BE MATCHED) ; 4. NUMLBN (THE NUMBER OF LBN'S IN WRKBUF) ; ; OUTPUTS: 1. LBNDIF (DIFFERENCE BETWEEN LBN VALUE IN WRKBUF AND BOTLBN) ; 2. OFFSET (BYTE OFFSET INTO WRKBUF FOR LBN) ; 3. REGISTERS R0-R3 PRESERVED ; ; ROUTINES ; CALLED: 1. ALLLBN ;- ; ; 1. SET REGISTERS UP TO BINARY SEARCH THE WORK BUFFER. ; R0 = LOW ; R1 = INDEX ; R2 = HIGH ; PUSH ; SAVE R0-R3 ON THE STACK MOV #1,R0 ; R0 = 1 (R0 = LOW) MOV NUMLBN,R2 ; R2 = NUMLBN (R2 = HIGH) ; ; 2. SEE IF SEARCH TERMINATES. IF NOT, PLACE MIDPOINT OF R0 AND R2 INTO R1. ; 10$: CMP R2,R0 ; HIGH INDEX - LOW INDEX < 0 ? BLT 999$ ; YES. SEARCH TERMINATES. NO LBN FOR ; THIS MAP RETRIEVAL POINTER MOV R0,R1 ; R1 = LOW ADD R2,R1 ; R1 = LOW + HIGH ASR R1 ; R1 = I = [LOW + HIGH]/2 ; ; 3. MANIPULATE R1 INDEX INTO APPROPRIATE OFFSET FROM THE BEGINNING OF THE ; WORK BUFFER, AND STORE THIS OFFSET IN THE OFFSET VARIABLE. ; MOV R1,R3 ; R3 = I (INDEX) DEC R3 ; R3 = I - 1 ASH #2,R3 ; R3 = (I - 1)*4 MOV R3,OFFSET ; OFFSET = BYTE OFFSET INTO WRKBUF ; FOR INDEX. USED TO FETCH ; INDEX LBN. ; ; 4. SEE HOW THE LBN AT THE ABOVE OFFSET FROM THE WORK BUFFER COMPARES WITH ; THE MAP RETRIEVAL POINTER. FIRST WE CALCULATE THE DIFFERENCE BETWEEN ; THE BOTTOM LBN OF THE MAP RETRIEVAL POINTER, AND THE INDEX LBN: ; LBNDIF = LBN(I) - BOTLBN ; ; THIS LBNDIF VALUE IS THEN USED AS FOLLOWS: ; 1. IF LBNDIF < 0 THEN DO; ; RESET LOW (R0); ; CALCULATE NEW INDEX; ; COMPARE NEW INDEX LBN WITH BOTLBN; ; END; ; ; 2. IF LBNDIF >= 0 AND COUNT-LBNDIF >= 0 THEN THE INDEX LBN IS CONTAINED ; BY THIS MAP RETRIEVAL POINTER. GO PRINT UP THIS LBN, AND SEE IF ; ANY SURROUNDING LBN'S ARE IN THE POINTER RANGE. ; ; 3. IF LBNDIF >= 0 AND COUNT-LBNDIF < 0 THEN DO; ; RESET HIGH (R2); ; CALCULATE NEW INDEX; ; COMPARE NEW INDEX LBN WITH BOTLBN; ; END; ; MOV #WRKBUF,R4 ; R4 -> WRKBUF ADD R3,R4 ; R4 -> INDEX LBN IN WRKBUF MOV (R4)+,LBNDIF ; FILL LBNDIF WITH LBN VALUE MOV (R4), ; UNDER CONSIDERATION SUB , ; CALCULATE LBN - BOTLBN SBC LBNDIF ; SUB BOTLBN,LBNDIF ; BLT 70$ ; IF LBN < BOTLBN, GO RESET LOW BNE 80$ ; HIGH ORDER LBNDIF CLEAR? NO. ; THEN LBNDIF > COUNT, SINCE COUNT ; FIELD IS ONLY 1 BYTE. GO RESET HIGH CMP COUNT, ; COUNT - LBNDIF >= 0 ? BLT 80$ ; NO. GO RESET HIGH BCS 80$ ; NO. (HIGH BIT SET IN LBNDIF) ; GO RESET HIGH ; ; 5A. INDEX LBN FALLS WITHIN MAP RETRIEVAL POINTER. GO DISPLAY IT AND SEE IF ; SURROUNDING LBN'S ALSO FALL WITHIN RANGE. ; CALL ALLLBN ; GO PRINT LBN,VBN AND FILENAME FOR ; ALL LBN'S IN WORK BUFFER ACCOUNTED ; FOR BY THIS MAP RETRIEVAL POINTER BR 999$ ; THEN EXIT ; ; -OR- ; 5B. INDEX LBN LOWER THAN MAP RETRIEVAL POINTER. RESET LOW TO INDEX + 1. ; 70$: MOV R1,R0 ; R0 = INDEX INC R0 ; R0 = INDEX + 1 BR 10$ ; GO FETCH NEXT MIDPOINT ; ; -OR- ; 5C. INDEX LBN HIGHER THAN MAP RETRIEVAL POINTER. RESET HIGH TO INDEX - 1. ; 80$: MOV R1,R2 ; R2 = INDEX DEC R2 ; R2 = INDEX - 1 BR 10$ ; GO FETCH NEXT MIDPOINT 999$: ; LABEL FOR EXIT POP ; RESTORE R3-R0 FROM THE STACK RETURN .SBTTL ALLLBN -> PRINTS INFO FOR LBN OBTAINED FROM BINARY SEARCH .SBTTL ALLLBN AND CHECKS LBN'S SURROUNDING THIS LBN AGAINST .SBTTL ALLLBN MAP RETRIEVAL POINTER. ALLLBN:: ;+ ; ROUTINE: ALLLBN ; ; EFFECTS: THIS ROUTINE IS USED TO PRINT ALL LBN'S IN THE WORK BUFFER ; WHICH ARE ASSOCIATED WITH THE MAP RETRIEVAL POINTER INDICATED ; BY THE VARIABLES COUNT AND BOTLBN. ; USING THE VARIABLE OFFSET, THE LBN FOUND IN THE BINARY SEARCH ; IS DISPLAYED. THE LBN'S PRECEDING AND FOLLOWING THIS LBN IN ; THE WORK BUFFER ARE THEN CHECKED TO SEE IF THEY FALL IN THE ; RANGE OF THE MAP RETRIEVAL POINTER (ANOTHER BENEFIT FROM ; REQUIRING THAT LBN'S IN THE WORK BUFFER BY ORDERED AND NOT ; DUPLICATED). ANY MATCHINGS LBN'S ARE DISPLAYED, AND THEN ; THE WORK BUFFER WRKBUF IS REORGANIZED, AND THE VARIABLE ; NUMLBN IS UPDATED. ; ; INPUTS: 1. OFFSET (BYTE OFFSET INTO WRKBUF FOR LBN FOUND IN BINARY ; SEARCH) ; 2. WRKBUF (WORK BUFFER CONTAINING ORDERED UNDUPLICATED LBN'S) ; 3. NUMLBN (NUMBER OF LBN'S IN WRKBUF) ; 4. COUNT (NUMBER OF LBN'S REPRESENTED BY THIS MAP RETRIEVAL ; POINTER) ; 5. BOTLBN (FIRST LBN REPRESENTED BY THIS MAP RETRIEVAL POINTER) ; 6. EXMFLG (BIT EXMNAM SET INDICATES THAT THE FILENAME HAS ALREADY ; BEEN OBTAINED) ; ; OUTPUTS: 1. WRKBUF (WORK BUFFER IS REORGANIZED TO EXCLUDE ALL LBN'S ; WHICH WERE ACCOUNTED FOR BY THIS MAP RETRIEVAL POINTER) ; 2. NUMLBN (NUMBER OF LBN'S IN WRKBUF IS APPROPRIATELY UPDATED) ; 3. REGISTERS R0-R5 PRESERVED ; 4. EXMFLG (BIT EXMNAM WILL BE SET - FILENAME OBTAINED) ; ; ROUTINES ; CALLED: 1. GETFIL ; 2. PRTLBN ;- ; ; 1. IF FILENAME HAS NOT YET BEEN OBTAINED, GO DETERMINE IT AND THEN PRINT ; THE MESSAGE FOR THE LBN OBTAINED FROM THE BINARY SEARCH. ; PUSH ; SAVE R0-R5 ON THE STACK BIT #EXMNAM,EXMFLG ; HAS FILENAME BEEN OBTAINED YET? BNE 1$ ; YES. (MEANS PRECEDING MAP RETRIEVAL ; POINTER HAD LBN(S) IN WRKBUF) CALL GETFIL ; NO. GO OBTAIN THE FILE NAME 1$: MOV #WRKBUF,R5 ; R5 -> WRKBUF ADD OFFSET,R5 ; R5 -> BINARY SEARCH LBN IN WRKBUF MOV R5,R4 ; R4 -> BINARY SEARCH LBN IN WRKBUF CALL PRTLBN ; GO PRINT LBN,VBN,FILENAME ; ; 2. UPDATE NUMLBN, AND IF THERE ARE MORE LBN'S IN THE WORK BUFFER, SET THE ; LOW AND THE HIGH SHUFFLE POINTERS TO THE BINARY SEARCH LBN. THE SHUFFLE ; POINTERS WILL BE USED IN THE FOLLOWING FASHION. LOWPT WILL EVENTUALLY ; POINT TO THE LOWEST ENTRY IN WRKBUF ACCOUNTED FOR BY THIS MAP RETRIEVAL ; POINTER, WHEREAS HIGHPT WILL BE THE HIGHEST ENTRY IN WRKBUF FOR THIS ; MAP RETRIEVAL POINTER. ; ; SET WRKPT POINTER TO THE LAST LBN CURRENTLY IN THE WORK BUFFER. ; ; IF THE COUNT VARIABLE =0, THEN THE ONLY LBN REFERRED TO BY THE MAP ; RETRIEVAL POINTER IS THE BINARY SEARCH LBN. ; MOV NUMLBN,R3 ; R3 = NUMLBN DEC R3 ; LESS ONE (FOR BINARY SEARCH LBN) BEQ 999$ ; WAS THAT LAST LBN IN WRKBUF? YES. MOV R4,LOWPT ; NO. SET LOW SHUFFLE MOV R4,HIGHPT ; AND HIGH SHUFFLE POINTERS TO BINARY ; SEARCH LBN MOV NUMLBN,WRKPT ; WRKPT = NUMLBN DEC WRKPT ; WRKPT = NUMLBN - 1 ASL WRKPT ; WRKPT = (NUMLBN-1) * 4 ASL WRKPT ; ADD #WRKBUF,WRKPT ; WRKPT -> LAST LBN CURRENTLY IN ; THE WORK BUFFER (LOGICAL END OF ; WORK BUFFER) MOV COUNT,R0 ; R0 = COUNT FIELD VALUE BEQ 100$ ; COUNT=0? YES. ALREADY HAVE ONLY ; POSSIBLE LBN. GO SHUFFLE ; ; 3. FOR ALL LBN'S PRECEDING THE BINARY SEARCH LBN WHICH ARE ACCOUNTED FOR ; BY THIS MAP RETRIEVAL POINTER, PRINT LBN,VBN,FILENAME INFORMATION. ; LOWPT SHUFFLE POINTER IS SET TO POINT TO THE LOWEST LBN IN THE WORK ; BUFFER WHICH IS ACCOUNTED FOR BY THIS MAP RETRIEVAL POINTER. ; REGISTERS: ; R4 PRECEDING LBN IN WORK BUFFER WORKING POINTER ; R5 POINTS TO "PRECEDING" LBN IN THE WORK BUFFER ; R3 EQUALS NUMBER OF LBNS IN THE WORK BUFFER ; R0 EQUALS NUMBER OF LBNS REFERRED TO BY MAP RETRIEVAL POINTER ; 10$: CMP R4,#WRKBUF ; ARE WE AT BEGINING OF WRKBUF? BEQ 60$ ; YES. NO PRECEDING LBNS. LOWPT IS SET MOV -(R4), ; FILL LBNDIF WITH PRECEDING LBN VALUE MOV -(R4),LBNDIF ; MOV R4,R5 ; R5 -> BYTE 0 OF LBN IN WRKBUF SUB , ; LBNDIF = LBN - BOTLBN SBC LBNDIF SUB BOTLBN,LBNDIF BNE 60$ ; HIGH ORDER LBNDIF CLEAR? NO. ; FINISHED WITH PRECEDING LBN'S CMP COUNT, ; COUNT - LBNDIF >= 0? BLT 60$ ; NO. FINISHED WITH PRECEDING LBN'S BCS 60$ ; NO. (HIGH BIT SET IN LBNDIF) ; FINISHED WITH PRECEDING LBN'S CALL PRTLBN ; YES. GO PRINT LBN,VBN,FILENAME MOV R5,LOWPT ; RESET LOW SHUFFLE POINTER DEC R3 ; DECREMENT NUMBER OF LBN'S IN WRKBUF BEQ 999$ ; NO LBN'S LEFT IN WORK BUFFER. ; EXIT. NO NEED TO SHUFFLE. DEC R0 ; DEC MAP RETRIEVAL COUNT AVAILABLE BEQ 100$ ; NO MORE LBN'S LEFT TO BE FOUND FOR ; THIS MAP RETRIEVAL POINTER. ; GO SHUFFLE BR 10$ ; OTHERWISE, CONTINUE DOWNWARD TILL WE ; REACH WRKBUF BOTTOM ; ; 4. FOR ALL LBN'S FOLLOWING THE BINARY SEARCH LBN WHICH ARE ACCOUNTED FOR ; BY THIS MAP RETRIEVAL POINTER, PRINT LBN,VBN,FILENAME INFORMATION. ; HIGHPT SHUFFLE POINTER IS SET TO POINT TO THE HIGHEST LBN IN THE WORK ; BUFFER WHICH IS ACCOUNTED FOR BY THIS MAP RETRIEVAL POINTER. ; REGISTERS: ; R4 FOLLOWING LBN IN WORK BUFFER WORKING POINTER ; R5 POINTS TO "FOLLOWING" LBN IN THE WORK BUFFER ; R3 EQUALS NUMBER OF LBNS IN THE WORK BUFFER ; R0 EQUALS NUMBER OF LBNS REFERRED TO BY MAP RETRIEVAL POINTER ; 60$: CMP WRKPT,HIGHPT ; IS BIN SEARCH LBN AT TOP OF WRKBUF? BEQ 999$ ; YES. NO FOLLOWING LBN'S. NO NEED TO ; SHUFFLE MOV HIGHPT,R4 ; R4 -> BINARY SEARCH LBN IN WRKBUF ADD #4,R4 ; R4 -> LBN AFTER BIN SEARCH LBN IN ; THE WORK BUFFER. 70$: CMP R4,WRKPT ; ARE WE PASS LOGICAL END OF WRKBUF? BGT 999$ ; YES. THEN EXIT. NO NEED TO SHUFFLE ; SINCE AT LEAST LBN'S FROM BIN LBN ; TO THE LAST LBN IN WRKBUF ARE ; ACCOUNTED FOR BY THIS MAP POINTER MOV R4,R5 ; NO. R5 -> BYTE 0 OF FOLLOWING LBN MOV (R4)+,LBNDIF ; FILL LBNDIF WITH LBN VALUE MOV (R4)+, ; SUB , ; LBNDIF = LBN - BOTLBN SBC LBNDIF SUB BOTLBN,LBNDIF BNE 100$ ; HIGH ORDER LBNDIF CLEAR? NO. ; FINISHED WITH FOLLOWING LBN'S CMP COUNT, ; COUNT - LBNDIF >= 0? BLT 100$ ; NO. FINISHED WITH FOLLOWING LBN'S BCS 100$ ; NO. (HIGH BIT SET IN LBNDIF) ; FINISHED WITH FOLLOWING LBN'S CALL PRTLBN ; YES. GO PRINT LBN,VBN,FILENAME MOV R5,HIGHPT ; RESET HIGH SHUFFLE POINTER DEC R3 ; DECREMENT NUMBER OF LBN'S IN WRKBUF BEQ 999$ ; NO LBN'S LEFT IN WORK BUFFER. ; EXIT. NO NEED TO SHUFFLE. DEC R0 ; DEC MAP RETRIEVAL COUNT AVAILABLE BEQ 100$ ; NO MORE LBN'S LEFT TO BE FOUND FOR ; THIS MAP RETRIEVAL POINTER. ; GO SHUFFLE BR 70$ ; OTHERWISE, CONTINUE UPWARD TILL WE ; REACH LOGICAL TOP OF WRKBUF ; ; 5. SHUFFLE THE WORK BUFFER ; WHEN(IF) WE ARRIVE HERE, WE HAVE LOWPT POINTING TO THE LOWEST LBN ; IN THE WORK BUFFER WHICH IS ACCOUNTED FOR BY THIS MAP RETRIEVAL ; POINTER, AND HIGHPT POINTING TO THE HIGHEST LBN. WRKPT POINTS TO ; THE LAST LBN WHICH IS CURRENTLY IN THE WORK BUFFER. ; THE WORK BUFFER IS REORGANIZED BY TAKING THE LBN'S STARTING AT THE ; FIRST LBN AFTER HIGHPT TO THE LBN AT WRKPT AND SHUFFLING THEM DOWN SO ; THAT THE FIRST LBN AFTER HIGHPT NOW RESIDES AT THE LOCATION LOWPT, ETC. ; 100$: MOV LOWPT,R0 ; R0 = LOWPT -> LOWEST LBN IN WRKBUF ; WITHIN MAP RETRIEVAL ; POINTER RANGE. MOV HIGHPT,R1 ; R1 = HIGHPT-> HIGHEST LBN IN WRKBUF ; WITHIN MAP RETRIEVAL ; POINTER RANGE. MOV WRKPT,R2 ; R2 = WRKPT -> HIGHEST LBN IN WRKBUF. ;**** CMP WRKPT,HIGHPT ; IS HIGHPT AT TOP OF WRKBUF? BEQ 999$ ; YES. NO NEED TO SHUFFLE. EXIT. ; (ONLY CASE WHERE THIS COULD HAPPEN ; IS WHERE BINARY SEARCH LBN IS AT ; TOP OF WRKBUF, AND THE EXAMINATION ; OF THE PRECEDING LBN'S EXHAUSTS ; THE MAP RETRIEVAL POINTER.) ;**** ADD #4,R1 ; R1 -> FIRST LBN AFTER HIGHPT 110$: CMP R2,R1 ; HAVE WE SHUFFLED EVERYTHING? BLT 999$ ; YES. GO RESET NUMLBN MOV (R1)+,(R0)+ ; SHUFFLE HIGH LBN MOV (R1)+,(R0)+ ; THEN LOW LBN DOWN BR 110$ 999$: MOV R3,NUMLBN ; RESET NUMLBN TO NUMBER OF LBN'S LEFT POP ; RESTORE R5-R0 FROM THE STACK RETURN .SBTTL PRTLBN -> PRINTS THE LBN,VBN, AND FILENAME PRTLBN:: ;+ ; ROUTINE: PRTLBN ; ; EFFECTS: PRINTS THE LBN REFERRED TO IN R5, THE VBN AND THE NAME ; OF THE FILE TO WHICH THE LBN IS OWNED. ; ; INPUTS: 1. REGISTER R5 (CONTAINS POINTER TO LBN IN WRKBUF) ; 2. EXMFIL (CONTAINS FILE DESCRIPTOR IN ASCII) ; 3. EXMFSZ (CONTAINS NUMBER OF CHARACTERS IN EXMFIL) ; 4. BOTVBN (THE FIRST VBN REFERRED TO BY THE MAP RETRIEVAL ; POINTER) ; 5. LBNDIF (THE NUMBER OF LBN'S THE LBN INDICATED BY R5 IS ; FROM THE FIRST LBN REFERRED TO BY THE MAP RETRIEVAL POINTER. ; ; OUTPUTS: 1. VBNVAL (THE VBN IN THE EXMFIL FILE FOR THE LBN INDICATED ; BY R5. ; 2. ARGBLK (USED TO CREATE MESSAGE) ; 3. ALL REGISTER PRESERVED (R0-R5) ; ; ROUTINES ; CALLED: 1. $EDMSG ;- ; ; 1. DETERMINE THE VBN IN EXMFIL WHICH THE LBN REFERRED TO BY R5 IS. THIS ; IS DONE BY TAKING LBNDIF, THE DIFFERENCE BETWEEN THE R5 LBN AND THE ; BOTTOM LBN FOR THE MAP RETRIEVAL POINTER, AND ADDING THE BOTTOM VBN ; VALUE FOR THE MAP POINTER. ; PUSH ; SAVE R0-R5 ON THE STACK MOV LBNDIF,VBNVAL ; VBNVAL = LBNDIF MOV , ; ADD , ; VBNVAL = LBNDIF + BOTVBN ADC VBNVAL ; ADD BOTVBN,VBNVAL ; ; ; 2. PLACE ARGUMENTS FOR $EDMSG INTO ARGBLK, AND DISPLAY THE MESSAGE ; MOV R5,ARGBLK ; ARGBLK -> LBN VALUE MOV #VBNVAL, ; -> VBN VALUE MOV EXMFSZ, ; = SIZE OF EXMFIL MOV #EXMFIL, ; -> FILE NAME MOV #LSTBUF,R0 ; R0 -> LISTING BUFFER MOV #FNDMSG,R1 ; R1 -> MESSAGE STRING MOV #ARGBLK,R2 ; R2 -> ARGUMENT BLOCK CALL $EDMSG ; CREATE MESSAGE PUT$S #LSTFDB,#LSTBUF,R1 ; PRINT MESSAGE IN LIST FILE POP ; RESTORE R5-R0 FROM THE STACK RETURN .SBTTL GETFIL -> OBTAIN THE FILE DESCRIPTION FOR THE FILE WHOSE .SBTTL GETFIL MAP RETRIEVAL POINTER JUST MATCHED AN LBN IN .SBTTL GETFIL THE WORK BUFFER FOR THE FIRST TIME. GETFIL:: ;+ ; ROUTINE: GETFIL ; ; EFFECTS: OBTAINS THE ASCII FILE NAME DESCRIPTION FOR THE FILE IN EXMFDB ; AND PLACES THE STRING IN EXMFIL AND THE SIZE OF THE STRING ; IN EXMFSZ. ; ; INPUTS: 1. EXMFDB (CONTAINS INFO VIA .FNDNX) ; ; OUTPUTS: 1. EXMFIL (CONTAINS THE FILENAME DESCRIPTION STRING) ; 2. EXMFSZ (CONTAINS SIZE OF STRING IN EXMFIL) ; 3. REGISTERS R0-R3 PRESERVED ; ; ROUTINES ; CALLED: 1. $CBTA ; 2. .RDFDR ; 3. $C5TA ;- ; ; 1. OBTAIN THE DEVICE NAME ; PUSH ; SAVE R0-R3 ON THE STACK MOV #EXMFIL,R0 ; R0 -> EXAMINATION FILE DESCRIPTION MOV ,(R0)+ ; DEVICE NAME MOV ,R1 ; NEXT THE UNIT NUMBER MOV #^B1111100000001000,R2 ; SUPPRESS LEADING 0'S, OCTAL CALL $CBTA MOVB #':,(R0)+ ; INTERJECTING : ; ; 2. OBTAIN THE DIRECTORY NAME (UIC) ; BIT #NB.DIR, ; WAS AN EXPLICIT UIC GIVEN BEQ 50$ ; NO. GO FETCH DEFAULT UIC MOV ,R3 ; R3 -> DATA SET DESCRIPTOR MOV (R3),R1 ; R1 -> UIC STRING MOV N.DIRD(R3),R2 ; R2 = UIC STRING LENGTH 25$: MOVB (R1)+,(R0)+ ; TRANSFER DATA SET UIC TO FILE DESC. SOB R2,25$ ; CONTINUE TILL DONE BR 80$ ; GO GET FILE NAME. 50$: CALL .RDFDR ; FETCH DEFAULT UIC 55$: MOVB (R2)+,(R0)+ ; THEN TRANSFER SOB R1,55$ ; DONE? ; ; 3. OBTAIN THE FILE NAME ; 80$: MOV ,R1 ; NOW THE FILE NAME CALL $C5TA MOV ,R1 CALL $C5TA MOV ,R1 CALL $C5TA MOV #9.,R2 ; R2 = 9. = FILE NAME SIZE 85$: CMPB #40,-(R0) ; IS THIS A SPACE? BNE 90$ ; NO. SOB R2,85$ ; YES. TRY PRECEDING BYTE 90$: INC R0 ; R0 -> BYTE AFTER COMPRESSED NAME MOVB #'.,(R0)+ ; INTERJECTING PERIOD ; ; 4. OBTAIN THE FILE TYPE ; MOV ,R1 ; THEN THE FILE TYPE CALL $C5TA MOV #3.,R2 ; R2 = 3. = FILE TYPE SIZE 185$: CMPB #40,-(R0) ; IS THIS A SPACE? BNE 190$ ; NO. SOB R2,185$ ; YES. TRY PRECEDING BYTE 190$: INC R0 ; R0 -> BYTE AFTER COMPRESSED NAME MOVB #';,(R0)+ ; THEN ';' ; ; 5. OBTAIN THE FILE VERSION NUMBER ; MOV ,R1 ; FINALLY THE VERSION MOV #^B1111100000001000,R2 ; SUPRESS LEADING 0'S, OCTAL CALL $CBTA ; CONVERT BINARY TO ASCII ; ; 6. CALCULATE THE FILE DESCRIPTION SIZE AND PLACE IN EXMFSZ ; SUB #EXMFIL,R0 ; R0 = SIZE OF EXAMINATION FILE DESC. MOV R0,EXMFSZ ; SAVE FILE DESCRIPTION SIZE POP ; RESTORE R3-R0 FROM THE STACK RETURN .SBTTL WRKREM -> DISPLAYS ANY REMAINING LBN'S IN THE WORK BUFFER .SBTTL WRKREM AFTER ALL [0,0] AND [*,*]*.*;* FILES HAVE BEEN .SBTTL WRKREM CHECKED AND LBN'S ARE UNACCOUNTED FOR. WRKREM:: ;+ ; ROUTINE: WRKREM ; ; EFFECTS: DISPLAYS ALL OF THE LBN'S LEFT IN THE WORK BUFFER AFTER ; ALL THE FILES ON THE SPECIFIED DEVICE HAVE BEEN CHECKED. ; (THIS IS A LEGITAMITE POSSIBILITY. ONE OCCURANCE WOULD BE:) ; 1. AN LBN IS PLACED INTO THE WORK BUFFER AFTER A CHECK ; OF THE STORAGE BITMAP FILE INDICATES THAT THE LBN ; IS IN USE. ; 2. BY THE TIME THE FILE TO WHOM THIS LBN WAS ALLOCATED ; GETS CHECKED, THE FILE IS DELETED. ; 3. THIS NO FILE HAS THIS LBN ALLOCATED, AND A FILE ; WHOSE FILE HEADER HAS ALREADY BEEN CHECKED APPENDS ; THIS BLOCK. ; ; INPUTS: 1. NUMLBN (NUMBER OF LBN'S LEFT IN THE WORK BUFFER) ; 2. WRKBUF (WORK BUFFER CONTAINING LBN'S REMAINING) ; ; OUTPUTS: 1. LSTBUF (FILLED WITH TEXT TO BE DISPLAYED) ; 2. ARGBLK (ARGUMENT FOR $EDMSG) ; ; ROUTINES ; CALLED: 1. $EDMSG ;- ; ; 1. PLACE THE NUMBER OF LBN'S LEFT IN THE WORK BUFFER IN R5. AFTER ENSURING ; THAT THERE ARE SOME LEFT, DISPLAY THE HEADING. ; PUSH ; SAVE R0-R5 ON THE STACK MOV NUMLBN,R5 ; R5 = NUMBER OF LBN'S IN BUFFER BEQ 999$ ; NO LBN'S LEFT OVER.NO REASON TO ; BE HERE. EXIT. PRINT #REMMSG,#REMSIZ ; PRINT HEADING MOV #WRKBUF,R4 ; R4 -> WRKBUF ; ; 2. DISPLAY EACH LBN WHICH IS LEFT IN THE WORK BUFFER ; 10$: MOV #LSTBUF,R0 ; R0 -> LIST FILE BUFFER MOV #LBNMSG,R1 ; R1 -> $EDMSG STRING MOV R4,ARGBLK ; ARGBLK -> LBN IN WRKBUF ADD #4,R4 ; R4 -> NEXT LBN IN WRKBUF(MAYBE) MOV #ARGBLK,R2 ; R2 -> ARGUMENT BLOCK CALL $EDMSG ; CREATE MESSAGE IN LIST FILE BUFFER PRINT #LSTBUF,R1 ; DISPLAY THE MESSAGE SOB R5,10$ ; CONTINUE UNTIL LAST LBN IS DONE 999$: POP ; RESTORE R5-R0 FROM THE STACK RETURN .END