;***************************************************************************** ; SHRINK.M68 - "Shrinks" a random file ; ; by Dave Heyliger - AMUS Staff ; ; Purpose: to shrink a random file without copying block-by-block. The blocks ; that are "chopped off" are gone to the wind - it is up to you to ; make sure that these blocks are not important. ; ; NOTE: the program requires a DSKANA after execution - SHRINK informs you of ; this requirement upon completion. ;***************************************************************************** AUTOEXTERN ;must "lnklit shrink" SEARCH SYS ;get the normals SEARCH SYSSYM SEARCH TRM VMAJOR=1 ;define a version number VMINOR=0 ;original by Dave Heyliger PHDR -1,0,PH$REE!PH$REU!PH$OPR ;must be in the OPR: account .OFINI ;define variables .OFDEF PPNDDB,D.DDB ;DDB for PPN reads .OFDEF RNDDDB,D.DDB ;DDB for the random file .OFDEF PPNPTR,4 ;DIR block link pointer .OFSIZ IMPSIZ ;IMPSIZ has total byte count ;start of program GETIMP IMPSIZ,A5 ;A5 points to user memory vars ;process the input line BYP ;bypass BS LIN ;just a CR? BNE 10$ ;nope, get the filespec TYPE <Usage: SHRINK {dev:filespec[PPN]}> TYPECR < - filespec must be a random file.> EXIT ;get the filespec 10$: LEA A4,RNDDDB(A5) ;point to the random DDB FSPEC @A4 ;filespec the input file INIT @A4 ;initialize the filespec LOOKUP @A4 ;find it? BEQ 20$ ;yup CRLF ;nope, MOV #7,D1 ;get a bell TTY ;beep! TYPE <?Cannot locate > ;error message PFILE @A4 CRLF EXIT ;and quit ;see if the file is random... 20$: CMPW D.WRK+6(A4),#-1 ;random file? BEQ 30$ ;yup CRLF ;nope MOV #7,D1 ;get a bell TTY ;beep! PFILE @A4 ;error message TYPECR < is not a random file.> EXIT ;and quit ;inform user of the consequences 30$: MOV #7,D1 ;get a bell TTY ;beep! CRLF ;crlf TYPECR < WARNING: you are about to "chop off" some blocks.> TYPECR < These blocks will be "lost" if you continue.> CRLF TYPE < Enter "Y" to continue.... > KBD ;get the "Y" CTRLC EXIT ;here on ^C CMPB @A2,#'Y ;yes, continue??? BEQ CONT ;yup EXIT: EXIT ;get the original block size, ask for new size CONT: MOV D.WRK(A4),D1 ;D1 holds number of blocks MOV D1,D2 ;D2 holds a copy CRLF ;crlf TYPE <Original size of > ;user message... PFILE @A4 ;type out filespec TYPE < is: > DCVT 0,OT$TRM ;here is original size CRLF ;crlf down two lines CRLF ;crlf TYPE <New desired size: > ;ask for new size KBD ;wait for input GTDEC ;get the input MOV D1,D3 ;D3 holds copy SUB D1,D2 ;sub "larger" from "smaller" BPL 10$ ;if positive, continue CRLF ;crlf MOV #7,D1 ;get a bell TTY ;beep! TYPECR <?New desired size must be LESS than Original size.> CRLF EXIT ;now find the file in the DIR 10$: LEA A2,PPNDDB(A5) ;point to PPNDDB CLR D1 ;fussy data registers MOVW D.PPN(A4),D1 ;D1 holds the PPN MOVW D.PPN(A4),D.PPN(A2) ;move in DEV:[PPN] MOVW D.DEV(A4),D.DEV(A2) MOVW D.DRV(A4),D.DRV(A2) INIT @A2 ;initialize the DDB CALL $FNPPN ;find the PPN CMP D0,#0 ;find it? BEQ 20$ ;yup MOV #7,D1 ;get a bell TTY ;beep! TYPECR <?PPN not found.> CRLF EXIT ;now find the DIR blocks and begin to look (A1 points to MFD entry) 20$: MOVW 2(A1),D.REC+2(A2) ;set block number 25$: READ @A2 ;read in the block MOV D.BUF(A2),A0 ;A0 points to block read in MOVW (A0)+,PPNPTR(A5) ;save block link ;for each DIR block, look for the file 42. times until end of DIR 30$: MOV #42.,D4 ;D4 counter 35$: CMM @A0,D.FIL(A4) ;filename match? BNE 40$ ;nope CMMW 4(A0),D.EXT(A4) ;extension match? BNE 40$ ;nope BR 50$ ;yup, found file, A0 pointer ;come here on non-match 40$: DEC D4 ;one less slot to examine BEQ 45$ ;if done w/ block, get next ADD #12.,A0 ;else point to next slot BR 35$ ;and look again ;come here when time for next block 45$: MOVW PPNPTR(A5),D.REC+2(A2) ;set new block number BR 25$ ;and scan the DIR some more ;come here when A0 points to file entry in block 50$: MOVW D3,6(A0) ;"write" new block size WRITE @A2 ;write changes to disk CRLF ;crlf MOV #7,D1 ;get a bell TTY ;beep! TYPECR < SHRINKing complete... %Run DSKANA immediately!> EXIT END