-- RunImage.mesa; edited by Sandman; July 1, 1980 8:27 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoDefs USING [PageSize], AltoFileDefs USING [CFP], BcplOps USING [BcplJSR], BFSDefs USING [MakeCFP], BinaryDefs USING [MesaBootLoader], ControlDefs USING [FieldDescriptor, StateVector, SVPointer], CoreSwapDefs USING [PuntInfo], DiskDefs USING [DA, RealDA], ImageFormat USING [ImageHeader, MapItem, VersionID], ImageDefs USING [], MiscDefs USING [DestroyFakeModule, Zero], Mopcodes USING [zLI4, zRFS, zSHIFT, zWFS], ProcessDefs USING [ConditionVector, CV, DIW], ProcessOps USING [ActiveWord], SegmentDefs USING [ CopyFileToDataSegment, DataSegmentAddress, DataSegmentHandle, DeleteDataSegment, DeleteFileSegment, FileHandle, FileSegmentAddress, FileSegmentHandle, GetFileSegmentDA, MakeDataSegment, memConfig, MemoryConfig, NewFileSegment, PageFromAddress, Read, SwapIn, VMnotFree]; RunImage: PROGRAM IMPORTS BFSDefs, BinaryDefs, DiskDefs, MiscDefs, BcplOps, SegmentDefs EXPORTS ImageDefs SHARES DiskDefs, SegmentDefs = BEGIN OPEN SegmentDefs, ImageFormat; PageSize: CARDINAL = AltoDefs.PageSize; BD: PROCEDURE [CARDINAL] RETURNS [ControlDefs.FieldDescriptor] = MACHINE CODE BEGIN Mopcodes.zLI4; Mopcodes.zSHIFT END; SetBit: PROCEDURE [[0..1], POINTER, ControlDefs.FieldDescriptor] = MACHINE CODE BEGIN Mopcodes.zWFS END; GetBit: PROCEDURE [POINTER, ControlDefs.FieldDescriptor] RETURNS [[0..1]] = MACHINE CODE BEGIN Mopcodes.zRFS END; BootData: TYPE = RECORD [ pageMap: POINTER TO PageTable, firstDa: DiskDefs.DA, initialState: ControlDefs.SVPointer, bltItem: BltItem, terminator: WORD]; -- = 0 BltItem: TYPE = RECORD [ firstSourceM1: POINTER, lastDest: POINTER, minusCount: INTEGER]; PageTableHeader: TYPE = RECORD [cfp: AltoFileDefs.CFP, firstpage: CARDINAL]; PageTable: TYPE = RECORD [ header: PageTableHeader, address: ARRAY [0..0) OF UNSPECIFIED]; InvalidImage: PUBLIC SIGNAL = CODE; NoRoomForLoader: PUBLIC SIGNAL = CODE; RunImage: PUBLIC PROCEDURE [headerseg: FileSegmentHandle] = BEGIN boottable: POINTER TO BootData; map: ARRAY [0..16) OF UNSPECIFIED; ptwords: CARDINAL ← SIZE[PageTableHeader] + 1; pt: POINTER TO PageTable; j: CARDINAL; mapi: POINTER TO MapItem; loader, pagetable, bootseg: DataSegmentHandle; image: POINTER TO ImageHeader; initMemConfig: POINTER TO SegmentDefs.MemoryConfig ← LOOPHOLE[3]; state: ControlDefs.SVPointer = LOOPHOLE[175000B - SIZE[ControlDefs.StateVector]]; ifile: FileHandle = headerseg.file; SwapIn[headerseg]; image ← FileSegmentAddress[headerseg]; IF image.prefix.versionident # ImageFormat.VersionID OR image.prefix.options # 0 THEN SIGNAL InvalidImage; MiscDefs.Zero[@map, 16]; mapi ← @image.map[0]; DO IF mapi.count = 0 THEN EXIT; ptwords ← ptwords + mapi.count; FOR j IN [mapi.page..mapi.page + mapi.count] DO SetBit[1, @map, BD[j]] ENDLOOP; WITH mapi SELECT FROM change => BEGIN ptwords ← ptwords + 2; mapi ← mapi + SIZE[change MapItem]; END; normal => mapi ← mapi + SIZE[normal MapItem]; ENDCASE => ERROR; ENDLOOP; SetBit[1, @map, BD[PageFromAddress[image.prefix.diskAddresses]]]; loader ← Alloc[@map, 1]; IF loader = NIL THEN ERROR NoRoomForLoader; bootseg ← Alloc[@map, 1]; IF bootseg = NIL THEN BEGIN DeleteDataSegment[loader]; ERROR NoRoomForLoader END; boottable ← DataSegmentAddress[bootseg]; pagetable ← Alloc[@map, (ptwords + PageSize - 1)/PageSize]; IF pagetable = NIL THEN BEGIN DeleteDataSegment[loader]; DeleteDataSegment[bootseg]; ERROR NoRoomForLoader; END; SetUpBootMap[pt ← DataSegmentAddress[pagetable], image]; BFSDefs.MakeCFP[cfp: @pt.header.cfp, fp: @ifile.fp]; pt.header.firstpage ← headerseg.base + 1; state↑ ← image.prefix.state; boottable↑ ← [pageMap: image.prefix.diskAddresses, firstDa: FindDa[ifile, pt.header.firstpage], initialState: state, bltItem: [firstSourceM1: pt - 1, lastDest: image.prefix.diskAddresses + ptwords - 1, minusCount: -INTEGER[ptwords]], terminator: 0]; CopyFileToDataSegment[ MiscDefs.DestroyFakeModule[LOOPHOLE[BinaryDefs.MesaBootLoader]].seg, loader]; initMemConfig↑ ← SegmentDefs.memConfig; initMemConfig.useXM ← initMemConfig.xmMicroCode AND initMemConfig.banks # 100000B; BEGIN OPEN ProcessDefs, ProcessOps; ActiveWord↑ ← DIW↑ ← 0; MiscDefs.Zero[CV, SIZE[ConditionVector]]; CoreSwapDefs.PuntInfo↑ ← NIL; END; [] ← BcplOps.BcplJSR[JSR, DataSegmentAddress[loader], boottable]; END; Alloc: PROCEDURE [map: POINTER, npages: CARDINAL] RETURNS [d: DataSegmentHandle] = BEGIN i, j: CARDINAL; d ← NIL; FOR i IN [4..249] DO IF GetBit[map, BD[i]] = 0 THEN BEGIN ENABLE VMnotFree => BEGIN SetBit[1, map, BD[i]]; CONTINUE END; d ← MakeDataSegment[i, npages, [hard, topdown, other]]; FOR j IN [0..npages) DO SetBit[1, map, BD[i + j]] ENDLOOP; IF d # NIL THEN RETURN; i ← i + npages - 1; END ENDLOOP; RETURN END; SetUpBootMap: PROCEDURE [ pt: POINTER TO PageTable, image: POINTER TO ImageHeader] = BEGIN j: CARDINAL ← 0; memaddress, memcount: CARDINAL; mapi: POINTER TO ImageFormat.MapItem ← @image.map[0]; DO IF (memcount ← mapi.count) = 0 THEN EXIT; memaddress ← mapi.page*PageSize; WITH mapi SELECT FROM change => BEGIN pt.address[j] ← base*2 + 1; pt.address[j + 1] ← da; j ← j + 2; mapi ← mapi + SIZE[change ImageFormat.MapItem]; END; normal => mapi ← mapi + SIZE[normal ImageFormat.MapItem]; ENDCASE; THROUGH [0..memcount) DO pt.address[j] ← memaddress; memaddress ← memaddress + PageSize; j ← j + 1; ENDLOOP; ENDLOOP; pt.address[j] ← 0; END; FindDa: PROCEDURE [file: FileHandle, page: CARDINAL] RETURNS [da: DiskDefs.DA] = BEGIN seg: FileSegmentHandle ← NewFileSegment[file, page, 1, Read]; da ← DiskDefs.RealDA[SegmentDefs.GetFileSegmentDA[seg]]; DeleteFileSegment[seg]; RETURN END; END...