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

    :Program.  	 Ersatzquelle.mod
    :Imports.    EQGadgets V1.0 [gs], GraphicLib V1.2.3 [gs] AMOK #28
    :Imports.    ComplexLib V1.0 [gs] AMOK#20, MathLibExt V1.0 [gs] AMOK #20
    :Imports.    PrinterSupport V2.01 (an m2c V3.3d angepasst) [mif] AMOK #8
    :Author.   	 Gary Struhlik
    :shortcut.   [gs]
    :Version.  	 1.0
    :Date.     	 24.10.89
    :Modified.   10.02.90 (bessere Fehlerbehandlung)
    :Copyright.  Dieses Programm habe ich als Public  Domain Programm frei-
    :Copyright.  gegeben. Aus diesem Programm und  Programmteilen darf kein
    :Copyright.  Gewinn erzielt werden. Die zweite Bedingung  ist, daß mein
    :Copyright.  Name im Quellcode erhalten bleiben muß  und  daß  man  das
    :Copyright.  Programm nur komplett mit Quellcode, compiliertes Programm
    :Copyright.  und der Dokumentation weiter kopiert.  Änderungen  sollten
    :Copyright.  bitte im Quellkopf mit Angabe des  Autors  angegeben  wer-
    :Copyright.  den,  damit  nicht   1000  verschiedene  Versionen  herum-
    :Copyright.  schwirren. Danke !!
    :Language. 	 Modula-II
    :Translator. M2Amiga AMSoft V3.3d, 28.11.89
    :Contents.   Berechnet passive analoge Schaltungen bestehend aus Spulen
    :Contents.   Kondensatoren, ohmschen Widerständen sowie starren  Strom-
    :Contents.   und Spannungsquellen.
    :Contents.   Die Schaltung  wird  als Ersatzspannungs- bzw. Stromquelle
    :Contents.   betrachtet.
    :History.    V 1.0 24.10.1989 [gs]

**********************************************************************)

MODULE Ersatzquelle;

FROM ComplexLib IMPORT COMPLEX,crcp,compop,crec,cpol;
FROM InOut IMPORT WriteLn, WriteString;
FROM RealInOut IMPORT ReadReal;
IMPORT Intuition;
FROM MathLib0 IMPORT ln,exp;
FROM MathLibExt IMPORT log, PwrOfTen;
FROM SYSTEM IMPORT ADR;
FROM EQGadgets IMPORT MaleGadgets, GadgetAbfrage, EntferneGadgets,Auswahl,
                      Anweisungen;
FROM GraphicLib IMPORT gwrite,sx,sy,GraphOn,GraphOff,gmove,vector,graph1,
                       STRING,textline,InitVector,xpos,ypos,ChSet,SetCross,
                       HardCopy,GraphOffWithOutMouse;
FROM Terminal IMPORT waitCloseGadget;
FROM PrinterSupport IMPORT OpenPrinter,ClosePrinter,PrintChar,PrintString;
FROM Strings IMPORT Copy, Length, Insert;
FROM RealConversions IMPORT RealToStr;
FROM Arts IMPORT TermProcedure;

CONST
      MaxIndex = 2500;
TYPE
     Ausgabeform = (NUME,OKURV,BLIN,WLIN,BLOG,WLOG);
     Quellenart = (Strom,Spannung,ZiNochNull); (* Flags für die Quellenart *)

     Zweipolspeicher = RECORD       (* Definition von Zweipolspeichern *)
      CASE Quelle : Quellenart OF
        Strom    : I,Y : COMPLEX |  (* Ersatzstromquelle *)
        Spannung : U,Z : COMPLEX    (* Ersatzspannungsquelle *)
      END
     END;
VAR
     Makro : ARRAY [1..MaxIndex] OF Auswahl;
                                       (* Speicherfeld für alle Anweisungen *)
     Wert  : ARRAY [1..MaxIndex] OF REAL;   (* eventuell dazugehöriger Wert *)
     MaxAnzAnw, Index, Input : CARDINAL;
     Ausfuehrung, Eingabe : Anweisungen;
     Ersatzquelle : Quellenart;
     A,B,C,D : Zweipolspeicher; (* 4 Zweipolspeicher definieren *)
     Anweisungscode : Auswahl;
     IntuiBase : Intuition.IntuitionBasePtr;
     aktuellesFenster : Intuition.WindowPtr;
     Druckflag,RECflag,err,PrinterOffen,GraphicFenster,
     BefehlsFenster : BOOLEAN;
     W,XA,XE,YA,YE,YE1,YA1,WH,Schritt,W1,W2,X2,X,Y : REAL;
     X1,Eingabeform,Umformung,AusgW : COMPLEX;
     AusArt : Ausgabeform;
     OX,OY : INTEGER;
     xcom,ycom : STRING;
     Text,reelleZahl,s1,s2 : ARRAY [0..80] OF CHAR;
     Marke : textline;
     P1,P2,Einheit : ARRAY [0..20] OF CHAR;
     NextLine : PROC;
     WriteText : PROCEDURE (ARRAY OF CHAR);

