// IfsIsfInit.bcpl -- initialize indexed sequential file
// Copyright Xerox Corporation 1979

// last modified March 19, 1979  3:54 PM by Butterfield

	get "IfsIsf.d"

external InitFmap;  // entry procedures

external
[		// O.S.
	MoveBlock
	ActOnDiskPages
	DefaultArgs
	Allocate; Free
	Dvec
	sysDisk
	sysZone
]


//---------------------------------------------------------------------------
let InitFmap(fmap, len, fp, check, xtnd, zone, disk, extendmap; numargs n) =
 valof
//---------------------------------------------------------------------------
[	DefaultArgs(lv n, -3, false, 10, -1, sysDisk, false)
	if len ls mapoffset+4 then resultis false
	fmap>>FM.seal = version
	MoveBlock(lv fmap>>FM.fp, fp, lFP)
	let leaderVda = fp>>FP.leaderVirtualDa
	fmap>>FM.DA0 = leaderVda
	fmap>>FM.DA1, fmap>>FM.DA2 = fillInDA, fillInDA
	fmap>>FM.last = mapoffset+2
	let end = (len-2)&-2
	fmap>>FM.onern, fmap>>FM.oneda = 0, fmap>>FM.DA0
	let map = fmap+mapoffset
	map!0, map!1, map!2, map!3 = 0, leaderVda, 1, fillInDA
	if zone eq 0 then zone = sysZone
	if check then
	 [ let pagesize = 1 lshift disk>>DSK.lnPageSize
	   let scratch, nch = pagesize, 0
	   test zone eq -1
	    ifso Dvec(InitFmap, lv scratch)
	    ifnot scratch = Allocate(zone, scratch)
	   ActOnDiskPages(disk, 0, lv fmap>>FM.DA0, fp, 0, 1, DCreadD, lv nch,
            DCreadD, scratch)
	   if (nch eq 2*pagesize) & (scratch>>FM.last ge mapoffset+2) &
            (scratch!mapoffset eq 0) then	// old map may be OK
	    [ for i = 0 to checksize-1 do if scratch!i ne fmap!i goto fail
	      let last = scratch>>FM.last
	      if last gr end then last = end
	      if last ge pagesize then last = pagesize-2
	      MoveBlock(fmap, scratch, last+2)
	    ]
fail:	if zone ne -1 then Free(zone, scratch)
	 ]
	fmap>>FM.end = end
	fmap>>FM.disk = disk
	fmap>>FM.zone = zone
	fmap>>FM.rewrite = check;
	if check then extendmap = 0;  // until WriteFmap writes extended maps
	fmap>>FM.extendmap = extendmap
	fmap>>FM.extend = (xtnd ls ppc? xtnd, ppc)
	fmap>>FM.fmap = fmap
	resultis true
]