;*****************************************************************************
; 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