PROCEDURE PrintLn; (* Zeilenvorschub (Drucker) *)
BEGIN
   PrintChar(CHAR(10)); PrintChar(CHAR(13))
END PrintLn;

       (* Aus dem Code soll ein Klartext gedruckt werden *)
PROCEDURE Anzeigen( Ausw : Auswahl);
BEGIN
     CASE Ausw OF
        RR : WriteText("RR/Ohm =") |
        RP : WriteText("RP/Ohm =") |
        XR : WriteText("XR/Ohm =") |
        XP : WriteText("XP/Ohm =") |
        LR : WriteText("LR/H =") |
        LP : WriteText("LP/H =") |
        CR : WriteText("CR/F =") |
        CP : WriteText("CP/F =") |
        U1 : IF RECflag THEN
               WriteText("Re{U}/V =")
             ELSE
               WriteText("|U|/V =")
             END |
        I1 : IF RECflag THEN
               WriteText("Re{I}/A =")
             ELSE
               WriteText("|I|/A =")
             END |
        U2 : IF RECflag THEN
               WriteText("Im{U}/V =")
             ELSE
               WriteText("<U/Grad =")
             END |
        I2 :IF RECflag THEN
               WriteText("Im{I}/A =")
             ELSE
               WriteText("<I/Grad =")
             END |
        RS : WriteText("RS") |
        PS : WriteText("PS") |
        U0 : WriteText("U0") |
        IK : WriteText("IK") |
        ZI : WriteText("ZI") |
       AnB : WriteText("A->B") |
       AnC : WriteText("A->C") |
       BvC : WriteText("B<=>C") |
        EE : WriteText("EE")
     END
END Anzeigen;

(* Es wird eine eigene Prozedur WriteComplex definiert, da auch eine *)
(* Druckerausgabe erfolgen soll, sonst würde ich natürlich von dem   *)
(* Modul ComplexInOut importieren !                                  *)
(* Diese Prozedur ist voll kompatibel nur wird WriteText anstatt     *)
(* WriteString benutzt                                               *)
PROCEDURE WriteComplex( A : COMPLEX; m,n : INTEGER; expo,pol : BOOLEAN );
VAR
        logo : BOOLEAN;
        x : REAL;
        Y : COMPLEX;
BEGIN
   IF NOT pol THEN
	x:=ABS(A.IM);
	RealToStr(A.RE,s1,m,n,expo,logo);
	RealToStr(x,s2,m,n,expo,logo);
	IF A.IM >= 0.0 THEN
          WriteText(s1); WriteText("+j"); WriteText(s2)
        ELSE
          WriteText(s1); WriteText("-j"); WriteText(s2)
        END
   ELSE
        cpol(Y,A); (* A in Polarform umwandeln *)
        RealToStr(Y.RE,s1,m,n,expo,logo);
        RealToStr(Y.IM,s2,m,n,expo,logo);
        WriteText(s1); WriteText(" <"); WriteText(s2)
   END
END WriteComplex;

(* Definition einer eigenen WriteReal Prozedur, weil eine Ausgabe in       *)
(* wissenschaftlicher Schreibweise erfolgen soll und eine Druckerausgabe ! *)
PROCEDURE WriteReal(x : REAL; m,n : INTEGER; expo : BOOLEAN);
VAR
       error : BOOLEAN;
BEGIN
     RealToStr(x,reelleZahl,m,n,expo,error);
     WriteText(reelleZahl);
END WriteReal;

PROCEDURE WerteAnzeigen( Index : CARDINAL);
BEGIN          (* eventuell Werte der aktuellen Anweisung ausgeben *)
 Anzeigen(Makro[Index]);
 IF Makro[Index] IN Eingabe THEN
  CASE Makro[Index] OF
    I1,U1: IF NOT(RECflag) THEN
             Umformung.RE:=Wert[Index];
             Umformung.IM:=Wert[Index+1];
             cpol(Umformung,Umformung);
             WriteReal(Umformung.RE,13,6,FALSE)
           ELSE
             WriteReal(Wert[Index],13,6,FALSE)
           END |
    I2,U2: IF NOT(RECflag) THEN
             Umformung.RE:=Wert[Index-1];
             Umformung.IM:=Wert[Index];
             cpol(Umformung,Umformung);
             WriteReal(Umformung.IM,13,6,FALSE)
           ELSE
             WriteReal(Wert[Index],13,6,FALSE)
           END
     ELSE CASE Makro[Index] OF
           LR,CR,LP,CP : WriteReal(Wert[Index],13,6,TRUE)
           ELSE          WriteReal(Wert[Index],13,6,FALSE)
          END
  END
 END;
 NextLine
