-- File: [Indigo]<Sakura>Dragon>DragonProcessorImpl2.sak
-- Dragon processor with random fetch
--  8-Mar-82 12:37:45

DIRECTORY
  DragonCache,
  DragonProcessor,
  RandomCard,
  SakuraRT,
  SimIO;
  
DragonProcessorImpl2: MONITOR
  IMPORTS 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 {
      Fetch: PROC [loc: 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 ← Fetch;
	  OutData ← [Instruction[vp, bl, word]]};
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	SimIO.WF1["  Fetch started %ld*n", @printval];
	WHEN ClockB UP: RQ ← FALSE;
	SimIO.WF1["  Fetch finished %ld*n", @printval]};
      
      FetchAndRead: PROC [loc, prevloc: CARDINAL] = {
        vp: LONG CARDINAL;
	bl: [0..37B];
	word: [0..3];
	printval: LONG CARDINAL;
	data: LONG CARDINAL;
	[vp, bl, word] ← SplitAddress[loc];
	printval ← word+bl*4+vp*128;
	data ← 37777777777B - prevloc;
	RQ ← TRUE;
	Op ← Fetch;
	OutData ← [Instruction[vp, bl, word]];
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	SimIO.WF1["  Fetch started %ld*n", @printval];
	WHEN ClockB UP: {
	  SakuraRT.Delay[30];
	  WITH b: InData SELECT FROM
	    Data => IF data # b.data THEN ERROR;
	    ENDCASE => ERROR;
	  RQ ← FALSE};
	SimIO.WF1["  Fetch finished %ld*n", @printval]};
      
      Read: PROC [prevloc: CARDINAL] = {
	data: LONG CARDINAL;
	data ← 37777777777B - prevloc;
	DO
	  WHEN ClockA UP: IF ~Reject THEN EXIT;
	  ENDLOOP;
	WHEN ClockB UP: SakuraRT.Delay[30];
	WITH b: InData SELECT FROM
	    Data => IF data # b.data THEN ERROR;
	    ENDCASE => ERROR};
      
      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;
      
      RQ ← FALSE;
      WHEN ClockB UP: NULL;
      WHEN ClockB UP: NULL;
      [ ] ← RandomCard.InitRandom[-1];
      prevloc ← RandomCard.Choose[0,2000];
      Fetch[prevloc];
      THROUGH [0..300] DO
        loc ← RandomCard.Choose[0,2000];
	FetchAndRead[loc, prevloc];
	prevloc ← loc;
	ENDLOOP;
      Read[prevloc];
      SimIO.WF0["++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"];
      }
    };
    
  }.