-- NewPadsDriver.sak
-- last edited by Suzuki: 20-Jan-82 16:53:33

DIRECTORY
  SakuraRT: TYPE, 
  NewPads: TYPE, 
  SimIO: TYPE;

NewPadsDriver: MONITOR
  IMPORTS SakuraRT, NewPads, SimIO
  
  = BEGIN
  PadsDriver: PROC
       [Clock: SakuraRT.Handle, AIn, BIn: SakuraRT.Handle, 
        EnableIn, EqualIn: SakuraRT.Handle, AOut, BOut: SakuraRT.Handle, 
        EnableOut, EqualOut: SakuraRT.Handle] = {
    Power: PROC [left, exponent: CARDINAL] RETURNS [ret: CARDINAL] = {
      ret ← 1; 
      THROUGH [0..exponent) DO
          ret ← ret * left
          ENDLOOP}; 
    Print: PROC [en, eq: CARDINAL, a, b: CARDINAL] = {
      SimIO.WF4["Enable = %d*nEqual = %d*nA = %d,  %d*n", en, eq, a, a]; 
      SimIO.WF2["B = %d,  %d*n", b, b]}; 
    Step: PROC [aOrB, out, enable: CARDINAL] = {
      SakuraRT.GetNewChange[Clock]; criticalSection4[]; 
      IF aOrB = 1 
         THEN SakuraRT.Put[AOut, NEW[CARDINAL ← out]] 
         ELSE SakuraRT.Put[BOut, NEW[CARDINAL ← out]]; 
      SakuraRT.Put[EnableOut, NEW[CARDINAL ← enable]]}; 
    UpAndDown: PROC [out, enable: CARDINAL] = {
      Step[enable, out, 0]; 
      Step[enable, out, enable]; 
      Step[enable, out, 0]}; 
    Enable: PROC [enable: CARDINAL] = {
      FOR i: NAT IN [0..8) DO
          UpAndDown[0, enable]; 
          UpAndDown[Power[2, i], enable]; 
          Step[enable, 0, 0]; 
          Step[enable, 0, enable]
          ENDLOOP}; 
    criticalSection4: ENTRY PROC = {
      Print
        [NARROW[SakuraRT.Get[EnableIn], REF CARDINAL]↑, 
         NARROW[SakuraRT.Get[EqualIn], REF CARDINAL]↑, 
         NARROW[SakuraRT.Get[AIn], REF CARDINAL]↑, 
         NARROW[SakuraRT.Get[BIn], REF CARDINAL]↑]}; 
    
    criticalSection5: ENTRY PROC = {
      {SakuraRT.Put[EnableOut, NEW[CARDINAL ← 0]]; 
       SakuraRT.Put[EqualOut, NEW[CARDINAL ← 0]]; 
       SakuraRT.Put[AOut, NEW[CARDINAL ← 0]]; 
       SakuraRT.Put[BOut, NEW[CARDINAL ← 0]]; 
       SakuraRT.Delay[10]}};
    {ENABLE {ABORTED => GO TO Aborted};
     SakuraRT.GetNewChange[Clock]; criticalSection5[]; 
     Enable[1]; 
     Enable[2]; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.ProcessEnd[]}; 
  
  ClockDriver: PROC [Clock: SakuraRT.Handle] = {
    {ENABLE {ABORTED => GO TO Aborted};
     DO SakuraRT.Put[Clock, NEW[BOOLEAN ← TRUE]]; 
        SakuraRT.Delay[20]
        ENDLOOP; 
     SakuraRT.ProcessEnd[]}
    EXITS
      Aborted => SakuraRT.ProcessEnd[]};
  
  SimIO.Start[]; 
  {a: SakuraRT.Handle ← SakuraRT.Create[]; 
   b: SakuraRT.Handle ← SakuraRT.Create[]; 
   c: SakuraRT.Handle ← SakuraRT.Create[]; 
   en: SakuraRT.Handle ← SakuraRT.Create[]; 
   eq: SakuraRT.Handle ← SakuraRT.Create[]; 
   cl, pd, pi: PROCESS; 
   SakuraRT.IncCurrent[];cl ← FORK ClockDriver[Clock: c]; 
   SakuraRT.IncCurrent[];
   pd ← FORK PadsDriver[Clock: c, AIn: a, BIn: b, EnableIn: en, EqualIn: eq, 
                        AOut: a, BOut: b, EnableOut: en, EqualOut: eq]; 
   SakuraRT.IncCurrent[];
   pi ← FORK NewPads.PadsFunc[Clock: c, A: a, B: b, Enable: en, Equal: eq]; 
   [] ← JOIN cl; [] ← JOIN pd; [] ← JOIN pi}; 
  SimIO.Stop[]
  
  END.