;*****************************************************************************
; 	All rights reserved by Dipl.-Ing (FH) Andreas Hoeger
;	Ditzenbrunner Str. 64, 71254 Ditzingen, Germany
;	Telefon: (+497156)490980	Telefax: (+497156)490981
;	E-Mail: ingbuero@andreas-hoeger.de
;*****************************************************************************
;
;       8051- Programm fuer ATMEL Flash- Mikrocontroller AT89S53
;	
;	Teilprogramm, wird durch INCLUDE eingebunden
;
;       Autor: Andreas Hoeger
;       Datum: 01.11.2000		
;
;	Aenderungen:
;	06_11_00: Menuetastenabfrage begonnen
;	12_11_00: Menuetastenabfrage fortgesetzt
;	18_11_00: LCD_Kontrasteinstellungen und CAN-Sondermode
;	26_11_00: Erweiterung Funktion 'Klemme 15'; Bugfix Mode 00
;	26_11_00: Erweiterung Funktion 'Innenbeleuchtung' Mode 19
;	04_03_02: Erweiterung fuer HSTG gemaess Spec
;	15_03_02: Codereduzierung, Scrollfunktion für Schaltfunktionen
;	02_04_02: weitere Codereduzierung mode 18 up
;	04_04_02: Standardzeilenauswahl implementiert
;	21_04_02: task_std_from_EEPROM eingefuegt
;		  task_check_update geaendert
;		  Standardausgabetasks- Auswahl vervollstaendigt
;	30_04_02: Mode 3B eingefuegt, Bugfix Mode 3A
;		  task_D+Sommer & Winter_in_EEPROM eingefuegt
;	07_05_02: Mode 3C eingefuegt: CAN Datenausgabe Identifier waehlen
;	08_05_02: Mode 3C erweitert; Ueberlaufabsicherung
;       19_06_02: Bugfix # an DPLUS Eintrag in EE fehlte
;	20_06_02: Kommentare korrigiert
;	22_12_02: Alle drei Fehlerspeicher werden mit Mode 3A geloescht
;
;*****************************************************************************

	; Menuesteuerung
	; wird aufgerufen nach der Tastenentprellung wenn eine gueltige
	; Taste erkannt wurde
	; --> auch im Sonderausgabe- Modus, somit ist ein Abbruch desselben
	; moeglich ! Dies geschieht durch Abfrage des Sondermode-Bits zu
	; Beginn dieser Routine
	;
	; Eingangswerte: PRELL_BITS.[7:4] entsprechen den Tasten
	;                LCD_MENU_CONTROL.5 ist gesetzt = gueltige Taste
	;				    
	; --> TASTEN NORMALERWEISE LOW- AKTIV, ABER HIER ZUVOR INVERTIERT
	;     DAMIT BESSER LESBAR; ES GILT JETZT "GEDRUECKT = 1"
	; Invertierung geschah bereits vor Tastenentprellung !
	
	; zuerst pruefen ob Menuemode schon aktiv ist
	; (wird durch Menü-Taste aktiviert und deaktiviert)
	; LCD_MENU_CONTROL. ist das Menümodus- Erkennungs- Bit
	; wenn noch nicht aktiv, dann setzen

	; Tasten-Bezeichnungen fuer entprellte Tasten:

	; Menu- Taste 		 = E = PRELL_BITS.4 = BUTTON_P_MENU
	; Pfeil nach oben Taste  = H = PRELL_BITS.7 = BUTTON_P_UP
	; OK- Taste 		 = G = PRELL_BITS.6 = BUTTON_P_OK
	; Pfeil nach unten Taste = F = PRELL_BITS.5 = BUTTON_P_DOWN

menu:	jnb	LCD_MENU_CONTROL.6,normalmenu	; Sondermode aktiv?

	; Jede Taste (und nur bei gedrueckter Taste ist man hier)
	; setzt den Sondermode zurueck.

	clr	LCD_MENU_CONTROL.6

	; Update-Bits der anderen Ausgabemodi aktivieren:

	setb	LCD_DATA_TASK_L1.7
	setb	LCD_DATA_TASK_L2.7
	setb	LCD_DATA_TASK_L3.7
	setb	LCD_DATA_TASK_L4.7

	mov	LCD_MENU_MODE_NR,#00H		; Menuemode zuruecksetzen
	call	set_cursor_line1
	clr	BITS.1				; Bit 'Funktionsebene'
	
	jmp	menu_end

normalmenu:
	jb	LCD_MENU_CONTROL.7,menu_ist_on

	; "erster" Tastendruck: pruefen, ob es die MENU- Taste ist	

	jnb	BUTTON_P_MENU,go_end		; erster Tastendruck !=
						; Menue-Taste = ENDE	

	setb	LCD_MENU_CONTROL.7		; Menuemodus aktivieren
						; denn es war Menuetaste
	; Das Update-Flag des Menue- Modes muss gesetzt werden.
	; Dieses Flag "LCD_MENU_CONTROL.4" gilt fuer alle vier Zeilen

	setb	LCD_MENU_CONTROL.4		; Menu Mode Update Flag

go_end:	jmp	menu_end			
	
menu_ist_on:

	; wenn MENU- Taste: wieder aus MENU- Mode rausgehen
	
	jnb	BUTTON_P_MENU,menu_start	
	clr	LCD_MENU_CONTROL.7		; Menuemodus deaktivieren
						; und in vorherigen Modus 
						; zurueckschalten
	; Update-Bits der anderen Ausgabemodi aktivieren:

	setb	LCD_DATA_TASK_L1.7
	setb	LCD_DATA_TASK_L2.7
	setb	LCD_DATA_TASK_L3.7
	setb	LCD_DATA_TASK_L4.7
	setb	LCD_XDATA_TASK.7

	mov	LCD_MENU_MODE_NR,#00H		; Menuemode zuruecksetzen
	call	set_cursor_line1

	clr	BITS.1				; Bit 'Funktionsebene'
						; zuruecksetzen
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	jmp	menu_end			; entspricht return

menu_start:

	; Menue- Modus feststellen und verzweigen

	mov	A,LCD_MENU_MODE_NR
	cjne	A,#00H,test_mode_000
	jmp	mode_00
test_mode_000:
test_mode_001:
	cjne	A,#10H,test_mode_002
	jmp	mode_10
test_mode_002:
	cjne	A,#20H,test_mode_003
	jmp	mode_20
test_mode_003:
	cjne	A,#30H,test_mode_004
	jmp	mode_30
test_mode_004:
	cjne	A,#40H,test_mode_005
	jmp	mode_40
test_mode_005:
	cjne	A,#38H,test_mode_006
	jmp	mode_38
test_mode_006:
	cjne	A,#39H,test_mode_007
	jmp	mode_39				
test_mode_007:					
	cjne	A,#3AH,test_mode_008
	jmp	mode_3A
test_mode_008:
	cjne	A,#3BH,test_mode_009
	jmp	mode_3B
test_mode_009:
	cjne	A,#18H,test_mode_010
	jmp	mode_18
test_mode_010:
	cjne	A,#19H,test_mode_011
	jmp	mode_19
test_mode_011:
	cjne	A,#1AH,test_mode_012
	jmp	mode_1A
test_mode_012:
	cjne	A,#1BH,test_mode_013
	jmp	mode_1B
test_mode_013:
	cjne	A,#1CH,test_mode_014
	jmp	mode_1C
test_mode_014:
	cjne	A,#1DH,test_mode_015
	jmp	mode_1D
test_mode_015:
	cjne	A,#1EH,test_mode_016
	jmp	mode_1E
test_mode_016:
;	cjne	A,#1FH,test_mode_017
;	jmp	mode_1F
test_mode_017:					
	cjne	A,#28H,test_mode_018
	jmp	mode_28
test_mode_018:					
;	cjne	A,#29H,test_mode_019
;	jmp	mode_29
test_mode_019:					
;	cjne	A,#2AH,test_mode_020
;	jmp	mode_2A
test_mode_020:					
	cjne	A,#48H,test_mode_021
	jmp	mode_48
test_mode_021:					
	cjne	A,#49H,test_mode_022
	jmp	mode_49
test_mode_022:					
	cjne	A,#4AH,test_mode_023
	jmp	mode_4A
