-- File: Script.Mesa -- Last edited by Sandman; July 10, 1980 8:01 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoDefs USING [PageSize], BootmesaOps, CommanderDefs USING [AddCommand], ControlDefs USING [GlobalFrameHandle], InlineDefs USING [COPY], MiscDefs USING [Zero], SegmentDefs USING [ AddressFromPage, DeleteFileSegment, FileSegmentAddress, FileSegmentHandle, NewFileSegment, Read, SwapIn, Unlock, Write], SegOps USING [DefaultFile, EnumerateSegs, ffvmp, lfvmp, NewSeg, Seg], StreamDefs USING [CleanupDiskStream, GetIndex, WriteBlock], Storage USING [Pages, FreePages, PagesForWords], WartDefs USING [ Header, LinkEntry, LinkHandle, LinkIndex, SegEntry, SegHandle, SegIndex, TableBase, VersionID]; Script: PROGRAM IMPORTS BootmesaOps, MiscDefs, InlineDefs, StreamDefs, SegmentDefs, SegOps, Storage, CommanderDefs EXPORTS BootmesaOps SHARES ControlDefs = BEGIN OPEN WartDefs; data: POINTER TO BootmesaOps.BootData _ @BootmesaOps.dataObject; -- Wart Script Management tableFileSegment: SegmentDefs.FileSegmentHandle _ NIL; segIndex: SegIndex; linkIndex: LinkIndex; segPages, linkPages: CARDINAL; segTable, linkTable, vmTable: PUBLIC TableBase; enableHyperspace: BOOLEAN _ TRUE; DisableHyperspace: PUBLIC PROCEDURE = BEGIN enableHyperspace _ FALSE END; InitializeBootScript: PUBLIC PROCEDURE = BEGIN segTable _ Storage.Pages[segPages _ 1]; segIndex _ LOOPHOLE[SIZE[Header]]; linkTable _ Storage.Pages[linkPages _ 1]; linkIndex _ FIRST[LinkIndex]; MiscDefs.Zero[@header, SIZE[Header]]; data.header _ @header; header.version _ VersionID; header.useHyperSpace _ enableHyperspace; RETURN END; header: Header; FinishBootScript: PUBLIC PROCEDURE [startframe: ControlDefs.GlobalFrameHandle] RETURNS [headerloc: POINTER] = BEGIN header.tablebase _ vmTable; header.user _ BootmesaOps.UserControl[]; header.nub _ BootmesaOps.NubFrame[]; header.ffvmp _ SegOps.ffvmp; header.lfvmp _ SegOps.lfvmp; segTable^ _ header; SegmentDefs.Unlock[tableFileSegment]; SegmentDefs.DeleteFileSegment[tableFileSegment]; RETURN[vmTable] END; BootTableOverflow: ERROR = CODE; ExpandingAllowed: BOOLEAN _ TRUE; ExpandSegTable: PROCEDURE = BEGIN newbase: POINTER; IF ~ExpandingAllowed THEN BootmesaOps.BootmesaError["SegTableOverflow"L]; newbase _ Storage.Pages[segPages + 1]; InlineDefs.COPY[ from: segTable, to: newbase, nwords: segPages*AltoDefs.PageSize]; segPages _ segPages + 1; Storage.FreePages[segTable]; segTable _ newbase; RETURN END; AppendSegEntry: PUBLIC PROCEDURE [seg: SegHandle] RETURNS [index: SegIndex] = BEGIN WHILE LOOPHOLE[segIndex, CARDINAL] + SIZE[SegEntry] > segPages*AltoDefs.PageSize DO ExpandSegTable[]; ENDLOOP; index _ segIndex; InlineDefs.COPY[from: seg, to: @segTable[index], nwords: SIZE[SegEntry]]; segIndex _ segIndex + SIZE[SegEntry]; RETURN END; ExpandLinkTable: PROCEDURE = BEGIN newbase: POINTER; IF ~ExpandingAllowed THEN BootmesaOps.BootmesaError["LinkTableOverflow"L]; newbase _ Storage.Pages[linkPages + 1]; InlineDefs.COPY[ from: linkTable, to: newbase, nwords: linkPages*AltoDefs.PageSize]; linkPages _ linkPages + 1; Storage.FreePages[linkTable]; linkTable _ newbase; RETURN END; AppendLinkEntry: PUBLIC PROCEDURE [link: LinkHandle] RETURNS [index: LinkIndex] = BEGIN WHILE LOOPHOLE[linkIndex, CARDINAL] + SIZE[LinkEntry] > linkPages*AltoDefs.PageSize DO ExpandLinkTable[]; ENDLOOP; index _ linkIndex; InlineDefs.COPY[from: link, to: @linkTable[index], nwords: SIZE[LinkEntry]]; linkIndex _ linkIndex + SIZE[LinkEntry]; RETURN END; NILZ: POINTER = LOOPHOLE[0]; PagePointer: TYPE = MACHINE DEPENDENT RECORD [page, byte: [0..256)]; DeclareSeg: PUBLIC PROCEDURE [s: SegOps.Seg] RETURNS [BOOLEAN] = BEGIN entry: SegEntry _ SegEntry[ data: s.data, write: s.write, locked: s.resident, in: s.in, base: 0, pages: s.pages, vmPage: s.vmPage, handle: NIL]; s.index _ AppendSegEntry[@entry]; RETURN[FALSE]; END; DeclareSegs: PUBLIC PROCEDURE = BEGIN [] _ SegOps.EnumerateSegs[DeclareSeg]; RETURN END; DeclareCodeLinks: PUBLIC PROCEDURE = BEGIN entry: LinkEntry; i: CARDINAL; mt: DESCRIPTOR FOR ARRAY OF BootmesaOps.ModuleInfo = data.moduleTable; FOR i IN [1..LENGTH[mt]) DO IF i # mt[i].mth.gfi THEN LOOP; entry _ LinkEntry[codeseg: mt[i].code.index, frame: mt[i].frame]; [] _ AppendLinkEntry[@entry]; ENDLOOP; RETURN END; WriteScriptSegments: PUBLIC PROCEDURE = BEGIN OPEN SegOps, StreamDefs; pages, segWords, linkWords, left: CARDINAL; tseg, daSeg: Seg; tEntry, daEntry: SegEntry; tIndex: SegIndex _ AppendSegEntry[@tEntry]; daIndex: SegIndex _ AppendSegEntry[@daEntry]; segWords _ LOOPHOLE[header.segLength _ segIndex]; header.linkOffset _ LOOPHOLE[segIndex]; linkWords _ LOOPHOLE[header.linkLength _ linkIndex]; pages _ Storage.PagesForWords[segWords + linkWords]; data.vmTableSeg _ tseg _ NewSeg[DefaultFile, SegOps.ffvmp, pages, TRUE]; data.daSeg _ daSeg _ NewSeg[DefaultFile, SegOps.ffvmp, 1, TRUE]; data.image.prefix.diskAddresses _ header.diskAddresses _ SegmentDefs.AddressFromPage[daSeg.vmPage]; BootmesaOps.SegmentToMap[tseg]; vmTable _ SegmentDefs.AddressFromPage[tseg.vmPage]; header.segOffset _ 0; tEntry _ SegEntry[ data: TRUE, write: FALSE, locked: TRUE, in: TRUE, pages: pages, vmPage: tseg.vmPage, base: 0, handle: NIL]; tseg.index _ tIndex; BootmesaOps.EnterMapSegment[tseg]; tEntry.base _ GetIndex[data.imageStream].page + 1; segTable[tIndex] _ tEntry; daEntry _ SegEntry[ data: TRUE, write: FALSE, locked: TRUE, in: TRUE, pages: 1, vmPage: daSeg.vmPage, base: 0, handle: NIL]; daSeg.index _ daIndex; segTable[daSeg.index _ daIndex] _ daEntry; IF WriteBlock[data.imageStream, segTable, segWords] # segWords THEN ERROR; IF WriteBlock[data.imageStream, linkTable, linkWords] # linkWords THEN ERROR; left _ AltoDefs.PageSize - (segWords + linkWords) MOD AltoDefs.PageSize; IF left # AltoDefs.PageSize THEN BEGIN p: POINTER = Storage.Pages[1]; MiscDefs.Zero[p, left]; IF WriteBlock[data.imageStream, p, left] # left THEN ERROR; Storage.FreePages[p]; END; CleanupDiskStream[data.imageStream]; Storage.FreePages[segTable]; Storage.FreePages[linkTable]; tableFileSegment _ SegmentDefs.NewFileSegment[ data.imageFile, tEntry.base, pages, SegmentDefs.Read + SegmentDefs.Write]; SegmentDefs.SwapIn[tableFileSegment]; segTable _ SegmentDefs.FileSegmentAddress[tableFileSegment]; linkTable _ segTable + header.linkOffset; ExpandingAllowed _ FALSE; RETURN END; [] _ CommanderDefs.AddCommand[ "DisableHyperspace", LOOPHOLE[DisableHyperspace], 0]; END..