END WerteAnzeigen;

PROCEDURE MakrosAnzeigen; (* Die gesamte Schaltung ausgeben *)
VAR
     Index : CARDINAL;
BEGIN
   IF MaxAnzAnw > 1 THEN
     Index:=1;
     NextLine;
     WHILE Makro[Index]<>EE DO
       WerteAnzeigen(Index);
       INC(Index)
     END;
     WerteAnzeigen(Index);
   ELSE
     WriteString("keine Bauelemente gespeichert !"); WriteLn
   END
END MakrosAnzeigen;

   (* Den Zweipolspeicher ZP löschen *)
PROCEDURE LoescheZPSpeicher( VAR ZP : Zweipolspeicher);
BEGIN   (* hier als Ersatzspannungsquelle betrachtet *)
    ZP.U.RE:=0.0; ZP.U.IM:=0.0; ZP.Z.RE:=0.0; ZP.Z.IM:=0.0
END LoescheZPSpeicher;

   (* In die erforderliche Ersatzquelle umrechnen *)
PROCEDURE Quellenumformung(VAR ZP : Zweipolspeicher);
BEGIN
    CASE Ersatzquelle OF
       Strom: (* in Ersatzstromquelle umwandeln *)
              crcp(ZP.Y,ZP.Z); (* YI=1/ZI *)
              compop(ZP.I,ZP.U,"*",ZP.Y) | (* IK=U0*YI *)
    Spannung: (* in Ersatzspannungsquelle umwandeln *)
              crcp(ZP.Z,ZP.Y); (* ZI=1/YI *)
              compop(ZP.U,ZP.I,"*",ZP.Z); (* U0=IK*ZI *)
    END (* CASE *)
END Quellenumformung;

  (* Überprüft, ob umgeformt werden kann, Grenzfälle ZI->0 => YI -> oo  *)
  (* Damit Schwierigkeiten vermieden werden. Falls am Anfang gleich I   *)
  (* oder RP o.ä. eingegeben wird.                                      *)
PROCEDURE QuellenumformungErlaubt;
BEGIN
    IF (Ersatzquelle=ZiNochNull) THEN
       Ersatzquelle:=Strom
    ELSE
       Ersatzquelle:=Strom; Quellenumformung(A)
    END
END QuellenumformungErlaubt;

PROCEDURE Ten ( X : REAL ) : REAL; (* 10^X *)
BEGIN
	RETURN exp(X*ln(10.0))
END Ten;

PROCEDURE Log ( X : REAL ) : REAL; (* Zehnerlogarithmus *)
BEGIN
	RETURN ln(X)/ln(10.0)
END Log;

PROCEDURE Ausgabe;

 PROCEDURE Bezeichne; (* Ausgabe der berechneten Werte *)
 BEGIN
	OX:=xpos; OY:=ypos; ChSet(0.0218,0.0420,0.0);
	SetCross; (* Markierung der Frequenz *)
        RealToStr(W,Marke,10,2,TRUE,err);
	Insert(Marke,0,"w=");
	Insert(Marke,Length(Marke)," 1/s");
	gwrite(sx(X)+0.009,sy(Y)-0.008,Marke);
	xpos:=OX; ypos:=OY
 END Bezeichne;