test_mode_023:					
	cjne	A,#4BH,test_mode_024
	jmp	mode_4B
test_mode_024:					
	cjne	A,#4CH,test_mode_025
	jmp	mode_4C
test_mode_025:					
	cjne	A,#4DH,test_mode_026
	jmp	mode_4D
test_mode_026:					
	cjne	A,#4EH,test_mode_027
	jmp	mode_4E
test_mode_027:					
	cjne	A,#3CH,test_mode_028
	jmp	mode_3C
test_mode_028:					
	cjne	A,#4FH,test_mode_00x
	jmp	mode_4F

test_mode_00x:
	jmp	mode_error

;*****************************************************************************

mode_00:
	; hier Taste und Aktion feststellen
	jb	BUTTON_P_UP,mode_00_up
	jb	BUTTON_P_DOWN,mode_00_down
	jb	BUTTON_P_OK,mode_00_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_00_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_00_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_00_alle
							
mode_00_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_00_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#10H
	call	set_cursor_line1
	jmp	mode_00_alle

mode_00_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_00_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle

mode_00_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_00_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle		; nochmal Texte von Mode 00
					; ausgeben

	;*****

mode_00_ok:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_00_error	; nicht Zeile 1 ?

	; ja, gehe zu --> Schaltfunktionen, erste Auswahl

	; Sonderfall: springe direkt nach Mode 18 weil
	; in diesem Fall zuvor keine Pfeiltaste auf Mode 10 umstellt !
	; wenn es zuvor Pfeiltasten gab, kommt man ueber Mode 10 dorthin

	mov	LCD_MENU_MODE_NR,#18H		; Mode 18 einstellen
	jmp	mode_10_alle			; Texte Mode 00 ausgeben
							
	;*****

mode_00_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_00_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle	
							
mode_00_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_00_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle

mode_00_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_00_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode 00 lassen
	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle

mode_00_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_00_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle			; nochmal Texte von
						; Mode 00 ausgeben
	
	;*****

mode_00_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG610		; Schaltfunktionen
	call	save_dptr_line1	
	mov	DPTR,#MSG620		; Sondermodus
	call	save_dptr_line2
	mov	DPTR,#MSG630		; Einstellungen
	call	save_dptr_line3
	mov	DPTR,#MSG640		; Anzeigen- Auswahl
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

mode_00_error:

	jmp	mode_error

;*****************************************************************************

mode_10:
	; hier Taste und Aktion feststellen
	jb	BUTTON_P_UP,mode_10_up
	jb	BUTTON_P_DOWN,mode_10_down
	jb	BUTTON_P_OK,mode_10_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_10_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_10_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_00_alle
							
mode_10_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_10_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#10H
	call	set_cursor_line1
	jmp	mode_00_alle

mode_10_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_10_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle

mode_10_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_10_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle		; nochmal Texte von Mode 00
					; ausgeben

	;*****

mode_10_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und zu Mode 18 wechseln
	
	mov	LCD_MENU_MODE_NR,#18H
	call	set_cursor_line1

	jmp	mode_10_alle

	;*****

mode_10_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_10_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#20H			; SONDERMODUS
	call	set_cursor_line2
	jmp	mode_00_alle	
							
mode_10_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_10_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#30H			; EINSTELLUNGEN
	call	set_cursor_line3
	jmp	mode_00_alle

mode_10_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_10_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode 10 lassen
	mov	LCD_MENU_MODE_NR,#40H			; ANZEIGEN-WAHL
	call	set_cursor_line4
	jmp	mode_00_alle

mode_10_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_10_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle			; nochmal Texte von
						; Mode 00 ausgeben
	
	;*****

mode_10_error:

	jmp	mode_error

	;*****

mode_10_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG611		; Display Beleuchtung
	call	save_dptr_line1	
	mov	DPTR,#MSG612		; Standheizung
	call	save_dptr_line2
	mov	DPTR,#MSG613		; Innenbeleuchtung
	call	save_dptr_line3
	mov	DPTR,#MSG614		; Steckdose
	call	save_dptr_line4

	ret

	;*****

mode_10_rotated1:

	; vier LCD- Zeilen eintragen
	; Auswahl um eine Zeile nach unten rotiert

	mov	DPTR,#MSG612		; Standheizung
	call	save_dptr_line1	
	mov	DPTR,#MSG613		; Innenbeleuchtung
	call	save_dptr_line2
	mov	DPTR,#MSG614		; Steckdose
	call	save_dptr_line3
	mov	DPTR,#MSG615		; Powerlicht
	call	save_dptr_line4

	ret

	;*****

mode_10_rotated2:

	; vier LCD- Zeilen eintragen
	; Auswahl um zwei Zeilen nach unten rotiert

	mov	DPTR,#MSG613		; Innenbeleuchtung
	call	save_dptr_line1	
	mov	DPTR,#MSG614		; Steckdose
	call	save_dptr_line2
	mov	DPTR,#MSG615		; Powerlicht
	call	save_dptr_line3
	mov	DPTR,#MSG616		; 
	call	save_dptr_line4

	ret

	;*****

mode_10_rotated3:

	; vier LCD- Zeilen eintragen
	; Auswahl um drei Zeilen nach unten rotiert

	mov	DPTR,#MSG614		; Steckdose
	call	save_dptr_line1	
	mov	DPTR,#MSG615		; Powerlicht
	call	save_dptr_line2
	mov	DPTR,#MSG616		; Klemme 15
	call	save_dptr_line3
	mov	DPTR,#MSG617		; Trennrelais Notstart
	call	save_dptr_line4

	ret

;*****************************************************************************

mode_18: 
	; Sonderfunktion fuer Schaltfunktionen

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 18 = Bestaetigung Anzeigetext
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 18 wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 18 ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit18
	jmp	mit_bit18

nobit18:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_18_up
	jb	BUTTON_P_DOWN,mode_18_down
	jb	BUTTON_P_OK,mode_18_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_18_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_18_error	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_10_alle
							
	;*****

mode_18_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#18H
	call	set_cursor_line1

	jmp	mode_18_alle

	;*****

mode_18_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_18_error	; Zeile 1 ?
	mov	LCD_MENU_MODE_NR,#19H
	call	set_cursor_line2
	jmp	mode_10_alle	
							
	;*****

mode_18_error:

	jmp	mode_error

	;*****

mode_18_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mit_bit18:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Displaybeleuchtung ein/aus schalten

	jb	BUTTON_P_UP,mode_18_mitbit_up
	jb	BUTTON_P_DOWN,mode_18_mitbit_down
	jb	BUTTON_P_OK,mode_18_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_18_mitbit_up:

	; hier Displaybeleuchtung 'ein' - wenn's schon ist dann bleibt's

        call    displaybel_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_18_mitbit_down:

        call    displaybel_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_18_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_19: 
	; Sonderfunktion fuer Schaltfunktionen

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 19 = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 19 wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 19 ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit19
	jmp	mit_bit19

nobit19:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_19_up
	jb	BUTTON_P_DOWN,mode_19_down
	jb	BUTTON_P_OK,mode_19_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****
						
mode_19_up:
	jnb	LCD_MENU_CONTROL.1,mode_19_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#18H
	call	set_cursor_line1
	jmp	mode_10_alle

	;*****

mode_19_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#19H
	call	set_cursor_line1

	jmp	mode_19_alle

	;*****

mode_19_down:
	jnb	LCD_MENU_CONTROL.1,mode_19_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#1AH
	call	set_cursor_line3
	jmp	mode_10_alle
	
	;*****

mode_19_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_19_error:

	jmp	mode_error

	;*****

mit_bit19:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_19_mitbit_up
	jb	BUTTON_P_DOWN,mode_19_mitbit_down
	jb	BUTTON_P_OK,mode_19_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_19_mitbit_up:

	; hier Standheizung 'ein' - wenn's schon ist dann bleibt's

        call    menu_hzg_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_19_mitbit_down:

        call    menu_hzg_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_19_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_1A: 
	; Sonderfunktion fuer Schaltfunktionen

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 1A = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 1A wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 1A ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit1A
	jmp	mit_bit1A

nobit1A:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_1A_up
	jb	BUTTON_P_DOWN,mode_1A_down
	jb	BUTTON_P_OK,mode_1A_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

					
