-- File: [Indigo]<Sakura>Dragon>DragonProcessorImpl.sak
-- Dragon processor
--  7-Mar-82 21:35:36

DIRECTORY
  DragonCache: TYPE, 
  DragonProcessor: TYPE, 
  SakuraRT: TYPE, 
  SimIO: TYPE;

DragonProcessorImpl: MONITOR
  IMPORTS SakuraRT, SimIO
  EXPORTS DragonProcessor
  
  = BEGIN
  Processor: PUBLIC PROC
       [ClockA, ClockB, Fault, Reject: SakuraRT.Handle, InData: SakuraRT.Handle, 
        Op: SakuraRT.Handle, RQ: SakuraRT.Handle, OutData: SakuraRT.Handle] = {
    Fetch: PROC [vp: LONG CARDINAL, bl: INTEGER [0..37B], word: INTEGER [0..3]] = {
      printval: LONG CARDINAL ← word + bl * 4 + vp * 128;
      SakuraRT.GetNew[ClockB, TRUE];
       {SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]]; 
        SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Fetch]]; 
        SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]]}; 
      DO SakuraRT.GetNew[ClockA, TRUE];
          IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
         ENDLOOP; 
      SimIO.WF1["  Fetch started %ld*n", @printval]; 
      SakuraRT.GetNew[ClockB, TRUE]; SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]]; 
      SimIO.WF1["  Fetch finished %ld*n", @printval]}; 
    
    Store: PROC
         [vp: LONG CARDINAL, bl: INTEGER [0..37B], word: INTEGER [0..3], 
          data: LONG CARDINAL] = {
      printval: LONG CARDINAL ← word + bl * 4 + vp * 128;
      SakuraRT.GetNew[ClockB, TRUE];
       {SakuraRT.Put[RQ, NEW[BOOLEAN ← TRUE]]; 
        SakuraRT.Put[Op, NEW[DragonCache.PbusOp ← Store]]; 
        SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Instruction[vp, bl, word]]]]}; 
      DO SakuraRT.GetNew[ClockA, TRUE];
          IF NOT NARROW[SakuraRT.Get[Reject], REF BOOLEAN]↑ THEN EXIT
         ENDLOOP; 
      SimIO.WF1["    Store started %ld*n", @printval]; 
      SakuraRT.GetNew[ClockB, TRUE];
       SakuraRT.Put[OutData, NEW[DragonCache.PbusType ← [Data[data]]]]; 
      -- Match
      SakuraRT.GetNew[ClockB, TRUE]; SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]]; 
      SimIO.WF1["    Store finished %ld*n", @printval]};
    
    {ENABLE {ABORTED => GO TO Aborted};
     SakuraRT.Put[RQ, NEW[BOOLEAN ← FALSE]]; 
     SakuraRT.GetNew[ClockB, TRUE]; NULL; 
     SakuraRT.GetNew[ClockB, TRUE]; NULL; 
     Fetch[0, 0, 1]; 
     Fetch[0, 0, 2]; 
     Fetch[0, 0, 3]; 
     Fetch[0, 1, 0]; 
     Store[0, 1, 3, 7]; 
     Store[0, 2, 1, 9]; 
     Store[0, 0, 2, 2]; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.AbortAll[]};
  
  END.