{---------------------------------------------------------------------------}
{                             SETUP.PAS                                     }
{               Ein Werkzeug zur Druckerinitialisierung                     }
{            fuer Panasonic KX-P1092 und Epson-Kompatible.                  }
{                                                                           }
{---------------------------------------------------------------------------}

PROGRAM SetUp;

CONST
  max   = 10;                        { maximale Anzahl Betriebsarten/Gruppe }
  Bell  = ^G;                        { ASCII-Zeichen laesst Ton ertoenen    }
  up    = ^E;                        { Control-Zeichen zur Cursorsteuerung  }
  down  = ^X;
  right = ^D;
  left  = ^S;
  enter = ^M;
  esc   = #27;
  backspace = ^H;

TYPE
  Arten  = (Schriften,ZeilenVor,PapierVor,ZeichenSt,Divers);
  str20  = STRING[ 20];
  str128 = STRING[128];

  Beschreiber =
    RECORD
      Text  : str20;          { Betriebsarten Beschreibung                  }
      Init  : STRING[6];      { Betriebsarten Initialsierung-Sequenz        }
      DeInit: STRING[6];      { Betriebsarten Deinitialisieruns-Sequenz     }
      Parm  : BYTE;           { wenn zur Initialisierung ein Parameter      }
                              { erfragt werden soll ist dieser Wert<>0      }
      Grp   : BYTE;           { Priority der Beriebsart:
                                0=Default Wert einer Gruppe,
                                  nach dem Reset anzuzeigen
                                1=nach dem Reset der Bertiebsart selektiere
                                  den Default-Wert der Gruppe
                                2=Diese Betriebsart kann normal gesetzt
                                  und rueckgesetzt werden
                                3=Definiertes Ruecksetzten nicht moeglich
                                4=Nach dem Reset setzen. Wird benutzt bei
                                  Betriebsarten anstatt Grp=0
                                7=fluechtige Betriebsart Einstellung z.b LF
                                8=reserviertes Feld, nicht benutzt
                                9=General Reset, IN allen Gruppen Default
                                  Werte anzeigen                            }
      Aktv  : BOOLEAN;        { Status der Betriebsart valid/invalid        }
    END;

  Menue =
    RECORD
      Kopf  : str20;                      { Titel eines Untermenues         }
      Anzahl: INTEGER;                    { Betriebsarten eines Untermenues }
      Xpos  : BYTE;                       { Anzeige eines Untermenues, an   }
      Ypos  : BYTE;                       { Bildschirmposition X,Y          }
      Rumpf : ARRAY[1..max] OF Beschreiber;
    END;