mode_1A_up:
	jnb	LCD_MENU_CONTROL.2,mode_1A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#19H
	call	set_cursor_line2
	jmp	mode_10_alle

	;*****

mode_1A_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#1AH
	call	set_cursor_line1

	jmp	mode_1A_alle

	;*****

mode_1A_down:
	jnb	LCD_MENU_CONTROL.2,mode_1A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1BH
	call	set_cursor_line3
	jmp	mode_10_rotated1

	;*****

mode_1A_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_1A_error:

	jmp	mode_error

	;*****

mit_bit1A:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_1A_mitbit_up
	jb	BUTTON_P_DOWN,mode_1A_mitbit_down
	jb	BUTTON_P_OK,mode_1A_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1A_mitbit_up:

	; hier Innenbeleuchtung 'ein' - wenn's schon ist dann bleibt's

        call    innenbel_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_1A_mitbit_down:

        call    innenbel_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_1A_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_1B: 
	; Schaltfunktion "Steckdose"

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 1B = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 1B wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 1B ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit1B
	jmp	mit_bit1B

nobit1B:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_1B_up
	jb	BUTTON_P_DOWN,mode_1B_down
	jb	BUTTON_P_OK,mode_1B_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****
				
mode_1B_up:
	jnb	LCD_MENU_CONTROL.2,mode_1B_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1AH
	call	set_cursor_line3
	jmp	mode_10_alle

	;*****

mode_1B_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#1BH
	call	set_cursor_line1

	jmp	mode_1B_alle

	;*****

mode_1B_down:
	jnb	LCD_MENU_CONTROL.2,mode_1B_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1CH
	call	set_cursor_line3
	jmp	mode_10_rotated2

	;*****

mode_1B_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_1B_error:

	jmp	mode_error

	;*****

mit_bit1B:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_1B_mitbit_up
	jb	BUTTON_P_DOWN,mode_1B_mitbit_down
	jb	BUTTON_P_OK,mode_1B_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1B_mitbit_up:

	; hier Steckdose 'ein' - wenn's schon ist dann bleibt's

        call    steckdose_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_1B_mitbit_down:

        call    steckdose_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_1B_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_1C: 
	; Schaltfunktion "Powerlicht"  --> PRELIMINARY

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 1C = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 1C wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 1C ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit1C
	jmp	mit_bit1C

nobit1C:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_1C_up
	jb	BUTTON_P_DOWN,mode_1C_down
	jb	BUTTON_P_OK,mode_1C_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****
				
mode_1C_up:
	jnb	LCD_MENU_CONTROL.2,mode_1C_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1BH
	call	set_cursor_line3
	jmp	mode_10_rotated1

	;*****

mode_1C_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#1CH
	call	set_cursor_line1

	jmp	mode_1C_alle

	;*****

mode_1C_down:
	jnb	LCD_MENU_CONTROL.2,mode_1C_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1DH
	call	set_cursor_line3
	jmp	mode_10_rotated3
	
	;*****

mode_1C_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_1C_error:

	jmp	mode_error

	;*****

mit_bit1C:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_1C_mitbit_up
	jb	BUTTON_P_DOWN,mode_1C_mitbit_down
	jb	BUTTON_P_OK,mode_1C_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1C_mitbit_up:

	; hier Steckdose 'ein' - wenn's schon ist dann bleibt's

 ;       call    steckdose_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_1C_mitbit_down:

;        call    steckdose_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_1C_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_1D: 
	; Schaltfunktion "Wegfahrsperre" --> PRELIMINARY

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 1D = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 1D wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 1D ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit1D
	jmp	mit_bit1D

nobit1D:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_1D_up
	jb	BUTTON_P_DOWN,mode_1D_down
	jb	BUTTON_P_OK,mode_1D_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1D_up:
	jnb	LCD_MENU_CONTROL.2,mode_1D_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1CH
	call	set_cursor_line3
	jmp	mode_10_rotated2

	;*****

mode_1D_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#1DH
	call	set_cursor_line1

	jmp	mode_1D_alle

	;*****

mode_1D_down:
	jnb	LCD_MENU_CONTROL.2,mode_1D_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#1EH
	call	set_cursor_line4
	jmp	mode_10_rotated3

	;*****

mode_1D_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_1D_error:

	jmp	mode_error

	;*****

mit_bit1D:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_1D_mitbit_up
	jb	BUTTON_P_DOWN,mode_1D_mitbit_down
	jb	BUTTON_P_OK,mode_1D_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1D_mitbit_up:

	; hier Steckdose 'ein' - wenn's schon ist dann bleibt's

;        call    steckdose_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_1D_mitbit_down:

;        call    steckdose_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_1D_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_1E: 
	; Schaltfunktion "Notstart" (Trennrelais verbinden)

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 1E = Bestaetigung Anzeigefunktion
	;    Text "ein   OK   aus" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 10 gelten lassen
	; 1= Mode 1E wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    tatsaechlich ein- und ausschalten

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 1E ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit1E
	jmp	mit_bit1E

nobit1E:

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 10

	jb	BUTTON_P_UP,mode_1E_up
	jb	BUTTON_P_DOWN,mode_1E_down
	jb	BUTTON_P_OK,mode_1E_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1E_up:
	jnb	LCD_MENU_CONTROL.3,mode_1E_error	; Zeile 4 ?
	mov	LCD_MENU_MODE_NR,#1DH
	call	set_cursor_line3
	jmp	mode_10_rotated3	; nochmal Texte von Mode 10
					; ausgeben

	;*****

mode_1E_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#1EH
	call	set_cursor_line1

	jmp	mode_1E_alle

	;*****

mode_1E_down:
	jnb	LCD_MENU_CONTROL.3,mode_1E_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#1EH
	call	set_cursor_line4
	jmp	mode_10_rotated3		; nochmal Texte von
						; Mode 10 ausgeben
	
	;*****

mode_1E_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG607		; ein --    -- aus
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_1E_error:

	jmp	mode_error

	;*****

mit_bit1E:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Standheizung ein/aus schalten

	jb	BUTTON_P_UP,mode_1E_mitbit_up
	jb	BUTTON_P_DOWN,mode_1E_mitbit_down
	jb	BUTTON_P_OK,mode_1E_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_1E_mitbit_up:

	; hier Trennrelais 'ein' - wenn's schon ist dann bleibt's

        call    trennrel_ein
 
        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_1E_mitbit_down:

        call    trennrel_aus
   
    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

	;*****

mode_1E_mitbit_ok:

	; hier keine Funktion, nur Taste abfangen

    	; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	ret

;*****************************************************************************

mode_20:
	; hier Taste und Aktion feststellen
	jb	BUTTON_P_UP,mode_20_up
	jb	BUTTON_P_DOWN,mode_20_down
	jb	BUTTON_P_OK,mode_20_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_20_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_20_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_00_alle
							
mode_20_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_20_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#10H
	call	set_cursor_line1
	jmp	mode_00_alle

mode_20_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_20_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle

mode_20_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_20_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle		; nochmal Texte von Mode 00
					; ausgeben

	;*****

mode_20_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und zu Mode 28 wechseln
	
	mov	LCD_MENU_MODE_NR,#28H
	call	set_cursor_line1

	jmp	mode_20_alle

	;*****

mode_20_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_20_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle	
							
mode_20_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_20_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle

mode_20_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_20_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode 20 lassen
	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle

mode_20_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_20_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle			; nochmal Texte von
						; Mode 00 ausgeben
	
	;*****

mode_20_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG621		; CAN- Ausgabemode
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

mode_20_error:

	jmp	mode_error

;*****************************************************************************

mode_28: 
	; Wechsel in den Sondermodus CAN- Ausgabe

	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf: Pfeile bezogen auf Texte Mode 20

	; Sobald das Sondermode-Bit gesetzt ist (LCD_MENU_CONTROL.6)
	; wird bereits am Anfang dieser Routine mit allen Tasten
	; der Sondermode verlassen

	jb	BUTTON_P_UP,mode_28_up
	jb	BUTTON_P_DOWN,mode_28_down
	jb	BUTTON_P_OK,mode_28_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_28_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_28_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_20_alle
							
mode_28_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_28_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#28H
	call	set_cursor_line1
	jmp	mode_20_alle

