'       ************************************
'       *** Das Lese- und Speichermodul  ***
'       ************************************
'
' Das im folg. gezeigte Tool ermöglicht es, Variablen in einem Programm,
' z.B. Betriebsparameter o.ä. ins EEPROM oder ins RAM abzuspeichern.
' Relevant sind nur die Zeilen 13000 ff. Der Rest ist nur
' für dieses Beispiel und ein besseres Verständnis aufgeführt
' Im folgenden seien als Beispiel irgendwelche Variablen definiert
' Wie die Unterroutinen aufgerufen werden, ist im Kommentar nachzulesen.
'
100 MTOP  = 3FFFH       ; bis MTOP wird nach dem Einschalten das RAM gelöscht
			; wenn es akkugepuffert ist.
110 GOSUB 10000         ; Initialisierung
; Dauerschleife:
700 DO
710  INPUT "Speicher schreiben (1), Speicher lesen (2), Ende (0):" Z
720  IF Z=1 THEN PUSH VARANZAHL,ADR,ADEPRO:GOSUB 13000 ; abspeichern
730  IF Z=2 THEN PUSH VARANZAHL,ADEPRO:GOSUB 13500 ELSE 700; lesen aus EEPROM
740  ?"FEHLER=",E
;    Der Einfachheit halber werden Fehlervariable von den Unterroutinen
;    ins Hauptmenu übertragen, um den Fehlergrund zu erkennen.
;
; Fehlervariable
;           E=0 : kein Fehler
;           E=20: Lesefehler
;           E=21: Schreibfehler
;           E=22: Lese- und Schreibfehler
750  E=0                ; Fehlerindex wieder gelöscht
790 UNTIL Z=0           ; mit 0 abbrechen
800 STOP
;
; ------------- Initialisierung (nur Beispiel) -----------------------------
10000 ADR   = 5000H     ; Speicheranfangsadresse RAM
10010 ADEPRO  = 9000H   ; Speicheranfangsadresse EPROM
10020 VARANZAHL   = 9   ; Anzahl der Variablen
10030 DIM V(VARANZAHL-1); Dimensionierung des Variablenfeldes V()
10040 GOSUB 11000       ; Defaultwerte zuweisen
10060 RETURN
; ----------- Defaultwerte
11000 V(0)=1
11010 V(1)=0
11020 V(2)=3.2
11030 V(3)=0.125
11040 V(4)=200
11050 V(5)=5.12
11060 V(6)=0
11070 V(7)=99
11080 V(8)=1
11090 V(9)=1
11100 RETURN
; -----------------------------------------------------------
;         Variablenfeld schreiben
; -----------------------------------------------------------
;  Aufruf: PUSH [Anzahl_Variablen, Adresse_RAM, Adresse_EEPROM]
;          GOSUB 13000 ïEinsprungadresse mit Meldung
;          GOSUB 13005 ïEinsprungadresse ohne Meldung
;
; Eingang: Speicheranfangsadresse  ADR für RAM
;          Speicheranfangsadresse  ADEPRO für EPROM
;          Anzahl der zu speich. Variablen VARANZAHL
; Ausgang: Fehlervariable E
;
;                Anzahl
;                ³ Checksumme 1
;                ³ ³ Checksumme 2
;                ³ ³ ³    je 6 Byte pro Variable
; Aufbau:       !_!_!_!__________________ ... ________!
;               ADR
; lokal  : X= laufender Index, X1, X2 = Checksummen
;          X3 = Variablenanzahl,
;          X4 = Startadresse RAM, X5 = Startadresse EEPROM
; global:  E = Fehlervariable, E=0: fehlerfrei
;
13000 CLS:PRINT "abspeichern ... "
13010 POP X5                    ; Beginn im EEPROM
13020 POP X4                    ; Beginn im RAM
13030 POP X3                    ; Variablenanzahl,
13040 XBY(X4) = X3              ; lade Variablenanzahl auf 1. Byte_RAM
13050 X = X4+2                  ; beginne bei RAM+2 mit dem Abspeichern
13060 FOR I=1 TO X3             ; Speichern der Feldvariablenwerte
13070    X = X+6                ; ins RAM, wobei jeweils 6 Byte Speicherplatz
13080    PUSH V(I-1)            ; für eine Variable reserviert werden
13090    ST@ X                  ; X ist Zeiger auf die höchste Adresse
13100 NEXT
13110 X1 = 0:X2 = 0             ; Initialisierung der Checksumvariablen
13120 FOR I=(X4+3) TO X         ; hohe Sicherheit durch
13130   X1= X1.XOR.XBY(I)       ; durchlaufende xor- und
13140   X2= X2 + XBY(I)         ; modulo 2-Verknüpfung
13150   IF X2>255 THEN X2=X2-256
13160 NEXT
13170 XBY(X4+1) = X1            ; Checksummen speichern
13180 XBY(X4+2) = X2
' Speicherbeschreiben in mehrere Varianten für MotorMaster und StepCon
' 1. MotorMaster mit šberschreibschutz
;13300 FOR I=X4 TO X            ; ges. Speicherbereich
;13310    PUSH X5-X4+I,XBY(I)   ; vom RAM ins EEPROM kopieren
;13320    CALL 554BH            ; nur bei MotorMaster
;13330    POP X3:IF X3>0 THEN E=21      ; Fehler vom Stack
;13340 NEXT
' 2. einfaches Kopieren ohne Schreibschutz beim StepCon
13300 FOR I=X4 TO X             ; ges. Speicherbereich
13310    XBY(X5-X4+I)=XBY(I)    ; vom RAM ins EEPROM kopieren
13340 NEXT
13350 RETURN
; -----------------------------------------------------------
;         Variablenfeld lesen
; -----------------------------------------------------------
; Funktion: Ein Speicherbereich aus dem RAM oder EPROM wird eingelesen
;           und geprüft. Im Fehlerfall werden die Variablen mit Default-
;           werten definiert. Im korrekten Fall wird das Variablenfeld
;           auf die Variablen zugewiesen. Aufbau identisch dem Abspeichern.
;
;   Aufruf: PUSH [Anzahl_Variablen, Adresse_EEPROM oder RAM]
;           GOSUB 13500 ïEinsprungadresse mit Meldung
;           GOSUB 13505 ïEinsprungadresse ohne Meldung
;  Eingang: Speicheranfangsadresse EPROM  --> X5
;           Anzahl der Variablen          --> X3
;  Ausgang: Fehlervariable                --> E
;
;    lokal: X= laufender Index, X1, X2 = Checksummen
;           X3 = Variablenanzahl,
;           X5 = Startadresse EEPROM oder RAM
;   global: E = Fehlervariable, E=0: fehlerfrei
;
13500 CLS:?"Speicher lesen  "
13505 POP X5                    ; Beginn im EEPROM
13510 POP X3                    ; Variablenanzahl,
13515 X = X5+3                  ; gehe zu Anfang Daten
13520 X1=0:X2=0                 ; Initialisierung der Checksumvariable
13530 FOR I=X TO (X3*6+X-1)     ; durchlaufende Decodierung
13540    X1=X1.XOR.XBY(I)       ; der beiden Checksummen
13550    X2= X2 + XBY(I)        ; modulo 2-Verknüpfung
13560    IF X2>255 THEN X2=X2-256
13570 NEXT
;berechnete Checksumme mit der im Speicher stehenden überprüfen
13600 IF X1<>XBY(X5+1) THEN GOSUB 13800:RETURN  ; Fehlerfall Chksum1
13610 IF X2<>XBY(X5+2) THEN GOSUB 13800:RETURN  ; Fehlerfall Chksum2
13620 IF X3<>XBY(X5) THEN GOSUB 13800:RETURN    ; Fehlerfall Varzahl
; im korrekten Fall
13710 X=X5+2
13720 FOR I=1 TO X3             ; hole aus dem Speicher die Werte der Variablen
13730    X = X+6                ; und lege sie im Variablen-Feld v ab.
13740    LD@ X                  ; im Speicher sind jeweils 6 Byte für eine
13750    POP V(I-1)             ; Variable reserviert worden.
13760 NEXT
'13770 GOSUB 11400               ; Variablenfeld zuweisen
13780 E=0:RETURN
; im Fehlerfall Defaultwerte lesen:
13800 FOR I=1 TO X3: V(I-1)=0: NEXT ; gesamtes Feld löschen
'13810 GOSUB 11000              ; Defaultwerte zuweisen
13890 E=20:RETURN               ; Fehlervariable E
;============================ ENDE ====================================
