-- File [Indigo]<Sakura>Dragon>DragonMemoryImpl.sak
--  5-Mar-82 13:03:21 

DIRECTORY
  DragonCache: TYPE, 
  DragonMemory: TYPE, 
  SakuraRT: TYPE;

DragonMemoryImpl: MONITOR
  IMPORTS SakuraRT
  EXPORTS DragonMemory
  
  = BEGIN
  Memory: PUBLIC PROC
       [ClockA, ClockB, CMDIn, SharedIn: SakuraRT.Handle, MDataIn: SakuraRT.Handle, 
        MDataOut: SakuraRT.Handle] = {
    CalcData: PROC [rp: LONG CARDINAL, bl: INTEGER [0..37B], word: INTEGER [0..3]]
                   RETURNS [LONG CARDINAL] = {
      ret: LONG CARDINAL ← rp * 40B * 4B + bl * 4B + word;
      ret ← 37777777777B - ret; 
      RETURN [ret]};
    {ENABLE {ABORTED => GO TO Aborted};
     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 => 
               SELECT m.command 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[ClockB, TRUE]; NULL; 
                    SakuraRT.GetNew[ClockA, TRUE]; NULL; 
                    SakuraRT.GetNew[ClockB, 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[ClockB, TRUE]; NULL; 
                    SakuraRT.GetNew[ClockA, TRUE]; NULL; 
                    SakuraRT.Put[MDataOut, NEW
                      [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 1) MOD 
                                                               4]]]]]; 
                    SakuraRT.GetNew[ClockB, TRUE]; NULL; 
                    SakuraRT.GetNew[ClockA, TRUE]; NULL; 
                    SakuraRT.Put[MDataOut, NEW
                      [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 2) MOD 
                                                               4]]]]]; 
                    SakuraRT.GetNew[ClockB, TRUE]; NULL; 
                    SakuraRT.GetNew[ClockA, TRUE]; NULL; 
                    SakuraRT.Put[MDataOut, NEW
                      [DragonCache.MbusType ← [Data[CalcData[rp, bl, (word + 3) MOD 
                                                               4]]]]]};
                 WriteQuad => ERROR;
                 WriteSingle => NULL;
                 NotReady => ERROR;
                 ReadMap => NULL;
                 DoMapOp => NULL;
                 SetRpDirty => NULL;
                 MapOpDone => NULL
                 ENDCASE;
             MapCommand => 
               SELECT m.command FROM 
                 ReadMap => NULL;
                 ReadQuad => ERROR;
                 MapOpDone => NULL
                 ENDCASE => ERROR;
             Data => ERROR
             ENDCASE => ERROR
        ENDLOOP; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.AbortAll[]};
  
  END.