BEGIN
  CASE AusArt OF
  NUME: (* numerisch ausgeben *)
       WriteText("Kreisfrequenz = "); WriteReal(W,13,6,FALSE);
       WriteText(" 1/s "); NextLine;
       WriteText(P1); WriteText(" = ");
       AusgW.RE:=X; AusgW.IM:=Y;
       WriteComplex(AusgW,13,6,FALSE,NOT(RECflag));
       WriteText(" "); WriteText(Einheit);
       NextLine |
  OKURV: (* Ortskurve zeichnen *)
       IF W=W1 THEN
         RealToStr(W,Marke,10,2,TRUE,err);
	 Insert(Marke,0,"w="); ChSet(0.0218,0.0420,0.0);
	 Insert(Marke,Length(Marke)," 1/s");
	 gwrite(sx(X)+0.009,sy(Y)-0.008,Marke);
	 gmove( sx(X), sy(Y));
         SetCross
       END;
       IF W=W1+REAL(TRUNC((W2-W1)/Schritt))*Schritt THEN
          Bezeichne
       END;
       IF W=W1+REAL(TRUNC((W2-W1)/(8.0*Schritt)))*Schritt THEN
          Bezeichne
       END;
       IF W=W1+REAL(TRUNC((W2-W1)/(6.0*Schritt)))*Schritt THEN
          Bezeichne
       END;
       vector(sx(X),sy(Y))
      |
  BLIN: (* Betrag |F|(w) graphisch darstellen *)
       X1.RE:=X; X1.IM:=Y;
       cpol(X1,X1);
       X:=X1.RE; Y:=X1.IM; (* Betrag entspricht X *)
       IF W=W1 THEN
         gmove( sx(W),sy(X))
       END;
       vector( sx(W),sy(X))
      |
  WLIN: (* Phase Phi(w) graphisch darstellen *)
       X1.RE:=X; X1.IM:=Y;
       cpol(X1,X1);
       X:=X1.RE; Y:=X1.IM; (* Phase entspricht Y *)
       IF W=W1 THEN
         gmove( sx(W),sy(Y))
       END;
       vector( sx(W),sy(Y))
      |
  BLOG: (* Betrag |F|/dB(lgw) graphisch darstellen (doppelt log.) *)
       X1.RE:=X; X1.IM:=Y;
       cpol(X1,X1);
       X:=X1.RE; Y:=X1.IM; (* Betrag entspricht X *)
       IF WH=W1 THEN
         gmove( sx(Log(W)),sy(20.0*Log(X)) )
       END;
       vector( sx(Log(W)),sy(20.0*Log(X)) )
      |
  WLOG: (* Phase Phi(lgw) graphisch darstellen (halblog.) *)
       X1.RE:=X; X1.IM:=Y;
       cpol(X1,X1);
       X:=X1.RE; Y:=X1.IM; (* Phase entspricht Y *)
       IF WH=W1 THEN
         gmove( sx(Log(W)),sy(Y))
       END;
       vector( sx(Log(W)),sy(Y))
   END (* CASE *)
END Ausgabe;