mode_28_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_28_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#29H
	call	set_cursor_line2
	jmp	mode_20_alle

mode_28_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_28_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#2AH
	call	set_cursor_line3
	jmp	mode_20_alle		; nochmal Texte von Mode 20
					; ausgeben

	;*****

mode_28_ok:

	; eigentlich nur wenn Zeile 1, also CAN:

	setb	LCD_MENU_CONTROL.6	; Sondermode einschalten
	
	mov	LCD_XDATA_TASK,#70H	; Task "CAN-Daten" vorgeben
					; für Sonderausgabemodus

	; Updateflag wird von TASK-CAN-OUT gesetzt !

	clr	LCD_MENU_CONTROL.7	; Bit 7 in Menuemode zuruecksetzen
					; weil Sondermode (Bit6) durch alle
					; Tasten beendet werden koennen soll
	mov	LCD_MENU_MODE_NR,#00H	; Menuemode zuruecksetzen
	call	set_cursor_line1

	jmp	mode_00_alle		; wieder Pointer fuer Texte
					; des Mode 00 eintragen
					; und UpdateFlags setzen

	;*****

mode_28_error:

	jmp	mode_error

	;*****

mode_28_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_28_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#29H
	call	set_cursor_line2
	jmp	mode_20_alle	
							
mode_28_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_28_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#2AH
	call	set_cursor_line3
	jmp	mode_20_alle

mode_28_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_28_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#2BH
	call	set_cursor_line4
	jmp	mode_20_alle

mode_28_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_28_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#2BH
	call	set_cursor_line4
	jmp	mode_20_alle			; nochmal Texte von
						; Mode 20 ausgeben
	
	;*****

;mode_28_alle:

	; keine Textausgabe noetig da Umschaltung in Sondermode

	ret

;*****************************************************************************

mode_30:
	; hier Taste und Aktion feststellen
	jb	BUTTON_P_UP,mode_30_up
	jb	BUTTON_P_DOWN,mode_30_down
	jb	BUTTON_P_OK,mode_30_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_30_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_30_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_00_alle
							
mode_30_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_30_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#10H
	call	set_cursor_line1
	jmp	mode_00_alle

mode_30_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_30_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle

mode_30_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_30_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle		; nochmal Texte von Mode 00
					; ausgeben

	;*****

mode_30_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und zu Mode 38 wechseln
	
	mov	LCD_MENU_MODE_NR,#38H
	call	set_cursor_line1

	jmp	mode_30_alle

	;*****

mode_30_error:

	jmp	mode_error

	;*****

mode_30_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_30_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle	
							
mode_30_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_30_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle

mode_30_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_30_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode 30 lassen
	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle

mode_30_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_30_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle			; nochmal Texte von
						; Mode 00 ausgeben
	
	;*****

mode_30_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG631		; LCD Kontrast
	call	save_dptr_line1	
	mov	DPTR,#MSG632		; Defaultwerte anzeigen
	call	save_dptr_line2
	mov	DPTR,#MSG633		; Fehlerspeicher loeschen
	call	save_dptr_line3
	mov	DPTR,#MSG634		; D+ Sommer / Winter
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mode_30_rotated1:

	; vier LCD- Zeilen eintragen
	; Auswahl um eine Zeile nach unten rotiert

	mov	DPTR,#MSG632		; Defaultwerte anzeigen
	call	save_dptr_line1	
	mov	DPTR,#MSG633		; Fehlerspeicher loeschen
	call	save_dptr_line2
	mov	DPTR,#MSG634		; D+ Sommer / Winter
	call	save_dptr_line3
	mov	DPTR,#MSG635		; CAN- Botschaftswahl
	call	save_dptr_line4

	ret


;*****************************************************************************

mode_38: 
	; Sonderfunktion zur Verstellung des LCD- Kontrastes

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 38 = Bestaetigung LCD- Kontrast
	;    Text "hell   OK   dunkel" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 30 gelten lassen
	; 1= Mode 38 wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    den Kontrast tatsaechlich verstellen


	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 38 ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit38
	jmp	mit_bit38

nobit38:
	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf, d.h. Pfeile bezogen auf Texte Mode 30

	jb	BUTTON_P_UP,mode_38_up
	jb	BUTTON_P_DOWN,mode_38_down
	jb	BUTTON_P_OK,mode_38_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_38_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_38_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_30_alle
							
mode_38_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_38_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#38H
	call	set_cursor_line1
	jmp	mode_30_alle

mode_38_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_38_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#39H
	call	set_cursor_line2
	jmp	mode_30_alle

mode_38_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_38_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#3AH
	call	set_cursor_line3
	jmp	mode_30_alle		; nochmal Texte von Mode 30
					; ausgeben

	;*****

mode_38_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#38H
	call	set_cursor_line1

	jmp	mode_38_alle

	;*****

mode_38_error:

	jmp	mode_error

	;*****

mode_38_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_38_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#39H
	call	set_cursor_line2
	jmp	mode_30_alle	
							
mode_38_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_38_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#3AH
	call	set_cursor_line3
	jmp	mode_30_alle

mode_38_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_38_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode wechseln
	mov	LCD_MENU_MODE_NR,#3BH
	call	set_cursor_line4
	jmp	mode_30_alle

mode_38_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_38_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#3BH
	call	set_cursor_line4
	jmp	mode_30_alle			; nochmal Texte von
						; Mode 30 ausgeben
	
	;*****

mode_38_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG608		; hell -- OK -- dunkel
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****
mit_bit38:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Kontrast verstellen

	jb	BUTTON_P_UP,mode_38_mitbit_up
	jb	BUTTON_P_DOWN,mode_38_mitbit_down
	jb	BUTTON_P_OK,mode_38_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_38_mitbit_up:

	; hier Kontrast nach "heller" verstellen

        call    eepot_up
        call    eepot_up

	ret

	;*****

mode_38_mitbit_ok:

        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	ret

	;*****

mode_38_mitbit_down:

        call    eepot_down
        call    eepot_down

	ret

;*****************************************************************************

mode_39: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_39_up
	jb	BUTTON_P_DOWN,mode_39_down
	jb	BUTTON_P_OK,mode_39_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_39_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.1,mode_39_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#38H
	call	set_cursor_line1
	jmp	mode_30_alle
							
	;*****

mode_39_ok:

	call	task_default_from_EEPROM

        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	;*****

mode_39_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.1,mode_39_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#3AH
	call	set_cursor_line3
	jmp	mode_30_alle	
							
	;*****

mode_39_error:

	jmp	mode_error

;*****************************************************************************

mode_3A: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_3A_up
	jb	BUTTON_P_DOWN,mode_3A_down
	jb	BUTTON_P_OK,mode_3A_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_3A_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_3A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#39H
	call	set_cursor_line2
	jmp	mode_30_alle
							
	;*****

mode_3A_ok:

	mov	I2C_ID,#EE_ID
	mov	I2C_DATA,#00H			; Fehler eintragen

	; es soll der Fehlerspeicher HSTG + ZSTG + MSTG
	; geloescht werden; auf Anfang FSZG-Fehlerspeicher setzen

	mov	CNT1,#(EE_ERRORMEM_LENGTH+EE_ERRORMEM_LENGTH_ZSTG+EE_ERRORMEM_LENGTH_MSTG)	
					; gesamte Laenge aller EEPROM Fehlerspeicher
	dec	CNT1			; Anzahl "Rotieraktionen"

	mov	I2C_ADR_L,#EE_ERRORMEM_ZSTG_0	; Byte 0 des ersten Fehlerspeichers
del_loop:
	call	write_byte
	inc	I2C_ADR_L
	djnz	CNT1,del_loop	
	
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	;*****

mode_3A_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_3A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#3BH
	call	set_cursor_line3
	jmp	mode_30_rotated1	
							
	;*****

mode_3A_error:

	jmp	mode_error

;*****************************************************************************

mode_3B:
	; Sonderfunktion zur Einstellung Trennrelais- Schaltverhalten
	; Sommer = Zweitbatterie wird gelegentlich zum Anlassen mitverwendet
	; Winter = Zweitbatterie wird nie zum Anlassen verwendet

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 38 = Bestaetigung LCD- Kontrast
	;    Text "hell   OK   dunkel" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 30 gelten lassen
	; 1= Mode 38 wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    den Kontrast tatsaechlich verstellen

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 3B ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit3B
	jmp	mit_bit3B

