-- File: AltoRamLoader.mesa, Last Edit: GEW December 11, 1981 5:45 PM -- This whole section was stolen and simplified from Mitchell's RamLoad for Juniper. -- There is no check to be sure that Mesa is running in the Rom. DIRECTORY AltoDefs USING [PageNumber, BytesPerPage, BytesPerWord], AllocDefs USING [MakeSwappedIn, DefaultDataSegmentInfo], BcplOps USING [BcplJSR], ControlDefs USING [GlobalFrameHandle], FrameDefs USING [GlobalFrame, SwapOutCode], FrameOps USING [Start, CodeHandle], ProcessDefs USING [DisableInterrupts, EnableInterrupts], SegmentDefs USING [ FileHandle, FileSegmentHandle, Read, OldFileOnly, DefaultBase, DefaultPages, NewFile, NewFileSegment, DeleteFileSegment, GetEndOfFile, FileSegmentAddress, SwapIn, Unlock, SwapOut, FileNameError], Trouble USING [SetRamUnBooter], AltoRam USING [DoSilentBoot, UnBoot]; AltoRamLoader: PROGRAM IMPORTS AllocDefs, BcplOps, FrameDefs, FrameOps, ProcessDefs, SegmentDefs, Trouble, AltoRam EXPORTS AltoRam = BEGIN maxConstAddr: CARDINAL = 377B; sizeRam: CARDINAL = 2000B; PackedMuFile: TYPE = MACHINE DEPENDENT RECORD [ brJunk: ARRAY [0..21B) OF UNSPECIFIED, -- header stuff in .br file bootVector: WORD, constVector: ARRAY [1..maxConstAddr] OF CARDINAL, -- const 0 is always zero ramVector: ARRAY [0..sizeRam) OF RamWord]; RamWord: TYPE = MACHINE DEPENDENT RECORD [high, low: WORD]; CantFindFile: PUBLIC ERROR = CODE; FileLooksCrufty: PUBLIC ERROR = CODE; LoadRamAndBoot: PUBLIC PROCEDURE [filename: STRING, dontLock: BOOLEAN ← FALSE] = BEGIN OPEN SegmentDefs; mu: POINTER TO PackedMuFile; muFH: FileHandle; muSeg: FileSegmentHandle; lastPage: AltoDefs.PageNumber; lastByteCount: [0..AltoDefs.BytesPerPage]; i: CARDINAL; bootLocusVector: WORD; checkConstVec: ARRAY [1..13] OF CARDINAL = [1, 2, 177776B, 177777B, 177777B, 17B, 177777B, 3, 4, 5, 6, 7, 10B]; muFH ← NewFile[ filename, Read, OldFileOnly ! SegmentDefs.FileNameError => ERROR CantFindFile]; [page: lastPage, byte: lastByteCount] ← GetEndOfFile[muFH]; IF lastPage # 12B THEN ERROR FileLooksCrufty; IF (lastByteCount MOD AltoDefs.BytesPerWord) # 0 THEN ERROR FileLooksCrufty; muSeg ← NewFileSegment[muFH, DefaultBase, DefaultPages, Read]; SwapIn[muSeg]; mu ← FileSegmentAddress[muSeg]; bootLocusVector ← mu.bootVector; FOR i IN [1..13] DO -- check first few constants to be sure file isn't garbage IF checkConstVec[i] # mu.constVector[i] THEN ERROR FileLooksCrufty; ENDLOOP; IF ~dontLock THEN LockThingsInLowMemory[]; ProcessDefs.DisableInterrupts[]; WriteRam[@mu.ramVector]; ProcessDefs.EnableInterrupts[]; Unlock[muSeg]; SwapOut[muSeg]; DeleteFileSegment[muSeg]; Trouble.SetRamUnBooter[AltoRam.UnBoot]; AltoRam.DoSilentBoot[bootLocusVector]; END; -- AltoRam.DoSilentBoot needs to be locked in bank 0 or things go POOF when we do the silent boot to move various tasks into the RAM. The problem is that SilentBoot boot clears the bank registers, and the Mesa microcode expects them to point to the code segment. NB: We leave AltoRam.DoSilentBoot locked because we must do another silent boot when we are finished to move the tasks back into the ROM. LockThingsInLowMemory: PUBLIC PROCEDURE = BEGIN gf: ControlDefs.GlobalFrameHandle; code: SegmentDefs.FileSegmentHandle; gf ← FrameDefs.GlobalFrame[AltoRam.DoSilentBoot]; FrameOps.Start[[frame[gf]]]; FrameDefs.SwapOutCode[gf]; code ← FrameOps.CodeHandle[gf]; AllocDefs.MakeSwappedIn[ code, SegmentDefs.DefaultBase, AllocDefs.DefaultDataSegmentInfo]; END; WriteRam: PROCEDURE [v: POINTER TO ARRAY [0..sizeRam) OF RamWord] = BEGIN -- This whole mess is in Bcpl code to make loading the RAM atomic for XMesa. code: ARRAY [0..14) OF CARDINAL ← [111000B, -- MOV 0,2 055003B, -- STA 3,3,2 025001B, -- LDA 1,1,2 035002B, -- LP: LDA 3,2,2 021400B, -- LDA 0,0,3 035401B, -- LDA 3,1,3 061012B, -- WRTRAM 125420B, -- INCZ 1,1 011002B, -- ISZ 2,2 011002B, -- ISZ 2,2 015000B, -- DSZ 0,2 000770B, -- JMP LP 035003B, -- LDA 3,3,2 001400B]; -- JMP 0,3 acs: MACHINE DEPENDENT RECORD [n, ramAddr, vecAddr, svAc3: UNSPECIFIED]; acs ← [n: sizeRam, ramAddr: 0, vecAddr: v, svAc3: NIL]; [] ← BcplOps.BcplJSR[JSR, BASE[code], @acs]; END; END.