-- File: [Indigo]<Sakura>Dragon>DragonProcessorImpl4.sak
-- Dragon processor with random fetch
-- 10-Mar-82 11:24:06

DIRECTORY
  DragonCache,
  DragonProcessor,
  RandomCard,
  SakuraRT,
  SimIO;
  
DragonProcessorImpl4: MONITOR
  IMPORTS DragonCache, RandomCard, SakuraRT, SimIO 
  EXPORTS DragonProcessor = {

  Processor: PUBLIC DEVICE = {
    IN ClockA, ClockB, Fault, Reject: BOOLEAN, InData: DragonCache.PbusType
    OUT Op: DragonCache.PbusOp, RQ: BOOLEAN, OutData: DragonCache.PbusType
    GUARDIAN {}
    CONTROL {
      
      Store: PROC [loc: CARDINAL, data: LONG CARDINAL]= {
        vp: LONG CARDINAL;
	bl: [0..37B];
	word: [0..3];
	printval: LONG CARDINAL;
	[vp, bl, word] ← SplitAddress[loc];
	printval ← word+bl*4+vp*128;
	WHEN ClockB UP: {
	  RQ ← TRUE;
	  Op ← Store;
	  OutData ← [Instruction[vp, bl, word]]};
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	SimIO.WF1["    Store started %ld*n", @printval];
	WHEN ClockB UP: OutData ← [Data[data]]; -- Match
	WHEN ClockB UP: RQ ← FALSE;
	SimIO.WF1["    Store finished %ld*n", @printval]};
      
      StoreAndRead: PROC [loc, prevloc: CARDINAL, data, 
          prevdata: LONG CARDINAL] = {
        vp, prevvp: LONG CARDINAL;
	bl, prevbl: [0..37B];
	word, prevword: [0..3];
	printval: LONG CARDINAL;
	[vp, bl, word] ← SplitAddress[loc];
	printval ← word+bl*4+vp*128;
	WHEN ClockB UP: {
	  RQ ← TRUE;
	  Op ← Store;
	  OutData ← [Instruction[vp, bl, word]]};
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
	SakuraRT.Delay[40];
	DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata];
	SimIO.WF1["    Store started %ld*n", @printval];
	WHEN ClockB UP: OutData ← [Data[data]]; -- Match
	WHEN ClockB UP: RQ ← FALSE;
	SimIO.WF1["    Store finished %ld*n", @printval]};
      
      Read: PROC [prevloc: CARDINAL, prevdata: LONG CARDINAL] = {
        prevvp: LONG CARDINAL;
	prevbl: [0..37B];
	prevword: [0..3];
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
	SakuraRT.Delay[40];
	DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata]};
       
      SplitAddress: PROC [loc: CARDINAL] RETURNS [vp: LONG CARDINAL, 
        bl: [0..37B], word: [0..3]] = {
	word ← loc MOD 4;
	loc ← loc / 4;
	bl ← loc MOD 40B;
	vp ← loc / 40B};
	  
      loc, prevloc: CARDINAL;
      data, prevdata: LONG CARDINAL;
      
      RQ ← FALSE;
      WHEN ClockB UP: NULL;
      WHEN ClockB UP: NULL;
      [ ] ← RandomCard.InitRandom[-1];
      prevloc ← RandomCard.Choose[0,3777B];
      prevdata ← RandomCard.Random[]*200000B + RandomCard.Random[];
      Store[prevloc, prevdata];
      THROUGH [0..300] DO
        loc ← RandomCard.Choose[0,3777B];
	data ← RandomCard.Random[]*200000B + RandomCard.Random[];
        StoreAndRead[loc, prevloc, data, prevdata];
	prevloc ← loc;
	prevdata ← data;
	ENDLOOP;
      Read[prevloc, prevdata];
      SimIO.WF0["++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"];
      }
    };
    
  }.