// ISF.BCPL -- implement indexed sequential files
// last modified March 28, 1977  11:22 AM
// revisions (file assignments) begun January 20, 1978, by DCS

	get "isf.d"

external	// entry procedures
[	IndexedPageIO	// (fmap, firstrn, core, npg, wflag[, lastnc]) -> lastnc
	LookupFmap

		// auxilliary (used in isfinit)
	NextFmap
]

external
[		// O.S.
	SetBlock; Zero
	CallSwat
	Allocate; Free
	Usc
	Dvec
		// BfsBase
	ActOnDiskPages
		// Spruce Utilities
	Min
	SwappedOut
		// IsfInit (sic)
	morepageio
]


let IndexedPageIO(fmap, firstrn, core, npg, wflag, lastnc; numargs na) = valof
// wflag=-1 for write, 0 for read, 1 for read + extend
// returns numchars of last page transferred
[	let action = (wflag ls 0? DCwriteD, DCreadD)
	let pagesize = 1 lshift fmap>>FM.disk>>DSK.lnPageSize
	if na ls 6 then lastnc = pagesize*2
	if morepageio ne SwappedOut & Usc(firstrn+npg, NextFmap(fmap)) ge 0 then
		morepageio(fmap, firstrn, core, npg, wflag)
	let CAs = vec ppc
	let DAs = vec ppc	// ppc+1 words!
	let ca, rn0, pagesleft = core, firstrn, npg
	let nch = nil
	while pagesleft gr 0 do
	 [ let np = Min(pagesleft, ppc)
	   for j = 0 to np-1 do
	    [ CAs!j = ca; ca = ca+pagesize
	      DAs!j = LookupFmap(fmap, rn0+j)
	    ]
	   DAs!np = fillInDA
	   pagesleft = pagesleft-np
	   nch = (pagesleft eq 0? lastnc, pagesize*2)
	   ActOnDiskPages(fmap>>FM.disk, CAs-rn0, DAs-rn0, lv fmap>>FM.fp, rn0, rn0+np-1, action, lv nch)
	   rn0 = rn0+np
	 ]
	resultis nch
]

and LookupFmap(fmap, rn, force; numargs n) = valof
[	if (rn eq fmap>>FM.onern) & ((n ls 3) % (not force)) then
	   resultis fmap>>FM.oneda
	let hi = fmap>>FM.last
	if Usc(rn, fmap!hi) ge 0 then resultis fillInDA
	let lo = mapoffset
	while hi-lo gr 2 do
	 [ let mid = ((lo+hi) rshift 1) & -2
	   test Usc(rn, fmap!mid) ge 0
	    ifso lo = mid
	    ifnot hi = mid
	 ]
	let lp = lv (fmap!lo)
	resultis (lp!1+rn-@lp)
]

and NextFmap(fmap) = fmap!(fmap>>FM.last)

// DCS, January 20, 1978  10:30 PM, file reassignments in local Spruce copies
// October 12, 1978  4:34 PM, move LookupFmap to SpruceFsBase.bcpl
//