(**********************************************************************

    :Program.  	 Interface.mod
    :Author.   	 Norbert Klapczynski
    :Address.    Kochelseestr. 9, D8900 Augsburg 1
    :Phone.      0821/662825
    :shortcut. 	 [kla]
    :Version.  	 1.0   
    :Date.     	 29.11.88
    :Copyright.  Public Domain (siehe ReadMe)
    :Language. 	 Modula-II
    :Translator. M2Amiga AMSoft
    :Update	 
    :Contents.	 Easy controling of Fischertechnik at parallelport
    :Remark.	 Copy and use it but please leave my name in, thanks.
    
**********************************************************************)

IMPLEMENTATION MODULE Interface;


FROM Arts   IMPORT  TermProcedure,Assert;
FROM Exec   IMPORT  Enable, Disable;
FROM SYSTEM IMPORT  ADR;

TYPE  Channels   = ( LOut,LIn,DOut,Clk,TX,TY,unused1,unused2 );
      CSet       = SET OF Channels;
      Bits       = ( D0,D1,D2,D3,D4,D5,D6,D7 );
      BSet       = SET OF Bits;
      
            
CONST RuheMaske    = CSet { TX,TY };
      LoadOutMaske = CSet { TX,TY,LOut };
      LoadInMaske  = CSet { TX,TY,LIn };
      
VAR Direction [0BFE301H] : CSet;
    Value     [0BFE101H] : CSet;
    BusyByte  [0BFD000H] : BSet;
         
    NextVal              : BSet;
    

(*------------------*)

PROCEDURE Write();
VAR i     : Bits;
    Maske : CSet;
BEGIN
  FOR i:=D7 TO D0 BY -1 DO
     Maske:=RuheMaske;
     IF i IN NextVal THEN
       INCL(Maske,DOut);
     END;
     Value:=Maske;
     INCL(Maske,Clk);
     Value:=Maske;
  END;
  Value:=LoadOutMaske;
END Write;

(*------------------*)

PROCEDURE Read() : ESet;
VAR ReadVal : ESet;
    Maske   : CSet;
    i       : Input;

BEGIN
  ReadVal:=ESet{};
  Maske:=LoadInMaske;
  Value:=Maske;
  INCL(Maske,Clk);
  Value:=Maske;
  FOR i:=E8 TO E1 BY -1 DO
     IF NOT(D0 IN BusyByte) THEN
       INCL(ReadVal,i);
     END;
     Maske:=RuheMaske;
     Value:=Maske;
     INCL(Maske,Clk);
     Value:=Maske;
  END;
  RETURN ReadVal;
END Read;

(*------------------*)

PROCEDURE PrepareM( m:Motor; wie:Richtung );
VAR set,reset: BSet;

BEGIN
    CASE m OF
       M1:  reset:= BSet {D0,D1};
     | M2:  reset:= BSet {D2,D3};
     | M3:  reset:= BSet {D4,D5};
     | M4:  reset:= BSet {D6,D7};
    END;
    NextVal:= NextVal-reset; (* ohne *)
    CASE wie OF
        Aus        : set:= BSet {};
      | Ein,Rechts : set:= BSet {D1,D3,D5,D7};
      | Links      : set:= BSet {D0,D2,D4,D6};   
      | Aus2       : set:= BSet {D0..D7};
    END;
    set:= set * reset;       (* Schnittmenge *);
    NextVal:= NextVal + set; (* Vereinigungsmenge *)  
END PrepareM;

(*------------------*)

PROCEDURE M( m: Motor; wie: Richtung);
BEGIN
  PrepareM(m,wie);
  Write();
END M;

(*------------------*)

PROCEDURE E( e: Input ): BOOLEAN;
VAR read: ESet;
BEGIN
  read:=Read();
  RETURN e IN read;
END E;

(*------------------*)

PROCEDURE Pot (p: PotType): CARDINAL;
VAR    Maske : CSet;
       count : CARDINAL;
BEGIN
  CASE p OF
      x : Maske:= CSet {TX};
    | y : Maske:= CSet {TY};
  END;
  Value:= Maske;
  count:=0;
  Maske:= RuheMaske;
  INCL(Maske,Clk);
  Disable();
  Value:= Maske;
  LOOP
    IF D0 IN BusyByte THEN
       EXIT;
    END;   
    INC(count);     
  END; 
  Enable();
  RETURN count;
END Pot;

(*------------------*)

PROCEDURE Init();
BEGIN
  NextVal := BSet{};
  Write();
END Init;                                          

(*------------------*)

PROCEDURE Exit();
BEGIN
  Direction:=CSet{};
END Exit;


BEGIN
  Assert( (Direction=CSet{}),ADR("Parallelport schon benutzt")); 
  Direction:= CSet { LOut,LIn,DOut,Clk,TX,TY };
  Init();
  TermProcedure( Exit );
  TermProcedure( Init ); (* Wird noch vor Exit ausgeführt *)
END Interface.


