-- File [Indigo]<Sakura>Dragon>DragonMemoryImpl2.sak -- 23-Mar-82 12:46:13 DIRECTORY DragonCache: TYPE, DragonMemory: TYPE, SakuraRT: TYPE; DragonMemoryImpl2: MONITOR IMPORTS SakuraRT EXPORTS DragonMemory = BEGIN MaxMem: CARDINAL = 4000B; MemType: TYPE = ARRAY INTEGER [0..MaxMem) OF LONG CARDINAL; Mem: REF MemType ← NEW[MemType]; Memory: PUBLIC PROC [ClockA, ClockB, CMDIn, SharedIn: SakuraRT.Handle, MDataIn: SakuraRT.Handle, MDataOut: SakuraRT.Handle] = { i: CARDINAL; CalcData: PROC [rp: LONG CARDINAL, bl: INTEGER [0..37B], word: INTEGER [0..3]] RETURNS [ret: LONG CARDINAL] = { ret ← rp * 40B * 4B + bl * 4B + word; ret ← Mem[ret]}; ReadDataFromBus: PROC RETURNS [LONG CARDINAL] = { WITH b: NARROW[SakuraRT.Get[MDataIn], REF DragonCache.MbusType]↑ SELECT FROM Data => RETURN [b.data] ENDCASE => ERROR}; {ENABLE {ABORTED => GO TO Aborted}; FOR i IN [0..MaxMem) DO Mem[i] ← i * 2 ENDLOOP; DO SakuraRT.GetNew[ClockB, TRUE]; NULL; IF NARROW[SakuraRT.Get[CMDIn], REF BOOLEAN]↑ THEN WITH m: NARROW[SakuraRT.Get[MDataIn], REF DragonCache.MbusType]↑ SELECT FROM Instruction => {mcom: DragonCache.MbusCommand ← m.command; SELECT mcom FROM ReadQuad => {rp: LONG CARDINAL ← m.rp; bl: INTEGER [0..37B] ← m.bl; word: INTEGER [0..3] ← m.word; SakuraRT.GetNew[ClockA, TRUE]; NULL; SakuraRT.GetNew[ClockA, TRUE]; NULL; SakuraRT.GetNew[ClockA, TRUE]; NULL; IF NARROW[SakuraRT.Get[SharedIn], REF BOOLEAN]↑ THEN LOOP; SakuraRT.Put[MDataOut, NEW [DragonCache.MbusType ← [Data[CalcData[rp, bl, word]]]]]; SakuraRT.GetNew[ClockA, TRUE]; NULL; SakuraRT.Put[MDataOut, NEW [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 1) MOD 4]]]]]; SakuraRT.GetNew[ClockA, TRUE]; NULL; SakuraRT.Put[MDataOut, NEW [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 2) MOD 4]]]]]; SakuraRT.GetNew[ClockA, TRUE]; NULL; SakuraRT.Put[MDataOut, NEW [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 3) MOD 4]]]]]}; WriteQuad => {rp: LONG CARDINAL ← m.rp; bl: INTEGER [0..37B] ← m.bl; word: INTEGER [0..3] ← m.word; ra: LONG CARDINAL ← rp * 40B * 4B + bl * 4B + word; SakuraRT.GetNew[ClockB, TRUE]; Mem[ra] ← ReadDataFromBus[]; SakuraRT.GetNew[ClockB, TRUE]; Mem[ra + 1] ← ReadDataFromBus[]; SakuraRT.GetNew[ClockB, TRUE]; Mem[ra + 2] ← ReadDataFromBus[]; SakuraRT.GetNew[ClockB, TRUE]; Mem[ra + 3] ← ReadDataFromBus[]}; WriteSingle => NULL; NotReady => ERROR; ReadMap => NULL; ReadMapAndSetRpDirty => NULL; DoMapOp => NULL; SetRpDirty => NULL; MapOpDone => NULL ENDCASE => ERROR}; MapCommand => SELECT m.command FROM ReadMap => NULL; ReadMapAndSetRpDirty => NULL; MapOpDone => NULL ENDCASE => ERROR; Data => ERROR ENDCASE => ERROR ENDLOOP; SakuraRT.ProcessEnd[]} EXITS Aborted => SakuraRT.Abort[]}; END.