-- File: FindDiskAddresses.mesa, Last Edit: HGM October 18, 1980 8:57 PM DIRECTORY AltoFileDefs USING [vDA, eofDA, fillinDA], BFSDefs USING [ActOnPages, GetNextDA], ControlDefs USING [GlobalFrameHandle], DiskDefs USING [DiskRequest], FrameOps USING [CodeHandle, MyGlobalFrame], MiscDefs USING [SetBlock], SegmentDefs USING [ DataSegmentHandle, FileSegmentHandle, FileHandle, EasyDown, SetFileSegmentDA, EnumerateFileSegments, MakeDataSegment, DefaultMDSBase, DeleteDataSegment, DataSegmentAddress], Storage USING [PagesForWords], TajoOps USING []; -- For getting things started FindDiskAddresses: PROGRAM IMPORTS BFSDefs, FrameOps, MiscDefs, SegmentDefs, Storage EXPORTS TajoOps = BEGIN -- This is just a hook to let Tajo call us. The actual work is done by START traps. StartClient: PUBLIC PROCEDURE = BEGIN END; FindDiskAddresses: PROCEDURE = BEGIN myFrame: ControlDefs.GlobalFrameHandle ← FrameOps.MyGlobalFrame[]; myCode: SegmentDefs.FileSegmentHandle ← FrameOps.CodeHandle[myFrame]; CollectDiskAddresses[myCode.file]; END; -- Copied from MakeImage CollectDiskAddresses: PROCEDURE [imageFile: SegmentDefs.FileHandle] = BEGIN OPEN Storage, SegmentDefs, AltoFileDefs; DAs: DESCRIPTOR FOR ARRAY OF vDA; maxunknown, maxknown: CARDINAL ← FIRST[CARDINAL]; minunknown: CARDINAL ← LAST[CARDINAL]; maxknownDA: vDA; diskrequest: DiskDefs.DiskRequest; bufseg, DAseg: DataSegmentHandle; FindEnds: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] = BEGIN WITH s: seg SELECT FROM disk => IF s.file = imageFile AND s.hint.da = eofDA THEN BEGIN maxunknown ← MAX[maxunknown, s.base]; minunknown ← MIN[minunknown, s.base]; END; ENDCASE; RETURN[FALSE]; END; FindKnown: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] = BEGIN WITH s: seg SELECT FROM disk => IF s.file = imageFile AND s.hint.da # eofDA AND s.base < minunknown AND s.base > maxknown THEN BEGIN maxknown ← s.base; maxknownDA ← s.hint.da END; ENDCASE; RETURN[FALSE]; END; PlugDA: PROCEDURE [seg: FileSegmentHandle] RETURNS [BOOLEAN] = BEGIN WITH s: seg SELECT FROM disk => IF s.file = imageFile AND s.hint.da = eofDA AND s.base IN (maxknown..maxunknown] THEN SegmentDefs.SetFileSegmentDA[@s, DAs[s.base]]; ENDCASE; RETURN[FALSE]; END; [] ← EnumerateFileSegments[FindEnds]; [] ← EnumerateFileSegments[FindKnown]; bufseg ← MakeDataSegment[DefaultMDSBase, 1, EasyDown]; DAseg ← MakeDataSegment[ DefaultMDSBase, PagesForWords[maxunknown - maxknown + 3], EasyDown]; DAs ← DESCRIPTOR[DataSegmentAddress[DAseg] - (maxknown - 1), maxunknown + 2]; diskrequest ← DiskDefs.DiskRequest[ ca: DataSegmentAddress[bufseg], fixedCA: TRUE, da: @DAs[0], fp: @imageFile.fp, firstPage: maxknown, lastPage: maxunknown, action: ReadD, lastAction: ReadD, signalCheckError: FALSE, option: update[cleanup: BFSDefs.GetNextDA]]; MiscDefs.SetBlock[@DAs[maxknown - 1], fillinDA, maxunknown - maxknown + 3]; DAs[maxknown] ← maxknownDA; [] ← BFSDefs.ActOnPages[LOOPHOLE[@diskrequest]]; -- we know it is an Update diskrequest [] ← EnumerateFileSegments[PlugDA]; DeleteDataSegment[DAseg]; DeleteDataSegment[bufseg]; END; FindDiskAddresses[]; END.