-- 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.