-- MMStart.Mesa Edited by Sandman on May 23, 1979 11:52 AM -- Edited by Forrest on October 8, 1980 2:42 PM DIRECTORY AltoDefs USING [PageNumber], BcplOps USING [BcplJSR], ControlDefs USING [FrameHandle, GlobalFrameHandle, NullFrame, StateVector], FrameOps USING [GetReturnFrame, MyLocalFrame], ImageDefs USING [UserCleanupProc], InlineDefs USING [BITSHIFT, BITOR], MMInit, MMSDEntries, ProcessDefs USING [ DefaultPriority, Detach, DisableInterrupts, DisableTimeout, DIW, EnableInterrupts, GetPriority, Priority, SetPriority, SetTimeout, TimeoutLevel], ProcessOps, PSBDefs, SDDefs USING [ sAllocTrap, sBLTE, sBLTEC, sBYTBLTE, sBYTBLTEC, sBreak, sControlFault, sCopy, SD, sError, sErrorList, sFork, sJoin, sLongDiv, sLongDivMod, sLongMod, sLongMul, sProcessTrap, sRestart, sGoingAway, sReturnError, sReturnErrorList, sSignal, sSignalList, sSignedDiv, sStackError, sStart, sStringInit, sSwapTrap, sUnbound, sULongDiv, sULongDivMod, sULongMod, sUnnamedError, sUnNew], SegmentDefs USING [DeleteDataSegment], SystemDefs USING [FreePages], SwapperOps, WartDefs; MMStart: PROGRAM [h: POINTER TO WartDefs.Header] RETURNS [PROGRAM] IMPORTS BcplOps, FrameOps, ImageDefs, InlineDefs, MMInit, MMSDEntries, ProcessDefs, ProcessOps, SegmentDefs, SystemDefs, SwapperOps EXPORTS MMInit = BEGIN OPEN MMInit, SDDefs; InitSD: PUBLIC PROCEDURE = BEGIN OPEN SDDefs, MMSDEntries; sd: POINTER TO ARRAY [0..0) OF UNSPECIFIED _ SD; sd[sSignalList] _ SignalList; sd[sSignal] _ Signal; sd[sErrorList] _ ErrorList; sd[sError] _ Error; sd[sReturnErrorList] _ ReturnErrorList; sd[sReturnError] _ ReturnError; sd[sUnnamedError] _ UnnamedError; sd[sStackError] _ StackErrorTrap; sd[sControlFault] _ ControlFaultTrap; sd[sStart] _ Start; sd[sRestart] _ Restart; sd[sBLTE] _ BlockEqual; sd[sBYTBLTE] _ ByteBlockEqual; sd[sBLTEC] _ BlockEqualCode; sd[sBYTBLTEC] _ ByteBlockEqualCode; sd[sStringInit] _ StringInit; sd[sSignedDiv] _ SignDivide; sd[sLongDivMod] _ DDivMod; sd[sLongMod] _ DMod; sd[sLongDiv] _ DDiv; sd[sLongMul] _ DMultiply; sd[sULongDivMod] _ DUnsignedDivMod; sd[sULongMod] _ DUnsignedMod; sd[sULongDiv] _ DUnsignedDiv; sd[sAllocTrap] _ AllocTrap[AllocTrap[ControlDefs.NullFrame]]; sd[sSwapTrap] _ CodeTrap; sd[sUnbound] _ UnboundProcedureTrap; sd[sCopy] _ Copy; sd[sUnNew] _ UnNew; sd[sGoingAway] _ ImageDefs.UserCleanupProc; END; Memory: PUBLIC PROCEDURE [ff, lf: AltoDefs.PageNumber] = BEGIN MMInit.lfvmp _ lf; MMInit.ffvmp _ ff; FOR i: CARDINAL IN [ff..lf] DO MMInit.pageMap[i] _ free ENDLOOP; END; Interrupt: PROCEDURE = BEGIN OPEN ProcessDefs; save: Priority = GetPriority[]; START MMInterrupt; SetTimeout[@wakeup, 1]; SetPriority[6]; Detach[FORK CheckInterrupt]; SetPriority[save]; RETURN END; InitializeProcesses: PROCEDURE = BEGIN OPEN SDDefs, ProcessDefs, ProcessOps, PSBDefs; sd: POINTER TO ARRAY [0..0) OF UNSPECIFIED _ SD; PSBBase: CARDINAL = 0; firstPSB: ProcessHandle _ FirstProcess^; lastPSB: ProcessHandle _ LastProcess^; psb: ProcessHandle; DisableTimeout[@dead]; DisableTimeout[@frameReady]; DisableTimeout[@frameTaken]; DisableTimeout[@rebirth]; CurrentState^ _ FirstStateVector^ + DefaultPriority*SIZE[ControlDefs.StateVector]; -- locate and initialize PSBs sd[sProcessTrap] _ ProcessTrap; sd[sFork] _ Fork; sd[sJoin] _ Join; -- fabricate PSB for self lastPSB^ _ PSB[ link: lastPSB, cleanup: Clean, timeout: 0, enterFailed: FALSE, detached: FALSE, fill: 0B, state: alive, timeoutAllowed:, abortPending: FALSE, timeoutPending: FALSE, waitingOnCV: FALSE, priority: DefaultPriority, frame: FrameOps.MyLocalFrame[]]; CurrentPSB^ _ ReadyList^ _ lastPSB; -- set up free PSB pool ("rebirth" condition) FOR psb _ firstPSB, psb+SIZE[PSB] UNTIL psb = lastPSB DO psb^ _ PSB[ link: psb-SIZE[PSB], cleanup: Clean, timeout: 0, enterFailed: FALSE, detached: FALSE, fill: 0B, state: dead, timeoutAllowed:, abortPending: FALSE, timeoutPending: FALSE, waitingOnCV: TRUE, priority: DefaultPriority, frame: ControlDefs.NullFrame]; ENDLOOP; LOOPHOLE[rebirth, Condition].queue _ (firstPSB.link _ lastPSB-SIZE[PSB])-PSBBase; -- CV^ already set up by Nova code ActiveWord^ _ 77777B; RETURN END; InitializeTimeouts: PROCEDURE = BEGIN OPEN InlineDefs, ProcessDefs; TimeoutMask: WORD = BITSHIFT[1,TimeoutLevel]; DisableInterrupts[]; -- Nova code has set up IntVec[TimeoutLevel] DIW^ _ BITOR[DIW^, TimeoutMask]; EnableInterrupts[]; RETURN END; ProcessWartList: PROCEDURE RETURNS [PROGRAM] = BEGIN OPEN WartDefs; segBase: TableBase = h.tablebase + h.segOffset; linkBase: TableBase = h.tablebase + h.linkOffset; ProcessOps.WriteWDC[0]; -- interrupts on FOR seg: SegIndex _ LOOPHOLE[SIZE[Header]], seg + SIZE[SegEntry] UNTIL seg = h.segLength DO s: SegHandle = @segBase[seg]; IF s.in THEN s.handle _ SwapperOps.BootDataSegment[s.vmPage, s.pages] ENDLOOP; FOR link: LinkIndex _ FIRST[LinkIndex], link + SIZE[LinkEntry] UNTIL link = h.linkLength DO frame: ControlDefs.GlobalFrameHandle = linkBase[link].frame; s: SegHandle = @segBase[linkBase[link].codeseg]; IF s.handle=NIL THEN ERROR; frame.code.handle _ LOOPHOLE[s.vmPage*256]; ENDLOOP; InitializeProcesses[]; InitializeTimeouts[]; Interrupt[]; SegmentDefs.DeleteDataSegment[segBase[h.loadState].handle]; SegmentDefs.DeleteDataSegment[segBase[h.initLoadState].handle]; IF segBase[h.bcd].in THEN SegmentDefs.DeleteDataSegment[segBase[h.bcd].handle]; SystemDefs.FreePages[h]; START MMDebug[LOOPHOLE[h.user]]; FrameOps.GetReturnFrame[].returnlink _ LOOPHOLE[MMSDEntries.Restart]; SDDefs.SD[sBreak] _ MMSDEntries.Break; RETURN[LOOPHOLE[MMDebug]]; END; WartBreak: PROCEDURE = BEGIN OPEN BcplOps, ControlDefs; s: StateVector; f: FrameHandle; break: RECORD[a,b: WORD]; s _ STATE; break _ [77400B, 1400B]; f _ FrameOps.GetReturnFrame[]; s.dest _ f; f.pc _ [IF f.pc < 0 THEN -f.pc ELSE (1-f.pc)]; s.instbyte _ BcplJSR[JSR, @break, 0]; RETURN WITH s; END; SDDefs.SD[sBreak] _ WartBreak; InitSD[]; START MMTraps; START MMMemory; START MMSignals; START MMProcess; Memory[h.ffvmp, h.lfvmp]; RETURN[ProcessWartList[]]; END......