DIRECTORY Atom, Basics, Cache2, CacheOps, Cluster2, Core, CoreClasses, CoreCreate, CoreFlat, CoreOps, Dragon, DragonRosemary, DragOpsCross, DragOpsCrossUtils, EU2, IFU2, IO, LizardCache, LizardHeart, Ports, Process, RandomCode, Rope, Rosemary, RosemaryUser, SparseMemory, TypeScript, ViewerClasses, ViewerIO, ViewRec; Cluster2Impl: CEDAR PROGRAM IMPORTS Atom, Cache2, CacheOps, CoreCreate, CoreOps, DragonRosemary, DragOpsCrossUtils, EU2, IFU2, IO, LizardCache, LizardHeart, Ports, Process, RandomCode, Rope, Rosemary, RosemaryUser, SparseMemory, TypeScript, ViewerIO, ViewRec EXPORTS Cluster2 = BEGIN OPEN Cluster2; nCacheLines: NAT _ 200; skipIFURejects: BOOL _ FALSE; skipEURejects: BOOL _ FALSE; fullEU: BOOL _ FALSE; lastKs: KitchenSink _ NIL; -- I put this in so that you can get your hands on the kitchen sink from a new command tool. If you take it out, I may not rip your lungs out, but ... MakeCluster: PUBLIC PROC RETURNS [ks: KitchenSink] = BEGIN ifuRoseInst, euRoseInst, iCacheRoseInst, eCacheRoseInst: CoreClasses.CellInstance _ NIL; DStateAddress: CoreCreate.WR _ CoreCreate.Seq["DStateAddress", 4]; publicInputNames: LIST OF CoreCreate.WR _ LIST[ "PhA", "PhB", "ResetAB", "RescheduleAB", "Vdd", "Gnd", "PadVdd", "PadGnd", "DExecuteAB", "DNSelectAB", "DHoldAB", "DrShA", "DrShB", "DrShRd", "DrShWt", "DrShIn" -- IFU's debugging shifter ]; publicOutputName: CoreCreate.WR _ "DrShOut"; -- IFU's debugging shifter public: CoreCreate.Wire = CoreCreate.WireList[CONS[DStateAddress, CONS[publicOutputName, publicInputNames]]]; internal: CoreCreate.Wire = CoreCreate.WireList[LIST[ CoreCreate.Seq["KBus", 32], CoreCreate.Seq["EUAluOp2AB", 4], CoreCreate.Seq["EUCondSel2AB", 4], "EUCondition2B", "EURes3BisPBus3AB", "EUWriteToPBus3AB", CoreCreate.Seq["IPData", 32], CoreCreate.Seq["IPCmdA", 8], "IPRejectB", CoreCreate.Seq["IPFaultB", 5], CoreCreate.Seq["DPData", 32], CoreCreate.Seq["DPCmdA", 8], "DPRejectB", CoreCreate.Seq["DPFaultB",5] ]]; flatInstance: CoreFlat.FlatInstance _ NEW[CoreFlat.FlatInstanceRec]; ks _ lastKs _ NEW[KitchenSinkRec _ [ log: ViewerIO.CreateViewerStreams["Rosemary Cluster Simulation"].out, vm: CacheOps.NewVirtualMemory[] ]]; TypeScript.ChangeLooks[ViewerIO.GetViewerFromStream[ks.log], 'f]; ks.iCache _ CacheOps.NewCache[mem: ks.vm, nLines: nCacheLines]; ks.eCache _ CacheOps.NewCache[mem: ks.vm, nLines: nCacheLines]; ks.coreInsts[iCache] _ CoreCreate.InstanceList[ type: Cache2.Cache[vm: ks.iCache, skipRejects: skipIFURejects], pas: LIST[ [public: "PData", actual: "IPData"], ["PCmdA", "IPCmdA"], ["PRejectB", "IPRejectB"], ["PFaultB", "IPFaultB"] ] ]; ks.coreInsts[eCache] _ CoreCreate.InstanceList[ type: Cache2.Cache[vm: ks.eCache, skipRejects: skipEURejects], pas: LIST[ [public: "PData", actual: "DPData"], ["PCmdA", "DPCmdA"], ["PRejectB", "DPRejectB"], ["PFaultB", "DPFaultB"] ] ]; ks.coreInsts[ifu] _ CoreCreate.InstanceList[ type: IFU2.IFU[NEW[IFU2.IFUTypeData _ [ data: ks, getLog: GetLog, checkSynch: CheckSynch, getCycle: GetCycle ]]], pas: LIST[] ]; ks.coreInsts[eu] _ CoreCreate.InstanceList[ type: Rosemary.AddCutSets[ cellType: EU2.CreateEU2[NEW[EU2.EUTypeData _ [ data: ks, storeNoted: FALSE, noteStore: NoteRegStore ]], fullEU], cs1: "TopLevel" ], pas: LIST[] ]; ks.cluster _ CoreCreate.Cell[ public: public, onlyInternal: internal, instances: LIST[ks.coreInsts[ifu], ks.coreInsts[eu], ks.coreInsts[iCache], ks.coreInsts[eCache]], name: "Cluster" ]; [] _ Rosemary.SetFixedWire[public[CoreOps.GetWireIndex[public, "Vdd"]], H]; [] _ Rosemary.SetFixedWire[public[CoreOps.GetWireIndex[public, "Gnd"]], L]; [] _ Rosemary.SetFixedWire[public[CoreOps.GetWireIndex[public, "PadVdd"]], H]; [] _ Rosemary.SetFixedWire[public[CoreOps.GetWireIndex[public, "PadGnd"]], L]; [] _ Ports.InitPort[wire: CoreCreate.FindWire[ks.cluster.public, DStateAddress], levelType: c, initDrive: force]; [] _ Ports.InitPort[wire: CoreCreate.FindWire[ks.cluster.public, publicOutputName], levelType: b, initDrive: none]; FOR rl: LIST OF CoreCreate.WR _ publicInputNames, rl.rest WHILE rl # NIL DO [] _ Ports.InitPort[wire: CoreCreate.FindWire[ks.cluster.public, rl.first], levelType: b, initDrive: force]; ENDLOOP; ks.clusterIOPort _ Ports.CreatePort[ks.cluster.public]; ks.rosemarySimulation _ Rosemary.InstantiateInstances[ cellType: ks.cluster, testPort: ks.clusterIOPort, cutSets: LIST["TopLevel"] ]; FOR inst: Instances IN Instances DO flatInstance.instance _ ks.coreInsts[inst]; ks.state[0].data[inst] _ Rosemary.GetInstanceState[ks.rosemarySimulation, flatInstance]; ENDLOOP; FOR i: NAT IN [1..historySize) DO ks.state[i].data _ [ ifu: IFU2.NewIFUState[NARROW[ks.state[0].data[ifu]]], eu: NEW[EU2.EU2StateRec], iCache: NEW[Cache2.CacheState], eCache: NEW[Cache2.CacheState]]; ENDLOOP; ks.euReject _ NEW[CoreFlat.FlatWireRec]; ks.euReject.wire _ CoreCreate.FindWire[internal, "DPRejectB"]; IF fullEU THEN { euCellType: Core.CellType _ ks.coreInsts[eu].type; ks.euSimulationTruthPort _ Ports.CreatePort[euCellType.public, TRUE]; ks.euSimulationTestPort _ Ports.CreatePort[euCellType.public, TRUE]; ks.euSimulation _ Rosemary.InstantiateInstances[euCellType, ks.euSimulationTestPort, LIST["AlpsCell", "EU2Ram"]]; ks.euFlatInstance _ NEW[CoreFlat.FlatInstanceRec]; ks.euFlatInstance.instance _ ks.coreInsts[eu]; ks.euDisplay _ RosemaryUser.DisplayViewer[ks.euSimulation, euCellType, "EU2", RosemaryUser.DisplayCellTypePortLeafWires[euCellType]]; Rosemary.Initialize[ks.euSimulation, FALSE]; }; StartPanel[ks]; END; runningMsg: Core.ROPE _ "Running..."; SetPublic: PUBLIC PROC [ks: KitchenSink, signal: ATOM, value: REF ANY _ NIL ] = BEGIN WITH value SELECT FROM refBool: REF BOOL => ks.clusterIOPort[CoreOps.GetWireIndex[ks.rosemarySimulation.coreCellType.public, Atom.GetPName[signal]]].b _ refBool^; ENDCASE => ERROR; END; SetPublicBool: PUBLIC PROC [ks: KitchenSink, signal: ATOM, value: BOOL ] = BEGIN SetPublic[ks, signal, NEW[BOOL _ value]]; END; SetPublicAndSettle: PUBLIC PROC [ks: KitchenSink, signal: ATOM, value: REF ANY _ NIL ] = BEGIN SetPublic[ks, signal, value]; Rosemary.Settle[ ks.rosemarySimulation ! ABORTED => IF ks.controlPanel.continueTestFromAbort THEN CONTINUE ELSE REJECT; ]; ks.controlPanel.continueTestFromAbort _ FALSE; END; GetPublicBool: PUBLIC PROC [ks: KitchenSink, signal: ATOM] RETURNS [value: BOOL] = {value _ ks.clusterIOPort[CoreOps.GetWireIndex[ks.rosemarySimulation.coreCellType.public, Atom.GetPName[signal]]].b}; DoCluster: PUBLIC PROC [ks: KitchenSink, diagnostic: Core.ROPE _ NIL] = BEGIN originalPriority: Process.Priority = Process.GetPriority[]; diagnosticName: Core.ROPE _ "unknown"; { ENABLE UNWIND => { ks.log.PutF["\nSimulation of %g aborted\n\n", IO.rope[diagnosticName]]; ks.log.Flush[]; Process.SetPriority[ originalPriority ] }; DoEval: PROC = { ks.controlPanel.continueTestFromAbort _ FALSE; IF GetPublicBool[ks, $PhA] THEN { SetPublicBool[ks, $RescheduleAB, ks.controlPanel.resched]; SetPublicBool[ks, $ResetAB, ks.controlPanel.reset]; }; Rosemary.Settle[ ks.rosemarySimulation ! ABORTED => IF ks.controlPanel.continueTestFromAbort THEN CONTINUE ELSE REJECT; ]; IF fullEU THEN { Rosemary.SettleToTest[simulation: ks.rosemarySimulation, instance: ks.euFlatInstance, test: ks.euSimulationTruthPort]; Ports.CopyPortValue[from: ks.euSimulationTruthPort, to: ks.euSimulationTestPort]; Rosemary.Settle[ks.euSimulation ! Rosemary.Stop => IF ks.euCyclesFromReject>0 AND data = $BoolWireHasX THEN RESUME ELSE {RosemaryUser.UpdateDisplay[ks.euDisplay]; REJECT}]; RosemaryUser.UpdateDisplay[ks.euDisplay]; Ports.CheckPortValue[root: ks.coreInsts[eu].type.public, truth: ks.euSimulationTruthPort, question: ks.euSimulationTestPort]; }; IF ks.controlPanel.reset THEN ks.controlPanel.instrCount _ -1; Process.Yield[]; ks.controlPanel.continueTestFromAbort _ FALSE }; Cycles: PROC [ n: INT ] = {FOR i: INT IN [0..n) DO DoPh[a]; DoPh[b] ENDLOOP}; Remark: PROC [explan: Core.ROPE] = { ks.controlPanel.msg _ explan; ks.controlPanel.running _ FALSE; DoEval[]; UNTIL ks.controlPanel.running DO Process.Pause[Process.MsecToTicks[1000]] ENDLOOP; ks.controlPanel.msg _ runningMsg; DoEval[]; }; DoPh: PROC [ ph: Dragon.Phase ] = { first: BOOL _ TRUE; ks.controlPanel.phase _ ph; WHILE first OR ks.controlPanel.repeatPhase DO SetPublicBool[ks, $PhB, ph=b]; SetPublicBool[ks, $PhA, ph=a]; IF ks.controlPanel.running THEN { ks.controlPanel.msg _ runningMsg; DoEval[]; } ELSE Remark[(IF ks.controlPanel.msg = runningMsg THEN "Simulation manually suspended..." ELSE ks.controlPanel.msg)]; IF first THEN { IF (ks.controlPanel.cycle >= ks.controlPanel.slowFromCycle OR (ks.controlPanel.cycle>=0 AND ks.controlPanel.instrCount >= ks.controlPanel.slowFromInstr)) AND ks.controlPanel.stopInPh[ph] THEN Remark[IO.PutFR["Doing cycle %g Ph%g...", IO.int[ks.controlPanel.cycle], IO.char[IF ph=a THEN 'A ELSE 'B]]]; } ELSE Remark[IO.PutFR["...repeating cycle %g Ph%g..", IO.int[ks.controlPanel.cycle], IO.char[IF ph=a THEN 'A ELSE 'B]]]; IF first THEN { -- cycle the history buffer s: ClusterState _ ks.state[historySize-1]; FOR i: NAT DECREASING IN (1..historySize) DO ks.state[i] _ ks.state[i-1]; ENDLOOP; s.cycle _ ks.controlPanel.cycle; s.phase _ ks.controlPanel.phase; NARROW[s.data[ifu], REF IFU2.IFUState]^ _ NARROW[ks.state[0].data[ifu], REF IFU2.IFUState]^; NARROW[s.data[eu], REF EU2.EU2StateRec]^ _ NARROW[ks.state[0].data[eu], REF EU2.EU2StateRec]^; NARROW[s.data[iCache], REF Cache2.CacheState]^ _ NARROW[ks.state[0].data[iCache], REF Cache2.CacheState]^; NARROW[s.data[eCache], REF Cache2.CacheState]^ _ NARROW[ks.state[0].data[eCache], REF Cache2.CacheState]^; ks.state[1] _ s; first _ FALSE; }; SetPublicBool[ks, $PhB, FALSE]; SetPublicBool[ks, $PhA, FALSE]; DoEval[]; ENDLOOP; ks.euCyclesFromReject _ SELECT TRUE FROM ks.controlPanel.reset => 3, ph=a OR Rosemary.WireValue[simulation: ks.rosemarySimulation, wire: ks.euReject][0]=H => ks.euCyclesFromReject, ks.euCyclesFromReject>0 => ks.euCyclesFromReject-1, ENDCASE => 0; }; Process.SetPriority[ Process.priorityBackground ]; ks.diagnostics _ IF diagnostic=NIL THEN "test end" ELSE diagnostic; ks.controlPanel.diagnostic _ ks.diagnostics; ks.controlPanel.running _ TRUE; DO -- over all diagnostics Chop: PROC RETURNS [ first, rest: Rope.ROPE _ NIL ] = BEGIN dStream: IO.STREAM = IO.RIS[ks.controlPanel.diagnostic]; first _ dStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token; rest _ ks.controlPanel.diagnostic.Substr[dStream.GetIndex]; END; diagnosticFileName: Core.ROPE _ diagnosticName _ Chop[].first; IF Rope.Length[diagnosticFileName] = 0 OR (Rope.Equal[s1: diagnosticFileName, s2: "END", case: FALSE] AND ks.controlPanel.randomSeed=0) THEN EXIT; ks.controlPanel.reset _ TRUE; WHILE ks.controlPanel.reset DO -- as often as RESET is asserted in the same diagnostic ks.controlPanel.stopInPh _ ALL[TRUE]; ks.controlPanel.repeatPhase _ ks.controlPanel.resched _ FALSE; ks.controlPanel.cycle _ -1; ks.controlPanel.instrCount _ -1; { public: Core.Wire _ ks.cluster.public; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DExecuteAB"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DNSelectAB"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DHoldAB"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DStateAddress"]].c _ 0; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DrShA"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DrShB"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DrShRd"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DrShWt"]].b _ FALSE; ks.clusterIOPort[CoreOps.GetWireIndex[public, "DrShIn"]].b _ FALSE; }; FOR j: NAT IN [0..3) DO DoPh[a ! DragonRosemary.AssertionFailed => RESUME; Rosemary.Stop => IF data = $FailedAssertion OR data = $BoolWireHasX THEN RESUME ELSE REJECT; IFU2.IFUInconsistent => CONTINUE ]; DoPh[b ! DragonRosemary.AssertionFailed => RESUME; Rosemary.Stop => IF data = $FailedAssertion OR data = $BoolWireHasX THEN RESUME ELSE REJECT; IFU2.IFUInconsistent => CONTINUE ]; ENDLOOP; Cycles[2]; SELECT TRUE FROM diagnosticFileName # NIL => BEGIN CacheOps.VirtualMemoryFromFile[ks.vm, diagnosticFileName ]; ks.lizardSimulation _ (IF ks.controlPanel.lizardToo THEN StartNewLizard[ks.vm] ELSE NIL); END; ks.controlPanel.randomSeed#0 => BEGIN diagnosticName _ IO.PutFR["random code (seed = %d)", IO.int[ks.controlPanel.randomSeed]]; InsertRandomProgramInVM[ks]; ks.lizardSimulation _ (IF ks.controlPanel.lizardToo THEN StartNewLizard[ks.vm] ELSE NIL); END; ENDCASE => ERROR; ks.controlPanel.reset _ FALSE; DoPh[a]; IF ks.controlPanel.reset THEN LOOP; -- restart this diagnostic DoPh[b]; IF ks.controlPanel.reset THEN LOOP; -- restart this diagnostic IF ks.controlPanel.slowFromCycle<=0 THEN Remark["Processor has been reset..."]; ks.controlPanel.cycle _ 0; ks.rosemaryStores _ NIL; ks.log.PutF["\n\n\n%g Dragon Rosemary simulation of %g beginning...\n\n", IO.time[], IO.rope[diagnosticName]]; WHILE ks.controlPanel.randomSeed=0 OR ks.controlPanel.cycle<=ks.controlPanel.randomCycleLimit DO ENABLE { SuccessHalt => { ks.log.PutF["\n%g Success XOP in %g at instruction %d, cycle %d.\n\n", IO.time[], IO.rope[diagnosticName], IO.int[ks.controlPanel.instrCount], IO.int[ks.controlPanel.cycle]]; EXIT; }; Breakpoint => { ks.log.PutF["\n%g Breakpoint XOP in %g at instruction %d, cycle %d.\n\n", IO.time[], IO.rope[diagnosticName], IO.int[ks.controlPanel.instrCount], IO.int[ks.controlPanel.cycle]]; SELECT TRUE FROM ks.controlPanel.emulateBreakpoint => RESUME; diagnosticFileName # NIL => REJECT; ENDCASE => EXIT; }; }; DoPh[a]; IF ks.controlPanel.reset THEN EXIT; -- restart this diagnostic DoPh[b]; IF ks.controlPanel.reset THEN EXIT; -- restart this diagnostic ks.controlPanel.cycle _ ks.controlPanel.cycle+1; ENDLOOP; -- on ks.controlPanel.cycle ENDLOOP; -- on a single diagnostic SELECT TRUE FROM diagnosticFileName # NIL => BEGIN first, rest: Rope.ROPE; [first, rest] _ Chop[]; IF first.Equal[diagnosticFileName] THEN ks.controlPanel.diagnostic _ Rope.Cat[rest, " ",first]; END; ks.controlPanel.randomSeed # 0 => ks.controlPanel.randomSeed _ ks.controlPanel.randomSeed+1; ENDCASE => NULL; ENDLOOP; -- on ks.diagnostic or ks.controlPanel.randomSeed }; -- for catching UNWIND Process.SetPriority[ originalPriority ]; END; GetLog: PROC [ data: OpaqueKitchenSink ] RETURNS [ Core.STREAM ] = BEGIN ks: KitchenSink = NARROW[data]; RETURN [ ks.log ]; END; GetCycle: PROC [ data: OpaqueKitchenSink ] RETURNS [ cycle: INT ] = BEGIN ks: KitchenSink = NARROW[data]; RETURN [ ks.controlPanel.cycle ]; END; NoteRegStore: PROC [ data: REF ANY, reg: [0..256), value: Dragon.Word ] -- EU2.NoteRegStoreProc -- = BEGIN ks: KitchenSink = NARROW[data]; ks.rosemaryStores _ CONS[NEW[Dragon.RegStoreRec _ [instr: ks.controlPanel.instrCount, reg: VAL[reg], data: value]], ks.rosemaryStores]; END; randomStartPC: Dragon.Word _ 102000H; randomBackground: Core.ROPE _ "RandomBackground.quad"; InsertRandomProgramInVM: PROC[ ks: KitchenSink ] = { WriteOneCodeByte: PROC [byte: [0..255]] = BEGIN background: Basics.LongNumber; CacheOps.SetFlags[c: ks.eCache, address: nextByteAddr/4, mapped: TRUE, writeProtect: FALSE, dirty: FALSE]; background.lc _ CacheOps.Access[c: ks.eCache, address: nextByteAddr/4].data; SELECT nextByteAddr MOD 4 FROM 0 => background.hh _ byte; 1 => background.hl _ byte; 2 => background.lh _ byte; 3 => background.ll _ byte; ENDCASE => ERROR; CacheOps.Write[c: ks.eCache, address: nextByteAddr/4, data: background.lc]; nextByteAddr _ nextByteAddr+1; END; nextByteAddr: Dragon.Word _ randomStartPC; CacheOps.VirtualMemoryFromFile[ks.vm, randomBackground]; RandomCode.GenerateRandomProgramBytes[ initialByteAddress: randomStartPC, randomSeed: ks.controlPanel.randomSeed, seeOneByte: WriteOneCodeByte, dribble: ks.log ]; ks.eCache _ CacheOps.NewCache[ks.eCache]; -- resets first free cycle, cache lines }; LizardEUCacheFetchTrap: PROC [base: LizardCache.CacheBase, addr: LizardCache.Word, cycle: INT, noEffect: BOOL _ FALSE] RETURNS [data: LizardCache.Word, status: LizardCache.TrapIndex, rejectCycles: INT] -- Lizard.CacheFetchProc -- = BEGIN sim: LizardSimulation = NARROW[base.data]; [data: data, status: status, rejectCycles: rejectCycles] _ sim.euCache.fetch[base: sim.euCache, addr: addr, cycle: cycle, noEffect: noEffect]; sim.lastInstrOps _ CONS[ NEW[Dragon.CacheTransRec _ [ instr: sim.processor.stats.instructions, cmd: Fetch, -- might be FetchHold, we can't tell here addr: DragOpsCrossUtils.WordToCard[addr], data: DragOpsCrossUtils.WordToCard[data], fault: SELECT status FROM ALUCondFalse => none, EUPageFault => page, EUWriteFault => write, ENDCASE => ERROR ]], sim.lastInstrOps]; END; LizardEUCacheStoreTrap: PROC [base: LizardCache.CacheBase, addr: LizardCache.Word, data: LizardCache.Word, cycle: INT] RETURNS [old: LizardCache.Word, status: LizardCache.TrapIndex, rejectCycles: INT] -- Lizard.CacheStoreProc -- = BEGIN sim: LizardSimulation = NARROW[base.data]; [old: old, status: status, rejectCycles: rejectCycles] _ sim.euCache.store[base: sim.euCache, addr: addr, data: data, cycle: cycle]; sim.lastInstrOps _ CONS[ NEW[Dragon.CacheTransRec _ [ instr: sim.processor.stats.instructions, cmd: Store, addr: DragOpsCrossUtils.WordToCard[addr], data: DragOpsCrossUtils.WordToCard[data], fault: SELECT status FROM ALUCondFalse => none, EUPageFault => page, EUWriteFault => write, ENDCASE => ERROR ]], sim.lastInstrOps]; END; NoteChangedReg: PROC [data: REF, processor: LizardHeart.Processor, reg: DragOpsCross.ProcessorRegister, old,new: DragOpsCross.Word] -- LizardHeart.RegChangeProc -- = BEGIN sim: LizardSimulation = NARROW[data]; sim.lastInstrOps _ CONS[ NEW[Dragon.RegStoreRec _ [ instr: sim.processor.stats.instructions, reg: reg, data: DragOpsCrossUtils.WordToCard[new] ]], sim.lastInstrOps]; END; NoteInstDone: PROC [data: REF, processor: LizardHeart.Processor, newPC, rtnPC: DragOpsCross.Word, control: LizardHeart.Control, cycles: INT] -- LizardHeart.InstDoneProc -- = BEGIN sim: LizardSimulation = NARROW[data]; sim.control _ control; END; StartNewLizard: PUBLIC PROC [ m: REF -- CacheOps.VM -- ] RETURNS [ sim: LizardSimulation ] = BEGIN StoreWord: PROC [ addr, data: Dragon.Word, readOnly, dirty: BOOL _ FALSE, privateData: REF _ NIL ] = {SparseMemory.Store[base: lizardVM, index: DragOpsCrossUtils.CardToWord[addr], new: DragOpsCrossUtils.CardToWord[data]]}; lizardVM: SparseMemory.Base; lizardSharedVM: LizardCache.SharedBase; sim _ NEW[LizardSimulationRec]; lizardVM _ SparseMemory.Create[]; lizardSharedVM _ LizardCache.NewBase[lizardVM]; CacheOps.EnumerateVirtualMemory[m, StoreWord]; -- initialize Lizard's memory sim.euCache _ LizardCache.NewCache[lizardSharedVM]; sim.processor _ LizardHeart.NewProcessor[ ifuCache: LizardCache.NewCache[lizardSharedVM], euCache: NEW[LizardCache.CacheBaseRep _ [ fetch: LizardEUCacheFetchTrap, store: LizardEUCacheStoreTrap, data: sim ]], logger: NEW[LizardHeart.ChangeLoggerRep _ [ data: sim, regChange: NoteChangedReg, instDone: NoteInstDone ]] ]; END; SuccessHalt: PUBLIC ERROR = CODE; Breakpoint: PUBLIC SIGNAL = CODE; CheckSynch: PUBLIC PROC [ data: OpaqueKitchenSink, basicInst: IFU2.BasicInst ] RETURNS [deltaInstrCount: INT _ 1] -- IFU2.CheckSynchProc -- = BEGIN retry: BOOL _ TRUE; WHILE retry DO retry _ FALSE; deltaInstrCount _ csProcRec.proc[data: data, basicInst: basicInst ]; -- debugger might set retry to TRUE NULL; -- for breakpoints and what-have-you ENDLOOP; END; DefaultCheckSynch: PUBLIC IFU2.CheckSynchProc = {RETURN[1]}; csProcRec: PUBLIC CSProcRec _ [DefaultCheckSynch]; StartPanel: PROC [ks: KitchenSink] = { IF ks.controlPanel = NIL THEN { ks.controlPanel _ NEW[ControlPanelRec _ [ msg: "Initialized...", enaIFULog: TRUE, diagnostic: ks.diagnostics ]]; ViewRec.SetBehavior[newBehavior: [delayParms: [min: 2000.0]]]; [] _ ViewRec.ViewRef[ agg: ks.controlPanel, label: "Dragon Cluster2 Rosemary5 Control Panel", specs: LIST[ ["cycle", Value[val:NIL, visible:TRUE, dontAssign:TRUE]], ["phase", Value[val:NIL, visible:TRUE, dontAssign:TRUE]], ["instrCount", Value[val:NIL, visible:TRUE, dontAssign:TRUE]] ]]; }; }; END.} "Cluster2Impl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. McCreight, May 13, 1986 2:28:33 pm PDT Louis Monier April 18, 1986 9:58:08 am PST Barth, April 28, 1986 4:25:45 pm PDT Curry, August 22, 1986 9:40:44 am PDT and implicitly the MBus -- Main body of Inner Κ7˜šœ™Jšœ Οmœ1™˜>šœžœ˜ Jšœ$˜$Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜—šœ,˜,šœ žœžœ˜'JšœD˜DJšœ˜—Jšœžœ˜ Jšœ˜—šœ+˜+šœ˜šœžœ˜.Jšœžœ˜4Jšœ˜Jšœ˜—J˜J˜—Jšœžœ˜ Jšœ˜—˜Jšœ˜Jšœ˜Jšœ žœR˜aJšœ˜Jšœ˜—J˜KšœK˜KKšœK˜KKšœN˜NKšœN˜NJ˜Kšœq˜qKšœs˜sš žœžœžœ žœžœžœž˜KKšœl˜lJšžœ˜J˜—Jšœ7˜7šœ6˜6Jšœ˜Jšœ˜Jšœ žœ ˜Jšœ˜—J˜šžœžœ ž˜#Jšœ+˜+JšœX˜XJšžœ˜J˜—šžœžœžœž˜!šœ˜Jšœžœ˜5Jšœžœ˜Jšœžœ˜Jšœžœ˜ —Jšžœ˜J˜—Jšœžœ˜(Jšœ?˜?J˜šžœžœ˜Kšœ2˜2Kšœ?žœ˜EKšœ>žœ˜DKšœUžœ˜qJšœžœ˜2Jšœ.˜.Kšœ…˜…Kšœ%žœ˜,K˜—K˜Jšœ˜Jšžœ˜J˜—Jšœžœ˜%J˜š  œžœžœžœ žœžœžœ˜OJšž˜šžœžœž˜šœ žœžœ˜Jšœv˜v—Jšžœžœ˜—Jšžœ˜J˜—š   œžœžœžœ žœ˜JJšž˜Jšœžœžœ ˜)Jšžœ˜J˜—š œž œžœ žœ˜XJšž˜Jšœ˜šœ&˜&šœžœžœ&˜5Jšžœžœžœžœ˜—Jšœ˜—Jšœ(žœ˜.Jšžœ˜J˜—š   œž œžœžœ žœ˜RJšœu˜uJ˜—š   œžœžœ$žœžœ˜GJšž˜Jšœ;˜;Jšœžœ ˜&šœ˜šžœžœ˜Jšœ.žœ˜GJšœ˜Jšœ*˜*J˜——š œžœ˜Jšœ(žœ˜.šžœžœ˜!Jšœ:˜:Jšœ3˜3Jšœ˜—šœ&˜&šœžœžœ&˜5Jšžœžœžœžœ˜—Jšœ˜—šžœžœ˜Kšœv˜vKšœQ˜QKš œ3žœžœžœžœžœ,žœ˜¬Kšœ)˜)Kšœ}˜}K˜—Jšžœžœ!˜>Jšœ˜Jšœ(ž˜-Jšœ˜J˜—š œžœžœ˜Jš œžœžœžœžœžœ˜3—J˜š œžœžœ˜$Jšœ˜Jšœžœ˜ Jšœ ˜ Jšžœžœ*žœ˜RJšœ!˜!Jšœ ˜ Jšœ˜J˜—š œžœ˜#Jšœžœžœ˜Jšœ˜šžœžœž˜-Jšœ˜Jšœ˜šžœžœ˜!Jšœ!˜!Jšœ ˜ J˜—Jšžœ žœ"žœ$žœ˜tšžœžœ˜šžœ9ž˜=šœžœ?ž˜_Jšœž˜!—šœžœ ˜)Jš žœžœžœžœžœ˜B——Jšœ˜—šžœžœ&˜4Jš žœžœžœžœžœ˜B—J˜šžœžœŸ˜+Jšœ*˜*š žœžœž œžœž˜,Jšœ˜Jšžœ˜—Jšœ ˜ Jšœ ˜ Jšžœžœžœžœ˜\Jšžœ žœžœžœ˜^Jšžœžœžœžœ˜jJšžœžœžœžœ˜jJšœ˜Jšœžœ˜J˜—J˜Jšœžœ˜Jšœžœ˜Jšœ ˜ Jšžœ˜—šœžœžœž˜(Jšœ˜Jšœžœh˜oJšœ3˜3Jšžœ˜ —J˜—J˜šœ™J˜Jšœ2˜2Jš œžœ žœžœ žœ ˜CJšœ,˜,Jšœžœ˜šžœŸ˜J˜š  œžœžœžœžœ˜5Jšž˜Jš œ žœžœžœžœ˜8Jšœžœ žœžœ˜KJšœ;˜;Jšžœ˜J˜—Jšœžœ!˜>J˜šžœ%ž˜)šœ5žœž˜?Jšœ˜—Jšžœžœ˜ —J˜Jšœžœ˜J˜šžœžœŸ7˜VJ˜Jšœžœžœ˜&Jšœ8žœ˜>Jšœ˜Jšœ!˜!J˜šœ˜Jšœ&˜&JšœAžœ˜GJšœAžœ˜GJšœ>žœ˜DJšœF˜FJšœ<žœ˜BJšœ<žœ˜BJšœ=žœ˜CJšœ=žœ˜CJšœ=žœ˜CJ˜—J˜šžœžœžœž˜šœ˜Jšœ"žœ˜)Jš œžœžœžœžœžœžœ˜\Jšœžœ˜!Jšœ˜—šœ˜Jšœ"žœ˜)Jš œžœžœžœžœžœžœ˜\Jšœžœ˜!Jšœ˜—Jšžœ˜—J˜ J˜Jšžœžœž˜˜šœžœ˜Jšž˜Jšœ;˜;Jš œžœžœžœžœ˜YJšžœ˜J˜—šœ˜Jšž˜Jšœžœ"žœ"˜YJšœ˜Jš œžœžœžœžœ˜YJšžœ˜J˜—šžœžœ˜J˜——Jšœžœ˜Jšœ˜JšžœžœžœŸ˜>Jšœ˜JšžœžœžœŸ˜>J˜Jšžœ"žœ'˜OJ˜Jšœ˜Jšœžœ˜J˜šœJ˜JJšžœ˜ Jšžœ˜—J˜šžœžœ9ž˜`J˜šžœ˜šœ˜šœG˜GJšžœ˜ Jšžœ˜Jšžœ!˜#Jšžœ˜—Jšžœ˜Jšœ˜—šœ˜šœJ˜JJšžœ˜ Jšžœ˜Jšžœ!˜#Jšžœ˜—šžœžœž˜Jšœ%žœ˜,Jšœžœžœ˜#Jšžœžœ˜—Jšœ˜—J˜J˜—Jšœ˜JšžœžœžœŸ˜>Jšœ˜šžœžœžœŸ˜>J˜—Jšœ0˜0JšžœŸ˜$—J˜JšžœŸ˜"J˜—šžœžœž˜šœžœ˜Jšž˜Jšœžœ˜J˜šžœ!ž˜'Jšœ7˜7—Jšžœ˜—šœ!˜!Jšœ:˜:—Jšžœžœ˜J˜—JšžœŸ1˜:—JšœŸ˜—Jšœ(˜(Jšžœ˜J˜J˜—š œžœžœžœ˜BJšž˜Jšœžœ˜Jšžœ ˜Jšžœ˜J˜J˜—š œžœžœ žœ˜CJšž˜Jšœžœ˜Jšžœ˜!Jšžœ˜J˜—š   œžœ žœžœ&Ÿœ˜dJšž˜Jšœžœ˜Jšœžœžœ?žœ)˜‡Jšžœ˜J˜J˜—Jšœ%˜%Jšœžœ˜6J˜Jš œžœ˜4˜š œžœ˜)Jšž˜Jšœ˜JšœAžœžœ žœ˜jJšœL˜Lšžœžœž˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšžœžœ˜—JšœK˜KJšœ˜Jšžœ˜J˜—Jšœ*˜*J˜Jšœ8˜8šœ&˜&Jšœ"˜"Jšœ)˜)Jšœ˜Jšœ˜Jšœ˜—Jšœ*Ÿ'˜QJšœ˜—J˜J˜š œžœ>žœ žœžœžœGžœŸœ˜ηJšž˜Jšœžœ ˜*J˜šœ:˜:JšœS˜SJ˜—šœžœ˜šžœ˜Jšœ(˜(Jšœ Ÿ)˜5Jšœ)˜)Jšœ)˜)šœžœž˜Jšœ˜Jšœ˜Jšœ˜Jšžœž˜—Jšœ˜—Jšœ˜J˜—Jšžœ˜J˜—Jš œžœVžœ˜všžœFžœŸœ˜oJšž˜Jšœžœ ˜*J˜šœ8˜8JšœK˜KJ˜—šœžœ˜šžœ˜Jšœ(˜(Jšœ ˜ Jšœ)˜)Jšœ)˜)šœžœž˜Jšœ˜Jšœ˜Jšœ˜Jšžœž˜—Jšœ˜—Jšœ˜J˜—Jšžœ˜J˜—J˜š œžœžœeŸœ˜₯Jšž˜Jšœžœ˜%šœžœ˜šžœ˜Jšœ(˜(Jšœ ˜ Jšœ'˜'Jšœ˜—Jšœ˜—J˜Jšžœ˜J˜J˜—š   œžœžœkžœŸœ˜­Jšž˜Jšœžœ˜%Jšœ˜Jšžœ˜J˜J˜—š  œžœžœžœŸœžœ˜\Jšž˜J˜š   œžœ-žœžœžœžœ˜dJšœy˜yJ˜—Jšœ˜Jšœ'˜'J˜Jšœžœ˜J˜Jšœ!˜!Jšœ/˜/Jšœ/Ÿ˜LJ˜Jšœ3˜3J˜šœ)˜)Jšœ/˜/šœ žœ˜)Jšœ˜Jšœ˜Jšœ ˜ Jšœ˜—šœžœ ˜+Jšœ ˜ Jšœ˜Jšœ˜J˜—Jšœ˜J˜—Jšžœ˜J˜J˜—Jšœ žœžœžœ˜!Jšœ žœžœžœ˜!J˜š   œžœžœ8žœžœŸœ˜ŽJšž˜Jšœžœžœ˜šžœž˜Jšœžœ˜JšœEŸ#˜hJšžœŸ$˜*Jšžœ˜—Jšžœ˜—J˜šœžœ˜0Jšœžœ˜ J˜—Jšœ žœ!˜2J˜š  œžœ˜&šžœžœžœ˜šœžœ˜*Jšœ˜Jšœ žœ˜Jšœ˜Jšœ˜—Jšœ>˜>šœ˜Jšœ˜šœ9žœ˜>Jšœžœ žœ žœ˜9Jšœžœ žœ žœ˜9Jšœžœ žœ žœ˜=—Jšœ˜—J˜—šœ˜J˜——Jšžœ˜J˜—J˜—…—NheΑ