PROCEDURE Berechne;
BEGIN
    LoescheZPSpeicher(A); Index:=1;
    WHILE Makro[Index]<>EE DO
      IF Makro[Index]=U0 THEN
	    Einheit:="V"; P1:="U0"
      ELSIF Makro[Index]=IK THEN
	    Einheit:="A"; P1:="IK"
      ELSIF Makro[Index]=ZI THEN
	    Einheit:="Ohm"; P1:="ZI"
      END;
      (* Der Innenwiderstand wird überprüft, ob er von Null verschieden ist, *)
      (* da bei einer Quellenumrechnung sonst eine Division durch Null er-   *)
      (* folgen würde :                                                      *)
       IF (A.Z.RE=0.0) AND (A.Z.IM=0.0) THEN
          Ersatzquelle:=ZiNochNull
       ELSE
          Ersatzquelle:=Spannung
       END;
       CASE Makro[Index] OF

       RR: A.Z.RE:=A.Z.RE+Wert[Index] | (* summiere RR in ZPS-A hinein *)

       RP: QuellenumformungErlaubt;
                                           (* Rechne ggf. in Stromquelle um  *)
           A.Y.RE:=A.Y.RE+1.0/Wert[Index]; (* summiere YP in    ZPS-A hin-   *)
           Ersatzquelle:=Spannung;         (* ein ->Spannungsquelle          *)
           Quellenumformung(A) |

       XR: A.Z.IM:=A.Z.IM+Wert[Index] | (* summiere jXR in ZPS-A hinein *)

       XP: QuellenumformungErlaubt;
                                           (* Rechne ggf. in Stromquelle um *)
           A.Y.IM:=A.Y.IM-1.0/Wert[Index]; (* summiere 1/jXP in ZPS-A hin-  *)
           Ersatzquelle:=Spannung;         (* ein ->Spannungsquelle         *)
           Quellenumformung(A) |

       LR: A.Z.IM:=A.Z.IM+W*Wert[Index] | (* summiere jwLR in ZPS-A hinein *)

       LP: QuellenumformungErlaubt;
                                            (* Rechne ggf. in Stromquelle um *)
           A.Y.IM:=A.Y.IM-1.0/(W*Wert[Index]);(*summiere 1/jwLP in ZPS-A hin-*)
           Ersatzquelle:=Spannung;            (* ein ->Spannungsquelle       *)
           Quellenumformung(A) |

       CR: A.Z.IM:=A.Z.IM-1.0/(W*Wert[Index]) | (* summiere 1/jwCR in ZPS-A *)
                                                (* hinein *)

       CP: QuellenumformungErlaubt;
                                           (* Rechne ggf. in Stromquelle um *)
           A.Y.IM:=A.Y.IM+W*Wert[Index];   (* summiere jwCP in ZPS-A hin-   *)
           Ersatzquelle:=Spannung;         (* ein ->Spannungsquelle         *)
           Quellenumformung(A) |

       U1: IF (Makro[Index+1]=U2) THEN
              (* summiere Re{U} in ZPS-A hinein *)
              A.U.RE:=A.U.RE+Wert[Index]
           ELSE
              WriteString("Die nächste Anweisung muß U2 lauten !"); WriteLn;
              WriteString("Bitte Korrektur durchführen !"); WriteLn
           END |

       I1: IF (Makro[Index+1]=I2) THEN
             IF Ersatzquelle=ZiNochNull THEN
                A.I.RE:=A.I.RE+Wert[Index]; Ersatzquelle:=ZiNochNull
             ELSE
               Ersatzquelle:=Strom; Quellenumformung(A);
                                             (* Rechne ggf. in Stromquelle um *)
               A.I.RE:=A.I.RE+Wert[Index];   (* summiere I in ZPS-A hin-      *)
               Ersatzquelle:=Spannung;       (* ein ->Spannungsquelle         *)
               Quellenumformung(A)
             END
           ELSE
             WriteString("Die nächste Anweisung muß I2 lauten !"); WriteLn;
             WriteString("Bitte Korrektur durchführen !"); WriteLn
           END |

       U2: IF (Makro[Index-1]=U1) THEN
              A.U.IM:=A.U.IM+Wert[Index] (* summiere Im{U} in ZPS-A hinein *)
           ELSE
              WriteString("Die vorherige Anweisung muß U1 lauten !"); WriteLn;
              WriteString("Bitte Korrektur durchführen !"); WriteLn
           END |

       I2: IF (Makro[Index-1]=I1) THEN
             IF Ersatzquelle=ZiNochNull THEN
                A.I.IM:=A.I.IM+Wert[Index]; Ersatzquelle:=ZiNochNull
             ELSE
               Ersatzquelle:=Strom; Quellenumformung(A);
                                             (* Rechne ggf. in Stromquelle um *)
               A.I.IM:=A.I.IM+Wert[Index];   (* summiere I in ZPS-A hin-      *)
               Ersatzquelle:=Spannung;       (* ein ->Spannungsquelle         *)
               Quellenumformung(A)
             END
       	   ELSE
       	     WriteString("Die vorherige Anweisung muß I1 lauten !"); WriteLn;
       	     WriteString("Bitte Korrektur durchführen !"); WriteLn
       	   END |

       RS: compop(A.U,A.U,"+",B.U); (* Spannungen addieren *)
           compop(A.Z,A.Z,"+",B.Z) | (* Innenwiderstände addieren *)

       PS: Ersatzquelle:=Strom; Quellenumformung(A); Quellenumformung(B);
           compop(A.I,A.I,"+",B.I); (* Ströme addieren *)
           compop(A.Y,A.Y,"+",B.Y); (* Leitwerte addieren *)
           Ersatzquelle:=Spannung; Quellenumformung(A); Quellenumformung(B) |

       U0: X:=A.U.RE; Y:=A.U.IM; Ausgabe |
                 (* Spannungswert der Ersatzquelle ausgeben *)

       IK: Ersatzquelle:=Strom; Quellenumformung(A);
           X:=A.I.RE; Y:=A.I.IM; Ausgabe;
           Ersatzquelle:=Spannung; Quellenumformung(A) |
                 (* Strom der Ersatzquelle ausgeben *)

       ZI: X:=A.Z.RE; Y:=A.Z.IM; Ausgabe |
                 (* Innenwiderstand der Ersatzquelle ausgeben *)

      AnB: B:=A;                   (* A -> B ; 0 -> A *)
           LoescheZPSpeicher(A) |

      AnC: C:=A;                   (* A -> C ; 0 -> A *)
           LoescheZPSpeicher(A) |

      BvC: D:=B; B:=C; C:=D        (* B und C vertauschen *)

       END; (* CASE *)
       INC(Index)
    END (* WHILE *)
END Berechne;