nobit3B:
	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf, d.h. Pfeile bezogen auf Texte Mode 30
 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_3B_up
	jb	BUTTON_P_DOWN,mode_3B_down
	jb	BUTTON_P_OK,mode_3B_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_3B_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_3B_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#3AH
	call	set_cursor_line3
	jmp	mode_30_alle
							
	;*****

mode_3B_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#3BH
	call	set_cursor_line1

	jmp	mode_3B_alle

	;*****

mode_3B_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_3B_error	; Zeile 3 ?

	mov	LCD_MENU_MODE_NR,#3CH	
	call	set_cursor_line4
	jmp	mode_30_rotated1	
							
	;*****

mode_3B_error:

	jmp	mode_error

	;*****

mode_3B_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG606		; Sommer --- Winter
	call	save_dptr_line1	
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mit_bit3B:
	; hier ist der Funktionsmode aktiv, d.h. Pfeiltasten
	; sollen Kontrast verstellen

	jb	BUTTON_P_UP,mode_3B_mitbit_up
	jb	BUTTON_P_DOWN,mode_3B_mitbit_down
	jb	BUTTON_P_OK,mode_3B_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_3B_mitbit_up:

	call	task_DPLUSSommer_in_EEPROM

        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

	;*****

mode_3B_mitbit_ok:

        ; ungueltige Eingabe, mache nix
	; nur Sommer (up) oder Winter (down) gelten lassen

	ret

	;*****

mode_3B_mitbit_down:

	call	task_DPLUSWinter_in_EEPROM

        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben

;*****************************************************************************

mode_3C:
	; Sonderfunktion zur Einstellung der CAN- Datenausgabe- Botschaft

	; Abgefragt wird BITS.1 als Statusanzeige "Funktionsebene"
	; 0= erstes mal in Mode 3C = Bestaetigung LCD- Kontrast
	;    Text "-   OK   +" anzeigen 
	;    und Pfeile fuer Menuetexte Mode 30 gelten lassen
	; 1= Mode 3C wiederholt OK, jetzt BITS. 1 gesetzt und mit den Pfeilen
	;    den Kontrast tatsaechlich verstellen

	; zuerst Bit BITS.1 abfragen und feststellen, ob es der erste Aufruf 
	; Mode 3C ist oder ob die Funktionsebene schon aktiviert ist 
	; (BITS.1 gesetzt)

	jnb	BITS.1,nobit3C
	jmp	mit_bit3C

nobit3C:
	; hier Taste und Aktion feststellen
	; fuer ersten Aufruf, d.h. Pfeile bezogen auf Texte Mode 30
 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_3C_up
	jb	BUTTON_P_DOWN,mode_3C_down
	jb	BUTTON_P_OK,mode_3C_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_3C_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.3,mode_3C_error	; Zeile 4 ?
	mov	LCD_MENU_MODE_NR,#3BH
	call	set_cursor_line3
	jmp	mode_30_rotated1
							
	;*****

mode_3C_ok:

	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und BITS.1 setzen
	
	setb	BITS.1			; umschalten in Funktionsmode
	mov	LCD_MENU_MODE_NR,#3CH
	call	set_cursor_line1

	jmp	mode_3C_alle

	;*****

mode_3C_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.3,mode_3C_error	; Zeile 4 ?

	mov	LCD_MENU_MODE_NR,#3CH	; nur fuenf Zeilen vorlaufig
	call	set_cursor_line4
	jmp	mode_30_alle	
							
	;*****

mode_3C_error:

	jmp	mode_error

	;*****

mode_3C_alle:

	; Botschaftsnummer eintragen in Zeile 1;
	; !! Es werden nur die benutzten Botschaften durchgezaehlt

	; Achtung ! Vergleichsnummern fortlaufend hochzaehlen da
	; in der Menueauswahl nur jeweils inc / dec wird

	mov	A,CAN_BOX_SWITCH
test_ident_500:
	cjne	A,#00H,test_ident_501
	mov	DPTR,#MSG850		; Botschaft 500 gewaehlt
	mov	CAN_BOX_6_L,#00H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_501:
	cjne	A,#01H,test_ident_502
	mov	DPTR,#MSG851		; Botschaft 501 gewaehlt
	mov	CAN_BOX_6_L,#01H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_502:
	cjne	A,#02H,test_ident_503
	mov	DPTR,#MSG852		; Botschaft 502 gewaehlt
	mov	CAN_BOX_6_L,#02H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_503:
	cjne	A,#03H,test_ident_504
	mov	DPTR,#MSG853		; Botschaft 503 gewaehlt
	mov	CAN_BOX_6_L,#03H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_504:
	cjne	A,#04H,test_ident_505
	mov	DPTR,#MSG854		; Botschaft 504 gewaehlt
	mov	CAN_BOX_6_L,#04H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_505:
	cjne	A,#05H,test_ident_506
	mov	DPTR,#MSG855		; Botschaft 505 gewaehlt
	mov	CAN_BOX_6_L,#05H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_506:
	cjne	A,#06H,test_ident_507
	mov	DPTR,#MSG856		; Botschaft 506 gewaehlt
	mov	CAN_BOX_6_L,#06H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_507:
	cjne	A,#07H,test_ident_508
	mov	DPTR,#MSG857		; Botschaft 507 gewaehlt
	mov	CAN_BOX_6_L,#07H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_508:
	cjne	A,#08H,test_ident_509
	mov	DPTR,#MSG858		; Botschaft 508 gewaehlt
	mov	CAN_BOX_6_L,#08H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_509:
	cjne	A,#09H,test_ident_510
	mov	DPTR,#MSG859		; Botschaft 509 gewaehlt
	mov	CAN_BOX_6_L,#09H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_510:
	cjne	A,#0AH,test_ident_511
	mov	DPTR,#MSG860		; Botschaft 510 gewaehlt
	mov	CAN_BOX_6_L,#10H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_511:
	cjne	A,#0BH,test_ident_512
	mov	DPTR,#MSG861		; Botschaft 511 gewaehlt
	mov	CAN_BOX_6_L,#11H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_512:
	cjne	A,#0CH,test_ident_513
	mov	DPTR,#MSG862		; Botschaft 512 gewaehlt
	mov	CAN_BOX_6_L,#12H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_513:
	cjne	A,#0DH,test_ident_517
	mov	DPTR,#MSG863		; Botschaft 513 gewaehlt
	mov	CAN_BOX_6_L,#13H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_517:
	cjne	A,#0EH,test_ident_518
	mov	DPTR,#MSG867		; Botschaft 517 gewaehlt
	mov	CAN_BOX_6_L,#17H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_518:
	cjne	A,#0FH,test_ident_519
	mov	DPTR,#MSG868		; Botschaft 518 gewaehlt
	mov	CAN_BOX_6_L,#18H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_519:
	cjne	A,#10H,test_ident_520
	mov	DPTR,#MSG869		; Botschaft 519 gewaehlt
	mov	CAN_BOX_6_L,#19H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_520:
	cjne	A,#11H,test_ident_521
	mov	DPTR,#MSG870		; Botschaft 520 gewaehlt
	mov	CAN_BOX_6_L,#20H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_521:
	cjne	A,#12H,test_ident_522
	mov	DPTR,#MSG871		; Botschaft 521 gewaehlt
	mov	CAN_BOX_6_L,#21H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_522:
	cjne	A,#13H,test_ident_527
	mov	DPTR,#MSG872		; Botschaft 522 gewaehlt
	mov	CAN_BOX_6_L,#22H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_527:
	cjne	A,#14H,test_ident_528
	mov	DPTR,#MSG877		; Botschaft 527 gewaehlt
	mov	CAN_BOX_6_L,#27H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_528:
	cjne	A,#15H,test_ident_529
	mov	DPTR,#MSG878		; Botschaft 528 gewaehlt
	mov	CAN_BOX_6_L,#28H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_529:
	cjne	A,#16H,test_ident_xxx
	mov	DPTR,#MSG879		; Botschaft 529 gewaehlt
	mov	CAN_BOX_6_L,#29H	; RX-Mailbox 6 Identifier
	jmp	mode_3C_for_all_line1
