;FIXDEL.M68 Recover a file that has been accidently erased ;Completely rewritten 03-86 ;No longer is DSKANA required to retrieve the lost disk blocks ;11-27-86 Change FNDUFD to use Alpha Micro's Call $FNPPN ; Allow File Spec on command line when calling program ; (FIXDEL DSK0:[75,1]) ; written by Steve Farnum AUTOEXTERN SEARCH SYS SEARCH SYSSYM SEARCH TRM BUFF = A0 MFD = A1 UFD = A1 BADD = A2 BDDB = A3 HADD = A4 BMP = A5 COUNTR = D0 DSPLY = D1 OFFSET = D2 RECNO = D3 FLAGS = D4 HASH = D5 BMPSIZ = D6 UFDLNK = 2 WIDTH = 4. BLOCKS = 6. MFDSIZ = 8. CONTIG = 8. BLOKNO = 10. UFDSIZ = 12. UFDTOT = 42. MFDTOT = 63. MFDLNK = 506. BLKSIZ = ^H0F DELREC = ^H0FFFF ; -1 = deleted record CLRHI = ^H0FF VMAJOR = 1 VMINOR = 4 VSUB = 1 VEDIT = 100. PHDR -1,PH$REE,PH$REU OBJNAM FIXDEL.LIT GETIMP D.DDB,MFD ; DDB for MFD & UFD directories GETIMP D.DDB,BDDB ; DDB for bitmap area CMPB (A2),#15 ; anything entered BNE CHKINP ; yep, start processing START: TYPESP KBD ENDIT CMPB (A2),#15 ; anything entered ? JEQ ENDIT ; no, tell user CHKINP: CALL OPNFIL ; open ddb buffers CLR FLAGS ; clear flag counter CALL FNDUFD ; find desired UFD TST FLAGS ; UFD found ? JNE NOPPN ; no exit CALL DSPDEL ; display deleted records in ppn TST FLAGS ; any record found JEQ NODR ; no exit NEWNAM: PUSH DSPLY ; save buffer index offset PUSH D.REC(UFD) ; save ufd record CALL GETBMP ; index bitmap area and hash total CLR FLAGS CRLF TYPESP CMPW CONTIG(BUFF),#DELREC ; is the file contiguous BNE SETBLK ; no, find all blocks MOVW BLOCKS(BUFF),COUNTR ; no of block to reallocate CNTFIL: CALL SETBIT ; set block in use in bitmap TST FLAGS ; block already in use bad news JNE BADFIL ; tell user INC RECNO ; set next block SOB COUNTR,CNTFIL ; set all blocks JMP GODFIL ; release bitmap SETBLK: MOV RECNO,D.REC(UFD) ; set up to read next linked block READ (UFD) ; read block CALL SETBIT ; set block in use in bitmap TST FLAGS ; block already in use bad news JNE BADFIL ; tell user MOV D.BUF(UFD),BUFF ; check if there is another block linked MOVW (BUFF),RECNO ; next link TST RECNO BNE SETBLK ; yes, set bit JMP GODFIL SETBIT: CLR DSPLY ; clear work reg PUSH RECNO ; save record number DIV RECNO,#^H10 ; divide by 16 (a word) MOVW RECNO,OFFSET ; compute bitmap word ASL OFFSET ; mul * 2 to find correct offset MOVW 0(BADD)[~OFFSET],DSPLY ; get bitmap word SWAP RECNO ; get remainder = bit to set BTST RECNO,DSPLY ; is block free BEQ SETOK ; yes, ok to set block SET FLAGS ; no output error message BR ENDBIT SETOK: SUB DSPLY,HASH ; calculate new hash total BSET RECNO,DSPLY ; set block in bitmap MOVW DSPLY,0(BADD)[~OFFSET] ; write new bitmap block word ADD DSPLY,HASH ; update hash total TYPE <.> ENDBIT: POP RECNO ; restore record number RTN GETBMP: DSKBMR (BDDB) ; read & lock bitmap MOV D.ARG(BDDB),BMP ; get address of bitmap area MOV BMP,BADD ; save bitmap address SUB #BM.SIZ,BMP ; index bitmap ddb MOV D.SIZ(BMP),BMPSIZ ; no of bytes in bitmap + hash total SUB #4,BMPSIZ ; compute bitmap size in bytes MOV D.BUF(BMP),HADD ; compute hash total address ADD BMPSIZ,HADD ; MOV (HADD),HASH ; get bitmap hash total SWAP HASH ; RTN ; Allocate DDB For reading and writing OPNFIL: PUSH A2 ; save file spec pointer CLR D.DEV(BDDB) CLR D.FIL(BDDB) CLR D.EXT(BDDB) CLR D.DEV(MFD) CLR D.FIL(MFD) CLR D.EXT(MFD) FSPEC (BDDB) ; setup for bitmap read INIT (BDDB) POP A2 ; restore ascii file spec FSPEC (MFD) INIT (MFD) ; get buffers for input ddb RTN ; Read the MFD and find desired UFD on specified device FNDUFD: CLR D1 MOVW D.PPN(MFD),D1 ; octal ppn now in d1 MOV MFD,A2 ; set A2 fo ppn find call CALL $FNPPN MOV D0,FLAGS ; D0 = completions codes CLR RECNO CLR OFFSET MOVW UFDLNK(MFD),RECNO ; store ufd link address MOV A2,MFD RTN ;Target PPN found check for deleted records DSPDEL: REDPPN: CLR FLAGS ; no deleted records yet TST RECNO ; at end of ufd link JEQ ENDDSP ; yes exit program MOV RECNO,D.REC(UFD) ; set up for block read READ (UFD) ; read ufd MOV D.BUF(UFD),BUFF ; save buffer address MOVW #^H0FF00,DSPLY ; clear screen TCRT CRLF MOV #UFDTOT,COUNTR ; max ufd's per block MOVW (BUFF)+,RECNO ; next ufd block link 1st word CLR DSPLY PPNLOP: CMPW (BUFF),#DELREC ; deleted record ? BNE NXTFIL ; no, look at nxt file TYPE <(> ; output file name to screen DCVT 2,OT$TRM TYPE <)> PRNAM (BUFF) INC OFFSET CMP OFFSET,#WIDTH BLT SPACE CRLF CLR OFFSET BR NOSPAC SPACE: TAB NOSPAC: SET FLAGS ; deleted records found NXTFIL: INC DSPLY ; index next filname ADDW #UFDSIZ,BUFF ; and display it SOB COUNTR,PPNLOP ;Check for another UFD for this PPN ;Or for the file to save NXTUFD: TST FLAGS ; any deleted records found JEQ REDPPN ; no read next ufd link CRLF CRLF TYPESP KBD ENDIT CMPB (A2),#15 ; anything entered ? JEQ REDPPN ; no, check for another ufd CLR DSPLY ; conver ascii to a number GTDEC TYPESP KBD ENDIT MOV D.BUF(UFD),BUFF ; index buffer start ADD #2,BUFF ; skip link word MUL DSPLY,#UFDSIZ ; calulate offset size * ufdsiz ADD DSPLY,BUFF ; index offset FILNAM D.FIL(UFD) ; write new file name to ufd MOVW BLOKNO(BUFF),RECNO ; set up to read the block ENDDSP: RTN GODFIL: POP D.REC(UFD) ; restore ufd record number READ (UFD) ; re-read ufd record POP DSPLY MOV D.BUF(UFD),BUFF ; index buffer start ADD #2,BUFF ; skip link word ADD DSPLY,BUFF ; index offset MOVW D.FIL(UFD),(BUFF) ; write new file name to ufd MOV (UFD),2(BUFF) WRITE (UFD) ; rewrite UFD block SWAP HASH ; write out new bitmap MOV HASH,(HADD) ; hash total ORW #BM$REW,(BMP) ; set bitmap rewrite flag XORW #BM$LOK,(BMP) ; clear bitmap lock flag DSKBMW (BDDB) ; rewite bitmap CRLF CRLF TYPECR JMP ENDIT BADFIL: POP ; clear stack POP ; clear stack XORW #BM$LOK,(BMP) ; clear bitmap lock flag CRLF TYPECR TYPECR TYPECR TYPECR BR ENDIT NOPPN: TYPECR BR ENDIT NODR: TYPECR BR ENDIT ENDIT: CRLF TYPESP KBD THEEND CMPB (A2),#15 ; anything entered ? BEQ THEEND ; no, tell user CMPB (A2),#'N BEQ THEEND CMPB (A2),#'n BEQ THEEND JMP START THEEND: CRLF EXIT END .