//  FANCYDISK.SR

// Last modified November 15, 1979  2:30 PM by Taft

get "BRAVO1.DF";
get "VM.DF";

// Incoming Procedures

external [
	errhlta;
	ugt;
	ActOnPages;
	movec;
	umin;
	WritePages;
	DeletePages;
	swat;
	ult;
	move;
	setmacfp;
	flushfn
	];

// Incoming Statics

external [
	dnfn;
	fillInDA;
	eofDA;
	DCwrite;
	DCread;
	vdeltafp;
	];

// Outgoing Procedures

external [
	getvp;
	clearbp;
	remakevmtb;
	diskwritegroup;
	trims;
	flushvm;
	DirtyBp
	];

// Outgoing Statics

external [
	vmtb;
	cvmfree;
	vbp;
	rgbp;
	rgvpa;
	lrutime;
	rglastused;
	dnbp;
	macbp;
	rgbs;
	vbphint;
	vwremain;
	mpfnof;
	vpwput;
	vlbput;
	vchremainput;
	vwremainput;
	vextendof;
	rgnchlast;
	vcpput;
	]; 


// D I S K W R I T E G R O U P
//
let diskwritegroup(fn,fpfirst,fplast,lastnumchars) be
[ let rgca = vec maxbp+1;
let rgbp = vec maxbp+1;
let vpa = nil;
if fplast ls fpfirst then return;
if (mpfnof ! fn) >> OF.macfp le fplast+2 then
	setmacfp(fn,(fplast lshift 1)+3-fpfirst);
//***			 i.e. ↑ = fplast+2+(fplast-fpfirst+1)
vpa << VPA.fn = fn;
for fp = fpfirst to fplast do
	[ vpa << VPA.fp = fp;
	rgca ! (fp-fpfirst) = getvp(vpa);
	rgbp ! (fp-fpfirst) = vbp;
	] 
rgca ! (fplast-fpfirst+1) = dnbp ! bpbuff;
for fp = fpfirst to fplast do
	[ let bp = rgbp ! (fp-fpfirst);
	rglastused ! bp = 1;
	rgbs ! bp = 0;
	rgnchlast ! bp = (fp eq fplast) ? lastnumchars,#1000;
	] 
let of = mpfnof ! fn;
let rgda = lv (of >> OF.rgda);
let fileid = lv (of >> OF.fileid);
unless of >> OF.wf then errhlta(149);
fpfirst = fpfirst+1;
fplast = fplast+1;
if ((rgda ! fpfirst eq fillInDA) % (rgda ! fpfirst eq eofDA)) & (fpfirst eq 1) then
	[ if ActOnPages(0,rgda,fileid,0,0,DCread,0,0,dnbp ! bpbuff,0) then errhlta(150);
	] 
test vextendof ifnot
	[ WritePages(rgca-fpfirst,rgda,fileid,fpfirst,fplast,0,0,lastnumchars,0);
	if ((rgda ! (fplast+1) eq eofDA) % (rgda ! (fplast+1) eq fillInDA)) & (lastnumchars eq #1000)  then
		[ WritePages(rgca-fpfirst,rgda,fileid,fplast,fplast+1,0,0,0,0);
		vextendof = true;
		] 
	] 
ifso	WritePages(rgca-fpfirst,rgda,fileid,fpfirst,((lastnumchars eq #1000) ? fplast+1,fplast),0,0,((lastnumchars eq #1000) ? 0,lastnumchars),0);
] 

// T R I M S
//
and trims(fn) be
[
flushfn(fn)
let of = mpfnof ! fn;
if of >> OF.wf then
	[ let rgda = lv (of >> OF.rgda);
	let fp = (of >> OF.macpos) << PCD.p+1;
	let fileid = lv(of >> OF.fileid);
	ActOnPages(0,rgda,fileid,fp,fp,DCread,0,0,dnbp ! bpbuff,0);
	let leftoverDA = rgda ! (fp+1)
	WritePages(0,rgda,fileid,fp,fp,0,0,(of >> OF.macpos) << PCD.rc,dnbp ! bpbuff);
	if (leftoverDA ne fillInDA) & (leftoverDA ne eofDA) then
		DeletePages(dnbp ! bpbuff,leftoverDA,fileid,fp+1);
	of >> OF.macfp = fp+1;
	rgda ! (fp+1) = 0;
	] 
]