test_ident_xxx:
	jmp	mode_error_ident


mode_3C_for_all_line1:

	call	save_dptr_line1		; momentan eingestellte Nummer
					; in Zeile 1 anzeigen

	mov	DPTR,#MSG605		; -  OK  +
	call	save_dptr_line2
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line3
	mov	DPTR,#MSG600		; ...
	call	save_dptr_line4

	; aktuelle Cursorzeile feststellen, wurde oben bereits 
	; festgelegt, kann bei Ausgabe auf LCD beruecksichtigt werden

	ret

	;*****

mit_bit3C:
	; hier ist der Funktionsmode aktiv, d.h. 
	; PlusMinus Tasten sollen die Werte veraendern

	jb	BUTTON_P_UP,mode_3C_mitbit_up
	jb	BUTTON_P_DOWN,mode_3C_mitbit_down
	jb	BUTTON_P_OK,mode_3C_mitbit_ok

	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_3C_mitbit_up:
	
	; Reaktion auf MINUS- Taste:
	; Achtung: Ueberlauf zu ungueltigen Zahlen verhindern.
	; --> Gueltiger Bereich momentan von 00h bis 16h

	mov	A,CAN_BOX_SWITCH
	dec	A

	cjne	A,#0FFH,mode3C_dec_overflow_no

	; "negativer Ueberlauf", also zu hoechstem Wert setzen
	
	mov	A,#16H
				
mode3C_dec_overflow_no:

	mov	CAN_BOX_SWITCH,A

	jmp	mode_3C_alle  ; Auswahl aufgrund von CAN_BOX_SWITCH
	
	;*****

mode_3C_mitbit_ok:

	; neuen CAN Identifier im EEPROM sichern

	call	task_CAN_Ausgabe_in_EEPROM

        ; Funktionsmode beenden, also Bit BITS.1 loeschen
       
        clr     BITS.1
        
        ; zurueck zu MODE 00

        mov	LCD_MENU_MODE_NR,#00H
	call	set_cursor_line1
	jmp	mode_00_alle			; Texte von
						; Mode 00 ausgeben
	;*****

mode_3C_mitbit_down:

	; Reaktion auf PLUS- Taste:
	; Achtung: Ueberlauf zu ungueltigen Zahlen verhindern.
	; --> Gueltiger Bereich momentan von 00h bis 16h

	mov	A,CAN_BOX_SWITCH
	inc	A

	cjne	A,#17H,mode3C_inc_overflow_no

	; "positiver Ueberlauf", also zu kleinstem Wert setzen
	
	mov	A,#00H
				
mode3C_inc_overflow_no:

	mov	CAN_BOX_SWITCH,A

	jmp	mode_3C_alle       ; Auswahl aufgrund von CAN_BOX_SWITCH

;*****************************************************************************

mode_40:
	; hier Taste und Aktion feststellen
	jb	BUTTON_P_UP,mode_40_up
	jb	BUTTON_P_DOWN,mode_40_down
	jb	BUTTON_P_OK,mode_40_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_40_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_40_up_test_2	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_00_alle
							
mode_40_up_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_40_up_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 1 setzen und Menuemode 40 lassen
	mov	LCD_MENU_MODE_NR,#10H
	call	set_cursor_line1
	jmp	mode_00_alle

mode_40_up_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_40_up_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 40 lassen
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle

mode_40_up_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_40_error	; Zeile 4 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 40 lassen
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle		; nochmal Texte von Mode 00
					; ausgeben

	;*****

mode_40_ok:
	; neues Auswahlmenue praesentieren,
	; in Zeile 1 gehen und zu Mode 48 wechseln
	
	mov	LCD_MENU_MODE_NR,#48H
	call	set_cursor_line1

	jmp	mode_40_alle

	;*****

mode_40_error:

	jmp	mode_error

	;*****

mode_40_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_40_down_test_2	; Zeile 1 ?
	; ja, Cursor in Zeile 2 setzen und Menuemode 20
	mov	LCD_MENU_MODE_NR,#20H
	call	set_cursor_line2
	jmp	mode_00_alle	
							
mode_40_down_test_2:
	jnb	LCD_MENU_CONTROL.1,mode_40_down_test_3	; Zeile 2 ?
	; ja, Cursor in Zeile 3 setzen und Menuemode 30
	mov	LCD_MENU_MODE_NR,#30H
	call	set_cursor_line3
	jmp	mode_00_alle

mode_40_down_test_3:
	jnb	LCD_MENU_CONTROL.2,mode_40_down_test_4	; Zeile 3 ?
	; ja, Cursor in Zeile 4 setzen und Menuemode 40
	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle

mode_40_down_test_4:
	jnb	LCD_MENU_CONTROL.3,mode_40_error	; Zeile 4 ?

	; ja, scrollen und neuen Menuemode einstellen
	; noch nicht implementiert, bleibt auf Zeile 4

	mov	LCD_MENU_MODE_NR,#40H
	call	set_cursor_line4
	jmp	mode_00_alle			; nochmal Texte von
						; Mode 00 ausgeben
	
	;*****

mode_40_alle:

	; vier LCD- Zeilen eintragen

	mov	DPTR,#MSG641		; Uhrzeit / Datum
	call	save_dptr_line1	
	mov	DPTR,#MSG642		; Temperatur aussen
	call	save_dptr_line2
	mov	DPTR,#MSG643		; Temperatur innen
	call	save_dptr_line3
	mov	DPTR,#MSG644		; Volt / Ampere
	call	save_dptr_line4

	ret

	;*****

mode_40_rotated1:

	; vier LCD- Zeilen eintragen
	; Auswahl um eine Zeile nach unten rotiert

	mov	DPTR,#MSG642		; Temperatur aussen
	call	save_dptr_line1	
	mov	DPTR,#MSG643		; Temperatur innen
	call	save_dptr_line2
	mov	DPTR,#MSG644		; Volt / Ampere
	call	save_dptr_line3
	mov	DPTR,#MSG645		; Ladelufttemperatur
	call	save_dptr_line4

	ret

	;*****

mode_40_rotated2:

	; vier LCD- Zeilen eintragen
	; Auswahl um zwei Zeilen nach unten rotiert

	mov	DPTR,#MSG643		; Temperatur innen
	call	save_dptr_line1	
	mov	DPTR,#MSG644		; Volt / Ampere
	call	save_dptr_line2
	mov	DPTR,#MSG645		; Ladelufttemperatur
	call	save_dptr_line3
	mov	DPTR,#MSG646		; Ladedruck
	call	save_dptr_line4

	ret

	;*****

mode_40_rotated3:

	; vier LCD- Zeilen eintragen
	; Auswahl um drei Zeilen nach unten rotiert

	mov	DPTR,#MSG644		; Volt / Ampere
	call	save_dptr_line1	
	mov	DPTR,#MSG645		; Ladelufttemperatur
	call	save_dptr_line2
	mov	DPTR,#MSG646		; Ladedruck
	call	save_dptr_line3
	mov	DPTR,#MSG647		; Oeltemperatur
	call	save_dptr_line4

	ret
	;*****

mode_40_rotated4:

	; vier LCD- Zeilen eintragen
	; Auswahl um drei Zeilen nach unten rotiert

	mov	DPTR,#MSG645		; Ladelufttemperatur
	call	save_dptr_line1	
	mov	DPTR,#MSG646		; Ladedruck
	call	save_dptr_line2
	mov	DPTR,#MSG647		; Oeltemperatur
	call	save_dptr_line3
	mov	DPTR,#MSG648		; Oeldruck
	call	save_dptr_line4

	ret

;*****************************************************************************

mode_48: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_48_up
	jb	BUTTON_P_DOWN,mode_48_down
	jb	BUTTON_P_OK,mode_48_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_48_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_48_error	; Zeile 1 ?
	; ja, tue nichts weil am oberen Anschlag
	jmp	mode_40_alle
							
	;*****

mode_48_ok:

	mov	A,#TASKNUMMER_DCF77	; entspricht Datum und Zeitangabe
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_alle

	;*****

mode_48_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.0,mode_48_error	; Zeile 1 ?
	mov	LCD_MENU_MODE_NR,#49H
	call	set_cursor_line2
	jmp	mode_40_alle	
							
	;*****

