// ISFINIT -- initialize indexed sequential file
// last edited November 12, 1976  12:42 PM
// Copyright Xerox Corporation 1979

	get "isf.d"

external	// entry procedures
[	InitFmap	// (fmap, len, fp[, check, xtnd, zone, disk]) -> ok
]

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


let InitFmap(fmap, len, fp, check, xtnd, zone, disk; numargs n) = valof
[	DefaultArgs(lv n, -3, false, 10, -1, sysDisk)
	if len ls mapoffset+3 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 = 0, leaderVda, 1
	fmap>>FM.rewrite = check
	fmap>>FM.extend = (xtnd ls ppc? xtnd, ppc)
	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+1)
	    ]
fail:	if zone ne -1 then Free(zone, scratch)
	 ]
	fmap>>FM.end = end
	fmap>>FM.disk = disk
	fmap>>FM.zone = zone
	resultis true
]