CONST
  Menuefeld : ARRAY[Arten] OF Menue =
   ((Kopf  :'** SCHRIFTARTEN **'  ; Anzahl:9; Xpos:2; Ypos:5;
     Rumpf :
     ((Text:'Pica              ';Init:#27#80    ;DeInit:#0
                                ;Parm:0         ;Grp:0         ;Aktv:TRUE),
      (Text:'Elite             ';Init:#27#77    ;DeInit:#27#80
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Komprimiert       ';Init:#15       ;DeInit:#18
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Fett              ';Init:#27#69    ;DeInit:#27#70
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'Breit             ';Init:#27#87#1  ;DeInit:#27#87#0
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'Kursiv-Schrift    ';Init:#27#52    ;DeInit:#27#53
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'NLQ-Schrift       ';Init:#27#110   ;DeInit:#27#80
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Proport. Schrift  ';Init:#27#111   ;DeInit:#27#80
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Proport. Abstand  ';Init:#27#112#1 ;DeInit:#27#112#0
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8       ;Aktv:FALSE))),
    (Kopf  :'** ZEILENSPRUNG **'; Anzahl:5; Xpos:22; Ypos:5;
     Rumpf :
     ((Text:'2,47mm (7/72i)    ';Init:#27#49    ;DeInit:#27#50
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'3,2 mm (1/8 i)    ';Init:#27#48    ;DeInit:#27#50
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'4,2 mm (1/6 i)    ';Init:#27#50    ;DeInit:#0
                                ;Parm:0         ;Grp:0         ;Aktv:TRUE ),
      (Text:'[xx]/72 i         ';Init:#27#65    ;DeInit:#27#50
                                ;Parm:1         ;Grp:1         ;Aktv:FALSE),
      (Text:'[xxx]/216i        ';Init:#27#51    ;DeInit:#27#50
                                ;Parm:1         ;Grp:1         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8       ;Aktv:FALSE))),
    (Kopf  :'** DRUCKBEREICH **'; Anzahl:3; Xpos:22; Ypos:12;
     Rumpf :
     ((Text:'[xxx] Ueber Perfor';Init:#27#78    ;DeInit:#27#79
                                ;Parm:1         ;Grp:2         ;Aktv:FALSE),
      (Text:'[xxx] Rand rechts ';Init:#27#81    ;DeInit:#0
                                ;Parm:1         ;Grp:3         ;Aktv:FALSE),
      (Text:'[xxx] Rand links  ';Init:#27#108   ;DeInit:#0
                                ;Parm:1         ;Grp:3         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8       ;Aktv:FALSE))),
    (Kopf  :'** ZEICHENSATZ  **'; Anzahl:10; Xpos:42; Ypos:5;
     Rumpf :
     ((Text:'USA               ';Init:#27#82#0  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:0         ;Aktv:TRUE ),
      (Text:'England           ';Init:#27#82#3  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Deutschland       ';Init:#27#82#2  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Frankreich        ';Init:#27#82#1  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Italien           ';Init:#27#82#6  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Schweden          ';Init:#27#82#5  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Spanien           ';Init:#27#82#7  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Japan             ';Init:#27#82#8  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Norwegen          ';Init:#27#82#9  ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1         ;Aktv:FALSE),
      (Text:'Daenemark         ';Init:#27#82#10 ;DeInit:#27#82#0
                                ;Parm:0         ;Grp:1       ;Aktv:FALSE))),
    (Kopf  :'**  STEUERUNG   **'; Anzahl:8; Xpos:62; Ypos:5;
     Rumpf :
     ((Text:'Reset             ';Init:#27#64    ;DeInit:#0
                                ;Parm:0         ;Grp:9         ;Aktv:FALSE),
      (Text:'Zeilenvorschub    ';Init:#10       ;DeInit:#0
                                ;Parm:0         ;Grp:7         ;Aktv:FALSE),
      (Text:'Seitenvorschub    ';Init:#12       ;DeInit:#0
                                ;Parm:0         ;Grp:7         ;Aktv:FALSE),
      (Text:'Halbe Geschwindkt ';Init:#27#115#1 ;DeInit:#27#115#0
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'Druck in e.Richtng';Init:#27#85#1  ;DeInit:#27#85#0
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'Papierendekennung ';Init:#27#57    ;DeInit:#27#56
                                ;Parm:0         ;Grp:4         ;Aktv:TRUE ),
      (Text:'Testbetrieb       ';Init:#27#105#1 ;DeInit:#27#105#0
                                ;Parm:0         ;Grp:2         ;Aktv:FALSE),
      (Text:'Probedruck'        ;Init:''        ;DeInit:''
                                ;Parm:255       ;Grp:7         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8         ;Aktv:FALSE),
      (Text:''                  ;Init:''        ;DeInit:''
                                ;Parm:0         ;Grp:8      ;Aktv:FALSE))));

VAR
  Xalt, Yalt: INTEGER;                         { fuer SHARP vom Type BYTE ! }
  Ch        : CHAR;
  f         : INTEGER;
  P         : Arten;
  Init      : BOOLEAN;

{---------------------------------------------------------------------------}

PROCEDURE DruckerReset;

BEGIN  Write(Lst, esc, '@');  END;

{---------------------------------------------------------------------------}

PROCEDURE Merke_alte_Position;

(* Version fuer SHARP MZ 80A unter CP/M 2.2:

VAR  CurHor: BYTE ABSOLUTE $0048;
     CurVer: BYTE ABSOLUTE $0049;

BEGIN
  Xalt := Succ(CurHor);
  Yalt := Succ(CurVer);
END;

  und hier fuer MS-DOS:

BEGIN
  Xalt := WhereX;
  Yalt := WhereY;
END;                                                                        *)

{---------------------------------------------------------------------------}

PROCEDURE Setze_alte_Position;

BEGIN  GotoXY(Xalt,Yalt);  END;

{---------------------------------------------------------------------------}

PROCEDURE ZeigeAn (x, y: BYTE; inverse: BOOLEAN; Text: str128);

BEGIN
  GotoXY(x,y);
  IF inverse THEN
    HighVideo;
  Write(Text);
  LowVideo;
END;

{---------------------------------------------------------------------------}

PROCEDURE Status_Aendern (Gruppe: Arten; feld: INTEGER);

BEGIN
  Merke_alte_Position;
  WITH Menuefeld[Gruppe].Rumpf[feld] DO
    Aktv := NOT Aktv;
  WITH Menuefeld[Gruppe] DO
    ZeigeAn(Xpos, Ypos+feld, Rumpf[feld].Aktv, Rumpf[feld].Text);
  Setze_alte_Position;
END;

{---------------------------------------------------------------------------}

PROCEDURE Wait_for_Ready;

VAR Stbyte      : BYTE;
    hell, PReady: BOOLEAN;

BEGIN
  Merke_alte_Position;
  REPEAT
    Stbyte := Port[$FE];  Stbyte := Stbyte AND $03;
    hell := NOT hell;
    CASE Stbyte OF
      1: BEGIN
           PReady := FALSE;
           ZeigeAn(1, 23, hell, '++Fehler: Drucker ONLINE  schalten !');
           Delay(150);                           { 150 Millisekunden warten }
         END;
      2: PReady := TRUE;
      3: BEGIN
           PReady := FALSE;
           ZeigeAn(1, 23, hell, '++Fehler: Drucker einschalten !');
           Delay(150);
         END;
    END;
  UNTIL PReady;
  GotoXY(1,23);  ClrEol;                          { bis Zeilenende loeschen }
  Setze_alte_Position;
END;

{---------------------------------------------------------------------------}

PROCEDURE Zeiger (x, y: BYTE; Mark: BOOLEAN);

VAR marker: STRING[2];

BEGIN
  Merke_alte_Position;
  IF Mark THEN
    marker := '><'
  ELSE
    marker := '  ';
  GotoXY(Pred(x),y);  Write(marker[1]);
  GotoXY(x+18,y);     Write(marker[2]);
  Setze_alte_Position;
END;

{---------------------------------------------------------------------------}

PROCEDURE Waehle_Betriebsart;

TYPE  Str80 = STRING[80];

VAR   j        : Arten;
      i        : INTEGER;
      parameter: INTEGER;
      satz     : Str80;

  {-------------------------------------------------------------------------}

  PROCEDURE GetParameter (VAR paramt: INTEGER);

  VAR   n,a,e, err: INTEGER;
        c         : CHAR;
        tmp       : STRING[6];

  BEGIN
    Merke_alte_Position;
    GotoXY(1,23);  Write('Parameter eingeben: ');
    WITH Menuefeld[P].Rumpf[f] DO
    BEGIN
      e := Pos(']', Text);
      a := Pos('[', Text);
      n := Pred(e-a);
      tmp := '';
      REPEAT
        Read(Kbd, c);                { Zeichen von Tastatur ohne Echo lesen }
        IF c IN ['0'..'9'] THEN
          BEGIN
            Write(c);  tmp := tmp+c;
          END
        ELSE IF (c = backspace) AND (Length(tmp) > 0) THEN
          BEGIN
            Write(c);  tmp[0] := Chr(Pred(Length(tmp)));
          END
        ELSE IF c <> enter THEN
          Write(Bell);
      UNTIL (c = ^M) OR (Length(tmp) = n);
      Val(tmp, paramt, err);
      Text := '['+Copy('000', 1, n-Length(tmp))+tmp+']'+
                  Copy(Text, Succ(e), Succ(Length(Text)-e));
    END; { WITH }
    GotoXY(1,23);  ClrEol;
    Setze_alte_Position;
  END;

  {-------------------------------------------------------------------------}

  PROCEDURE GetString (VAR Satz: Str80);

  BEGIN
    Merke_alte_Position;
    GotoXY(1,23);  Write('String: ');
    ReadLn(Satz);
    GotoXY(1,23);  ClrEol;
    Setze_alte_Position;
  END;

  {-------------------------------------------------------------------------}

BEGIN { Waehle_Betriebsart }
  WITH Menuefeld[P].Rumpf[f] DO
    CASE Grp OF
      0: IF Aktv THEN
           Write(Bell)
         ELSE
           BEGIN
             Write(Lst, Bell, Init);
             Status_Aendern(P, f);
             FOR i := 1 TO max DO
               WITH Menuefeld[P].Rumpf[i] DO
                 IF (Grp = 1) AND Aktv THEN
                   Status_Aendern(P, i);
           END;
      1: IF Aktv THEN
           BEGIN
             Write(Lst, Bell, DeInit);
             Status_Aendern(P, f);
             FOR i := 1 TO max DO
               WITH Menuefeld[P].Rumpf[i] DO
                 IF (Grp = 0) AND NOT Aktv THEN
                   Status_Aendern(P, i);
           END
         ELSE
           BEGIN
             IF Parm = 0 THEN
               Write(Lst, Bell, Init)
             ELSE
               BEGIN
                 GetParameter(parameter);
                 Write(Lst, Bell, Init, Chr(parameter));
               END;
             Status_Aendern(P, f);
             FOR i := 1 TO max DO
               WITH Menuefeld[P].Rumpf[i] DO
                 IF (Grp IN [0..1]) AND Aktv AND (i <> f) THEN
                   Status_Aendern(P, i);
           END;
   2, 4: BEGIN
           IF Aktv THEN
             Write(Lst, Bell, DeInit)
           ELSE
             BEGIN
               IF Parm = 0 THEN
                 Write(Lst, Bell, Init)
               ELSE
                 BEGIN
                   GetParameter(parameter);
                   Write(Lst, Bell, Init, Chr(parameter));
                 END;
             END;
           Status_Aendern(P, f);
         END;
      3: IF NOT Aktv THEN
           BEGIN
             IF Parm = 0 THEN
               Write(Lst, Bell, Init)
             ELSE
               BEGIN
                 GetParameter(parameter);
                 Write(Lst, Bell, Init, Chr(parameter));
               END;
             Status_Aendern(P, f);
           END
         ELSE
           BEGIN
             Merke_alte_Position;
             Write(Bell, Bell, Bell);
             GotoXY(1,23);  HighVideo;
             Write('++Fehler:Benutze RESET zum Ruecksetzen ');
             Write('dieser Betriebsart');
             Delay(2000);
             LowVideo;  GotoXY(1,23);  ClrEol;
             Setze_alte_Position;
           END;
      7: IF NOT Aktv THEN
           IF Parm = 255 THEN
             BEGIN
               GetString(Satz);
               WriteLn(Lst, Satz);
             END
           ELSE
             BEGIN
               Status_Aendern(P, f);
               Write(Lst, Bell, Init);
               Delay(150);
               Status_Aendern(P, f);
             END;
      9: BEGIN
           DruckerReset;
           Status_Aendern(P, f);
           FOR j := Schriften TO Divers DO
             FOR i := 1 TO max DO
               WITH Menuefeld[j].Rumpf[i] DO
                 IF ((Grp = 0) OR (Grp = 4)) AND NOT Aktv THEN
                   Status_Aendern(j, i)
                 ELSE IF (Grp IN [1..3]) AND Aktv THEN
                   Status_Aendern(j, i);
             Status_Aendern(P, f);
         END;
    END; { CASE }
END;

{---------------------------------------------------------------------------}

PROCEDURE Baueauf;

CONST  limiter = '==================';

VAR    i: INTEGER;
       z: Arten;

BEGIN
  LowVideo;
  ZeigeAn(25, 1, FALSE, '** DRUCKER-SETUP Ver 1.01 **');
  ZeigeAn(27, 2, FALSE, '(c) PASCAL International');
  ZeigeAn(1, 21, FALSE, '<CURSOR>=Auswahl der Betriebsart ');
  ZeigeAn(34,21, FALSE, '/ <CR>=Setzen der Betriebsart / <ESC>=Ende');
  WriteLn;
  FOR z := Schriften TO Divers DO
    WITH Menuefeld[z] DO
    BEGIN
      ZeigeAn(Xpos, Ypos, FALSE, Kopf);
      FOR i := 1 TO Anzahl DO
        WITH Rumpf[i] DO
          ZeigeAn(Xpos, Ypos+i, Aktv, Text);
      ZeigeAn(Xpos, Succ(Ypos+Anzahl), FALSE, limiter);
    END;
    GotoXY(1,22);  Write('CMD>');
END;

{---------------------------------------------------------------------------}

PROCEDURE NeuesFeld (c: CHAR);


BEGIN
  WITH Menuefeld[p] DO
    CASE c OF
      down : IF f < Anzahl THEN
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 f := Succ(f);
                 Zeiger(Xpos, Ypos+f, TRUE);
               END
             ELSE IF Ord(p) = 4 THEN
               Write(Bell)
             ELSE
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 p := Succ(p);
                 f := 1;
                 Zeiger(Menuefeld[p].Xpos, Menuefeld[p].Ypos+f, TRUE);
               END;
      up   : IF f > 1 THEN
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 f := Pred(f);
                 Zeiger(Xpos, Ypos+f, TRUE);
               END
             ELSE IF Ord(p) = 0 THEN
               Write(Bell)
             ELSE
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 p := Pred(p);
                 f := Menuefeld[p].Anzahl;
                 Zeiger(Menuefeld[p].Xpos, Menuefeld[p].Ypos+f, TRUE);
               END;
      left : IF Ord(p) > 0 THEN
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 p := Pred(p);
                 f := 1;
                 Zeiger(Menuefeld[p].Xpos, Menuefeld[p].Ypos+f, TRUE);
               END
             ELSE
               Write(Bell);
      right: IF Ord(p) < 4 THEN
               BEGIN
                 Zeiger(Xpos, Ypos+f, FALSE);
                 p := Succ(p);
                 f := 1;
                 Zeiger(Menuefeld[p].Xpos, Menuefeld[p].Ypos+f, TRUE);
               END
             ELSE
               Write(Bell);
    END; { CASE c }
END;

{---------------------------------------------------------------------------}

BEGIN { SetUp }
(*  ClrScr;
  Baueauf;
{ Wait_for_Ready;                                         s. Begleitartikel }
  DruckerReset;
  p := Schriften;
  f := 1;
  Zeiger(Menuefeld[p].Xpos, Menuefeld[p].Ypos+f, TRUE);
  REPEAT
    Read(Kbd, Ch);
    CASE Ch OF
      up, down, right, left: NeuesFeld(Ch);
      enter                : Waehle_Betriebsart;
    ELSE
      Write(Bell);
    END;
  UNTIL Ch = esc; *)
END.