mode_48_error:

	jmp	mode_error

;*****************************************************************************

mode_49: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_49_up
	jb	BUTTON_P_DOWN,mode_49_down
	jb	BUTTON_P_OK,mode_49_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_49_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.1,mode_49_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#48H
	call	set_cursor_line1
	jmp	mode_40_alle
							
	;*****

mode_49_ok:

	mov	A,#TASKNUMMER_TEMP_OUT	; entspricht Aussentemperaturanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_alle

	;*****

mode_49_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.1,mode_49_error	; Zeile 2 ?
	mov	LCD_MENU_MODE_NR,#4AH
	call	set_cursor_line3
	jmp	mode_40_alle	
							
	;*****

mode_49_error:

	jmp	mode_error

;*****************************************************************************

mode_4A: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4A_up
	jb	BUTTON_P_DOWN,mode_4A_down
	jb	BUTTON_P_OK,mode_4A_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4A_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#49H
	call	set_cursor_line2
	jmp	mode_40_alle
							
	;*****

mode_4A_ok:

	mov	A,#TASKNUMMER_TEMP	; entspricht Innentemperaturanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_alle

	;*****

mode_4A_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4A_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4BH
	call	set_cursor_line3
	jmp	mode_40_rotated1	
							
	;*****

mode_4A_error:

	jmp	mode_error

;*****************************************************************************

mode_4B: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4B_up
	jb	BUTTON_P_DOWN,mode_4B_down
	jb	BUTTON_P_OK,mode_4B_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4B_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4B_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4AH
	call	set_cursor_line3
	jmp	mode_40_alle
							
	;*****

mode_4B_ok:

	mov	A,#TASKNUMMER_VOLTAMP	; entspricht Volt / Ampereanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_rotated1

	;*****

mode_4B_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4B_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4CH
	call	set_cursor_line3
	jmp	mode_40_rotated2	
							
	;*****

mode_4B_error:

	jmp	mode_error

;*****************************************************************************

mode_4C: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4C_up
	jb	BUTTON_P_DOWN,mode_4C_down
	jb	BUTTON_P_OK,mode_4C_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4C_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4C_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4BH
	call	set_cursor_line3
	jmp	mode_40_rotated1
							
	;*****

mode_4C_ok:

	mov	A,#TASKNUMMER_LLK_TEMP	; entspricht Ladelufttemperaturanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_rotated2

	;*****

mode_4C_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4C_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4DH
	call	set_cursor_line3
	jmp	mode_40_rotated3	
							
	;*****

mode_4C_error:

	jmp	mode_error

;*****************************************************************************

mode_4D: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4D_up
	jb	BUTTON_P_DOWN,mode_4D_down
	jb	BUTTON_P_OK,mode_4D_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4D_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4D_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4CH
	call	set_cursor_line3
	jmp	mode_40_rotated2
							
	;*****

mode_4D_ok:

	mov	A,#TASKNUMMER_LLK_DRUCK	; entspricht Ladedruckanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_rotated3

	;*****

mode_4D_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4D_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4EH
	call	set_cursor_line3
	jmp	mode_40_rotated4	
							
	;*****

mode_4D_error:

	jmp	mode_error

;*****************************************************************************

mode_4E: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4E_up
	jb	BUTTON_P_DOWN,mode_4E_down
	jb	BUTTON_P_OK,mode_4E_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4E_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4E_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4DH
	call	set_cursor_line3
	jmp	mode_40_rotated3
							
	;*****

mode_4E_ok:

	mov	A,#TASKNUMMER_OELTEMP	; entspricht Oeltemperaturanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_rotated4

	;*****

mode_4E_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.2,mode_4E_error	; Zeile 3 ?
	mov	LCD_MENU_MODE_NR,#4FH
	call	set_cursor_line4
	jmp	mode_40_rotated4	
							
	;*****

mode_4E_error:

	jmp	mode_error

;*****************************************************************************

mode_4F: 
	; Anzeigenauswahl: Bei O.K. die gewuenschte Funktion eintragen

	; hier Taste und Aktion feststellen

	jb	BUTTON_P_UP,mode_4F_up
	jb	BUTTON_P_DOWN,mode_4F_down
	jb	BUTTON_P_OK,mode_4F_ok
	
	jmp	mode_error		; Fehlermeldung ausgeben

	;*****

mode_4F_up:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.3,mode_4F_error	; Zeile 4 ?
	mov	LCD_MENU_MODE_NR,#4EH
	call	set_cursor_line3
	jmp	mode_40_rotated4
							
	;*****

mode_4F_ok:

	mov	A,#TASKNUMMER_LLK_DRUCK	; entspricht Ladedruckanzeige
	call	task_new_and_rotate	; in Zeile 1 eintragen, andere rotieren

	call	task_new_in_EEPROM	; die neue Zeileninhalte (Tasknummern) 
					; in EE sichern
	jmp	mode_40_rotated4

	;*****

mode_4F_down:
	; Cursorzeile feststellen
	jnb	LCD_MENU_CONTROL.3,mode_4F_error	; Zeile 4 ?
	; tue nix, ist schon unten
	jmp	mode_40_rotated4	
							
	;*****

mode_4F_error:

	jmp	mode_error

;*****************************************************************************

mode_error:
	mov	ERROR,#EW_MODE_UNKNOWN
	call	errorcode_out		 ; Fehlermeldung generieren
					 ; weil unbekannter Menuemode
menu_end:
	ret				 ; beenden von "call menu"

;*****************************************************************************

mode_error_ident:

	mov	ERROR,#EW_IDENT_UNKNOWN
	call	errorcode_out		 ; Fehlermeldung generieren
					 ; weil unbekannter Menuemode
	ret

