// GOVERLAY.SR

// **	IF MORE BB FILES ARE ADDED, ADD fn MANIFESTS TO GINN.DF
//	AND ADD FILE NAME BELOW IN openoverlay

get "BRAVO.DF";
get "HEAP.DF";
get "GINN.DF";

// Incoming Procedures

external [
	errhlt
	updatedisplay
	ult
	hpfree
	makeroominheap
	hpcompact
	loadcore
	qinit;
	junta;
	open
	filldisplay
	];

// Incoming Statics

external
	[
	vpzone
	macww
	rgdllast
	rgmaxdl
	rgcdlblank
	rgcplast
	rgmaccp
	rgdoc
	rgupdate
	freet
	mpfnof
	]

// Outgoing Procedures

external [
	overlay
	initoverlay
	hplay
	opensomeoverlay
	];

// Outgoing Statics

external [
	ozone
	ozonel
	currentoverlay
	modulel
	currentbb
	]; 

// Local Statics

static [
	ozone
	ozonel
	currentoverlay
	modulel
	currentbb
	];

let initoverlay() be
[
ozone = qinit-2-15 ;
ozonel = junta-ozone
if ozonel << odd then ozonel = ozonel - 1
currentbb = initmodule ;
]

and opensomeoverlay() = valof
	[
	for fnbb = firstfnbb to lastfnbb do
		if mpfnof ! fnbb eq -1 then
			[
			openoverlay(fnbb)
			resultis true
			]
	resultis false
	]

and openoverlay(fnbb) = valof
	[
	let bname = nil ;
	switchon fnbb into
		[
		case fnfilebb:	bname = "GYPSYFILEX.BB" ; endcase
		case fneditbb:	bname = "GYPSYEDITX.BB" ; endcase
		case fnwwbb:	bname = "GYPSYWWX.BB" ; endcase
		case fnmenubb:	bname = "GYPSYMENUX.BB" ; endcase
		case fndevbb:	bname = "GYPSYDEVX.BB" ; endcase
		default:	errhlt("NBB")
		]
	unless open(fnbb,bname,false) do errhlt("MBB");
	resultis mpfnof ! fnbb ;
	]

and overlay(fnbb) be
[
if fnbb eq resmodule % fnbb eq currentbb then return ;
let of = mpfnof ! fnbb ;
if of eq -1 then of = openoverlay(fnbb) ;
let macpos = of >> OF.macpos;
modulel = (macpos rshift 1)+1 ;
if modulel << odd then modulel = modulel + 1
if modulel gr ozonel % modulel+worthcompact ls ozonel then
	[
	hplay(modulel-ozonel, true)
	if modulel ls ozonel then filldisplay()
	ozonel = modulel ;
	];
loadcore(fnbb, ozone) ;
currentbb = fnbb ;
]

and hplay(shrinkamount, up) be
	[
	let zmin = vpzone >> ZONE.min
	let zmax = vpzone >> ZONE.max
	test shrinkamount gr 0 ifso
		[
		if shrinkamount gr vpzone>>ZONE.cfree then	
			makeroominheap(shrinkamount)
		hpcompact(up,
		    vpzone >> ZONE.min + (not up? 0, shrinkamount),
		    vpzone >> ZONE.max + (up? 0, -shrinkamount)) ;
		] 
	ifnot	[ let newblock = nil;
		test up ifso
			[ vpzone >> ZONE.min = zmin+shrinkamount;
			newblock = zmin+shrinkamount;
			] 
		ifnot	[ vpzone >> ZONE.max = zmax-shrinkamount;
			newblock = zmax;
			] 
 		newblock >> HP.siz = -shrinkamount;
		newblock >> HP.fp = 0;
		rv(newblock-shrinkamount-bsiz) = -shrinkamount;
		hpfree(lv (newblock >> HP.use));
		] 
	]