PROCEDURE Abfragen; (* Abfrage der Intervallgrenzen und der Schrittweite *)
BEGIN
    	WHILE ((W1=0.0) OR (W2=0.0)) DO
            WriteString("Geben Sie die Anfangskreisfrequenz für Schaltungen");
            WriteLn; WriteString("mit L und C ein."); WriteLn;
            WriteString("w1 = "); ReadReal(W1); WriteLn;
            WriteString("Geben Sie die Endkreisfrequenz für Schaltungen");
            WriteLn; WriteString("mit L und C ein."); WriteLn;
            WriteString("w2 = "); ReadReal(W2); WriteLn
        END;
        WriteString("Geben Sie die Schrittweite ein."); WriteLn;
        WriteString("s = "); ReadReal(Schritt); WriteLn
END Abfragen;

PROCEDURE NachAbsturz;
BEGIN
    IF PrinterOffen THEN ClosePrinter END;
    IF GraphicFenster THEN GraphOffWithOutMouse END;
    IF BefehlsFenster THEN EntferneGadgets END
END NachAbsturz;

BEGIN (* Hauptprogramm *)
    GraphicFenster:=FALSE; PrinterOffen:=FALSE; BefehlsFenster:=FALSE;
    TermProcedure(NachAbsturz);
    OpenPrinter; PrinterOffen:=TRUE;
    Druckflag:=FALSE; (* FALSE = keine Ausgabe auf dem Drucker *)
    RECflag:=FALSE; (* FALSE = keine Ausgabe in Normalform *)
    IntuiBase:=ADR(Intuition); (* Für die Abfrage des aktiven Fensters *)
    aktuellesFenster:=IntuiBase^.activeWindow; (* Hole Adresse des *)
                                               (* aktiven Fensters *)
    waitCloseGadget:=FALSE;(* Wenn PEND angeklickt wird -> Workbench Fenster *)
                           (* schließen                                      *)
    WriteLn;
    WriteString("Dieses Programm kann eine einfache passive analoge Schaltung");
    WriteLn;
    WriteString("bestehend aus ohmschen Widerständen,  Spulen,  Kondensatoren");
    WriteLn;
    WriteString("und starren Spannungs- und Stromquellen berechnen.");
    WriteLn; WriteLn;
    WriteString("Es  kann mit Quellen sinusförmiger  Ausgangsgrößen oder mit");
    WriteLn;
    WriteString("Gleichgrößen gerechnet werden."); WriteLn;
    WriteString("Die Schaltung wird  als  Ersatzspannungsquelle  betrachtet.");
    WriteLn; WriteLn;
    WriteString("======== Bitte  die Bedienungsanleitung beachten ! ========");
    WriteLn;
    WriteString("========     Version 1.0 ist Public Domain !       ========");
    WriteLn; WriteLn;
    MaleGadgets; (* Fenster mit Gadgets öffnen *) BefehlsFenster:=TRUE;
    Index:=1;               (* Den Speicherindex initialisieren *)
    MaxAnzAnw:=Index;       (* maximale Anzahl der eingegebenen Anweisungen *)
    Eingabe:=Anweisungen{RR,RP,LR,LP,CR,CP,XR,XP,U1,I1,U2,I2};
    Ausfuehrung:=Anweisungen{VOR,RCK,NUM,BODELIN,BODELOG,OK,NS,ANWAZ};

    GadgetAbfrage(Anweisungscode,Druckflag,RECflag);
                             (* Welches Gadget wurde gewählt ? *)
    Intuition.ActivateWindow(aktuellesFenster);
   (* Damit der Benutzer nicht zwischen den Fenstern hin und her klicken muß *)
    IF Druckflag THEN WriteText:=PrintString; NextLine:=PrintLn
                 ELSE WriteText:=WriteString; NextLine:=WriteLn END;

    WHILE Anweisungscode <> PEND DO
      IF Anweisungscode IN Ausfuehrung THEN
         CASE Anweisungscode OF
           VOR : IF Index <= 65534 THEN (* Bereichskontrolle *)
                  INC(Index);
                  IF Index < MaxAnzAnw THEN           (* in der Liste eine *)
                    WerteAnzeigen(Index)              (* Anweisung vor     *)
                  ELSE
                    Index:=MaxAnzAnw-1;
                    IF Index = 0 THEN Index:=1 END
                  END
                 ELSE
                   Index:=MaxAnzAnw-1;
                   IF Index = 0 THEN Index:=1 END
                 END |
           RCK : IF Index > 0 THEN (* Bereichskontrolle *)
                  DEC(Index);
                  IF Index > 0 THEN         (* In der Liste eine *)
 		    WerteAnzeigen(Index)    (* Anweisung zurück  *)
                  ELSE
                    Index:=1
                  END
	         ELSE
	           Index:=1
	         END |
	    NUM: IF MaxAnzAnw>1 THEN (* Die Rechnung soll numerisch erfolgen *)
                   AusArt:=NUME; W:=0.0;
                   WHILE W=0.0 DO
                    WriteLn;
	            WriteString("Geben Sie die Kreisfrequenz für Schaltungen");
	            WriteString(" mit L und C ein oder eine"); WriteLn;
	            WriteString("von 0.0 verschiedene Zahl."); WriteLn;
	            WriteString("w = "); ReadReal(W); WriteLn;
                   END;
	           Berechne
	         ELSE
	           WriteString("Bitte die Bauelemente eingeben !"); WriteLn
	         END |
    OK:IF MaxAnzAnw>1 THEN
        AusArt:=OKURV;
        WriteLn; W1:=0.0; W2:=0.0;
        WriteString("Aufnahme einer Ortskurve"); WriteLn;
        WriteString("Nur bei Eingabe von L und C sinnvoll !"); WriteLn;
        WriteLn;
        Abfragen;
        W:=W1;
        WriteString("Geben Sie die Bereiche der komplexen Zahlenebene ein.");
        WriteLn; WriteString("Re{Z}min = "); ReadReal(XA); WriteLn;
                 WriteString("Re{Z}max = "); ReadReal(XE); WriteLn;
                 WriteString("Im{Z}min = "); ReadReal(YA); WriteLn;
                 WriteString("Im{Z}max = "); ReadReal(YE); WriteLn;
                 GraphOn; GraphicFenster:=TRUE;
                 InitVector; xcom:="Re/"; ycom:="jIm/";
                 Insert(xcom,3,Einheit);
                 Insert(ycom,4,Einheit);
                 graph1(2,XA,XE,5,YA,YE,5,0.16,0.98,0.13,0.93,"ORTSKURVE",
                        xcom,ycom);
                 WHILE W<=W2 DO
                   Berechne; W:=W+Schritt
                 END;
                 IF Druckflag THEN HardCopy END;
                 GraphOff; GraphicFenster:=FALSE
       ELSE
            WriteString("Bitte die Bauelemente eingeben !"); WriteLn
       END |
 BODELIN:
       IF MaxAnzAnw > 1 THEN
        WriteLn; W1:=0.0; W2:=0.0;
        WriteString("Aufnahme des Betrages und der Phase."); WriteLn;
        WriteString("Nur bei Eingabe von L und C sinnvoll !"); WriteLn;
        WriteLn;
        Abfragen; Copy(P2,P1,0,1);
        WriteString("Geben Sie Bereiche des Betrages ein."); WriteLn;
        WriteString("|"); WriteString(P2);
	WriteString("| min = "); ReadReal(YA); WriteLn;
        WriteString("|"); WriteString(P2);
        WriteString("| max = "); ReadReal(YE); WriteLn;
        WriteString("Geben Sie die Bereiche der Phase ein."); WriteLn;
        WriteString("Phi min = "); ReadReal(YA1); WriteLn;
        WriteString("Phi max = "); ReadReal(YE1); WriteLn;
        GraphOn; GraphicFenster:=TRUE;
        InitVector; ycom:="||/"; Insert(ycom,1,P2);
        xcom:="w/(1/s)";
        Insert(ycom,4,Einheit);
        graph1(2,W1,W2,5,YA,YE,5,0.16,0.98,0.13,0.93,"Amplitudenverlauf",
               xcom,ycom);
        W:=W1;
        AusArt:=BLIN;
        WHILE W<=W2 DO
          Berechne; W:=W+Schritt
        END;
        IF Druckflag THEN HardCopy END;
        GraphOff; GraphicFenster:=FALSE;
        GraphOn; GraphicFenster:=TRUE; InitVector;
        ycom:="Phi/o"; xcom:="w/(1/s)";
        graph1(2,W1,W2,5,YA1,YE1,5,0.16,0.98,0.13,0.93,"Phasenverlauf",
               xcom,ycom);
        W:=W1;
        AusArt:=WLIN;
        WHILE W<=W2 DO
          Berechne; W:=W+Schritt
        END;
        IF Druckflag THEN HardCopy END;
        GraphOff; GraphicFenster:=FALSE
       ELSE
         WriteString("Bitte die Bauelemente eingeben !"); WriteLn
       END |