;*****************************************************************************
	; Diese Unterfunktion prueft, ob die Ergebnisse eines Tasks aktuell 
	; am LCD angezeigt werden (sollen). Wenn ja, wird das Update- Flag 
	; gesetzt.

	; Eingangswerte: in A ist die Nummer des zu findenden Tasks
	; Funktion: Wird die Tasknummer in einer Zeile gefunden, wird das 
	;           Update- Flag (MSB) gesetzt.
	;           Ist die Tasknummer nicht dabei wird der Akku gelöscht
	;	    (ansonsten bleibt die Tasknummer drin)
	; Ausgangswerte: Akku bleibt wie uebergeben (dann wurde UpdateFlag
	;                gesetzt fuer diesen Task.
	;		 Akku auf Null wenn Tasknummer nicht gefunden
	;		 in den vier auszugebenden Zeilen.

	; !! jmp test_end wurde auskommentiert damit es möglich ist 
	;    zweimal dasselbe anzuzeigen (in zwei Zeilen der Standardanzeige,
	;    sonst wird nur eine davon aktualisiert)

task_check_update:
	
test_l1:
	cjne	A,LCD_DATA_TASK_L1,test_l2	; Tasknummer Line 1 / Update Flag
	setb	LCD_DATA_TASK_L1.7		; MSB setzen (Update-Flag)
;	jmp	test_end
test_l2:
	cjne	A,LCD_DATA_TASK_L2,test_l3
	setb	LCD_DATA_TASK_L2.7		; MSB setzen (Update-Flag)
;	jmp	test_end
test_l3:
	cjne	A,LCD_DATA_TASK_L3,test_l4
	setb	LCD_DATA_TASK_L3.7		; MSB setzen (Update-Flag)
;	jmp	test_end
test_l4:
	cjne	A,LCD_DATA_TASK_L4,nixfound
	setb	LCD_DATA_TASK_L4.7		; MSB setzen (Update-Flag)
;	jmp	test_end
nixfound:
	mov	A,#00H				; Akku loeschen als Zeichen 
						; daß Task nicht dabei war

test_end:
	ret

;*****************************************************************************
	; Diese Unterfunktion prueft, ob ein angegebener Task momentan
	; am LCD ausgegeben wird. Wenn ja, wird das Update- Flag gesetzt.

	; Eingangswerte: in A ist die Nummer des zu pruefenden Tasks
	; Funktion: Wird die Tasknummer gefunden, wird das Update- Flag (MSB) 
	;           gesetzt.
	;           Ist die Tasknummer nicht gleich wird der Akku gelöscht
	;	    (ansonsten bleibt die Tasknummer drin)
	; Ausgangswerte: Akku bleibt wie uebergeben (dann wurde UpdateFlag
	;                gesetzt fuer diesen Task.
	;		 Akku auf Null wenn Tasknummer nicht gefunden

taskx_check_update:
	
	cjne	A,LCD_XDATA_TASK,nixfoundx	; Tasknummer / Update Flag
	setb	LCD_XDATA_TASK.7		; MSB setzen (Update-Flag)
	jmp	testx_end

nixfoundx:
	mov	A,#00H				; Akku loeschen als Zeichen 
						; daß Task nicht aktuell ist
testx_end:
	ret

;*****************************************************************************
	; Diese Unterfunktion traegt im Standardausgabemodus eine neue 
	; Tasknummer in Zeile 1 ein und rotiert die alten nach unten

	; Die neue Tasknummer fuer Zeile 1 wird in A uebergeben.

	; Die Updateflags aller Zeilen (Tasks) werden gesetzt.

task_new_and_rotate:

	mov	B,A		; neue Tasknummer in B sichern

	; Zeile 3 nach Zeile 4

	mov	A,LCD_DATA_TASK_L3	; Tasknummern tauschen
	mov	LCD_DATA_TASK_L4,A	
	setb	LCD_DATA_TASK_L4.7	; Updateflag setzen

	; Zeile 2 nach Zeile 3

	mov	A,LCD_DATA_TASK_L2	; Tasknummern tauschen
	mov	LCD_DATA_TASK_L3,A	
	setb	LCD_DATA_TASK_L3.7	; Updateflag setzen

	; Zeile 1 nach Zeile 2

	mov	A,LCD_DATA_TASK_L1	; Tasknummern tauschen
	mov	LCD_DATA_TASK_L2,A	
	setb	LCD_DATA_TASK_L2.7	; Updateflag setzen

	; neue Tasknummer in Zeile 1

	mov	LCD_DATA_TASK_L1,B	; Tasknummer eintragen
	setb	LCD_DATA_TASK_L1.7	; Updateflag setzen
	ret


;*****************************************************************************
	; Diese Unterfunktion setzt den Cursor auf eine Zeile des Menues
	; indem sie den Zeilenmerker setzt in LCD_MENU_CONTROL[3..0]

set_cursor_line1:

	setb	LCD_MENU_CONTROL.0
	clr	LCD_MENU_CONTROL.1
	clr	LCD_MENU_CONTROL.2
	clr	LCD_MENU_CONTROL.3
	ret

set_cursor_line2:

	setb	LCD_MENU_CONTROL.1
	clr	LCD_MENU_CONTROL.0
	clr	LCD_MENU_CONTROL.2
	clr	LCD_MENU_CONTROL.3
	ret

set_cursor_line3:

	setb	LCD_MENU_CONTROL.2
	clr	LCD_MENU_CONTROL.1
	clr	LCD_MENU_CONTROL.0
	clr	LCD_MENU_CONTROL.3
	ret

set_cursor_line4:

	setb	LCD_MENU_CONTROL.3
	clr	LCD_MENU_CONTROL.1
	clr	LCD_MENU_CONTROL.2
	clr	LCD_MENU_CONTROL.0
	ret

;*****************************************************************************
	; Diese Unterfunktion traegt die ausgewaehlten Tasknummern fuer die
	; Standardausgabe ins EEPROM ein um sie zu sichern

task_new_in_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_1	; Platz fuer Zeile 1 Task
	mov	I2C_DATA,LCD_DATA_TASK_L1	; Tasknummer eintragen
	call	write_byte

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_2	; Platz fuer Zeile 2 Task
	mov	I2C_DATA,LCD_DATA_TASK_L2	; Tasknummer eintragen
	call	write_byte

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_3	; Platz fuer Zeile 3 Task
	mov	I2C_DATA,LCD_DATA_TASK_L3	; Tasknummer eintragen
	call	write_byte

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_4	; Platz fuer Zeile 4 Task
	mov	I2C_DATA,LCD_DATA_TASK_L4	; Tasknummer eintragen
	call	write_byte

	ret

;*****************************************************************************
	; Diese Unterfunktion traegt in den EEPROM Merker den neu 
	; ausgewaehlten Identifier fuer die CAN- Datenausgabe ein

task_CAN_Ausgabe_in_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_CAN_BOX_SWITCH	; Platz fuer Identifier
	mov	I2C_DATA,CAN_BOX_SWITCH		; Kennung eintragen
	call	write_byte

	mov	I2C_ADR_L,#EE_CAN_BOX_6_L	; Platz fuer Identifier
	mov	I2C_DATA,CAN_BOX_6_L		; Kennung eintragen
	call	write_byte

	ret

;*****************************************************************************
	; Diese Unterfunktion traegt in den EEPROM Merker fuer das D+
	; Schaltverhalten "SOMMER" ein

task_DPLUSSommer_in_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_DPLUS_SOWI	; Platz fuer D+ Merker
	mov	I2C_DATA,#DPLUS_SOMMER		; Kennung eintragen
	call	write_byte

	ret

;*****************************************************************************
	; Diese Unterfunktion traegt in den EEPROM Merker fuer das D+
	; Schaltverhalten "WINTER" ein

task_DPLUSWinter_in_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_DPLUS_SOWI	; Platz fuer D+ Merker
	mov	I2C_DATA,#DPLUS_WINTER		; Kennung eintragen
	call	write_byte

	ret

;*****************************************************************************
	; Diese Unterfunktion liest die Default-Tasknumnmern fuer die
	; Standardausgabe vom EEPROM und traegt sie als aktuelle Nummer ein.
	; Updateflags werden gesetzt

task_default_from_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_MENU_DEF_LINE_1	; Platz fuer Zeile 1 Task
	call	read_random
	mov	LCD_DATA_TASK_L1,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_DEF_LINE_2	; Platz fuer Zeile 2 Task
	call	read_random
	mov	LCD_DATA_TASK_L2,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_DEF_LINE_3	; Platz fuer Zeile 3 Task
	call	read_random
	mov	LCD_DATA_TASK_L3,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_DEF_LINE_4	; Platz fuer Zeile 4 Task
	call	read_random
	mov	LCD_DATA_TASK_L4,I2C_DATA	; Tasknummer eintragen

	setb	LCD_DATA_TASK_L4.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L3.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L2.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L1.7	; Updateflag setzen

	call	task_new_in_EEPROM	; neue Nummern auch im EEPROM
					; sichern fuer naechsten Neustart
	ret

;*****************************************************************************
	; Diese Unterfunktion liest in Init die Soll- Tasknumnmern fuer die
	; Standardausgabe vom EEPROM und traegt sie als aktuelle Nummer ein.
	; Updateflags werden gesetzt

task_std_from_EEPROM:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_1	; Platz fuer Zeile 1 Task
	call	read_random
	mov	LCD_DATA_TASK_L1,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_2	; Platz fuer Zeile 2 Task
	call	read_random
	mov	LCD_DATA_TASK_L2,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_3	; Platz fuer Zeile 3 Task
	call	read_random
	mov	LCD_DATA_TASK_L3,I2C_DATA	; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_MENU_STD_LINE_4	; Platz fuer Zeile 4 Task
	call	read_random
	mov	LCD_DATA_TASK_L4,I2C_DATA	; Tasknummer eintragen

	setb	LCD_DATA_TASK_L4.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L3.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L2.7	; Updateflag setzen
	setb	LCD_DATA_TASK_L1.7	; Updateflag setzen

	ret

;*****************************************************************************
	; Diese Unterfunktion liest in Init den SOLL- Identifier fuer die
	; CAN- Datenausgabe vom EEPROM

task_can_box_switch_from_EE:

	mov	I2C_ID,#EE_ID

	mov	I2C_ADR_L,#EE_CAN_BOX_SWITCH	; Platz fuer Identifier
	call	read_random
	mov	CAN_BOX_SWITCH,I2C_DATA		; Tasknummer eintragen

	mov	I2C_ADR_L,#EE_CAN_BOX_6_L	; Platz fuer Identifier
	call	read_random
	mov	CAN_BOX_6_L,I2C_DATA		; Tasknummer eintragen

	ret

;*****************************************************************************
; ENDE DES QUELLTEXTES
;*****************************************************************************

