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

DIRECTORY
  DragonCache,
  DragonMemory,
  SakuraRT;
  
DragonMemoryImpl: MONITOR 
  IMPORTS SakuraRT
  EXPORTS DragonMemory = {

Memory: PUBLIC DEVICE = {
  IN ClockA, ClockB, CMDIn, SharedIn: BOOLEAN, MDataIn: DragonCache.MbusType
  OUT MDataOut: DragonCache.MbusType
  GUARDIAN {}
  CONTROL {
    CalcData: PROC [rp: LONG CARDINAL, bl: [0..37B], word: [0..3]] 
      RETURNS [LONG CARDINAL] = {
      ret: LONG CARDINAL ← rp*40B*4B + bl*4B + word;
      ret ← 37777777777B - ret;
      RETURN[ret]};
    DO
      WHEN ClockB UP: NULL;
      IF CMDIn THEN
        WITH m: MDataIn SELECT FROM
          Instruction =>  
  	    SELECT m.command FROM  
	      ReadQuad => {
	        rp: LONG CARDINAL ← m.rp;
		bl: [0..37B] ← m.bl;
		word: [0..3] ← m.word;
		WHEN ClockA UP: NULL;
		WHEN ClockB UP: NULL;
		WHEN ClockA UP: NULL;
		WHEN ClockB UP: NULL;
		WHEN ClockA UP: NULL;
		IF SharedIn THEN LOOP;
		MDataOut ← [Data[CalcData[rp, bl, word]]];
		WHEN ClockB UP: NULL;
		WHEN ClockA UP: NULL;
		MDataOut ← [Data[CalcData[rp, bl, (word+1) MOD 4]]];
		WHEN ClockB UP: NULL;
		WHEN ClockA UP: NULL;
		MDataOut ← [Data[CalcData[rp, bl, (word+2) MOD 4]]];
		WHEN ClockB UP: NULL;
		WHEN ClockA UP: NULL;
		MDataOut ← [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}
};
  
}.