.MCALL .MODULE .MODULE BUPBAK,VERSION=07,IDENT=NO,COMMENT= ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion 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 Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; 29-Jun-89 RHH V5.5 Work .SBTTL Macro References .MCALL .BR .SERR .HERR .LOOKUP .ENTER .FETCH .PURGE .MCALL .PRINT .RCTRLO .READW .ASSUME SOB .MACRO ...... .ENDM .SBTTL BUPBAK - BUP BACKUP common code .NLIST BEX .PSECT .PURE.,D ; BACKUP messages MESCON::.ASCII /?BUP-I-Creating output volume /<200> MESAPP::.ASCIZ /?BUP-I-Appending to volume/ MESVER::.ASCIZ /?BUP-I-Verify pass started/ NOFBAK: .ASCIZ /?BUP-F-No files backed up/ FBAKD: .ASCIZ / Files backed up:/ BLSTR: .ASCII / of /<200> .EVEN .PSECT .IMPU.,D ; File entry table offsets for GINBLK FT.REP =: 0. ; no. of blocks represented FT.STR =: 2. ; starting logical block FT.FBL =: 4. ; file's starting physical block FT.SPA =: 6. ; spare FT.SPC =: 8. ; filespec FT.SIZ =: 16. ; bytes per table entry FT$NUM =: 25. ; no. of file table entries FT$SIZ =: ; total table size PHYBLK: .WORD 0 ; block number being read by GINBLK PHYBUF: .WORD 0 ; 1st block number in buffer NFREPR: .WORD 0 ; no. of files in DBLK table, minus 1 NBLREP: .WORD 0 ; pointer to BLOCKS REPRESENTED entry CFSIZE: .WORD 0 ; current file's size BFDPTR: .WORD DUMMY ; pointer to file table DUMMY: .WORD 0 ; for /DEVICE mode GBCALL: .WORD 0 ; CALL GINBLK counter REABAD::.WORD 0 ; Set when abort of backup is needed TOPENT: .BLKW FT.SIZ/2 ; Space for saving top entry SAVENT: .BLKW FT.SIZ/2 ; for saving TOPENT during VERIFY VBGENT: .BLKW FT.SIZ/2 ; for saving TOPENT during BACKUP REMBUF: .WORD 0 ; No. blocks free in buffer .PSECT .CODE.,I .SBTTL TBAC, IMAGE, INITI entries ; These entries are called by the root. They serve to load this ; overlay before performing BUP BACKUP functions. TBAC:: JMP TBACO ; Go to Tape BACKUP Code in Ovly 2 IMAGE:: JMP IMAGEO ; Go to Disk BACKUP Code in Ovly 2 INITI:: JMP INITIO ; Go to Disk INIT Code in Ovly 2 .SBTTL GINBLK - Get Input Blocks for BACKUP ;+ ; Get input blocks for BACKUP operation. At first, blocks are read ; from the temporary container file through TMPCHA. After that file ; is exhausted, IGTENT is used to determine the location and length ; of files being backed up so that I/O can be performed directly from ; the input disk volume. Therefore, no individual .LOOKUPs of input ; files is necessary. ; ; GINBLK is used for both DISK and MAGTAPE backups. ; ; On entry, ; ; R1 = buffer address (maybe altered) ; R2 = next block number to read from (updated, stored in RESUME) ; R3 = word count (not altered) ; R4 is preserved ; ; R0 and R5 are not preserved ; ; Before entering this routine for the first time, REMFIL and CONBLK ; must contain the number of blocks in the container area (excluding ; prefix block), RESUME must contain zero (first container block). ; This is because the container file is treated as an already-open ; zeroth file to be backed up. ; ; Logging of the filename on the terminal is controlled by the byte ; variable VERFYG, and whether the first character of ASCNAM is NULL. ; VERFYG prevents filenames from appearing on the screen during VERIFY. ; ; These routines use a table of file descriptors (other than the directory) ; allocated in the dynamic area and pointed to by BFDPTR, to keep track ; of files represented in the I/O buffers. The table is used to correctly ; display verify errors, should they occur. ;- .ENABL LSB GINBLK::MOV R3,-(SP) ; Save word count R3 MOV R4,-(SP) ; Save R4 CLR REABAD ; Init the "really bad input" flag MOV BFDPTR,NBLREP ; init pointer to BLOCKS REPRESENTED SWAB R3 ; get BLOCK count MOV R3,REMBUF ; declare entire buffer free BIT #I$OPT,OPTACT ; /DEVICE? BNE 40$ ; Branch if so. ; File Mode. ; Begin by moving the current top entry to the bottom, as the first file. ; This handles the case where if in the previous GINBLK call, a file ; exactly fit in the top of the buffer, IGTENT was still called to find ; the next file entry, none of which has been transferred yet. MOV #TOPENT,R0 ; from here, MOV BFDPTR,R5 ; to here CALL MOVENT ; move entry. CLR @R5 ; terminate table CLR NFREPR ; (zero means ONE entry) ; Are we getting input from the WORKFILE or the INPUT files? CMP R2,CONBLK ; Beyond "container" blocks? BHIS 20$ ; Branch if so TST R2 ; beginning of WF? BNE 10$ ; This is the very first call with the WORKFILE as input. MOV CONBLK,REMFIL ; fake file entry size MOV CONBLK,CFSIZE CLR FILBLK ; Store workfile information at bottom of table. 10$: MOV BFDPTR,R5 CLR (R5)+ ; reserve space for BLOCKS REPRESENTED CLR (R5)+ ; starting block CLR (R5)+ ; "FILBLK" CLR (R5)+ ; spare MOV #TMPFIL,R0 ; WF:BUPTMP.TMP is current file .REPT 4 MOV (R0)+,(R5)+ .ENDR CLR @R5 ; terminate table CLR NFTRAN ; Cause first IGTENT to init table CLRB ASCNAM ; Inhibit first file transferred log CALL SAV1ST ; If 1st call, save status. MOV TMPCHA,R4 ; Start with TEMP FILE channel BR 50$ ; If this is the first call to GINBLK for this volume, save status now. 20$: CALL SAV1ST ; Take input from regular INPUT files. MOV RESUME,R2 ; Get REAL input block number. 40$: MOV INCHAN,R4 ; Use INPUT channel ; Check to see whether the remainder of the current file will fit in ; (the remainder of) the buffer. 50$: INC GBCALL ; Count calls to GINBLK CMP REMFIL,REMBUF ; Room in buffer for remainder? BLOS 60$ ; Branch if so. ; The amount of file (or /DEVICE) blocks left exceeds the buffer space. ; Fill the buffer and return. MOV REMBUF,R3 ; Do no. of blocks remaining in buffer BEQ 110$ ; If exactly full, return. CALL READBL ; read the blocks, SUB R3,REMFIL ; account for them, BR 110$ ; and then return. ...... ; The remainder of the file fits in the available buffer space. Read it in. 60$: MOV REMFIL,R3 ; Do no. of blocks remaining in file CALL READBL ; read the blocks SUB REMFIL,REMBUF ; reduce amount of buffer space BIT #I$OPT,OPTACT ; /DEVICE mode? BNE 120$ ; If so, done. ; Ready for NEXT file. If not verifying and not /NOLOG, print the name ; of the file just transferred. TSTB ASCNAM ; Haven't gone through IGTENT yet? BEQ 90$ ; Then no files transferred yet. TSTB VERFYG ; verifying or /NOLOG? BMI 80$ ; TSTB WILDFG ; wildcards specified? ; BEQ 80$ ; Don't display files if not. TST NFTRAN ; If this is first file transferred, BNE 70$ .PRINT #FBAKD ; print "Files backed up:" 70$: CALL NFROFS ; get address of top entry ADD #FT.SPC,R0 ; point to filespec CALL DPLYDB ; display filename, 80$: INC NFTRAN ; count the file as transferred. ; Request of IGTENT the next matching file entry. 90$: MOV #IGTENT,R0 ; File mode... MOV #IGEBLK,R5 CALL CALL$F ; Get next file entry TSTB GIV.P ; /EXCLUDE in effect? BPL 92$ ; branch if not. CMP R0,#E.NOMA ; /EXCLUDE. Successful NOMATCH? BEQ 95$ ; Yes. Backup the file. TST R0 BPL 90$ ; Non-matching entry. Ask again. 92$: TST R0 ; look at return code BMI 130$ ; can't continue BIS R0,FNDBTS ; OR-in file-found bits 95$: MOV #DIRENT,R2 ; point to entry buffer MOV E.LENG(R2),REMFIL ; set new REMAINING IN FILE value MOV E.LENG(R2),CFSIZE ; save it locally too. ; Add this file to the entry table. CMP NFREPR,# ; ready to overflow table? BHIS 100$ ; please don't. INC NFREPR ; else add 1 to no. of entries 100$: CALL NFROFS ; get address of new entry .ASSUME FT.REP EQ 0 MOV R0,NBLREP ; save pointer to BLOCKS REPRESENTED .ASSUME FT.REP EQ 0 CLR (R0)+ ; no blocks represented yet .ASSUME FT.STR EQ CLR (R0)+ ; starting logical block .ASSUME FT.FBL EQ MOV FILBLK,(R0)+ ; store file's starting block, CLR (R0)+ ; spare word .ASSUME FT.SPC EQ MOV INPDEV,(R0)+ ; physical device name, ; .ASSUME E.NAME EQ 2 TST (R2)+ ; point to filename in DIRENT .REPT 3 MOV (R2)+,(R0)+ ; save filespec in entry table .ENDR CLR (R0)+ ; terminate table MOV FILBLK,R2 ; starting block number BR 40$ ; go try to do some more ...... ; If /DEVICE mode, simply return. If FILE mode, transfer the current ; top entry to a static location, TOPENT. 110$: BIT #I$OPT,OPTACT ; /DEVICE mode? BNE 120$ ; If so, done. CALL NFROFS ; point to top entry of table MOV #TOPENT,R5 CALL MOVENT ; save the entry in TOPENT. 120$: MOV R2,RESUME ; Store next block no. for later TST (PC)+ 130$: SEC MOV (SP)+,R4 ; restore registers MOV (SP)+,R3 ; Guarantee unaltered R3 RETURN ...... .DSABL LSB .SBTTL NFROFS - Get address of top table entry ;+ ; This routine calculates the address of the top table entry, ; and returns it in R0. ;- .ENABL LSB NFROFS: MOV NFREPR,R0 ; no. files currently in buffers .ASSUME FT.SIZ EQ 16. ASL R0 ; *2 ASL R0 ; *4 ASL R0 ; *8 make 8-word offset ASL R0 ; *16. (16. byte offset) ADD BFDPTR,R0 ; address of table entry 10$: RETURN ...... .SBTTL SAV1ST - Save First Block Represented ;+ ; For FILE backup, after entering GINBLK and setting up the first ; file table entry, adjust the starting block number noted in the ; table to reflect blocks transferred in previous calls. ; ; If this is the first call to GINBLK, move the top file entry ; and a few other variables to a special place. AFTVER will restore ; them for resuming after VERIFY. GETPOS restores them after certain ; error recoveries. ;- SAV1ST: MOV BFDPTR,R5 ; Get pointer to current file entry ADD #FT.STR,R5 ; Point to 1ST LOG_BLOCK value MOV CFSIZE,@R5 ; FT.STR(R5) = FILESIZE - REMAINING SUB REMFIL,@R5 ; TST GBCALL ; first call to GINBLK? BNE 10$ ; branch if not. MOV FILBLK,VBGFBL ; save current file's start block MOV CFSIZE,VBGCFS ; save current file size MOV BFDPTR,R0 MOV #VBGENT,R5 ; Area to save top entry across VFY .BR MOVENT ; Now, move an entry ; Move a file table entry from (R0) to (R5) MOVENT: MOV R2,-(SP) MOV #,R2 ; no. of words to move 20$: MOV (R0)+,(R5)+ SOB R2,20$ MOV (SP)+,R2 30$: RETURN ...... .DSABL LSB .SBTTL READBL - Read blocks from DISK device ;+ ; Read blocks from a device whose channel is in R4. ; ; READBL is a service routine for GINBLK above ; WAIT-mode transfer is used. ; ; R1 = BUFFER ADDRESS (updated) ; R2 = BLOCK NUMBER (updated) ; R3 = NUMBER OF BLOCKS (not altered) ; R4 = CHANNEL to read from ;- .ENABL LSB READBL: MOV R3,-(SP) ; save no. of blocks SWAB R3 ; make WORD count MOV R2,PHYBUF ; save physical block number .READW #EMTARE,R4,R1,R3,R2 ; Fill a buffer. BCC 40$ ; Branch on success. ; Carry set... read error from input device. ; Read data into the buffer one block at a time. 10$: MOV R2,PHYBLK ; save physical block number .READW #EMTARE,R4,R1,#256.,R2 ; Read 1 block BCC 30$ CMPB @#$ERRBY,#1 ; Hard error? BEQ 20$ ; Branch if so. Try to read blocks. ; MOV #RE2,R1 ; otherwise it can't be corrected ; JMP FATAL ; by re-reading. INC REABAD ; Set "need to abort" flag 20$: CALL PRERER ; Display READ ERROR message 30$: ADD #512.,R1 ; Bump buffer address pointer INC R2 ; next block number, SUB #256.,R3 ; and word count. BNE 10$ ; Loop until all blocks read. MOV (SP)+,R3 ; Restore block count BR 50$ 40$: ADD R3,R1 ; Update buffer address. ADD R3,R1 ; (Add byte count to buf address) MOV (SP)+,R3 ; Restore block count ADD R3,R2 ; Update starting block 50$: MOV R3,@NBLREP ; save number of blocks read RETURN .DSABL LSB .SBTTL INLOAD - Fetch and open channel to input to BACKUP ;+ ; FUNCTION: ; Load the device handler and open the input device for a BACKUP operation ;- .ENABL LSB INLOAD::MOV INFIL,DEVSPC ; input device name MOV NHDRAD,R1 ; Next avail hdlr address CALL FETHAN ; Fetch input handler BIT #I$OPT,OPTACT ; /DEVICE operation? BNE 50$ ; If so, go do lookup now. ; File operation: ; Allocate buffer and work area for IGTDIR and IGTENT MOV #INCHAN,IGDCHN ; specify channel for IGTDIR MOV R0,IGDBUF ; use this address as IGTDIR buffer ADD #2000,R0 ; skip over it, MOV R0,WKAREA ; use this address for work area MOV R0,WKARED ADD #,R0 ; move beyond it MOV R0,WKARAR ; and a work area for RECOVERY ADD #,R0 TSTB GIV.V ; /VERIFY specified? BPL 40$ ; branch if not. MOV R0,WKARAV ; and a work area for it ADD #,R0 40$: MOV R0,BFDPTR ; Allocate file entry table ADD #FT$SIZ,R0 ; Determine main data buffer location. If XM try using high memory. 50$: CMP R0,TOPADD ; Check for allocation above limit BHIS 90$ ; and branch if so. MOV R0,BUFADD ; Save address above handlers CALL XMBUFR ; If XM, reset BUFADD to high mem ; Do NFS LOOKUP on input device. MOV INCHAN,R2 MOV #DEVSPC,R3 MOV INFIL,@R3 CALL LOOKD ; Do NFS LOOKUP on input BCS 90$ ; branch on error BIT #I$OPT,OPTACT ; /DEVICE operation? BNE 60$ ; File operation stuff: ; Call IGTDIR to start wildcard search through container in workfile. MOV #IGDBLK,R5 ; point to arg block CALL IGTDIR ; set up wildcard search TST R0 ; inspect return code BMI 90$ ; Return on errors MOV FILSIZ,TOTLLN ; determined by MAKDIR in BUPCMD CLRB ASCNAM ; no-log before 1st IGTENT call BR 70$ ; DEVICE operation stuff: ; Determine the size of the device being backed up. 60$: MOV INFIL,DEVSPC ; Get input device CALL GSIZE ; Get device size BCS 90$ ; Branch if error MOV R1,FILSIZ ; Get device size CLR FILBLK ; so that PVERER prints abs blk nos ; Initialize some input-related variables 70$: CLR INBLK ; reset starting input block no. CLR RESUME ; 1st block no. of container file 80$: TST (PC)+ ; Good return. 90$: SEC ; Bad return. RETURN .DSABL LSB .SBTTL LOOKD - LOOKUP and ENTER code for BACKUP ;+ ; Do .LOOKUP (or .ENTER) on disk or disk file. ; ; R2 = channel number ; R3 -> DBLK ; ; CALL LOOKD ; or ; CALL ENTERD (for DISK-TO-DISK saveset creation on backup volume) ; ; ; On return, R0 contains .LOOKUP's (.ENTER's) return value. ;- .ENABL LSB EERTBL: .WORD LO2,SPA,LO3,FEP ; .ENTER error table LERTBL: .WORD LO2,LO1 ; .LOOKUP error table ENTERD::.SERR ; .ENTER entry .ENTER #EMTARE,R2,R3,ENTSIZ BCC 40$ MOV #EERTBL,R1 ; get appropriate msg pointer BR 10$ ...... LOOKD:: .SERR ; .LOOKUP entry .LOOKUP #EMTARE,R2,R3 ; Attempt the open... BCC 40$ ; Branch if no error MOV #LERTBL,R1 10$: MOVB @#$ERRBY,R0 ; Which class of errors? BMI 20$ ; Branch if .SERR in effect. ASL R0 ; convert error to word offset ADD R0,R1 ; get appropriate msg pointer MOV @R1,R1 ; get the error code .HERR ; Turn off SERR .ERR #ERRARE,R1,LEVEL=FATAL,RETURN=YES,FILE=R3 SEC ; Error return RETURN ...... 20$: .PURGE R2 MOV #WR1,R1 ; <-F-Directory I/O Error > JMP FATAL3 ...... 40$: MOV R0,-(SP) ; Save LOOKUP's return .HERR ; Turn off SERR MOV (SP)+,R0 RETURN ...... .DSABL LSB .SBTTL PVERER - Print VERIFY ERROR Message ;+ ; Inform user of VERIFY ERROR ; R2 = No. of blocks into verify buffer, where the error occurred. ;- .ENABL LSB PVERER::.PRINT #VERMES ; Print VERIFY error message MOV R2,-(SP) MOV R4,-(SP) ; Determine which file in the buffer caused the error. Look through ; entry table (BFDBLK) for the file whose last block is higher than ; the physical block BIT #I$OPT,OPTACT ; If /DEVICE, BNE 40$ ; just format the block number MOV NFREPR,R0 ; number of files in table minus 1 MOV BFDPTR,R4 ; start of table MOV R1,-(SP) CLR R1 ; accumulator 10$: TST @R4 ; any more entries? BEQ 20$ ; branch if not. .ASSUME FT.REP EQ 0 ADD @R4,R1 ; accum. blocks represented CMP R1,R2 ; is this the correct entry? BHI 30$ ; branch if so. ADD #FT.SIZ,R4 ; point to NEXT entry DEC R0 BPL 10$ 20$: ; .PRINT #XXX ; BR 30$ ;XXX: .ASCIZ /???BUP-XXX-Ran out of table entries!/ ; .EVEN 30$: SUB @R4,R1 ; back to beginning of entry SUB R1,R2 ; make verify offset rel to this file MOV (SP)+,R1 ; restore R1 TST (R4)+ ; point to START_BLOCK entry .ASSUME FT.STR EQ ADD (R4)+,R2 ; make relative to file starting blk .ASSUME FT.FBL EQ CMP (R4)+,(R4)+ ; move past FILBLK and SPARE entries .ASSUME FT.SPC EQ PVE1: MOV R4,-(SP) ; save pointer to file's DBLK CALL DECIMA ; display the block number .PRINT #BLSTR ; print ' of ' MOV (SP)+,R0 ; get DBLK address of the file CALL DPLYDB ; Display the filename MOV (SP)+,R4 MOV (SP)+,R2 RETURN ...... ; /DEVICE display 40$: ADD PHYBUF,R2 ; PBN = Buf block no. + offset PVE2: MOV #INFIL,R4 ; Point to input device BR PVE1 ...... .DSABL LSB .SBTTL PRERER - Display READ ERROR message ;+ ; Display "?BUP-E-Input error at block n of DEV:FILNAM.EXT" ;- .ENABL LSB PRERER::.PRINT #JNKTXT ; Print "Input error" message MOV R2,-(SP) MOV R4,-(SP) ; Determine which file in the buffer caused the error. Look through ; entry table (BFDBLK) for the file whose last block is higher than ; the physical block MOV PHYBLK,R2 ; for the /DEVICE case BIT #I$OPT,OPTACT ; If /DEVICE, BNE PVE2 ; just format the block number 10$: CALL NFROFS ; get address of current file entry MOV R0,R4 ADD #FT.SPC,R4 ; point to DBLK of entry SUB FILBLK,R2 ; get logical block of file BR PVE1 ; go print the message ...... .SBTTL DPLYDB - Display filespec ; Display a filename whose DBLK is pointed to by R0 DPLYDB: MOV R1,-(SP) ; Save R1 MOV #LBLBUF,R1 ; put ASCII here CALL $FNASC ; convert RAD50 to ASCII filename CLRB @R1 ; Null terminate .PRINT #LBLBUF ; Print it MOV (SP)+,R1 ; restore R1 RETURN ...... .DSABL LSB .SBTTL BAKDON - Display BACKUP OPERATION COMPLETE message ;+ ; Display BACKUP[/VERIFY] OPERATION COMPLETE message ;- .ENABL LSB BAKDON::.RCTRLO ; wake up user if asleep BIT #I$OPT,OPTACT ; /DEVICE backup? BNE 50$ ; Branch if so TSTB GIV.P ; /EXCLUDE? BMI 50$ ; Don't do this if so. ; Loop for all input file specs, checking the IGTENT bit that indicates ; a match was found. For any zero values, display ; ; ?BUP-W-File Not Found MOVB NISPEC,R2 ; Number of non-/S input specs BEQ 40$ ; None? MOV FNDBTS,R3 ; Bitmap of matches found MOV #,R4 ; FSPEC input area 10$: ADD #INSPSZ,R4 ; Next input spec ROR R3 ; Get the bit for input file BCS 30$ ; Branch if file was found MOV INPDEV,@R4 ; Set proper inp dev for msg .ERR #ERRARE,#LO1,LEVEL=ERROR,RETURN=YES,FILE=R4 30$: DEC R2 ; Count down no. of inputs BGT 10$ ; Branch if more to do. ; Now finish by printing "Backup operation complete" or "No files transferred" 40$: TST NFTRAN ; any files found? BEQ 80$ ; if not, tell the user. 50$: TSTB GIV.W ; /NOLOG? BMI 70$ MOV #BOCOP,R0 ; "Backup operation" TSTB GIV.V ; /VERIFY specified? BPL 60$ ; branch if not. MOV #BVOCOP,R0 ; "Backup/verify operation" 60$: .PRINT ; print 1st part of message, .PRINT #COMPMS ; print "is complete" 70$: RETURN ...... 80$: .PRINT #NOFBAK ; print "No files backed up" RETURN ...... .DSABL LSB .SBTTL SAVPOS - Store current parameters for verify/recovery ;+ ; This routine is called just before each output volume is made. ; Parameters that control the copy operation are stored so that ; the volume may be re-made if an error is discovered during the ; copy. If /VERIFY was specified, another copy is made so that ; the VERIFY routine can pick up where the copy was begun. ; ; Most of the work involved pertains to wildcard file backups. ; Save a copy of the impure area governed by IGTDIR and IGTENT, ; and reset the work area to describe the beginning of the input ; volume. ;- .PSECT .IMPU.,D INBLKK: .WORD 0 ; new INBLK while VERIFYING BLKCOK: .WORD 0 ; new BLKCOP while VERIFYING RESUMK: .WORD 0 ; new RESUME while VERIFYING REMFIK: .WORD 0 ; new REMFIL while VERIFYING INBLKV: .WORD 0 ; INBLK for start of VERIFY BLKCOV: .WORD 0 ; BLKCOP for start of VERIFY RESUMV: .WORD 0 ; RESUME for start of VERIFY REMFIV: .WORD 0 ; REMFIL for start of VERIFY INBLKR: .WORD 0 ; RECOVERY INBLK BLKCOR: .WORD 0 ; RECOVERY BLKCOP RESUMR: .WORD 0 ; RECOVERY RESUME REMFIR: .WORD 0 ; RECOVERY REMFIL SAVCFS: .WORD 0 ; "current file size" for resume VBGCFS: .WORD 0 ; "current file size" for verify SAVFBL: .WORD 0 ; "current file block" for resume VBGFBL: .WORD 0 ; "current file block" for verify IGDBFV: .WORD 0 ; IGT buffer pointer for VERIFY WKARAV: .WORD 0 ; IGT workarea pointer for VERIFY IGDBFR: .WORD 0 ; IGT buffer pointer for RECOVERY WKARAR: .WORD 0 ; IGT workarea pointer for RECOVERY .PSECT .CODE.,I .ENABL LSB SAVPOS::MOV INBLK,INBLKV ; Save current input block number MOV BLKCOP,BLKVER ; Blocks to COPY and VERIFY MOV RESUME,RESUMV ; Save block-to-resume-on for VERIFY MOV REMFIL,REMFIV ; Save remaining file size for VERIFY MOV INBLK,INBLKR ; Save current input block number MOV BLKCOP,BLKCOR ; Save current number of blocks to go MOV RESUME,RESUMR ; Save block-to-resume-on for RECVR MOV REMFIL,REMFIR ; Save remaining file size for RECVR BIT #I$OPT,OPTACT ; /DEVICE backup? BNE 50$ ; Branch if so. MOV WKARAR,R1 ; point to recovery's work area CALL XFERWA ; copy work area CLR GBCALL ; Init CALL GINBLK counter TSTB GIV.V ; /VERIFY specified? BPL 50$ ; Branch if so. MOV WKARAV,R1 ; point to verify's work area XFERWA: MOV WKAREA,R0 ; Point to IGT(DIR,ENT) work area XFERAW: MOV #WASIZE,R2 ; this many words 20$: MOV (R0)+,(R1)+ ; copy the work area DEC R2 BGT 20$ 50$: RETURN ...... .DSABL LSB .SBTTL GETVER - Restore information for VERIFY ;+ ; This routine is called after making an output volume, and before ; verifying it. The copy parameters for the volume are re-initialized, ; so that the VERIFY operation mimics the BACKUP. When the VERIFY part ; is done, AFTVER will restore these variables so that the BACKUP can ; procede, (perhaps mid-file) as though nothing had happened. ;- .ENABL LSB GETVER:: MOV INBLK,INBLKK ; save current INBLK value MOV BLKCOP,BLKCOK ; save current BLKCOP value MOV RESUME,RESUMK ; save current RESUME value MOV REMFIL,REMFIK ; save current REMFIL value MOV INBLKV,INBLK ; insert old INBLK parameter MOV BLKVER,BLKCOP ; insert old BLKCOP parameter MOV RESUMV,RESUME ; insert old RESUME parameter MOV REMFIV,REMFIL ; insert old REMFIL parameter BIT #I$OPT,OPTACT ; /DEVICE backup? BNE 50$ ; Branch if so. MOV WKARAV,WKAREA ; Let IGTENT see WKARAV ; Move the current top entry (TOPENT, saved by GINBLK) to a special place ; before running the VERIFY pass. It will be returned when VERIFY ; is finished. MOV R5,-(SP) ; save registers MOV FILBLK,SAVFBL ; save current file's start block MOV CFSIZE,SAVCFS ; save the current file size MOV #TOPENT,R0 ; source is normal top entry buffer MOV #SAVENT,R5 ; save it here CALL MOVENT ; move entry to BACKUP RESUME value MOV VBGFBL,FILBLK ; restore current file's start block MOV VBGCFS,CFSIZE ; restore the current file size MOV #VBGENT,R0 MOV #TOPENT,R5 ; move VERIFY START value to TOPENT ENTTBL: CALL MOVENT ; move the entry MOV (SP)+,R5 ; restore registers 50$: RETURN ...... .DSABL LSB .SBTTL AFTVER - Restore information AFTER VERIFY ;+ ; After verifying a saveset, restore backup parameters. ;- .ENABL LSB AFTVER:: MOV INBLKK,INBLK ; restore new INBLK MOV BLKCOK,BLKCOP ; restore new BLKCOP MOV RESUMK,RESUME ; restore GINBLK's RESUME parameter MOV REMFIK,REMFIL ; restore GINBLK's REMFIL parameter BIT #I$OPT,OPTACT BEQ 20$ RTN1: RETURN ...... 20$: MOV WKARED,WKAREA ; restore IGTENT's wk area pointer ; In FILE mode, restore the top entry of the file table RESTEN: MOV R5,-(SP) ; save registers MOV SAVCFS,CFSIZE ; restore the current file size MOV SAVFBL,FILBLK ; restore current file's start block MOV #SAVENT,R0 ; source is saved top entry MOV #TOPENT,R5 ; destination is normal top entry BR ENTTBL ...... .DSABL LSB .SBTTL GETPOS - Restore information for RECOVERY ;+ ; This routine is called after an error has been discovered during ; the making of an output volume. The copy parameters for the volume ; are re-initialized. ;- .ENABL LSB GETPOS::MOV INBLKR,INBLK ; restore INBLK parameter MOV BLKVER,BLKCOP ; restore BLKCOP parameter MOV RESUMR,RESUME ; restore RESUME parameter MOV REMFIR,REMFIL ; restore REMFIL parameter BIT #I$OPT,OPTACT ; /DEVICE backup? BNE RTN1 ; Branch if so. MOV WKARAR,R0 ; point to recovery's work area MOV WKAREA,R1 ; Point to IGT(DIR,ENT) work area CALL XFERAW ; Restore original work area BR RESTEN ; Restore file entry table top ...... .DSABL LSB .END