// // OVERLAYSINIT.BCPL - initialize structures for OVERLAYS package // last edited September 7, 1976 10:42 AM // get "overlays.d" get "altofilesys.d" get "disks.d" external // procedures defined [ OverlayScan // (fptr, odvec, length[, fa, buf, bufsize, fixvec, fixsize]) -> npages/-1 OverlayInit // (odvec[, fixvec]) ] external // procedures used [ // O.S. SetBlock; MoveBlock; Zero // BFS ActOnDiskPages ] external // statics used [ // O.S. sysDisk ] structure ODV: // first part of overlay vector [ nov word // # of overlays fp @FP // FP for overlay file ] manifest lODV = size ODV/16 manifest [ MaxScanPages = 40 ] static [ OVbuf // page buffer OVbsize // size of buffer in pages OVcurpn // current first page in buffer OVcurnp // current # of pages in buffer OVdas // DA vector for pages in buffer +1 OVfp // overlay file FP ] let OverlayInit(odv, fixv; numargs na) be [ external // in OVERLAYS [ OverlayFp OverlayFaults @OverlayNumber @OverlayFaultProc FirstOD LastOD ] OverlayFp = lv odv>>ODV.fp OverlayFaults = odv+lODV let nov = odv>>ODV.nov SetBlock(OverlayFaults, #10000+lv OverlayNumber, nov) // ISZ OverlayFaults!(nov-1) = #2000+lv OverlayFaultProc // JMP @ FirstOD = OverlayFaults+nov LastOD = FirstOD+(nov-1)*ODsize if na ge 2 then // fix up swapped-out statics [ let fixp, val = fixv, OverlayFaults while @fixp ge 0 do [ let nfixp = fixp+@fixp+1 [ fixp = fixp+1 if fixp eq nfixp break (@fixp)!0 = val ] repeat val = val+1 ] ] ] let OverlayScan(fptr, odv, len, fa, pbuf, bsize, fixv, fsize; numargs na) = valof [ // Initialize the work area Zero(odv, len) MoveBlock(lv odv>>ODV.fp, fptr, lFP) let maxovs = (len-lODV)/(ODsize+1) let mybuf = vec #402 test (na ls 6) % (bsize ls #402) ifso OVbuf, OVbsize = mybuf, 1 ifnot [ OVbuf, OVbsize = pbuf, (bsize-1)/#401 if OVbsize gr MaxScanPages then OVbsize = MaxScanPages ] OVdas = OVbuf+(OVbsize lshift 8) @OVdas = fptr>>FP.leaderVirtualDa OVcurpn, OVcurnp = 0, 0 OVfp = fptr let buf = advancetopage(1, 2) // read first data page let pn = buf!1+1 if pn ls 2 resultis 0 // no overlays if na ge 4 then // use fa [ OVcurpn, OVcurnp, @OVdas = fa>>FA.pageNumber, 0, fa>>FA.da ] let ovnum = 0 let ofv = odv+lODV let fod = ofv+maxovs let od = fod let fixi = 0 [ if ovnum eq maxovs resultis -1 od>>OD.firstPn = pn let buf = advancetopage(pn, MaxScanPages) if buf eq 0 break od>>OD.da = OVdas!((buf-OVbuf) rshift 8) let skip = buf!1+#20 let npages = (buf!4+#377) rshift 8 let buf = advancetopage(pn + skip rshift 8, MaxScanPages) let wn = skipŹ let n = buf!wn let nw = OVbuf+(OVcurnp lshift 8)-buf if na ge 8 then [ if fixi+n+1 ge fsize resultis -2 fixv!fixi = n fixi = fixi+1 ] for i = 1 to n do [ wn = wn+1 if wn ge nw then [ buf = advancetopage(OVcurpn+OVcurnp, MaxScanPages) wn = wn-nw nw = OVcurnp lshift 8 ] let stat = buf!wn @stat = ofv+ovnum if na ge 8 then [ fixv!fixi = stat fixi = fixi+1 ] wn = wn+1 ] pn = pn+npages ovnum = ovnum+1 od = od+ODsize ] repeat MoveBlock(ofv+ovnum, fod, od+ODsize-fod) // need 1 extra firstPn odv>>ODV.nov = ovnum OverlayInit(odv) if na ge 8 then fixv!fixi = -1 resultis fixi+1 ] and advancetopage(newpn, npages) = valof [ while newpn ge (OVcurpn+OVcurnp) do [ let nextda = OVdas!OVcurnp if nextda eq eofDA resultis 0 OVcurpn = OVcurpn+OVcurnp let nsp0 = MaxScanPages-OVbsize let nsp1 = newpn-OVcurpn let nsp = (nsp0 ls nsp1? nsp0, nsp1) let np1 = nsp+OVbsize if npages gr np1 then npages = np1 let CAs = vec MaxScanPages SetBlock(CAs, OVbuf, MaxScanPages) for i = 1 to OVbsize-1 do CAs!(nsp+i) = OVbuf+(i lshift 8) let DAs = vec MaxScanPages+1 DAs!0 = nextda SetBlock(DAs+1, fillInDA, MaxScanPages) let lastnc = nil let lastpn = ActOnDiskPages(sysDisk, CAs-OVcurpn, DAs-OVcurpn, OVfp, OVcurpn, OVcurpn+npages-1, DCreadD, lv lastnc) OVcurpn = OVcurpn+nsp OVcurnp = lastpn+1-OVcurpn MoveBlock(OVdas, DAs+nsp, OVcurnp+1) if lastnc eq 0 then [ OVcurnp = OVcurnp-1; OVdas!OVcurnp = eofDA ] ] resultis OVbuf+(newpn-OVcurpn) lshift 8 ]