BODELOG:
       IF MaxAnzAnw > 1 THEN
        WriteLn; W1:=0.0; W2:=0.0;
        WriteString("Aufnahme eines Bodediagrammes mit logarithmischer");
        WriteLn; WriteString("Frequenzachse und Betrag in dB."); WriteLn;
        WriteString("Nur bei Eingabe von L und C und bei");
        WriteString(" Berechnung");  WriteLn;
        WriteString("mit Spannungswerten sinnvoll !"); WriteLn; WriteLn;
        WriteString("Geben Sie die Frequenz, den Betrag und die Schritt");
        WriteString("weite logarithmisch ein !"); WriteLn; WriteLn;
        Abfragen;
        WriteString("Geben Sie die Bereiche des Betrages ein."); WriteLn;
        WriteString("|F|/dB min = "); ReadReal(YA); WriteLn;
        WriteString("|F|/dB max = "); ReadReal(YE); WriteLn;
        WriteString("Geben Sie die Bereiche der Phase ein."); WriteLn;
        WriteString("Phi min = "); ReadReal(YA1); WriteLn;
        WriteString("Phi max = "); ReadReal(YE1); WriteLn;
        GraphOn; GraphicFenster:=TRUE; InitVector;
        ycom:="|F|/dB"; xcom:="lg(w)";
        graph1(2,W1,W2,5,YA,YE,5,0.16,0.98,0.13,0.93,"Amplitudenverlauf",
               xcom,ycom);
        WH:=W1;
        AusArt:=BLOG;
        WHILE WH<=W2 DO
          W:=Ten(WH);
          Berechne; WH:=WH+Schritt
        END;
        IF Druckflag THEN HardCopy END;
        GraphOff; GraphicFenster:=FALSE;
        GraphOn; GraphicFenster:=TRUE; InitVector;
        ycom:="Phi/o"; xcom:="lg(w)";
        graph1(2,W1,W2,5,YA1,YE1,5,0.16,0.98,0.13,0.93,"Phasenverlauf",
               xcom,ycom);
        WH:=W1;
        AusArt:=WLOG;
        WHILE WH<=W2 DO
          W:=Ten(WH);
          Berechne; WH:=WH+Schritt
        END;
        IF Druckflag THEN HardCopy END;
        GraphOff; GraphicFenster:=FALSE
       ELSE
        WriteString("Bitte die Bauelemente eingeben !"); WriteLn
       END |
    NS: Index:=1; MaxAnzAnw:=1 | (* Neue Schaltung eingeben  *)
    ANWAZ: MakrosAnzeigen (* alle Eingaben anzeigen *)
	 END (* CASE *)
     ELSE
      IF Index < (MaxIndex-1) THEN
       IF (Anweisungscode<>DR) AND (Anweisungscode<>RECPOL) THEN
	 Anzeigen( Anweisungscode);
	 Makro[Index]:=Anweisungscode;
	 IF Makro[Index]=U0 THEN
	       Einheit:="V"; P1:="U0"
         ELSIF Makro[Index]=IK THEN
	       Einheit:="A"; P1:="IK"
         ELSIF Makro[Index]=ZI THEN
	       Einheit:="Ohm"; P1:="ZI"
         END;
	 IF Anweisungscode IN Eingabe THEN
	   ReadReal(Wert[Index]);
	   Anzeigen(Makro[Index]);
	   CASE Makro[Index] OF
	     LR,CR,LP,CP : WriteReal(Wert[Index],13,6,TRUE)
	     ELSE          WriteReal(Wert[Index],13,6,FALSE)
	   END;
	    IF (Anweisungscode=U2) OR (Anweisungscode=I2) THEN
             IF NOT(RECflag) THEN             (* Werte stets in Normalform *)
                Umformung.RE:=Wert[Index-1];  (* speichern *)
                Umformung.IM:=Wert[Index];
                crec(Umformung,Umformung);
                Wert[Index-1]:=Umformung.RE;
                Wert[Index]:=Umformung.IM
             END
           END
	 END;
	 WriteLn;
	 INC(Index);
	 IF MaxAnzAnw < Index THEN
	    MaxAnzAnw:=Index
	 END
       END
      ELSE
       WriteString("Zu viele Anweisungen eingegeben !!"); WriteLn
      END
     END;
     GadgetAbfrage(Anweisungscode,Druckflag,RECflag);
             (* Welches Gadget wurde gewählt ? *)
     Intuition.ActivateWindow(aktuellesFenster);
     IF Druckflag THEN WriteText:=PrintString; NextLine:=PrintLn
                  ELSE WriteText:=WriteString; NextLine:=WriteLn END;
    END;
    EntferneGadgets; BefehlsFenster:=FALSE;
    ClosePrinter; PrinterOffen:=FALSE
END Ersatzquelle.
