'       *************************
'       *** Das Editiermodul  ***
'       *************************
'
' Das im folg. gezeigte Tool ermöglicht es, Variablen in einem Programm,
' z.B. Betriebsparameter auf einem zweizeiligen Display zu editieren.
' Relevant sind nur die Zeilen 4000 ff und 14000 ff. Der Rest ist nur
' für dieses Beispiel und ein besseres Verständnis aufgeführt.
' Im folgenden seien als Beispiel irgendwelche Variablen
' als Feld V(0) ...V(n) definiert.
' Die Routine funktioniert nur, wenn es zu jeder Variablen V() auch ein
' MIN() und ein MAX() gibt, innerhalb deren der erlaubte Wert sein muá.
'
100 STRING 500,17               ; Speicherplatz für Strings
115 VARANZAHL=4                 ; Anzahl der editierbaren Variablen
' Die Tastaturbelegung wird später von den Editierroutinen benutzt. Jede
' Taste hat dann ihre Funktion, möglichst eine, die man vom PC kennt.
' Belegung der groáen Tastatur
120 DEL=127                     ; ASC-Code der Del-Taste
130 ENT=13                      ; ASC-Code der ENTER-Taste
140 ESC=27                      ; ASC-Code der ESC-Taste auf der gr. Tastatur
'                                 auf der kleinen Tastatur esc = ASC(U)
200 F1=ASC(I)                   ; Funktionstastencode
210 F2=ASC(N)                   ; auf der Folientastatur
220 F3=ASC(T)                   ;
230 F4=ASC(,)                   ;
240 F5=ASC(O)                   ;
250 F6=ASC(U)                   ;
260 BLANK=ASC(P)                ; Leertaste oberhalb enter
' bei der kleinen Tastatur
'140 ESC=ASC(U)                 ; ASC-Code der esc-Taste, oben rechts
'200 F1=ASC(I)                  ; Funktionstastencode
'210 F2=ASC(O)                  ; auf der Folientastatur
' --------------einige Testvariablen für dieses Beispiel -------
' ------------- Defaultwerte:
300 V(0)=0.25                   ; P-Faktor
310 V(1)=1.256                  ; Vorhalt
320 V(2)=3                      ; Wartezeit
330 V(3)=0                      ; Leerlaufzeit
' ------------- MIN-Werte:
400 MIN(0)=0                    ; P-Faktor
410 MIN(1)=0                    ; Vorhalt
420 MIN(2)=0                    ; Wartezeit
430 MIN(3)=0                    ; Leerlaufzeit
' ------------- MAX-Werte:
500 MAX(0)=1                    ; P-Faktor
510 MAX(1)=5                    ; Vorhalt
520 MAX(2)=10                   ; Wartezeit
530 MAX(3)=3                    ; Leerlaufzeit
; -----------------------------------------------------------------------
;                       Betriebsdaten
; -----------------------------------------------------------------------
;
;  Die folgenden Daten sind nur als Beispiel zu sehen:
;
; Funktion: Die Parameter werden zuerst aufgerufen und mit dem aktuellen
; Wert ins Display geschrieben (Zeile 15500 ff).
; Danach können sie je nach Art als ganze Zahl (Zeile 14600 ff)
; oder mit Nachkommastellen (Zeile 14800 ff, 14900ff oder direkt in 15000ff)
; editiert werden. Ein Enter übernimmt den Wert, überprüft MIN und MAX und
; geht dann zum nächsten Parameter, ein <esc> speichert
; das gesamte Zahlenfeld ab und verläát die Routine. Hat man alle Parameter
; durch, geht es beim ersten weiter.
;
; Fehlervariable E:
;               E=0  kein Fehler
;               E=9  Wert <min oder >max (wird beim Edit wieder gelöscht)
;               E=15 esc-Taste gedrückt
;
4000 CLS:Y=0                    ; Display löschen, Index auf 0
4010 DO
'      verzweige nacheinander je nach Index zu den einzelnen Variablen:
4020   ON Y GOSUB 4450,4500,4550,4600
4030   Y=Y+1: IF Y=VARANZAHL THEN Y=0
4040 UNTIL E>0                  ; bis esc oder Fehler
' zum Abspeichern siehe Modul PAR_SAVE.MOD
' PUSH [Anzahl_var],[adresse_ram],[adresse_eeprom]
' GOSUB 13000                   ; speichern
' RETURN                        ; normaler Ausstieg aus Unterroutine
4050 ?:?"fertig ...":END
; --------------- Bearbeitung --------------------
; zuerst wird ein Editierfenster für das kleine Display geöffnet:
; Aufruf: $(1) Bezeichnungstext
;         $(2) Benennung
;         GOSUB 15500
;
; dann wird die Variable editiert:
; Aufruf: PUSH var (lege die Var. auf den Stack)
;         GOSUB xxxx (zur Editierroutine)
;         POP var (hole die Var. vom Stack, jezt aber mit neuem Wert)
;
; dann werden die Var. auf Plausibilität überprüft:
;    IF var<unterer_wert.AND.var>oberer_wert THEN meldung und von vorne
; zuletzt
;         bei enter-> nächste var., bei esc -> Abbruch
;    --------- Prop-Faktor
4450   $(1)="P-Faktor        ":$(2)=""
4455   GOSUB 15500              ; anzeigen
4460 DO
4465   PUSH V(Y):GOSUB 14800:POP V(Y) ;Zahl mit 3 Vor- und 3 Nachkommast.
4470   GOSUB 15700              ; Wertebereich eingehalten
4475 UNTIL E=0.OR.E=15          ; bis enter oder esc gedrückt
4480 RETURN
;    --------- Vorhalt
4500 $(1)="Vorhalt         ":$(2)="V"
4505 GOSUB 15500
4510 DO
4515   PUSH V(Y):GOSUB 14800:POP V(Y) ;Zahl mit 3 Vor- und 3 Nachkommast.
4520   GOSUB 15700              ; Wertebereich eingehalten
4525 UNTIL E=0.OR.E=15          ; bis enter oder esc gedrückt
4530 RETURN
;    --------- Wartezeit
4550 $(1)="Wartezeit       ":$(2)="s"
4555 GOSUB 15500
4560 DO
4565   PUSH 3,V(Y):GOSUB 14600:POP V(Y) ; ganze dreistellige Zahl
4570   GOSUB 15700              ; Wertebereich eingehalten
4575 UNTIL E=0.OR.E=15          ; bis enter oder esc gedrückt
4580 RETURN
;    --------- Leerlaufzeit
4600 $(1)="Leerlaufzeit    ":$(2)="s"
4605 GOSUB 15500
4610 DO
4615   PUSH 3,V(Y):GOSUB 14600:POP V(Y) ; ganze Zahl mit 3 Vorkommast.
4620   GOSUB 15700              ; Wertebereich eingehalten
4625 UNTIL E=0.OR.E=15          ; bis enter oder esc gedrückt
4630 RETURN
'----------------------------------------------------------------
'****** Hilfsroutinen zum Editieren und Darstellen *************
'----------------------------------------------------------------
' ------------ Backspace
14000 P. CHR(8)," ",CHR(8),
14010 RETURN
' ------------ Ausgabe einer ganzen Zahl auf dem Display mit fester
'              Stellenzahl, ohne Vorzeichen
' Eingang: X1 Zahl
'        : X2 Stellenzahl
' Ausgang: keine
' lokal  : X1..X4
' global : keine
14100 X3=10**(X2-1)                     ; hoechster moeglicher Wert
14110   X4=INT(X1/X3):P. CHR(X4+48),:X1=X1-X4*X3
14120   X3=X3/10:IF X3>=1 GOTO 14110
14130 RETURN
' ------------ Ausgabe einer Zahl auf dem Display mit 3 Vor- und 3
'              Nachkommastellen, ohne Vorzeichen
' Eingang: X1 Zahl
' Ausgang: keine
' lokal  : X1..X4
' global : keine
14200 X2=100                            'hoechster moeglicher Wert
14210 FOR X3=1 TO 6                     '6 Stellen
14220   X4=INT(X1/X2):X1=X1-X4*X2:P. CHR(X4+48),
14230   X2=X2/10:IF X3=3 THEN P. ".",   'Dezimalpunkt an der dritten Stelle
14240 NEXT
14250 RETURN
; ------------ Ausgabe einer Zahl auf dem Display mit 3 Vor- und 1
;              Nachkommastelle, ohne Vorzeichen
; Eingang: X1 Zahl
; Ausgang: keine
; lokal  : X1..X4
; global : keine
14300 X2=100                            ; hoechster moeglicher Wert
14310 FOR X3=1 TO 4                     ; 3 Stellen
14320   X4=INT(X1/X2):X1=X1-X4*X2:P. CHR(X4+48),
14330   X2=X2/10:IF X3=3 THEN P. ".",
14340 NEXT
14350 RETURN
' ------------ warte auf die Taste ENTER
' Eingang: keine
' Ausgang: keine
' lokal  : X1
' global : keine
14500 DO:X1=GET:UNTIL X1=13
14505 RETURN
' ------------ warte auf die Tasten 0 oder 1
' Eingang: keine
' Ausgang: X1 = 48 oder 49
' lokal  : keine
' global : keine
14510 DO:X1=GET:UNTIL X1=48.OR.X1=49
14515 RETURN
' ------------ warte auf eine Zahlen-Taste
' Eingang: keine
' Ausgang: X1   Tastencode - 48
' lokal  : keine
' global : keine
14520 DO:X1=GET:WHILE X1=0
14525 X1=X1-48:RETURN
' -----------------------------------------------------------
' die Editiermöglichkeiten beziehen sich auf die Tasten der Tastatur
' diese können prinzipiell auch mit dem PC nachvollzogen werden.
' Den Tasten wurde in der Initialisierung ein Tastencode zugewiesen.
' Mit dieser Taste kann dann die gewollte Funktion ausgeführt werden.
'
' Z.B. DEL = 127: Tastencode 127 bewirkt löschen des Zeichens vor dem Cursor
' oder BLANK = ASC(P): Mit "P" kann man die ganze Zahl löschen
'
' -----------------------------------------------------------
'               Ausgabe einer ganzen Zahl auf dem Display
'       mit fester Stellenzahl und Editieren durch den Benutzer
' -----------------------------------------------------------
' Eingang: Wert, auf dem Stack
'          Stellenzahl, auf dem Stack
' Ausgang: Wert, auf dem Stack
' lokal  : X1..X5
' global : E, Fehlervariable
14600 POP X1,X2:PUSH X2,X1:GOSUB 14100  'gebe Zahl aus
14610 POP X3,X4:PUSH X3:P. CHR(4),      'hohle nochmals vom Stack, Cursor on
; Tastenabfrage:
14620 DO:X1=GET:WHILE X1=0              'warte auf eine Taste
'       wenn Enter dann hole alten Wert vom Stack, lege den neuen
'       drauf, setze Fehlervariable auf 0
14630   IF X1=ENT THEN POP X2:PUSH X3:E=0:P. CHR(5),:RETURN
'       wenn Abbruch dann liegt der alte Wert bereits auf dem Stack
'       setze Fehlervariable
14640   IF X1=ESC THEN E=15:P. CHR(5),:RETURN   'verlassen mit ESC
14650   IF X1=DEL THEN 14700            'Delete
14655   IF X1=BLANK THEN 14780          'gesamte Zahl loeschen
14660   IF (X1>=48.AND.X1<=57) THEN 14750
14670 GOTO 14620                        'Schleife
'       ---- Delete
14700   IF X2<=0 THEN 14620             'bereits alles geloescht
14710   ? CHR(8)," ",CHR(8),            'loesche Ziffer
14720   X3=INT(X3/10):X2=X2-1:GOTO 14620
'       ---- Taste
14750   IF X2>=X4 THEN 14620            'maximale Stellenzahl erreicht
14760   P. CHR(X1),:X3=X3*10+X1-48
14770   X2=X2+1:GOTO 14620
'       ---- gesamte Zahl loeschen
14780   IF X2=0 THEN 14782
14781     FOR X1=1 TO X2:GOSUB 14000:NEXT
14782   X2=0:X3=0:GOTO 14620
' -----------------------------------------------------------
'               Ausgabe einer Zahl auf dem Display
'       mit 3 Vor- und 3 Nachkommastellen und Editieren durch den Benutzer
' -----------------------------------------------------------
' Eingang: Zahl, auf dem Stack
' Ausgang: Zahl, auf dem Stack
'          E, Fehlervariable
' lokal  : X1..X5
' global : E
14800 POP X1:PUSH X1:GOSUB 14200        'gebe Zahl aus
14810 POP X3:PUSH X3:X2=7:X4=4:X5=2:X6=3
14820 GOSUB 15000                       'Editieren
14830 RETURN
' -----------------------------------------------------------
'              Ausgabe einer Zahl auf dem Display
'       mit 3 Vor- und 1 Nachkommastelle und Editieren durch den Benutzer
' -----------------------------------------------------------
14900 POP X1:PUSH X1:GOSUB 14300
14910 POP X3:PUSH X3:X2=5:X4=4:X5=0:X6=3
14920 GOSUB 15000
14930 RETURN
' -----------------------------------------------------------
'              Editieren einer Zahl auf dem Display
'       mit beliebigen Vor- und Nachkommastellen durch den Benutzer
' -----------------------------------------------------------
' Eingang: Zahl auf dem Stack
'          X3    Zahl
'          X4    Stelle des Punktes
'          X2    gesamte Stellenzahl
'          X5    maximale Zahl der Stellen nach dem Komma-1
'          X6    maximale Zahl der Stellen vor dem Komma
' Ausgang: Zahl, auf dem Stack
'          E, Fehlervariable
' lokal  : X1..X5
' global : E
15000 P. CHR(4),                        ; Cursor on
; Tastenabfrage:
15020 DO:X1=GET:WHILE X1=0              'warte auf Taste
15030   IF X1=ENT THEN POP X1:PUSH X3:E=0:P. CHR(5),:RETURN
15040   IF X1=ESC THEN E=15:P. CHR(5),:RETURN   ' verlassen mit esc
15050   IF X1=DEL THEN 15100            'Delete
15055   IF X1=BLANK THEN 15200          'gesamte Zahl loeschen,
15060   IF X1=ASC(.) THEN 15190         'Dezimalpunkt
15070   IF (X1>=48.AND.X1<=57) THEN 15150
15080 GOTO 15020                        'Schleife
'       ---- Delete
15100   IF X2<=0 THEN 15020             'bereits alles geloescht
15105   IF X4=0 THEN 15130
15106   IF X4=X2 THEN 15142
15107   X3=INT(X3*10**(X2-X4-1)):X3=X3/10**(X2-X4-1)
15110   ? CHR(8)," ",CHR(8),            'loesche Ziffer
15120   X2=X2-1:GOTO 15020
15130   ? CHR(8)," ",CHR(8),            'loesche Ziffer
15140   X2=X2-1:X3=INT(X3/10):GOTO 15020
15142   ? CHR(8)," ",CHR(8),            'loesche Punkt
15143   X2=X2-1:X4=0
15144   IF X2>0 THEN 15130 ELSE 15020
'       ---- Taste
15150   IF X4>0 THEN 15180              'wenn Punkt schon gesetzt
'       ------- noch kein Punkt gesetzt
15170   P. CHR(X1),:X3=X3*10+X1-48:X2=X2+1
15175   IF X2=X6 THEN X2=X2+1:X4=X2:P. ".",
15177   GOTO 15020
'       ------- Punkt bereits gesetzt
15180   IF X2-X4>X5 THEN 15020          'bereits genug Stellen hinter dem Komma
15182   P. CHR(X1),:X2=X2+1:X3=X3+(X1-48)/10**(X2-X4)
15185   GOTO 15020
'       ---- Punkt
15190   IF X4>0 THEN 15020              'Punkt bereits eingegeben
15192   P. CHR(X1),:X2=X2+1:X4=X2:GOTO 15020
'       ---- gesamte Zahl loeschen
15200   IF X2=0 THEN 15210
15205     FOR X1=1 TO X2:GOSUB 14000:NEXT
15210   X2=0:X3=0:X4=0:GOTO 15020
' -----------------------------------------------------------
'         Text und Einheit auf den Bildschirm ausgeben
' -----------------------------------------------------------
' Eingang: $(0)=Leerstring
'          $(1)=Bezeichnung
'          $(2)=Einheit, wobei "" = keine Einheit
' Ausgang: keine
' lokal  : X1..X2
' global : keine
' Funktion: Auf dem Display wird in der 1. Zeile die Bezeichnung angegeben,
'           in der 2. rechtsbündig die Einheit. Rest bleibt frei.
' 1. mit MotorMaster
'15500 CUR 1,0:P. $(0),                  ; lösche 2. Zeile
'15510 IF ASC($(2),1)=13 GOTO 15530      ; keine Einheit ausgeben wenn <0
'15515 X2=1
'15520 DO:X2=X2+1:UNTIL ASC($(2),X2)=13  ; berechne Länge der Einheit
'15525 CUR 1,17-X2:P. $(2),              ; plaziere ganz rechts
'15530 CUR 0,0:P. $(1),                  ; print 1. Zeile
'15535 CUR 1,0                           ; Cursor auf Startposition Zahl
'15550 RETURN
' 2. mit StepCon
15500 DISPLAY 1,0,"                 "   ; lösche 2. Zeile
15510 IF ASC($(2),1)=13 GOTO 15530      ; keine Einheit ausgeben wenn <0
15515 X2=1
15520 DO:X2=X2+1:UNTIL ASC($(2),X2)=13  ; berechne Länge der Einheit
15525 DISPLAY 1,17-X2:?$(2),            ; plaziere ganz rechts
15530 DISPLAY 0,0:?$(1),                ; print 1. Zeile
15535 DISPLAY 1,0                       ; Cursor auf Startposition Zahl
15550 RETURN
' -----------------------------------------------------------
'         Wert auf Plausibiltät prüfen
' -----------------------------------------------------------
' Eingang: Y = Index einer Variablen des Feldes V()
'          V(Y)=Variable
'          MIN(), MAX() zulässiger Min-, bzw. Maxwert der Variablen
' Ausgang: E=9, wenn nicht korrekt, sonst unverändert
' lokal  : X1..X2
' global : keine
' Funktion: Auf dem Display wird in der 1. Zeile die Bezeichnung angegeben,
'           in der 2. rechtsbündig die Einheit. Rest bleibt frei.
' 1. mit MotorMaster
'15700 IF V(Y)<=MAX(Y).AND.V(Y)>=MIN(Y) THEN RETURN        ; alles i.O.
'15710 CUR 0,0:?$(0)                     ; lösche 1. Zeile
'15720 CUR 0,0
'15730 IF V(Y)>MAX(Y) THEN ?"Wert >",MAX(Y),
'15740 IF V(Y)<MIN(Y) THEN ?"Wert <",MIN(Y),
'15750 FOR K=0 TO 300:NEXT               ; Wartezeit
'15760 GOSUB 15500                       ; wieder alte Anzeige
'15770 E=9                               ; Fehlermeldung
'15790 RETURN
' 2. mit StepCon
15700 IF V(Y)<=MAX(Y).AND.V(Y)>=MIN(Y) THEN RETURN        ; alles i.O.
15710 DISPLAY 0,0,"                "    ; lösche 1. Zeile
15720 DISPLAY 0,0
15730 IF V(Y)>MAX(Y) THEN ?"Wert >",MAX(Y),
15740 IF V(Y)<MIN(Y) THEN ?"Wert <",MIN(Y),
15750 FOR K=0 TO 1000:NEXT              ; Wartezeit für die Meldung
15760 GOSUB 15500                       ; wieder alte Anzeige
15770 E=9                               ; Fehlermeldung
15790 RETURN
'============================ ENDE ====================================
